banner
innei

innei

写代码是因为爱,写到世界充满爱!
github
telegram
twitter

自建 Drone を GitHub にバインドして CI/CD を実現する

群友が言うには、私のサイトへのアクセスが遅すぎるとのことです。

Vercel にデプロイされていて、API インターフェースが国内にあるため、Zero を通してもう一層重ねているので、国内からのアクセスは確かにあまり良くありません。

国内にミラーサイトを作ることを考えています。

元々Kami は GitHub Actions を使っていて、リリースを発行して成果物をリリースに公開し、SSH でサーバーに接続してから GitHub リリースを取得していましたが、今は国内のサーバーから GitHub にアクセスするのが本当に遅くなっており、主要な国内のアクセラレーションサイトも次々にダウンしています。

そこで、家庭用の小型サーバーを利用してローカルデプロイを行い、最終的な成果物をクラウドサーバーにプッシュすることを考えています。

群友に聞いたところ、Drone CI は良い選択肢のようです。Go で書かれていて、比較的速くて軽量で、GitHub と非常に簡単に連携できます。

全体の流れは以下のようになります:

Mermaid Loading...

流れは比較的シンプルです。次に、ゼロから 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 アプリを作成する必要もあります。

参考:

Runner を忘れないでください。私は Runner の設定を忘れたため、CI がずっと Loading 状態でした。

Drone と GitHub を接続するにはドメイン名が必要です(ドメインがない場合は、内部 IP の方法を試すことができます)。OAuth の方式で、認証が成功した後は設定したアドレスにリダイレクトされます。私の場合は drone.innei.in です。以降はこれに従います。

公開トンネル#

上記の設定を行った後、内部ネットワークの 10.0.0.47 でログインしようとすると、ログインできません。GitHub OAuth を通過すると、設定した drone.innei.in に戻りますが、このアドレスはまだ設定していません。

私はCloudflare Zero Trustを使用してトンネルを開通させました。非常に便利です。

image

これで完了です。

image

入ると、パネルは空っぽです。これは問題ありません。これで 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 を開いてそれを有効にします。

image

私はここで、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 周目を試みました😂。

image

成果物の設定#

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

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。