群友が言うには、私のサイトへのアクセスが遅すぎるとのことです。
Vercel にデプロイされていて、API インターフェースが国内にあるため、Zero を通してもう一層重ねているので、国内からのアクセスは確かにあまり良くありません。
国内にミラーサイトを作ることを考えています。
元々Kami は GitHub Actions を使っていて、リリースを発行して成果物をリリースに公開し、SSH でサーバーに接続してから GitHub リリースを取得していましたが、今は国内のサーバーから GitHub にアクセスするのが本当に遅くなっており、主要な国内のアクセラレーションサイトも次々にダウンしています。
そこで、家庭用の小型サーバーを利用してローカルデプロイを行い、最終的な成果物をクラウドサーバーにプッシュすることを考えています。
群友に聞いたところ、Drone CI は良い選択肢のようです。Go で書かれていて、比較的速くて軽量で、GitHub と非常に簡単に連携できます。
全体の流れは以下のようになります:
流れは比較的シンプルです。次に、ゼロから Drone を自分で構築し、このプロセスを作成する方法を見ていきましょう。
Drone デプロイ#
Docker Compose 一発で#
全体で使用するのは:Arch Linux + Docker 環境で、他の環境は参考程度です。
公式ドキュメントは散漫に書かれているので、私は多くの落とし穴にハマりました。しかし、最終的な設定は特に難しいものではないので、ここにそのまま貼り付けます。
name: drone
services:
drone-runner:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_RPC_PROTO=https
- DRONE_RPC_HOST=drone.innei.in
- DRONE_RUNNER_CAPACITY=2
- DRONE_RUNNER_NAME=runner
- DRONE_GITHUB_CLIENT_ID=
- DRONE_GITHUB_CLIENT_SECRET=
- DRONE_RPC_SECRET=
- DRONE_SERVER_HOST=
- DRONE_SERVER_PROTO=https
ports:
- 3000:3000
restart: always
container_name: runner
image: drone/drone-runner-docker:1
drone:
volumes:
- ./data:/data
environment:
- DRONE_GITHUB_CLIENT_ID=
- DRONE_GITHUB_CLIENT_SECRET=
- DRONE_RPC_SECRET=
- DRONE_SERVER_HOST=drone.innei.in
- DRONE_SERVER_PROTO=https
- DRONE_TLS_AUTOCERT=true
- DRONE_USER_CREATE=username:innei,machine:false,admin:true
ports:
- 80:80
- 443:443
restart: always
container_name: drone
image: drone/drone:2
networks:
mvlan:
ipv4_address: 10.0.0.47
networks:
mvlan:
external: true
上記の設定で不足している環境変数はドキュメントを読んで補完する必要があります。その際に、自分の GitHub アプリを作成する必要もあります。
参考:
- https://docs.drone.io/server/provider/github/
- https://docs.drone.io/runner/docker/installation/linux/
Runner を忘れないでください。私は Runner の設定を忘れたため、CI がずっと Loading 状態でした。
Drone と GitHub を接続するにはドメイン名が必要です(ドメインがない場合は、内部 IP の方法を試すことができます)。OAuth の方式で、認証が成功した後は設定したアドレスにリダイレクトされます。私の場合は drone.innei.in です。以降はこれに従います。
公開トンネル#
上記の設定を行った後、内部ネットワークの 10.0.0.47 でログインしようとすると、ログインできません。GitHub OAuth を通過すると、設定した drone.innei.in に戻りますが、このアドレスはまだ設定していません。
私はCloudflare Zero Trustを使用してトンネルを開通させました。非常に便利です。
これで完了です。
入ると、パネルは空っぽです。これは問題ありません。これで Drone は完了しました。
Pipeline の作成#
CI を実行する必要がある GitHub リポジトリに移動し、ルートディレクトリに.drone.yml
ファイルを作成して GitHub にプッシュします。この時点で Drone はこのリポジトリを表示するはずです。入ったら、アクティブにします。
kind: pipeline
name: build-and-package
platform:
os: linux
arch: amd64
steps:
- name: build
image: node:20-alpine
commands:
- 'npm i -g pnpm'
- 'pnpm install --no-frozen-lockfile'
- 'npm run build'
このステップが成功した後は、次はパイプラインの調整を行います。
NextJS のビルド時に.env
が必要ですが、私は一つ一つをシークレットに送信したくありません。彼はバッチインポートをサポートしていません(隣の Vercel を学んでほしい)。そこで、別の方法で env を渡す方法を考えました。ここでも多くの時間を費やしました。
最初は http-server を使って.env
をホストし、ビルド時にダウンロードしようと考えましたが、内部ネットワークでリッスンしているため、相対的には安全です。後に Drone のボリュームマッピングが可能であることがわかり、今はこの方法を使用しています。
Note
ボリュームマッピングを使用するには、Trusted オプションを有効にする必要があります。
このステップを行うには、まず管理者権限を有効にする必要があります。Docker でデプロイしている場合は、ENV を Drone サーバーに追加する必要があります。DRONE_USER_CREATE=username:innei,machine:false,admin:true
username
を GitHub のユーザー名に置き換えます。
コンテナを再起動した後、再度 Drone のリポジトリ設定に入り、プロジェクト設定 - Trusted を開いてそれを有効にします。
私はここで、Drone が各ステップで Docker を実行することを選択しました。
各ステップでホストファイルパスにボリュームをマッピングできます。
プロジェクトに必要な.env
を/home/innei/docker-compose/drone/public/shiro/.env
に保存し、ビルドステップにボリュームマッピングを追加しました。
volumes:
- name: shiro-env
host:
path: /home/innei/docker-compose/drone/public/shiro/.env
steps:
- name: build
image: node:20-alpine
commands:
- 'npm i -g pnpm'
- 'pnpm install --no-frozen-lockfile'
- 'npm run build'
volumes:
- name: shiro-env
path: /drone/src/.env
ボリュームは二回書く必要があります。トップレベルのボリュームはホストの絶対パスとボリューム名を定義し、ステップでは Docker 再起動の絶対パスです。
ビルドとデプロイを二つのパイプラインに分けることができますが、前後の依存関係があります。
ビルドが完了した後、成果物を一時的に保存する必要があります。私はボリューム方式を選択し、一時的に /tmp に保存して、デプロイが成果物を取得してクラウドサーバーにプッシュできるようにします。
volumes:
- name: shiro-dist
host:
path: /tmp/shiro-dist
steps:
- name: build
image: node:20-alpine
commands:
- 'npm i -g pnpm'
- 'pnpm install --no-frozen-lockfile'
- 'npm run build'
volumes:
- name: shiro-env
path: /drone/src/.env
- name: dns
path: /etc/resolv.conf
- name: package
image: node:20-alpine
commands:
- 'pwd'
- 'ls -a'
- 'ls .next'
- 'apk add zip'
- 'sh ./standalone-bundle.sh'
volumes:
- name: shiro-dist # ここでマッピング
path: /drone/src/assets
depends_on:
- build
その後、デプロイでは scp と ssh を使用します。
kind: pipeline
name: deploy
platform:
os: linux
arch: amd64
volumes:
- name: shiro-dist
host:
path: /tmp/shiro-dist
steps:
- name: transfer file
image: appleboy/drone-scp
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
key:
from_secret: ssh_key
port: 22
target: /home/deploy/shiro
source:
- assets/release.zip
rm_target: true
strip_components: 1
debug: true
volumes:
- name: shiro-dist # ここでボリュームがビルドパイプラインの成果物を取得できます
path: /drone/src/assets
- name: deploy
image: appleboy/drone-ssh
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
key:
from_secret: ssh_key
port: 22
script:
- '\npm install --os=linux --cpu=x64 sharp --registry=https://registry.npmmirror.com'
- cd ~/shiro
- unzip -o release.zip
- rm release.zip
- ls
- cd standalone
- cp -r ~/node_modules/sharp ./node_modules
- ~/.n/bin/pm2 restart ecosystem.config.js
debug: true
depends_on:
- transfer file
depends_on:
- build-and-package # ここで依存関係があります
ssh_
に関連するものはシークレットから取得します。
これで終了です。私はこれで 40 周目を試みました😂。
成果物の設定#
https://github.com/Innei/Shiro/blob/main/.drone.yml
参考:https://www.timochan.cn/posts/jc/drone_workflows#Preface
この記事は Mix Space によって xLog に同期更新されました。元のリンクは https://innei.in/posts/Z-Turn/drone-self-host-ci-cd-with-github