GitHub Actionsでさくらインターネットの共有サーバにデプロイ
GitHub Actionsを使って、RemixのSPAモードで作ったサイトをサーバにアップする。
GitHub Actionsでやりたいのは、
- masterリポジトリにpushした時に実行
- package.jsonに設定したVoltaのNode、Yarnのバージョンを使ってインストール
- Yarnでインストールしたパッケージはキャッシュしておく
- 構文チェックと型チェック
- RemixをビルドしてSPA化する
- さくらインターネットの共有サーバーにSFTPを使ってアップロード
VoltaでNodeとYarnのバージョンを固定
Voltaを使うことで、NodeとYarnのバージョンを指定できるので、このバージョンを使ってGitHub Actionsでも動かす。
"volta": {
"node": "20.18.3",
"yarn": "4.7.0"
}
「volta-cli/action」アクションを使うことで、package.jsonのバージョンを拾ってインストールしてくれる。
- name: Setup Node
uses: volta-cli/action@v4
with:
package-json-path: 'package.json'
少しでも速く動かすためにパッケージのデータをキャッシュしておく。YarnのPnPモードを使っているので、Yarnのcacheディレクトリをキャッシュ。
- name: Get yarn cache directory path
id: yarn-cache-path
run: echo "cache=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- name: Cache Dependency
uses: actions/cache@v4
id: cache_dependency
with:
path: ${{ steps.yarn-cache-path.outputs.cache }}
key: ${{ runner.os }}-build-${{ hashFiles('yarn.lock') }}
- name: Install Dependency
run: yarn install --immutable
Remixのアプリをビルド
続いて、lintとtypecheck実行後にRemixのアプリをビルドする。するとbuild/client以下に出力されるので、これをアップロードすればいいようだ。
この時にRemix側に渡したい環境変数も設定する。
- name: Lint
if: ${{ !env.ACT }}
run: |
yarn run lint
yarn run typecheck
- name: Build
if: ${{ !env.ACT }}
run: |
cat <<EOF > ./build/htaccess
SetEnv RECAPTCHA_SECRET_KEY ${{ secrets.RECAPTCHA_SECRET_KEY }}
EOF
env:
VITE_CONTACT_URL: ${{ vars.VITE_CONTACT_URL }}
VITE_RECAPTCHA_SITE_KEY: ${{ vars.VITE_RECAPTCHA_SITE_KEY }}
VITE_GA_TRACKING_ID: ${{ vars.VITE_GA_TRACKING_ID }}
さくらインターネットの共有サーバにSFTPでアップロード
あとはサーバにアップロードすればいいだけだが、さくらインターネットの設定で「国外IPアドレスフィルター」を有効にしている場合、GitHub Actions側からFTPに接続できないので注意が必要だ。
無効にすればアクセスできるようにはなるが、セキュリティが落ちるのであまりよくない気もする。SSH接続はアクセス制限の対象外となるので、無効にしなくてもSFTPを利用することで回避できそう。
まずは、さくらインターネットの管理画面にあるSSH公開鍵の設定から、公開鍵を追加する。この時に作成した鍵を使ってGitHub Actions側から接続する。リポジトリSecretsにFTP情報やアップロード先、秘密鍵なんかを設定しておく。
アップロードする処理は、パーミッションやディレクトリも設定したかったのでlftpを使う。ここで別途作成したlftpを使うためのアクションを使用する。
https://github.com/pontago/lftp-deploy-action
- name: Upload Files
uses: pontago/lftp-deploy-action@master
with:
debug: false
dry_run: false
protocol: sftp
host: ${{ secrets.FTP_SERVER }}
username: ${{ secrets.FTP_USERNAME }}
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
local_dir: ./build/client/
remote_dir: ${{ secrets.FTP_UPLOAD_DIRECTORY }}
script: |
cd ${{ secrets.FTP_UPLOAD_DIRECTORY }}
mkdir -p -f php
put ./backend/app/contact.php -o php/
chmod 600 php/contact.php
put ./build/htaccess -o php/.htaccess
chmod 600 php/.htaccess
自分でシェルスクリプトを作ってアップロードする方法もある。
- name: Upload Files
run: |
which lftp || sudo apt-get update -y && sudo apt-get install lftp -y
sh ./.github/upload.sh
env:
FTP_SERVER: ${{ secrets.FTP_SERVER }}
FTP_USERNAME: ${{ secrets.FTP_USERNAME }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
FTP_UPLOAD_DIRECTORY: ${{ secrets.FTP_UPLOAD_DIRECTORY }}
RECAPTCHA_SECRET_KEY: ${{ secrets.RECAPTCHA_SECRET_KEY }}
#!/bin/bash -l
set -eux
TEMP_SSH_PRIVATE_KEY_FILE='../private_key.pem'
TEMP_HTACCESS_FILE='../htaccess'
printf "%s" "$SSH_PRIVATE_KEY" >$TEMP_SSH_PRIVATE_KEY_FILE
chmod 600 $TEMP_SSH_PRIVATE_KEY_FILE
cat <<EOF > $TEMP_HTACCESS_FILE
SetEnv RECAPTCHA_SECRET_KEY $RECAPTCHA_SECRET_KEY
EOF
echo 'Uploading files to server...'
lftp <<EOS
set sftp:connect-program 'ssh -a -x -o StrictHostKeyChecking=no -i $TEMP_SSH_PRIVATE_KEY_FILE'
open sftp://$FTP_USERNAME:dummy@$FTP_SERVER
mirror --reverse --overwrite ./build/client/ $FTP_UPLOAD_DIRECTORY
mkdir -p ${FTP_UPLOAD_DIRECTORY}php
put ./backend/app/contact.php -o ${FTP_UPLOAD_DIRECTORY}php/
chmod 600 ${FTP_UPLOAD_DIRECTORY}php/contact.php
put $TEMP_HTACCESS_FILE -o ${FTP_UPLOAD_DIRECTORY}php/.htaccess
chmod 600 ${FTP_UPLOAD_DIRECTORY}php/.htaccess
close
EOS
echo 'Files uploaded successfully!'
exit 0
GitHub Actionsをローカルでテスト
workflowを設定してみたものの上手く動かないこともあった。そのたびにコミットしてやり直していては効率が悪い。
ローカルでテストできるactというGitHub Actionsをテスト環境で動かせるものがあるので、HomeBrewからインストールできる。
brew install act
actで動かす際はコマンドの引数にテスト用のworkflowファイルを指定できたり、環境変数やSecretsも設定できる。ワークスペースに.vars、.secretsファイルを作っておけば自動で読み込んでくれる模様。
秘密鍵ファイルは別ファイルにあるので、-sオプションで割り当てる。
下記のような感じで指定して上手く動いた。SiliconMacなのでコンテナアーキテクチャの指定、終了後にコンテナを削除するように–rmを指定。.github/workflowsのworkflowをテストしたい場合は、workflowファイルの指定は必要ない。ちなみにactで動かした際は、env.ACTが自動セットされるので、このフラグをみて特定のステップをスキップさせることも可能。ジョブ単位なら-jで指定すればそれだけ動かせる。
act -b -W .github/act/test.yml -s SSH_PRIVATE_KEY="$(cat xxx.pem)" --container-architecture linux/amd64 --rm