g00ceyの技術ブログ

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の処理対象となるプロジェクトを選択し、保存
    • ss
  • 対象となるプロジェクトでdroneの定義ファイルを作成。
    • 例は後ほどに示します。
    • 実行されると、こういう風に結果が出ます。ss

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指定がなくなるし、何よりパワーがありますからね)


Share

comments powered by Disqus