インストール

dockerdocker-composeをインストールします。

Ubuntu

環境

以下の環境で実行してます。

cat /etc/lsb-release && echo ------ && arch
# DISTRIB_ID=Ubuntu
# DISTRIB_RELEASE=18.04
# DISTRIB_CODENAME=bionic
# DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
# ------
# x86_64

インストールコマンド

# Docker インストール
curl -fsSL get.docker.com | sh

# Docker Compose インストール
curl -L https://github.com/docker/compose/releases/download/`curl -fsS https://api.github.com/repos/docker/compose/releases | grep '"tag_name":' | xargs -n 2 | cut -d ' ' -f2 | sed 's/,//' | grep -v rc | head -n1`/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose \
  && chmod 755 /usr/local/bin/docker-compose

# dockerグループ編集
usermod -aG docker <user>

# ubuntu@14.04 だとサービスが起動していなかったので必要かも?
service docker start

バージョン確認

そしてバージョンの確認や実行ができれば大丈夫です。

docker -v \
  && docker-compose -v \
  && docker run hello-world
# Docker version 19.03.1, build 74b1e89
# docker-compose version 1.24.1, build 4667896b
# 
# Hello from Docker!
# This message shows that your installation appears to be working correctly.
# 
# To generate this message, Docker took the following steps:
#  1. The Docker client contacted the Docker daemon.
#  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
#     (amd64)
#  3. The Docker daemon created a new container from that image which runs the
#     executable that produces the output you are currently reading.
#  4. The Docker daemon streamed that output to the Docker client, which sent it
#     to your terminal.
# 
# To try something more ambitious, you can run an Ubuntu container with:
#  $ docker run -it ubuntu bash
# 
# Share images, automate workflows, and more with a free Docker ID:
#  https://hub.docker.com/
# 
# For more examples and ideas, visit:
#  https://docs.docker.com/get-started/

プロセス一覧

ps コマンド

psコマンドを使うとプロセスを一覧できます。

docker ps

-a, --all オプション

オプションを何も指定しない場合は現在稼働中のプロセスが一覧されますが、-a, -allオプションを指定すると稼働が終了したプロセスに関しても表示できます。

docker ps -a
# docker ps --all

-f, --filter オプション

filterオプションを使うことで指定したcolと等しいものだけに結果を絞れます。例えばdocker run時に付けたnameで絞りたい場合は、-f 'name=...'labelの場合は-f 'label=...'という具合です。

docker ps -f 'name=...'

# すべてのプロセス対象
docker ps -f 'label=...' -a

# 稼働してないプロセス一覧
docker ps -f status=exited -a

--format オプション

formatオプションを使うことで出力形式をカスタマイズできます。例えば、{{.Names}}という指定でnameだけを取得でき、table {{.Names}}のように頭にtalbeと書くことでテーブルヘッダを付けて出力できます。指定の部分はスペースの数など好きに指定できます。

これで「稼働していないプロセス一覧のidを取得したい」というような場合は、

docker ps -a -f status=exited --format '{{.ID}}'
docker ps -a -f status=exited --format '{{.ID}}' | xargs docker rm

という感じで取得できます。2行目のようにそれをdocker rm渡してまとめて削除するといったことができます。

自分のログイン済 Now を扱えるプライベート Docker イメージを作る

動機

nowはCLIを提供していてくれてすごく便利なんですけど、ログインするのに入力が必要な感じなのでcliだけで自動処理させようとか思っても無理です。APIはあるので、一時期自作してましたがメンテナンスが面倒くさいのでやっぱりどうしても公式のを使いたい。

5分で作れる

方法は以下の通り

  1. 公式のnodeイメージを使ってコンテナを走らせる
  2. 中でnowにログイン
  3. docker commit
  4. DockerHubへpush

DockerHubへプッシュ前にプライベートリポジトリを作っておくのと、docker loginはしておく必要があります。

コンテナを走らせる

以下のようなコマンドで立ち上げて中に入ります。--nameには分かりやすい名前を付けるといいです。

docker run -it --rm --name now node:10 /bin/sh

nowにログイン

中にはいったらまずnowコマンドをインストール。そしてnow loginと実行するとメールアドレスを聞かれるので入力して認証します。

yarn global add now
# [1/4] Resolving packages...
# [2/4] Fetching packages...
# [3/4] Linking dependencies...
# [4/4] Building fresh packages...
# success Installed "now@11.4.0" with binaries:
#       - now
now login
# > Enter your email:

認証が終わった直後の状態をイメージ化

ここまで終わったら一旦コンテナから抜けます。抜ける方法はctrl+p``ctrl+qです。exitしちゃったりしたら最初からです。
そしてdocker commitします。以下のコマンドはnowという名前のコンテナからnju33/nowというイメージを作るというような意味です。名前はDockerHub上に作ったリポジトリと同じにします。

docker commit now nju33/now

できたら以下のコマンドで出てくるか確認します。

docker image ls
# REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
# nju33/now                  latest              xxxxxxxxxxxx        3 days ago          790MB

DockerHubへプッシュ

以下のようにイメージ名を指定してpushするだけです。

docker push nju33/now

使用例

# 一覧
docker run --rm nju33/now now ls
# static deploy
docker run -it --rm -v `pwd`/src:/root/src nju33/now now /root/src

Docker Compose で MySQL が起動しなくなった

問題

ログ。

db_1   | mysqld(_Z24ha_initialize_handlertonP13st_plugin_int+0x4f)[0x5564931aebff]
db_1   | mysqld(+0xb138e6)[0x5564936258e6]
db_1   | mysqld(_Z40plugin_register_builtin_and_init_core_sePiPPc+0x2f0)[0x556493628ad0]
db_1   | mysqld(+0x64a566)[0x55649315c566]
db_1   | mysqld(_Z11mysqld_mainiPPc+0xc71)[0x55649315e121]
db_1   | /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f570700f2e1]
db_1   | mysqld(_start+0x2a)[0x55649315480a]
db_1   | The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
db_1   | information that should help you find out what is causing the crash.
xxx_db exited with code 2

解決

docker-compose down
docker-compose kill
# したのち
docker-compose up

Postgresql を建てる

ターミナルでずっと開いていて ctrl+c で壊せるやつ

起動

docker run --rm \
  --publish 32778:5432 \
  --env POSTGRES_PASSWORD=postgres \
  postgres

ログイン

以下で中に入れます。

sh -c "PGPASSWORD=postgres psql -h0.0.0.0 -p32778 -Upostgres"

日本語化

公式のpoostgresイメージそのままでは日本語化できないようなので、できるものを作りました。

DockerHub - nju33/postgres

DockerHub へプッシュする

以下の流れで行います。

  1. Docker イメージ作成
  2. 必要ならタグ付け
  3. DockerHub へプッシュ

Docker イメージ作成

今回はDockerfileからイメージを作ります。ただDockerfileの中身については触れません。

Dockerfileからイメージを作るにはdocker build <dir> -t <image-name>コマンドでできます。例えば、

docker build . -t nju33/foo
# 現在いるディレクトリのDockerfileから
# `nju33/foo`イメージを作る


作れたかは以下のようなコマンドで表示されるかどうかで確認できます。

docker images | grep nju33/foo
nju33/foo ... latest

ちなみにデフォルトではlatestタグが付いています。

タグを付ける

latest以外でプッシュしたい(例えばバージョンを付けたりしたい)時は、docker tag <元イメージ> <作りたいイメージ>で付けたいタグを付ける必要があります。例えば今回バージョン0.0.1を付けたいという場合は、

docker tag nju33/foo nju33/foo:0.0.1
# ログはなし

でできます。ログが何も出力されないので分かりづらいですが、ちゃんとタグが付けれたかは先ほどと同じコマンドで確認できます。

docker images | grep nju33/foo
nju33/foo ... 0.0.1

DockerHub へプッシュ

これは楽勝です。docker push <イメージ名>を実行するだけです。

例えば以下のように実行すればlatest0.0.12つをプッシュすることができます。

docker push nju33/foo
docker push nju33/foo:0.0.1

GitHub Packages で公開する

docker login

まずレジストリが使えるようにhttps://docker.pkg.github.com/へのログインが必要ですが、この時にwrite:packagesを許可したアクセストークンが必要になるので、まずそれを取得します。

Image from Gyazo

用意できたら以下のようなCLIからログインします。(<...>は適当なものに書き換えてください)

docker login docker.pkg.github.com --username <github-user-name> --password <access-token>
# 上では警告がでるかも
# cat password-file | docker login docker.pkg.github.com --username <github-user-name> --password-stdin

タグ付け

まずdocker images時に<user-name>/hello-worldという自作Dockerイメージがあるとします。

その状態で、docker.pkg.github.compushする用のタグを付けてあげます。<package-name>push後パッケージ名となるものです。今は<package-name>appと指定して実行してみます。

docker tag <user-name>/hello-world docker.pkg.github.com/<github-user-name>/<repository-name>/<package-name>:1.0

# 今回は以下で試してみる
docker tag <user-name>/hello-world docker.pkg.github.com/<github-user-name>/<repository-name>/app:1.0

公開

上で作ったタグをpushするだけです。

docker push docker.pkg.github.com/<github-user-name>/<repository-name>/app:1.0
# The push refers to repository [docker.pkg.github.com/<github-user-name>/<repository-name>/app]
# 006d3faadc77: Pushed
# f74cd803d60f: Pushed
# 2af6f58893e9: Pushed
# 414e34102ae8: Pushed
# 7dcca1b6d2c7: Pushed
# 1a86ff1d449f: Pushed
# f1b5933fe4b5: Pushed
# ...

うまく行っていればリポジトリのナビゲーション

Pacakgesを含むGitHubナビゲーションのキャプチャ

から今pushしたものがあると思います。

pushしたパッケージがちゃんと存在するキャプチャ

使いたい場合はpushした名前で持ってくるだけです。

docker pull docker.pkg.github.com/<github-user-name>/<repository-name>/app:1.0

エラー

Error logging in to v2 endpoint, trying next endpoint: ...

恐らくDockerデーモンが起動していない。

docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock.

Linuxカーネルが古い。(2019-08-21時点で)最新のバージョンでは3.10+を要求しているので、バージョンがそれ以下の可能性があります。

uname -r                                                                  
# 2.6.32-042stab120.6

また古い場合はdockerdコマンドの最後で以下のようなエラーメッセージを確認できるはずです。

dockerd
# ...
# FATA[2019-08-21T12:34:44.647055425+09:00] Your Linux kernel version 2.6.32-042stab120.6 is not supported for running docker. Please upgrade your kernel to 3.10.0 or newer.

No space left on device

残っている volume をすべて削除したら治りました。

sh -c 'docker volume rm -f $(docker volume ls -q)'