Docker でGitBucket＆Jenkinsを立ち上げる


# はじめに

Docker上でGitBucketによるバージョン管理と、Jenkins+GitBucket連携による自動化の環境を立ち上げます。
近い将来、GitBucket上でレビュー、Jenkinsによるビルド、textlint、PDF化などを自動実行するなどテキストベースの開発環境を整え、Copilotもフル活用し、生産性UPしようと目論んでいます。その実験環境を作ります。

OSのアップデートが開発環境に及ぼす影響を可能な限り抑えたいという考えから、Dockerでサーバアプリケーションを実行します。

ベースとなるPCのセットアップは、下記の記事で紹介しています。

https://qiita.com/triple3packun/items/69b5e08876245976c713

# GitBucket on Docker

Dockerコンテナ上で動作するGitBucketを準備します。
GitBucketで保管するデータは、容量が多くなることやハード移行などを見越し、サブストレージに保管します。

## インストール

GitBucket用のユーザを作成し、GitBucketをユーザのサービスのような立ち位置でマシン起動時に実行されるように設定します。作成するユーザには sudoを許可せず、ファイルのアクセス権も最小限にします。

:::note info
* サブストレージのパス `/mnt/hdd1` は適宜変更します
* gitbucketコンテナの自動起動のテストのため最後rebootしていますが、必須ではないです
:::

```bash
sudo useradd -m -U -s /bin/bash gitbucket
sudo passwd gitbucket
# パスワードを入力
sudo gpasswd -a gitbucket docker
sudo mkdir -p /mnt/hdd1/gitbucket_data
sudo chown gitbucket:gitbucket /mnt/hdd1/gitbucket_data
su - gitbucket
# パスワードを入力
docker run -d -p 18080:8080 -v /mnt/hdd1/gitbucket_data:/gitbucket --restart unless-stopped gitbucket/gitbucket
docker container ls
# 下記 docker.log 参照
exit
sudo reboot
# 再起動後
docker container ls
```

```docker.log
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
85189042b4d0   gitbucket/gitbucket   "sh -c 'java -jar /o…"   8 minutes ago   Up 8 minutes   29418/tcp, 0.0.0.0:18080->8080/tcp, :::18080->8080/tcp   nostalgic_colden
```

:::note info
`--restart unless-stopped` を指定するとPCを起動するなどDocker daemonが起動したとき、GitBucketが落ちたときに再起動します。
:::

再起動後、Firefoxなどのブラウザで `http://localhost:18080/` にアクセスし、GitBucketのページが表示されることを確認します。
また、実機以外から`localhost` の部分をホスト名、もしくはIPアドレスに変えてアクセスします。アクセスできない場合はファイアウォールの設定を見直します。

## 初期設定

1. Firefoxなどのブラウザで `http://localhost:18080/` にアクセス > 右上の `Sign in` > `Username` と `Password` に `root` を入力 > `Sign in`
1. 右上の `Signed is as root` > `System administration` > `root(Administrator)` の `Edit` > `Password` に新しいパスワードを入力 > `Update user`
1. `New user` > 個人アカウントの情報を入力 > `Create User`
1. 右上の `Signed is as root` > `Sign out`

:::note warn
`root` の `Mail Address` に個人メールアドレスを登録すると、本人のアカウント作成で同じメールアドレスを指定できません。
:::

# Jenkins on Docker

GitBucketと同じ構成で準備します。

## インストール

GitBucketと異なる点として、JenkinsはインターネットからPluginをダウンロードし、インストールすることができます。インストールはJenkinsのソフトウェア内で操作できるようになっているため、プロキシの設定をDockerイメージに加えます。
また、Jenkinsはビルドや静的解析などを代行するソフトウェアであり、処理に必要なツール類をDockerコンテナで実行されるJenkinsから操作できなければなりません。ツールをJenkinsのDockerコンテナにインストールすると、ツール間の依存関係が生じます。この課題は、dind(docker-in-docker)とdood(docker-outside-of-docker)と呼ばれるDockerコンテナから別のDockerコンテナを操作する技術を使用し解決します。このために、DockerイメージにDockerをインストールします。

:::note info
* サブストレージのパス `/mnt/hdd1` は適宜変更します
* ツールのインストールを操作するため、ENTRYPOINTは再設定しません
:::

```bash
sudo useradd -m -U -s /bin/bash jenkins
sudo passwd jenkins
# パスワードを入力
sudo gpasswd -a jenkins docker
sudo mkdir -p /mnt/hdd1/jenkins_data
sudo chown jenkins:jenkins /mnt/hdd1/jenkins_data
su - jenkins
# パスワードを入力
```

以下のファイルを作成します。

```file.system
docker_jenkins
├── Dockerfile
├── build.sh
└── docker-compose.yml
```

dindもしくはdood、どちらにせよDockerが必要になるためインストールします。

```.Dockerfile
FROM jenkins/jenkins:lts-jdk17

ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG VPROXY_HOST
ARG VPROXY_PORT
ARG VPROXY_HOST_S
ARG VPROXY_PORT_S
 
ENV http_proxy ${HTTP_PROXY}
ENV https_proxy ${HTTPS_PROXY}

ENV JAVA_OPTS="-Dhttp.proxyHost="${VPROXY_HOST}" -Dhttp.proxyPort="${VPROXY_PORT}" -Dhttps.proxyHost="${VPROXY_HOST_S}" -Dhttps.proxyPort="${VPROXY_PORT_S}

USER root

RUN touch /etc/apt/apt.conf.d/90proxy && \
    echo 'Acquire::http::proxy "'${http_proxy}'";' | tee -a /etc/apt/apt.conf.d/90proxy > /dev/null && \
    echo 'Acquire::https::proxy "'${https_proxy}'";' | tee -a /etc/apt/apt.conf.d/90proxy > /dev/null && \
    echo 'Acquire::ftp::proxy "'${http_proxy}'";' | tee -a /etc/apt/apt.conf.d/90proxy > /dev/null && \
     echo 'Acquire::socks::proxy "'${http_proxy}'";' | tee -a /etc/apt/apt.conf.d/90proxy > /dev/null

RUN apt-get update && apt-get install -y apt-transport-https \
       ca-certificates curl gnupg2 \
       software-properties-common
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN apt-key fingerprint 0EBFCD88
RUN add-apt-repository \
       "deb [arch=arm64] https://download.docker.com/linux/debian \
       $(lsb_release -cs) stable"
RUN apt-get update && apt-get install -y docker.io docker-compose

USER jenkins
```

```build.sh
#!/bin/bash

vproxy_host=$(echo ${http_proxy} | sed -e 's/http:\/\///' -e 's/https:\/\///' -e 's/:[0-9]\{1,5\}//')
vproxy_port=$(echo ${http_proxy} | sed -e 's/http:\/\///' -e 's/https:\/\///' -e 's/.*://')
vproxy_host_s=$(echo ${https_proxy} | sed -e 's/http:\/\///' -e 's/https:\/\///' -e 's/:[0-9]\{1,5\}//')
vproxy_port_s=$(echo ${https_proxy} | sed -e 's/http:\/\///' -e 's/https:\/\///' -e 's/.*://')

docker-compose build \
    --build-arg HTTP_PROXY=${http_proxy} \
    --build-arg HTTPS_PROXY=${https_proxy} \
    --build-arg VPROXY_HOST=${vproxy_host} \
    --build-arg VPROXY_PORT=${vproxy_port} \
    --build-arg VPROXY_HOST_S=${vproxy_host_s} \
    --build-arg VPROXY_PORT_S=${vproxy_port_s} \
    jenkins

docker-compose run --service-ports -u $(id -u):$(id -g) jenkins
```

```docker-compose.yml
version: "3.7"
 
services:
  jenkins:
    image: jenkins_setup
    build: 
      context: ./
      dockerfile: ./Dockerfile
      args:
        - HTTP_PROXY=${http_proxy}
        - HTTPS_PROXY=${https_proxy}
        - VPROXY_HOST
        - VPROXY_PORT
        - VPROXY_HOST_S
        - VPROXY_PORT_S
    volumes:
      - type: bind
        source: /mnt/hdd1/jenkins_data
        target: /var/jenkins_home
    ports:
      - "28080:8080"
      - "50000:50000"
    restart: unless-stopped
    entrypoint: /usr/bin/tini -- /usr/local/bin/jenkins.sh
```

:::note info
Jenkins pluginをインストールしJenkinsが再起動してもコンテナが自動起動するように `restart: unless-stopped` を指定します。
:::

Dockerイメージを作成し、Dockerコンテナを起動します。

```bash
chmod +x ./build.sh
./build.sh
# 下記 docker run.log 参照
```

```docker run.log
*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

e02ba6c41d9b498097c3e612092b04b6

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************
```

初回起動時に、管理アカウントを登録します。

Firefoxなどのブラウザで `http://localhost:28080/` にアクセスし、`Administrator password` に、コンソールへ出力される `e02ba6c41d9b498097c3e612092b04b6` にあたる文字列を入力 > `Continue` > `Install suggested plugins` を選択 > `Create First Admin User` の各項目を入力 > `Continue` > `Save and Finish` > `Start using Jenkins`

:::note info
- `e02ba6c41d9b498097c3e612092b04b6` は起動する度に変わります
- `Create First Admin User` は管理者が変わる可能性を鑑みて個人に関係の無い情報を入力することが望ましいです
:::

一度 JenkisのDockerコンテナを `Ctrl + p + q` で停止し、`-d` オプションを付けて起動します。

:::note info
jenkinsコンテナの自動起動のテストのため最後rebootしていますが、必須ではありません。
:::

```bash
docker-compose run -d --service-ports -u $(id -u):$(id -g) jenkins
exit
sudo reboot
# 再起動後
docker container ls
```

```docker.log
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
bd4bfbc51127   jenkins_setup         "/usr/bin/tini -- /u…"   4 seconds ago   Up 3 seconds   8080/tcp, 50000/tcp                                      docker_jenkins_jenkins_run_c506e5d8d848
```

再起動後、Firefoxなどのブラウザで `http://localhost:28080/` にアクセスし、Jenkinsのページが表示されることを確認します。
また、実機以外から`localhost` の部分をホスト名、もしくはIPアドレスに変えてアクセスします。アクセスできない場合はファイアウォールの設定を見直します。

## 初期設定

Jenkinsに個人アカウントを追加します。

Firefoxなどのブラウザで `http://localhost:28080/` にアクセス > 管理者のユーザ名とパスワードを入力 > `サインイン` > `Jenkinsの管理` > `Users` > `Create User` > 個人アカウントの情報を入力 > `ユーザ作成`

:::note info
Jenkins内でのプロキシ設定は、Dockerのイメージに設定しているため不要です。
:::