Docker に関する投稿を表示しています

docker の出すログファイルでディスクが 100% になった

まとめると?

  • タイトル通り。 docker の出すログファイルでディスクが 100% になった。
  • ログファイルの削除と daemon.json の設定をして完。

起きたこと

環境依存的に難しいので docker を使っているバッチスクリプトがあるのだが、このスクリプトがモリモリと標準出力に出している。や、本来は捨てられる前提のものなので、問題はあるけどない、みたいな状態。
docker は docker 内で動いているメインプロセスの標準出力のログを取っているっぽく、そのログが溜まりに溜まって、ホストマシンのディスクを埋め尽くしてしまった。

それをたまたま、同じホストマシン上の、まったく違う docker コンテナで動いている web アプリケーション上で、セッションがうまく動いていないっぽいという事象が発生したところから、調べてみると、ホストマシンのディスクがいっぱいだった、ということが判明した。

やったこと

何が容量を食っているのか確認した

du コマンドでチマチマ確認したのだが、もうちょっと効率のいい方法がしりたい。一発でバチコーンとわかるような何か。

# du -sh /* | sort -nr
...

# du -sh /var/lib/docker/* | sort -nr
436K    /var/lib/docker/containerd
104K    /var/lib/docker/network
72K     /var/lib/docker/volumes
37G     /var/lib/docker/containers
22M     /var/lib/docker/image
20K     /var/lib/docker/plugins
20K     /var/lib/docker/builder
8.1G    /var/lib/docker/overlay
4.0K    /var/lib/docker/trust
4.0K    /var/lib/docker/tmp
4.0K    /var/lib/docker/swarm
4.0K    /var/lib/docker/runtimes

# du -sh /var/lib/docker/containers/* | sort -nr
372K    /var/lib/docker/containers/df16f7083353204424150c80cb7c87dc9dda19627c7f09632e797a48d3bea2cf
372K    /var/lib/docker/containers/0d9b9a46c096f977921b682b40d7aa9de5dee443ea01a8d0b157f8f366bce764
288K    /var/lib/docker/containers/8d813f2238daa78186881017d1d6b675715f7602549cfb8285cbb08f5832f88d
252K    /var/lib/docker/containers/ce637310ed46de127cfc78813df94b1a269370a07a0f8ab24dc11f2c87bbadc8
228K    /var/lib/docker/containers/fd837df4343e6c54f5c145385bd93e23e8705114243f8a3d856458bf89c454a0
64K     /var/lib/docker/containers/bc4cdc66666f835980147bbc8105741a45db5018777ca883e35fdd3a072a7970
37G     /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80
36K     /var/lib/docker/containers/8d9bb861db601facac528d60ee855fd5b38a05dcdc2949fee72e9c3dcb4dd177

# du -sh /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/* | sort -nr
37G     /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80-json.log
4.0K    /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/resolv.conf.hash
4.0K    /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/resolv.conf
4.0K    /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/hosts
4.0K    /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/hostname
4.0K    /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/hostconfig.json
4.0K    /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/config.v2.json
4.0K    /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/checkpoints
0       /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/shm

# tail /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80-json.log
....
// このログしってる!ぼくが標準出力に出すようにしたやつだ!

ログファイルの削除をした

中身を確認した上で、完全に不要なものだったので削除した。お手軽 echo 。

# echo > /var/lib/docker/containers/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80/4d81d71c1ea8eaea101cab745f2c16a2bcb096a2bba78f9aecd385f560e62e80-json.log

/etc/docker/daemon.json の設定をした

実際には次のような設定を書いている。これで docker 自体が勝手にログファイルの容量制限とローテートをしてくれるっぽい。べんりちゃん。

# cat /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

容量制限とローテートされた様子。上で出したものと別コンテナだけど。

# du -sh /var/lib/docker/containers/61ffb4d88381cd2556a91f6944a2b2d2b57bb7837d8ad9a21ed772748f490b66/* | grep json.log
4.6M    /var/lib/docker/containers/61ffb4d88381cd2556a91f6944a2b2d2b57bb7837d8ad9a21ed772748f490b66/61ffb4d88381cd2556a91f6944a2b2d2b57bb7837d8ad9a21ed772748f490b66-json.log
9.6M    /var/lib/docker/containers/61ffb4d88381cd2556a91f6944a2b2d2b57bb7837d8ad9a21ed772748f490b66/61ffb4d88381cd2556a91f6944a2b2d2b57bb7837d8ad9a21ed772748f490b66-json.log.1
9.6M    /var/lib/docker/containers/61ffb4d88381cd2556a91f6944a2b2d2b57bb7837d8ad9a21ed772748f490b66/61ffb4d88381cd2556a91f6944a2b2d2b57bb7837d8ad9a21ed772748f490b66-json.log.2

公式ドキュメントを見ると他にも設定項目がいろいろあって、デーモン自体の設定なので、どんな権限で動かすか、とか、そういう…。あまり変更するような出番はないかも。
daemon — Docker-docs-ja 17.06.Beta ドキュメント

log-driver として json-file 以外にも fluentd や AWS CloudWatch なども指定できるので、もしかしたら何か活用できる…?具体的にどういう活用方法があるんだろう
Fluentd logging driver | Docker Documentation


docker 入れてる環境、事故防止のためにもログローテート系の設定はとりあえず入れると良いとおもった一件

Apache 2.4 で WebSocket もリバースプロキシする

Apache 2.4 で WebSocket をプロキシしたい。以前書いた docker-compose のフロントとして Apache を立てると、バックエンドで WebSocket を使う場合にすこしの設定を足す必要がある。

docker-compose で LDAP 認証のリバースプロキシを設定する | ごみばこいん Blog

nginx 使えよって話、めっちゃわかる。そのうちやる…たぶん…

ちなみに Apache 2.2 だとパッチがいたりするそうなので、がんばって!って感じっぽい。

 

httpd.conf あるいはその手の Apache 設定ファイルで以下のような設定を足すと良い。

# ...略...

# WebSocket をプロキシするモジュールを読み込み
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so


# ...略...


# 例えば Jupyter の場合はこんなパスをプロキシしてあげる

# websocket
ProxyPass /api/kernels/ ws://${REVERSE_PROXY}/api/kernels/
ProxyPassReverse /api/kernels/ ws://${REVERSE_PROXY}/api/kernels/

ProxyPass /terminals/websocket/ ws://${REVERSE_PROXY}/terminals/websocket/
ProxyPassReverse /terminals/websocket/ ws://${REVERSE_PROXY}/terminals/websocket/

# http
ProxyPass / http://${REVERSE_PROXY}/
ProxyPassReverse / http://${REVERSE_PROXY}/

 

REVERSE_PROXY は環境変数で、バックエンド( Jupyter )のホスト(とポート)を指定する。ぼくの手元のやつは docker-compose を使ってるのでこんな感じに書いている。

version: "3"

services:
  jupyter:
    container_name: "${APP_NAME}_jupyter"
    build: ./docker-jupyter
    command: start-notebook.sh --NotebookApp.token=''
    volumes:
      - ./notebooks:/home/jovyan/work
    environment:
      GRANT_SUDO: 1
      NB_UID: ${NB_UID}
      NB_GID: ${NB_GID}
  proxy:
    container_name: "${APP_NAME}_proxy"
    build: ./docker-proxy
    ports:
      - "${HTTP_PORT}:80"
    links:
      - jupyter:jupyter
    environment:
      REVERSE_PROXY: jupyter:8888

httpd:alpine の Docker イメージを利用しても WebSocket のプロキシが出来るので、そんな感じ。
いじょ

docker-compose 自体を更新する

Github にリリースされていっているので、そこを見て、コマンドを実行したらよいといえば良い。

Releases · docker/compose

が、毎回見るのもあれなので、思い立ったときに動かせるようにしたいなあと思ったので更新するやつを作った。

sters/docker-compose-updater: Semi automatic docker-compose updater

原理はめっちゃそのままで、こんな処理をしている。

  • インストールされている docker-compose を which で探す
  • インストールされていなければ終了
  • curl と cut で Github のリリースページから最新版のバージョンを探す
  • OSとアーキテクチャを uname で識別(ドキュメントのまま)
  • Github のリリースページから最新版をダウンロードし、インストールされているものを置き換える(ドキュメントのまま)
  • chmod で実行権限を渡しておわり

Makefile がいいよ!って言われたので試しに見よう見まねで Makefile でやった。 Makefile のお試したかっただけ、みたいなところはある。なるほどなあ~~

 

どうやるのがいちばん良さそうかわからないけれど、docker-compose を扱う docker イメージがあってそっちを使うほうが楽そう…?

とはいえコンテナ内から docker-compose な操作をほにゃほにゃするとなると /var/run/docker.sock とか docker-compose.yml もといアプリケーションディレクトリをマウントしないと行けないので、記述がめんどうになりそうな気がする… というかちょっと試した程度ではできなかったのでうーん。
docker-compose って名前でエイリアスして、実態は docker/compose イメージを docker run してますよ~~みたいなものが出来ると、 docker-compose の準備する手間が無くてちょっとだけ便利になりそうなのだけど…

 

ちなみに作ったものと同じように、手元へと docker-compose バイナリを取り出すのはこんな感じ。

$ docker run --rm --entrypoint "" -v $(pwd):/tmp/bin docker/compose:1.18.0 cp /usr/local/bin/docker-compose /tmp/bin/

$ ls -l docker-compose
-rwxr-xr-x 1 root root 8479184 Jan 18 12:10 docker-compose

※ root が所有者になってるので移動させたりするときは sudo しないとだめ

docker-compose で LDAP 認証のリバースプロキシを設定する

色々が色々あって、社内限定ツールに Active Directory を参照した LDAP 認証を掛けることがある。
それ自体は別にいいのだが Docker を使ってペペッと作って展開するといったときがやや面倒になった。

ので、それを docker-compose を使ってリバースプロキシを作ったら解決できたよ、というメモ。

 

こんな感じで docker-compose.yml を作って。

version: "2"

services:
  application:
    container_name: "${APP_NAME}_application"
    build: ./docker-app
    volumes:
      - ./src:/var/www/html
  proxy:
    container_name: "${APP_NAME}_proxy"
    build: ./docker-proxy
    ports:
      - "${HTTP_PORT}:80"
    links:
      - application:application

docker-compose をやったことがある人はご存知と思うが、このときの ${APP_NAME} や ${HTTP_PORT} は環境変数を指していて .env ファイルなどを作り APP_NAME=hogehoge みたいなことをしたらいい。

余談なのだけど、ドキュメントみたら version 3 のフォーマットがいつの間にかリリースされていて(しらなかった!!)、そっちに移行していく流れのほうがいいよねって思った。
Compose file version 3 reference | Docker Documentation

 

こんな感じで ./docker-proxy/Dockerfile を作って。

FROM httpd:alpine
COPY ./httpd.conf /usr/local/apache2/conf/httpd.conf

 

こんな感じで ./docker-proxy/httpd.conf を作って。

# default configures
ServerRoot "/usr/local/apache2"
Listen 80
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so

<IfModule unixd_module>
    User daemon
    Group daemon
</IfModule>

ServerAdmin you@example.com
ServerName localhost:80

<Directory />
    AllowOverride none
    Require all denied
</Directory>

DocumentRoot "/usr/local/apache2/htdocs"

<Files ".ht*">
    Require all denied
</Files>

ErrorLog /proc/self/fd/2
LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog /proc/self/fd/1 common
</IfModule>

<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
</IfModule>

<IfModule ssl_module>
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
</IfModule>



# Load modules
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule auth_basic_module modules/mod_auth_basic.so

LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule ldap_module modules/mod_ldap.so

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so


# LDAP
LDAPTrustedMode SSL
LDAPVerifyServerCert off


# Proxy
<VirtualHost *:80>
    ProxyRequests Off
    ProxyPreserveHost Off
    AllowEncodedSlashes On
    KeepAlive Off

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    <Location />
        AuthName "Basic Auth"
        AuthType Basic
        AuthBasicProvider ldap
        AuthLDAPURL [ここにLDAPを参照するのURI]
        Require valid-user
    </Location>

    RequestHeader unset Authorization

    ProxyPass / http://application/
    ProxyPassReverse / http://application/
</VirtualHost>

 

あとは docker-compose up -d --build などと実行したら出来上がる。

$ docker-compose up -d --build

 

Apache をつかっている理由としては nginx の場合は公式イメージの中で LDAP のモジュールが提供されていないこと、組み込む場合にビルドが必要なことがあげられる。 Apache のイメージであればデフォルトで LDAP のモジュールが提供されている。さらに言えば
alpine イメージでも提供されているので debian ベースなイメージなどと比べて、軽量で高速上げ下げ出来たりしてめっちゃ良いよねってところもあった。調べると debian ベースにビルドしてるものもあって、良いんだけどう~~ん。

まあ「docker nginx ldap proxy」とか普通のワードで調べたらイメージだったり Dockerfile だったりが出てくるので、そのあたりを使ってもよかったのかもしれない。

debian ベースで nginx 1.11.13 をビルドする。 PR したらマージされる感あるのでバージョンアップもやっていけそう。
h3nrik/nginx-ldap - Docker Hub

debian ベースで nginx 1.9.9 をビルドする。2 年前から更新されていないので今後も更新されなさそう感
confirm/docker-nginx-ldap: nginx Docker image with ldap support

nginx 公式なのだけど nginx で LDAP ではなく、横にいる LDAP してくれるやつがよろしくやる、というものでちょっと違うかも。
nginxinc/nginx-ldap-auth: Example of LDAP authentication using ngx_http_auth_request_module

あるいは nginx-proxy っていうめっちゃ便利なリバースプロキシできる君があるので、これをベースに LDAP 認証のモジュールを追加するっていうのが、お手軽楽ちんで一番いいかもしれない。
jwilder/nginx-proxy: Automated nginx proxy for Docker containers using docker-gen

 

とりあえず一旦のところは Apache でやったよっていう話と、 nginx でも調べたら出てくるよ、ってまとめでおわり。

Dockerfile を Github で書いて Docker Hub へ自動で連携する

出来ると思うんだけど~~って言いながら、なかなかやってなかったのでいい加減やった。

Docker Hub にアカウント登録

Docker Hub

右上からサインアップ出来る。適当な ID とメールアドレス、パスワードを入力すると良い。メールで確認がやってくるので、リンクぽちー。

以上で終わり。

Github でリポジトリを作る

Github にリポジトリを作っていきます。

Github 上からファイルの追加が出来るので、手元の Dockerfile をアップする。当然ながらパブリックなリポジトリで扱うのであれば、社外秘です!みたいな内容を含まないように気をつけて。パスワードとか、脆弱性ある古いバージョン使ってるじゃんとか、鍵が載ってるよとか、うっかり事故気をつけようね。

というわけで出来ました。

sters/docker-php7-cakephp3-base: docker base image for php7 x cakephp3

Docker Hub で Automated Build の設定をする

Docker Hub 側で自動ビルドが出来ます(便利!)URL が提供されるので、正しいトークンを送るとビルドキューへ追加され、自動でビルド、イメージの提供がされ始めます。
というわけで連携を進めていきます。

この URL および トークンを Github の Webhook に追加します。

ちなみに Docker Hub に Webhook もありますが、これはビルドが終わったときにそのイベントを指定した URL に通知できるものです。でっかいイメージを扱いたい時とか、ビルドしたイメージがちゃんと使えるかテストしたいとか、そういうときに使えるんじゃないですかね。

Github で Webhook の設定

Docker Hub で取得できたトリガーの URL を Github の Webhook に設定します。

とりあえずは Push された時、でいいと思います。タグが付いたとき、にすると Docker Hub 側でタグごとのビルドがされていきます。バージョニングしていく上ではそうするほうがいいでしょうね~。

Docker Hub で確認

ビルドが動き始めました。しばらく待つと完了します。

何事もなければこれでイメージが利用できるようになります。

 $ docker run -it --rm sters/php7-cakephp3-base "/bin/sh"

// ここからゲスト側

/ # composer
Do not run Composer as root/super user! See https://getcomposer.org/root for details
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.5.2 2017-09-11 16:59:25

Usage:
  command [options] [arguments]

Options:
  -h, --help                     Display this help message
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi                     Force ANSI output
      --no-ansi                  Disable ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --profile                  Display timing and memory usage information
      --no-plugins               Whether to disable plugins.
  -d, --working-dir=WORKING-DIR  If specified, use the given directory as working directory.
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  about           Shows the short information about Composer.
  archive         Creates an archive of this composer package.
  browse          Opens the package's repository URL or homepage in your browser.
  clear-cache     Clears composer's internal package cache.
  clearcache      Clears composer's internal package cache.
  config          Sets config options.
  create-project  Creates new project from a package into given directory.
  depends         Shows which packages cause the given package to be installed.
  diagnose        Diagnoses the system to identify common errors.
  dump-autoload   Dumps the autoloader.
  dumpautoload    Dumps the autoloader.
  exec            Executes a vendored binary/script.
  global          Allows running commands in the global composer dir ($COMPOSER_HOME).
  help            Displays help for a command
  home            Opens the package's repository URL or homepage in your browser.
  info            Shows information about packages.
  init            Creates a basic composer.json file in current directory.
  install         Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.
  licenses        Shows information about licenses of dependencies.
  list            Lists commands
  outdated        Shows a list of installed packages that have updates available, including their latest version.
  prohibits       Shows which packages prevent the given package from being installed.
  remove          Removes a package from the require or require-dev.
  require         Adds required packages to your composer.json and installs them.
  run-script      Runs the scripts defined in composer.json.
  search          Searches for packages.
  self-update     Updates composer.phar to the latest version.
  selfupdate      Updates composer.phar to the latest version.
  show            Shows information about packages.
  status          Shows a list of locally modified packages.
  suggests        Shows package suggestions.
  update          Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
  upgrade         Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
  validate        Validates a composer.json and composer.lock.
  why             Shows which packages cause the given package to be installed.
  why-not         Shows which packages prevent the given package from being installed.

/ # php -v
PHP 7.1.10 (cli) (built: Sep 30 2017 01:01:44) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

/ # exit

おわり

基本的に Official なイメージを使うとおおよそ大丈夫だと思うけど、再ビルド必要です!とか拡張機能必要です!とか、そういう状況になったら都度やるのもアレなので、オレオレイメージを作ると便利ちゃん。

そういえば Docker Hub って Dcokerfile によって記述された Docker イメージを管理共有してくれているけど、 docker-compose.yml で記述されるコンテナ管理セットを共有する場ってあるのかな。ちょっと調べたけどクエリが悪いのか見つからず…。

docker を使っていてポートを指定するときに IP アドレスを指定できる

この記事は公開されてから1年以上経過しており、情報が古い可能性があります。

開発用だったり検証用だったりで docker をぼちぼち使っているのですが、ゲストのポートをホストのポートへバインドするときに、IPアドレスを指定できます。

$ docker run -it -d -p 127.0.0.1:10080:80 myapp

どこで使うんだよって話ですが、セキュリティを考えるときには使うんじゃないっすかね、たぶん。

IPアドレスの指定がないと 0.0.0.0 で待ち受けるので、接続をどこからでも受け付けます。そのため、例えばホスト側で nginx 等を使って何かしらの認証が必要なリバースプロキシをしていたとしても、指定ポートでコンテナに直接アクセスができてしまいます。

nginx で不特定多数から見られないよう Basic 認証を設定していたのですが、見れるのかな?ってポート指定してアクセスしたら無事に見れてしまって、うふふってなってました。

$ docker run -it -d -p 10080:80 nginx
485e21a84ea180bc69db198bcdb7e417fb61d2747642059b8bd4435873aa1503

$ netstat -nao | grep 10080
tcp        0      0 :::10080                    :::*                        LISTEN      off (0.00/0/0)

$ docker rm -f 485
485

$ docker run -it -d -p 127.0.0.1:10080:80 nginx
94ea5a9d74578fc69777cf0dc3b7dc918ce2e4ec74fef52441521a8d163680d8

$ netstat -nao | grep 10080
tcp        0      0 127.0.0.1:10080             0.0.0.0:*                   LISTEN      off (0.00/0/0)

ドキュメントはここ
https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p-expose

docker で MySQL を立ち上げたい。

この記事は公開されてから1年以上経過しており、情報が古い可能性があります。

タイトルそのまま。

// たぶん mysql 5.7 がプルされる
// が、わからんので DockerHub を要確認
$ docker pull mysql:latest

// mysqlコンテナの起動
//   オプションについて
//     -e    : 環境変数
//     --name: コンテナ名
//     -d    : バックグラウンド
//     -p    : ポートバインディング(ホスト:ゲスト)
//   環境変数について
//     MYSQL_DATABASE     : 作るデータべース
//     MYSQL_USER         : 作るユーザ
//     MYSQL_PASSWORD     : 作るユーザのパスワード
//     MYSQL_ROOT_PASSWORD: ルートパスワード
$ docker run --name my_mysql \
  -e MYSQL_DATABASE=homestead \
  -e MYSQL_USER=homestead \
  -e MYSQL_PASSWORD=secret \
  -e MYSQL_ROOT_PASSWORD=secret \
  -d \
  -p 13306:3306 \
  mysql

// 接続確認
//   -h : ホスト名
//   -P : ポート番号
//   -u : ユーザ名
//   -p : パスワードを入力するプロンプトを出す
$ mysql -h 127.0.0.1 -P 13306 -u root -p

記事書くときに Docker Hub を確認したら 5.7.19 が latest で指定されているっぽい。というか 8.0 系も指定できるのか、検証なんかにも便利そうだ。

library/mysql - Docker Hub

でもって docker で MySQL が立ち上がると、こうさ、ほら、ユニットテスト回すときなんかに、こうしてクリーンな DB を提供できてよさそうだなーって。
イメージとしてはこんな感じ。

{
    ...
    "scripts": {
        "test": "phpunit --verbose",
        "docker-test": [
            "composer docker-db-remove"
            "composer docker-db-create",
            "composer test",
            "composer docker-db-remove"
        ],
        "docker-db-create": "docker run --name test_mysql -e MYSQL_DATABASE=homestead -e MYSQL_USER=homestead -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=secret -d -p 13306:3306 mysql",
        "docker-db-remove": "docker rm --force test_mysql",
        "docker-db-connect": [
          "#  Copy this command!",
          "#  mysql --host=127.0.0.1 --port=13306 --user=homestead --password=secret homestead"
        ]
    },
    ...
}

composer docker-test とやったらコンテナが立ち上がり 127.0.0.1:13306 で待ち受けているので、そこを指定するように phpunit.xml だとか .env だとかで DB 接続用の値を設定すればよい。テストの後はコンテナがポイされるので、テスト用のDBはいつでもクリーンに。テストでコケても大丈夫なように、最初にコンテナをポイしたほうがいいのかな。

composer スクリプトで I/O を全部引き渡す方法がわからなかったので docker-db-connect タスクが非常にあやしい感じだけど、これくらいでもまあまあ運用していけるんじゃないかなーー