関連

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 

# 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は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

問題

ログ。

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

ターミナルでずっと開いていて 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イメージそのままでは日本語化できないようなので、できるものを作りました。

以下の流れで行います。

  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

docker login

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

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

docker login docker.pkg.github.com --username  --password 
# 上では警告がでるかも
# cat password-file | docker login docker.pkg.github.com --username  --password-stdin

タグ付け

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

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

docker tag /hello-world docker.pkg.github.com///:1.0

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

公開

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

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

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

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

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

docker pull docker.pkg.github.com///app:1.0

ubuntu のバージョンは18.04を使います。

cat /etc/lsb-release
# DISTRIB_ID=Ubuntu
# DISTRIB_RELEASE=18.04
# DISTRIB_CODENAME=bionic
# DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"

以下の順に見ていきます。

  1. リモートの設定

  2. ubuntu on WSL 上の設定

  3. hello-world

1. リモートの設定

Windows 10 Home では Docker for Windows をインストールして使うことができないので、この代わりに外部の VPS を借りて、そこの Docker を使います。

今回は Amazon EC2 を借りました。

cat /etc/os-release
# NAME="Amazon Linux"
# VERSION="2"
# ID="amzn"
# ID_LIKE="centos rhel fedora"
# VERSION_ID="2"
# PRETTY_NAME="Amazon Linux 2"
# ANSI_COLOR="0;33"
# CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
# HOME_URL="https://amazonlinux.com/"
# [ec2-user@ip-172-31-18-243 ~]$ cat /etc/os-release
# NAME="Amazon Linux"
# VERSION="2"
# ID="amzn"
# ID_LIKE="centos rhel fedora"
# VERSION_ID="2"
# ID="amzn"
# ID_LIKE="centos rhel fedora"
# VERSION_ID="2"
# PRETTY_NAME="Amazon Linux 2"
# ANSI_COLOR="0;33"
# CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
# HOME_URL="https://amazonlinux.com/"

リモートのマシンに Docker が入っているかは以下で分かります。

docker -v
# Docker version 19.03.6-ce, build 369ce74

Docker version ...と出なかった場合は以下のコマンドで入れられます。

sudo yum update -y
sudo amazon-linux-extras install docker
sudo usermod -a -G docker "$(whoami)"
sudo service docker start

docker -v
# Docker version 19.03.6-ce, build 369ce74

2. ubuntu on WSL 上の設定

リモートに鍵でsshできるようにする話はここでは省略します。

例えばリモートは以下のような情報で接続できるとします。

  1. ホストはn.n.n.n

  2. ユーザー名はec2-user

  3. 鍵は~/.ssh/id_rsaを使う

ここにssh docker-hostコマンドで接続できるようにしたい場合、~/.ssh/configに以下を追記します。

Host docker-host
    Hostname n.n.n.n
    User ec2-user
    IdentityFile 

ただ、これだけの設定だとリモートに接続するだけで、先程 Docker をインストールした意味がないので、設定にもう1行加えて以下のようにします。

Host docker-host
    Hostname n.n.n.n
    User ec2-user
    IdentityFile
    LocalForward 127.0.0.1:12312 /var/run/docker.sock

このLocalForwardの設定のおかげで、ssh docker-hostしている間localhost:12312へのアクセスがリモートの/var/run/docker.sockに転送されるようになります。

Docker がlocalhost:12312を使うようにするにはDOCKER_HOST環境変数を設定してあげます。

export DOCKER_HOST='localhost:12312'

そういえば、ubuntu on WSL にも Docker を入れてあげる必要があったので以下でインストールします。

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker "$(whoami)"

Docker Compose が必要なら以下も実行します。

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

3. hello-world

以下が ubuntu on WSL から実行できれば完了です。

docker run hello-world
# Hello from Docker!
関連

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)'

JavaScript で飯食べたい歴約 9 年、 純( nju33 ) によるノートサイトです。

このサイトではドリンク代や奨学金返済の為、広告などを貼らせて頂いてますがご了承ください。

Change Log