備忘録。
Githubを利用するのではなく、セルフホスティングなGiteaサーバーを立て、
さらに、Drone CIと連携して自動デプロイする方法。
用意したもの
・Gitリポジトリを保管するサーバー(以下、リポジトリサーバーとします)
ここにDroneサーバを共存させます。
AlmaLinux8
・Webサーバー
自動デプロイ先のサーバー。AlmaLinux8
・独自ドメイン
Droneの立ち上げ時に必要。予めドメインの向き先をリポジトリサーバーのIPアドレスに設定しておきます。
手順は
① リポジトリサーバーにGiteaを立ち上げる
②リポジトリサーバーにDroneを立ち上げる
③Gitea⇒Droneを連携する
④Drone⇒Webサーバーを連携させる
⑤自動デプロイの動作を設定する
となります。
① Giteaを立ち上げる
Giteaの実行にはデータベースサーバーが必要なので予めインストールしておきます。ここではMySQLを選択しました。インストール手順は省略します。インストールされたら、以下のようにGitea用のデータベースとユーザーを作成します。
# mysql -u root -p
mysql > SET old_passwords=0;
mysql > CREATE USER 'gitea' IDENTIFIED BY 'password';
mysql > CREATE DATABASE gitea CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
mysql > GRANT ALL PRIVILEGES ON gitea.* TO 'gitea';
mysql > FLUSH PRIVILEGES;
次にGiteaプログラム本体をダウンロードします。
# dnf -y install wget
# wget -O gitea https://dl.gitea.com/gitea/main/gitea-main-nightly-linux-amd64
# chmod +x gitea
Giteaのプログラムを実行するためのLinuxユーザーを作成します。
# adduser --system --shell /sbin/nologin --create-home git -c /etc/gitea/app.ini
ディレクトリとファイルの所有者、権限を変更します。
# mkdir -p /var/lib/gitea/{custom,data,log}
# chown -R git:git /var/lib/gitea/
# chmod -R 750 /var/lib/gitea/
# mkdir /etc/gitea
# chown root:git /etc/gitea
# chmod 770 /etc/gitea
# chmod 750 /etc/gitea
実行ファイルを移動させます。
# cp gitea /usr/local/bin/gitea
Linuxサービスを記述するserviceファイルを作成し、内容の内容で保存します。
# vi /etc/systemd/system/gitea.service
gitea.service
[Unit]
Description=Gitea
After=syslog.target
After=network.target
After=mariadb.service
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.target
待ち受けポートはデフォルトで3000番になります。ファイアフォールを使用している場合はポートを空けておきます。
# firewall-cmd --zone=public --add-port=3000/tcp --permanent
# firewall-cmd --reload
サービスを起動させます。
# systemctl start gitea
# systemctl enable gitea
立ち上がったらウェブブラウザからhttp://[リポジトリサーバーのドメイン名またはIPアドレス]:3000/user/loginにアクセスしGitea Webインターフェースを表示します。初期設定画面が表示されるのでリポジトリサーバーの情報を入力し完了させます。
引き続き、Gitリポジトリを作成します。「新しいリポジトリ」より新規作成するか、別のサーバーから引っ越しさせることが可能です。
リポジトリが用意できたら、リポジトリにデプロイキーを設定します。デプロイキーはWebサーバーからSSHでGit pullを行うために必要です。
ウェブサーバー上で鍵ペアを用意します。
SSH鍵ペアの作成例
# ssh-keygen
# mv ./id_rsa.pub authorized_keys
# chmod 600 ./authorized_keys
~/.ssh以下にid_rsa(秘密鍵)とid_rsa.pub(公開鍵)が作成されるので、id_rsa.pubをauthorized_keysに名称変更し、さらに権限を変更します。
リポジトリの設定→デプロイキーでWebサーバーの公開鍵を登録します。
SSH接続の度に中断されないよう、先に適当なユーザーで一度接続しknown_hostsに登録させます。
# ssh alma@[リポジトリサーバーのドメイン名またはIPアドレス]
known_hostsに登録するか確認されるのでyで続行します。
gitリポジトリを取得できるか確認します。
# git clone git@[リポジトリサーバーのドメイン名またはIPアドレス]:repository_name/user-name.git
# git pull
② Droneを立ち上げる
Droneを立ち上げる前にGiteaでOAuthアプリケーションを作成します。Droneを立ち上げる際にそのIDとシークレットを埋め込む必要があるためです。
リポジトリにアクセス権限があるユーザーでGiteaにログインしユーザーの設定→アプリケーションを開きます。アプリケーション名は任意の名称、リダイレクトURIはDrone Webインターフェースのトップ画面 https://[リポジトリサーバーのドメイン名]:8080/loginとします。
アプリケーションを作成するとクライアントIDとクライアントシークレットが生成されるので、保管しておきます。
次にDroneを立ち上げます。
Droneの形態はいくつかオプションがありますがDocker上での動作を選択しました。
まず以下のコマンドでDockerをインストールします。
# dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# dnf -y install docker-ce docker-ce-cli containerd.io
# systemctl start docker
# systemctl enable docker
# docker --version
複数のコンテナを立ち上げるのに便利なDocker-composeもインストールしておきます。
# curl -L "https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# docker-compose --version
任意の場所にdocker-compose.ymlを作成し以下の内容で保存します。
# vi /home/drone/docker-compose.yml
Giteaと連携させるため、必要な変数に値を設定します。
docker-compose.yml
services:
drone-server:
image: drone/drone:2
ports:
- 8080:80
volumes:
- /var/lib/drone:/data
restart: always
environment:
- DRONE_GITEA_SERVER=https://xxx.xxx:3000
- DRONE_GITEA_CLIENT_ID=
- DRONE_GITEA_CLIENT_SECRET=
- DRONE_RPC_SECRET=
- DRONE_SERVER_HOST=xxx.xxx:8080
- DRONE_SERVER_PROTO=https
drone-ssh-runner:
image: drone/drone-runner-ssh
restart: always
depends_on:
- drone-server
environment:
- DRONE_RPC_PROTO=http
- DRONE_RPC_HOST=drone-server
- DRONE_RPC_SECRET=
DRONE_RPC_SECRETにはDrone-serverとdrone-ssh-runnerの間の認証に利用され、次のコマンドで生成することができます。
# rand -hex 16
Ee2a9ea4ab72b4767f1f97104da1e1a6
変数の内容は
DRONE_GITEA_SERVER=GiteaサーバーのURL(ポート番号有り)
DRONE_GITEA_CLIENT_ID=先ほど作成したOAuthアプリケーションのクライアントID
DRONE_GITEA_CLIENT_SECRET=先ほど作成したOAuthアプリケーションのシークレット
DRONE_RPC_SECRET=DroneサーバーとDrone Runnerの間の認証に使用するシークレット
DRONE_SERVER_HOST=Droneサーバーのドメイン名(ポート番号有り)
DRONE_SERVER_PROTO=通信プロトコル(httpsかhttp)
DRONE_RPC_HOST:Droneサーバーのコンテナ名
DRONE_RPC_PROTO:通信プロトコル(httpsかhttp)
DRONE_RPC_SECRET:DroneサーバーとDrone Runnerの間の認証に使用するシークレット
サービスは2つあり、drone-serverとdrone-ssh-runnerです。drone-serverはDroneの本体であり、Giteaと通信します。drone-ssh-runnerにはWebサーバーにSSH接続させGit pullを実行させます。
同じ階層で以下を実行しコンテナを立ち上げます。
# docker-compose up -d
立ち上がったら正常に動作しているかlogを確認します。
# docker logs drone-ssh-runner
③ Gitea⇒Droneの連携を設定する
DroneからGiteaにアクセスするため、認可を行います。認可は対象のリポジトリにアクセス権があるGiteaユーザーを介して行います。
先程OAuthアプリケーションを作成したユーザーでGiteaにログインしていることを確認します。
次にブラウザでhttp://[リポジトリサーバーのドメイン名]:8080/loginにアクセスしDroneの設定画面を開きます。
指示に従って認可操作を行います。Giteaにリダイレクトされるので、許可するとOAuth2アプリケーションは許可済みとなります。
Droneに戻るとリポジトリの一覧が表示されているのでActivateを実行します。この時点でリポジトリの設定にWebhookが自動的に追加されます。
Giteaでリポジトリの設定を確認するとWebhookが作成され、ターゲットURLが自動的に設定されていることが確認できます。ここで、Authorizationヘッダーが未設定になっているので以下のように入力します。
例: Bearer [Your personal token]
[Your personal token]の部分にDroneのトークンを入れます。またはDroneの個人ページで確認できます。
④ Drone⇒Webサーバーの連携を設定する
DroneにSSH Runner用のシークレットを登録します。SSH RunnerがWebサーバーにSSH接続するために使用されます。SSHパスワードか、公開鍵のいずれかを登録しておきます。
Droneでリポジトリの設定→Secretsを開きNew Secretsから登録します。
⑤自動デプロイの動作を設定する
Gitリポジトリの直下に.drone.ymlという名称でファイルを作成します。以下のようにパイプラインを設定します。
.drone.yml
kind: pipeline
type: ssh
name: deploy
server:
host: [webserverのドメイン名またはIPアドレス]
user: alma
password:
from_secret: [先ほど設定したsecret]
clone:
disable: true
steps:
- name: git-pull
commands:
- cd /home/repo; sudo git pull
trigger:
branch:
- master
event:
- push
password: の部分はSSHパスワードを使用する場合はpassword: 、公開鍵を使用する場合はssh_key: とします。
hostにはデプロイ対象となるサーバーのアドレスを設定します。userは任意のユーザーとします。
このパイプラインではmasterブランチにpushされた際にSSHで接続しgit pullを行います。
上記のファイルをリポジトリにpushし結果を確認します。
ウェブサーバでソースコードの更新が確認できたら成功です。うまく行かない場合はリポジトリの設定でWebhookのステータス、Droneでパイプラインのステータスを確認してみます。