Permalink: 2016-11-12 03:05:00+09:00 by ruy@ainoniwa.net in technical tags: docker systemd social:

はじめに

Dockerも当然のように使われていたりするので、さて現状ではどのように扱うのが良さそうかな、と言うところで手習いをします。

jarを置くだけで良いgitbucketを例に、

  1. Dockerfileを書いて
  2. docker-compose.ymlを書いて
  3. systemdのユーザーモードで動かしてみる

ところまでやってみます。

システムセットアップ

Ubuntu server 16.04.1 amd64をインストールしました。

そして適当にアップデート。

$ sudo apt update
$ sudo apt upgrade -y

Dockerとdocker-composeの導入

まずはDockerサービスとPythonの基本セットをインストールして、一般ユーザーをdockerグループに所属させます。

$ sudo apt install -y docker.io python-virtualenv
$ sudo usermod -aG docker $USER
$ virtualenv docker
$ source ~/docker/bin/activate
$ pip install docker-compose

Ubuntu 16.04のaptから入るdocker-composeは1.5.2なので、docker-composeのversion2フォーマットが使えません。 docker-composeのフォーマットは互換性がないので、どうせなら今のうちからversion2が使える最新版にしてしまおう、と言うことでpipから入れています。

なんとなく、まだvirtualenvの方が安定してる気がします。pyvenvを使うと一部failするぽいけど追いかけてないのです。

dockerサービスを有効にして立ち上がることを確認したら再起動。

$ sudo systemctl enable docker
$ sudo systemctl start docker
$ sudo systemctl status docker
$ sudo reboot

ちゃんと立ち上がっていれば、次からdockerにアクセスできます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

dockerコンテナの作成

ディレクトリを作ってそこで作業します。

$ source ~/docker/bin/activate
$ mkdir -p ~/docker/gitbucket
$ cd ~/docker/gitbucket

こんな感じの Dockerfile を作成します。

$ cat Dockerfile
FROM openjdk:8-jdk

MAINTAINER ruy <ruy [at] ainoniwa.net>

ADD https://github.com/gitbucket/gitbucket/releases/download/4.5/gitbucket.war /opt/gitbucket.war

RUN ln -s /opt/gitbucket_data /root/.gitbucket

VOLUME /opt/gitbucket_data

EXPOSE 8080
EXPOSE 29418

CMD ["java", "-jar", "/opt/gitbucket.war"]

次にこんな感じの docker-compose.yml を作成します。

$ cat docker-compose.yml
version: '2'

services:
  gitbucket:
    build: .
    image: ainoniwa/gitbucket:4.5
    ports:
    - "8080:8080"
    - "29418:29418"
    volumes:
    - ./gitbucket_data:/opt/gitbucket_data

そしてDockerコンテナを作成します。

$ docker-compose build

dockerコンテナの自動起動設定

systemdに登録して、自動で起動するようにします。

今回は、ユーザーをdockerグループに加えたので、どうせならユーザーモードに登録します。

$ mkdir -p ~/.config/systemd/user/
$ cat ~/.config/systemd/user/gitbucket.service
[Unit]
Description=gitbucket docker container

[Service]
Restart=always
ExecStart=/home/user/docker/bin/docker-compose -f /home/user/docker/gitbucket/docker-compose.yml up
ExecStop=/home/user/docker/bin/docker-compose -f /home/user/docker/gitbucket/docker-compose.yml stop

[Install]
WantedBy=default.target

起動します。

$ systemctl --user daemon-reload
$ systemctl --user enable gitbucket
$ systemctl --user start gitbucket

起動したらこんな感じ。

$ docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                              NAMES
38b085179522        ainoniwa/gitbucket:4.5   "java -jar /opt/gitbu"   5 minutes ago       Up 33 seconds       0.0.0.0:8080->8080/tcp, 0.0.0.0:29418->29418/tcp   gitbucket_gitbucket_1

まぁ悪くない気もする。

起動に失敗する場合は journalctl | grep docker なり、 docker-compose up でフォアグラウンド実行するなりして調べます。

Dockerサービスと権限回りで引っかかってるかもしれないので、再起動してから確認しましょう。

ユーザーモードのsystemdは、対象のユーザーの初回ログイン時にサービスが起動し、同ユーザーの最終ログアウト時に終了するようにできています。

参考: https://wiki.archlinux.org/index.php/Systemd/User#Automatic_start-up_of_systemd_user_instances

マシンの起動時にユーザーモードのsystemd(および、systemdからdocker-compose)を起動したい場合は、以下のように対象のユーザーのlingerを有効にしておく必要があります。

$ loginctl enable-linger user
==== AUTHENTICATING FOR org.freedesktop.login1.set-user-linger ===
Authentication is required to run programs as a non-logged-in user.
Authenticating as: user,,, (user)
Password:
==== AUTHENTICATION COMPLETE ===

これをしないと、ログアウトしたらユーザーモードのsystemdから起動しているdocker-composeは全て終了してしまいます。でも、GUIを使っている場合はログアウトしてもゴミが残ってしまう可能性があるので、対象ユーザーをちゃんと管理する必要がありそうです。

おわり

上手くデプロイできるアプリケーションの場合は、あまり複雑にならずに扱えそうな気がするよね。

出先でも立ち上がりが早くできるように、いくつか自分用の道具を仕込んでおきたい感じです。