DroneCI入門
DroneciでHUGOで記述したものをデプロイするまで奮闘した話です。
環境
- Raspberry Pi 4
- Raspberry Pi OS(64bit)
- droneci(docker)
ちょっとわかりにくいけど、図示してみる。
giteaでホストしているMarkdownをHUGOで記事を生成して、GCPに対してdeployを行うことを自動化したいってのが今回の話。
Dockerコンテナの状況
現在の自宅サーバー環境で動いているコンテナは下記の通り
- unbound
- giteaやdroneのLAN内でのネットワーク名解決に使用している。(docker内部ネットー枠向けの名前解決は行っていない)
- postgres
- giteaなどの情報をホストしている
- nginx
- giteaやdroneなどのリクエストを各コンテナに渡す
- gitea
- Githubの軽量OSSクローン
- registry
- Dockerのプライベートレジストリ
これに
- drone
- gitにpushされたものに応じて動くCI/CDツール
- drone-runner-docker
- 上記Droneサーバーと通信して、DinDにより、コンテナを生成してCI/CDできるようにしているものっぽい
を追加する
構成方法
docker-composeで行っています。
下記が使用しているdocker-compose.ymlです。
version: "3.7"
services:
unbound:
build:
context: ./docker/unbound
dockerfile: Dockerfile-unbound
ports:
- "53:53"
- "53:53/udp"
restart: always
volumes:
- "./unbound/unbound.conf:/tmp/unbound.conf"
entrypoint: /bin/sh -c
"
envsubst < /tmp/unbound.conf > /etc/unbound/unbound.conf
&& unbound -d
"
env_file:
- .env
network_mode: host
# networks:
# gitea:
# ipv4_address: 172.31.0.3
postgres:
image: postgres:12-alpine
restart: always
environment:
- "POSTGRES_USER=${POSTGRES_USER}"
- "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}"
- "POSTGRES_DB=${POSTGRES_DB}"
volumes:
- "db-data:/var/lib/postgresql/data"
- "./postgres:/postgres-data"
- "./gitea-dump:/gitea-dump"
- "./gitea-bin:/gitea-bin"
networks:
gitea:
ipv4_address: 172.31.0.7
env_file:
- .env
nginx:
image: nginx:mainline-alpine
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/site.conf:/etc/nginx/conf.d/site.conf
- ./auth/registry.localdomain.cert.pem:/etc/ssl/certs/registry.localdomain.cert.pem
- ./auth/registry.localdomain.key-nopass.pem:/etc/ssl/private/registry.localdomain.key-nopass.pem
depends_on:
- gitea
- drone
- registry-ui
env_file:
- .env
networks:
gitea:
ipv4_address: 172.31.0.4
# dns:
# - 172.31.0.3
gitea:
image: gitea/gitea:1.12.4
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
volumes:
- ./gitea:/data
- ./gitea-dump:/gitea-dump
- ./gitea-bin:/gitea-bin
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "222:22"
depends_on:
- postgres
links:
- postgres
env_file:
- .env
networks:
gitea:
ipv4_address: 172.31.0.5
# dns:
# - 172.31.0.3
drone:
image: drone/drone:1.9.1
restart: always
environment:
- DRONE_AGENTS_ENABLED=true
- DRONE_GITEA_SERVER=http://${GITEA_DOMAIN}/
- DRONE_RPC_SECRET=${DRONE_SECRET}
- DRONE_SERVER_HOST=${DRONE_DOMAIN}
- DRONE_SERVER_PROTO=http
- DRONE_LOGS_DEBUG=true
- DRONE_DEBUG=TRUE
- DRONE_TRACE=TRUE
env_file:
- .env
networks:
gitea:
ipv4_address: 172.31.0.6
# dns:
# - 172.31.0.3
extra_hosts:
- "gitea.localdomain:172.31.0.4"
- "drone.localdomain:172.31.0.4"
drone-runner:
image: drone/drone-runner-docker:1.5.2
volumes:
- /var/run/docker.sock:/var/run/docker.sock
container_name: runner
environment:
- DRONE_RPC_PROTO=http
- DRONE_RPC_HOST=172.31.0.6
- DRONE_RPC_SECRET=${DRONE_SECRET}
- DRONE_RUNNER_CAPACITY=4
- DRONE_RUNNER_NAME=DRONE_RUNNER
- DRONE_UI_USERNAME=root
- DRONE_UI_PASSWORD=root
- DRONE_DEBUG=TRUE
- DRONE_TRACE=TRUE
- DRONE_RPC_DUMP_HTTP=TRUE
- DRONE_RUNNER_NAME=runner
# dns:
# - 172.31.0.3
extra_hosts:
- "gitea.localdomain:172.31.0.4"
- "drone.localdomain:172.31.0.4"
networks:
gitea:
ipv4_address: 172.31.0.11
restart: always
git-mirroring:
build:
context: ./docker/mirroring
dockerfile: Dockerfile-mirroring
restart: always
volumes:
- ./git:/data
- ./git-bin:/script
- ~/.ssh:/home/workuser/.ssh
working_dir: /data
environment:
- USER_UID=1000
- USER_GID=1000
networks:
gitea:
ipv4_address: 172.31.0.8
# dns:
# - 172.31.0.3
registry:
image: registry:latest
container_name: registry
volumes:
- /opt/registry:/var/lib/registry
- ./registry-ui/config.yml:/etc/docker/registry/config.yml
restart: always
networks:
gitea:
ipv4_address: 172.31.0.10
registry-ui:
image: joxit/docker-registry-ui:arm64v8-static
networks:
gitea:
ipv4_address: 172.31.0.9
env_file:
- .env
environment:
- URL=https://registry.localdomain
# dns:
# - 172.31.0.3
restart: always
networks:
gitea:
name: gitea
driver: bridge
ipam:
driver: default
config:
- subnet: 172.31.0.0/24
volumes:
db-data:
driver: local
いろいろ試行錯誤しながら作っています。
Kubernetesに移行したいな。
作りながら記事を書こうと思いましたが、上記のymlファイルで安定稼働するまでにちょこちょことしか作業ができなかったのでハンズオン形式での記事じゃなくて、できたよどん!になっております。
作業手順
この辺結構うろ覚えです。
gitea、nginx、unboundなどの設定が完了している状態から、drone・drone-ciの設定を行う。
- droneサーバー http://drone.localdomain/にアクセス
- Gitea | Droneを見ながら行いましょう。
- 確かここですごいはまった(Gitea->DroneへのOAuth2アプリケーション追加) 確か、drone->gitea->droneみたいな感じになるんだけど、その時うまくいかなかったからdrone側にextra_hostを追加した記憶があります。(extra_hostはコピペしていったので不要なところも多いかも)
- droneでdroneの処理対象となるプロジェクトを選択し、保存
- 対象となるプロジェクトでdroneの定義ファイルを作成。
- 例は後ほどに示します。
- 実行されると、こういう風に結果が出ます。
droneの定義ファイルは下記の通り。
はまりどころは
- pi4とかはarm64なので、指定をしないとコンテナが反応してくれない。
- cloneするだけでは、submoduleはcloneしてこないので、追加でsubmoduleを追加。
いいなと思った個所は、
- droneでもsecretが定義できる => .drone.ymlに直書きとかやりたくなかった。
- 何よりガンガン回してもコンピュートタイムが増えないので素敵!
今後やりたいのは、push&debugではなく、.drone.ymlだけはローカルのものを使用して、それ以外は、指定ブランチのものを使用するとか。。。(優先度:低)
drone execでは動くのだけど、実際の挙動とは違う気がする。(CircleCIのCLIでexecしたら動かない多くの機能があるのと同様だと思う)
---
kind: pipeline
type: docker
name: default
platform:
os: linux
arch: arm64
clone:
git:
image: plugins/git
recursive: true
steps:
- name: submodules
image: registry.localdomain/alpine/git
commands:
- git submodule init
- git submodule update
- name: build_workblog
image: registry.localdomain/hugo
settings:
username: luna
password: totugeki
repo: registry.localdomain/hugo
registry: registry.localdomain
tags:
- latest
commands:
- hugo -c ./content --config ./config/pro/config.toml
- name: deploy file
image: registry.localdomain/drone-rsync
settings:
hosts: ["34.69.241.97"]
key:
from_secret: gcp_ssh_key
user: totugekiluna
source: ./public/*
target: /var/www/html/workblog
recursive: true
trigger:
branch:
- master
苦労したこと
- そもそもなんですけどprivate registryは元々ありませんでした。
- Pi4使う以上どうしてもARMなコンテナイメージを作成する必要が出てきたので追加。(パブリックだとなんだかなと思うところもあるので)
- unboundを動かしているPi4自身で名前解決できなかった。
- network_mode: host で対応
drone環境構築するときに参照したほうがいいもの
- Drone CI / CD | Drone
- ここを見て初めて気づくことがあります。
- Drone
- 困ったことがあったら検索してみると先駆者がいます。
- 検索方法: drone ci 困ったことで検索しましょう。
最後に
結構手間暇がかかった感じになりましたが、実際に動いてみると、ガンガンCICDをま和すことができるんで、CICDサーバーなんて買わないで社内においてしまってもいいんじゃないか?と思えるようなサーバーになりました。
社内等で使う場合は、AMD64とかでやったほうがいいとは思います。(platform指定がなくなるし、何よりパワーがありますからね)