- 投稿日:2019-03-23T23:15:00+09:00
 
【小ネタ】docker環境を掃除するコマンド
はじめに
Dockerを普通に使っていると、停止状態のコンテナやdanglingなイメージ(REPOSITORYやTAGが<none>になっているもの)がたまっていきます。
これらを一括削除する方法をまとめてみました。実行コマンド
不要なリソースすべて削除する (docker system prune)
何も考えずに、使われていないと思われるリソースを削除します。ローカルの開発環境であればこれが一番簡単です。
docker system prune | Docker Documentation
https://docs.docker.com/engine/reference/commandline/system_prune/$ docker system prune WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all dangling images - all dangling build cache Are you sure you want to continue? [y/N] y Deleted Containers: d75069ae85738508edbbcb7027d0caff3174ac09629089462f7bdcafd0a56223 b342fa0ac8d3d5e75e403ad77940045a71e221865cb866f46140d1633249d6ba Total reclaimed space: 8.402MBDocker imageで不要なものを削除する (docker image prune)
どのコンテナからも参照されておらず、且つdanglingなイメージを削除します。
docker image prune | Docker Documentation
https://docs.docker.com/engine/reference/commandline/image_prune/$ docker image prune WARNING! This will remove all dangling images. Are you sure you want to continue? [y/N] y Total reclaimed space: 0Bdocker image pruneがなかった時代は、以下のようにコマンドを組み合わせていましたが、今となっては不要でしょう。
xargsの代わりに、シェルのコマンド置換(「$()」若しくはバッククォート「``」)を組み合わせたパターンもよく見ました。$ docker images --filter "dangling=true" -q | xargs docker rmi $ docker rmi `docker images --fileter "dangling=true" -q` $ docker rmi $(docker images --fileter "dangling=true" -q)停止状態のDocker containerをすべて削除する (docker container prune)
停止状態のコンテナ(STATUSがExitedかDeadのもの?)をすべて削除します。
docker container prune | Docker Documentation
https://docs.docker.com/engine/reference/commandline/container_prune/Description
Remove all stopped containers「stoppped」の定義が見つからなかったのですが、コマンドの挙動からおそらくSTATUSがExitedとDeadのコンテナが対象になるのではと思います。
$ docker container prune WARNING! This will remove all stopped containers. Are you sure you want to continue? [y/N] y Deleted Containers: ba802702150e13e1b95d4868b1eabee1c929d37b38da548786b6f4872be056b4 3dbd0f7d84f6d918473e6e90b971af3bf1b0eb2ce3e524a5db1f00061517859f Total reclaimed space: 4.201MBdocker container pruneがなかった時代は、以下のようなコマンドがよく使われていたと思います。
これも、xargsの代わりにシェルのコマンド置換(「$()」若しくはバッククォート「``」)を組み合わせたバリエーションがあります。$ docker ps -q -a| xargs docker rm $ docker rm `docker ps -q -a` $ docker rm $(docker ps -q -a)「-a」オプションをつけると、停止状態のコンテナも実行中のコンテナもすべて出力され、docker rmコマンドの対象となります。
実行中のコンテナを削除しようとしてもエラーになるので、結果として停止状態のコンテナのみが削除される、という動きになります。補足:docker image/docker containerに関するコマンドの詳細
最近のdockerコマンドは、第一引数に「container」や「image」、「network」などを指定して実行できるように整理されており、何を対象とした操作なのかわかりやすくなっています。
「docker ps」や「docker container ls」は実質的に同じことを実行します。
しかしながら、公式ドキュメントは古いほうのコマンドの説明しか詳細に書いていなかったりするので、探すときには注意が必要です。Docker image lsの詳細
「docker images」に詳細が記載してあります。
docker images | Docker Documentation
https://docs.docker.com/engine/reference/commandline/images/Docker container lsの詳細
「docker ps」に詳細が記載してあります。
docker ps | Docker Documentation
https://docs.docker.com/engine/reference/commandline/ps/
- 投稿日:2019-03-23T22:39:43+09:00
 
数学科がDockerの理解度チェックとしてJupyterLabの環境構築
背景
Dockerをとりあえず勉強したけど
では、何か環境を構築できるのか?
つまり、理解に繋がっているのか?の確認対象読者
- 初めてDockerで環境構築してみたい人
 - Linuxにそもそも疎い人(ggrksの完全独学野郎)
 - Macユーザー
 完成品について
GitHubにあります。
kz-jpylb ├── Dockerfile ├── work ├── README.md └── docker-compose.yml使い方について
はじめに、Gitを使えるようにしておいてください。
例えば、
このリポをforkしてから
Clone with HTTPSってところをおして
出てきたやつをコピーする$ cd Desktop $ git clone ここにコピーしたやつです。これでDesktopにディレクトリができたと思うので
env.exampleUID=下の方で取得方法が観れるのでそれをここにで
.env.exampleを.envにrenameしてから$ docker-compose up -dでOKです
docker-composeで困ったこと
docker-compose.ymlを記述の際に次の点がわからなかった。
一応、その他のところも簡単にコメントを書くdocker-compose.ymlversion: "3" # docker-composeのバージョン、俺の時の最新は3 services: jupyterlab: # サービス名 build: # imageを直接とってもいいけどDockerfileを別で用意してるからいらない # pipで何か追加したいときはDockerfileにかこう context: . # Dockerfileがあるところ user: root ########### ← これよ, このuser ########### ports: - "8888:8888" # ホスト:コンテナ volumes: - "./work:/home/jovyan/work" ########### ← これよ, この/home/jovyan/work ########### environment: NB_UID: $UID ########### ← これよ, このUID ########### GRANT_SUDO: "yes" ########### ← これよ, このSUDO ########### command: start.sh jupyter lab --NotebookApp.token='' # passwordなし、これですぐ使えるまずUIDについては
を参考にすると
| ユーザーのユーザーID(uid)やグループID(gid)を調べるには、idコマンドを使用する。以下の例では、ユーザーIDが500、グループIDが501であることが分かる。また、所属グループが501となっていることから、ユーザー名と同じ名前のグループ名であることも分かる。 |
$ whoami unkoman $ id unkoman uid=500(nori) gid=501(nori) 所属グループ=501(nori)次にGRANT_SUDOについては
を参考にすると
GRANT_SUDO=yesは
ユーザー権限なしにjupyterを利用できるするようにするオプションです。よくわからないけど他の人もみんなこうしてるから俺もこうしよう
できれば解説をコメントでお願いします ?♂️次にvolumeのmountについては
公式の
を参考にすると
docker run --rm -p 10000:8888 -e JUPYTER_ENABLE_LAB=yes -v "$PWD":/home/jovyan/work jupyter/datascience-notebook:9b06df75e445Example 3: This command pulls the jupyter/datascience-notebook image tagged 9b06df75e445 from Docker Hub if it is not already present on the local host. It then starts an ephemeral container running a Jupyter Notebook server and exposes the server on host port 10000. The command mounts the current working directory on the host as /home/jovyan/work in the container. The server logs appear in the terminal. Visiting http://:10000/?token= in a browser loads JupyterLab, where hostname is the name of the computer running docker and token is the secret token printed in the console. Docker destroys the container after notebook server exit, but any files written to ~/work in the container remain intact on the host.:
と書いてあるのでコンテナ側はどうやら
/home/jovyan/workらしい最後にuser: rootについては
を参考にすると
エラーとかの回避のためにとりあえずつけてる感じ?
できれば解説をコメントでお願いします ?♂️Dockerfileについて
これも簡単にコメント
FROM jupyter/datascience-notebook MAINTAINER kiwamizamurai # 名前<mail address> が慣習のよう RUN pip install jupyterlab RUN jupyter serverextension enable --py jupyterlabベースイメージに何が入っていんかの確認方法がわからんかったし
何を追加でpip installすればいいかわからんかったパスワード設定について(読み飛ばして良い)(設定したい人向け)
上では
command: start.sh jupyter lab --NotebookApp.token='' # passwordなし
としたが
command: start.sh jupyter lab
とすれば後からパスワードが設定できる上のリンクによると
$ docker-compose build $ docker-compose upでコンテナ起動させるとパスワード入力画面が現れて、入力しログインする、
その後、JupyterLab上で下記を実行してfrom IPython.lib import passwd passwd()SHA1の文字列が得られるのでこの文字列を起動時に渡すようにする、つまり
docker-compose.ymlversion: "3" services: jupyterlab: build: context: . user: root ports: - "8888:8888" volumes: - "./work:/home/jovyan/work" environment: NB_UID: $UID GRANT_SUDO: "yes" command: start.sh jupyter lab --NotebookApp.token='ここに貼り付ける'で、
# foregroundで起動していた場合 (-d なし) ターミナルの画面で Ctr + C をしてから $ docker-compose up -dここら辺は
を参考にどうぞ
おっけー
- 投稿日:2019-03-23T22:39:43+09:00
 
数学科が独学でDockerの理解度チェックとしてJupyterLabの環境構築
背景
Dockerをとりあえず勉強したけど
では、何か環境を構築できるのか?
つまり、理解に繋がっているのか?の確認対象読者
- 初めてDockerで環境構築してみたい人
 - Linuxにそもそも疎い人(ggrksの完全独学野郎)
 - Macユーザー
 完成品について
GitHubにあります。
kz-jpylb ├── Dockerfile ├── work ├── README.md └── docker-compose.yml使い方について
はじめに、Gitを使えるようにしておいてください。
例えば、
このリポをforkしてから
Clone with HTTPSってところをおして
出てきたやつをコピーする$ cd Desktop $ git clone ここにコピーしたやつです。これでDesktopにディレクトリができたと思うので
env.exampleUID=下の方で取得方法が観れるのでそれをここにで
.env.exampleを.envにrenameしてから$ docker-compose up -dでOKです
docker-composeで困ったこと
docker-compose.ymlを記述の際に次の点がわからなかった。
一応、その他のところも簡単にコメントを書くdocker-compose.ymlversion: "3" # docker-composeのバージョン、俺の時の最新は3 services: jupyterlab: # サービス名 build: # imageを直接とってもいいけどDockerfileを別で用意してるからいらない # pipで何か追加したいときはDockerfileにかこう context: . # Dockerfileがあるところ user: root ########### ← これよ, このuser ########### ports: - "8888:8888" # ホスト:コンテナ volumes: - "./work:/home/jovyan/work" ########### ← これよ, この/home/jovyan/work ########### environment: NB_UID: $UID ########### ← これよ, このUID ########### GRANT_SUDO: "yes" ########### ← これよ, このSUDO ########### command: start.sh jupyter lab --NotebookApp.token='' # passwordなし、これですぐ使えるまずUIDについては
を参考にすると
| ユーザーのユーザーID(uid)やグループID(gid)を調べるには、idコマンドを使用する。以下の例では、ユーザーIDが500、グループIDが501であることが分かる。また、所属グループが501となっていることから、ユーザー名と同じ名前のグループ名であることも分かる。 |
$ whoami unkoman $ id unkoman uid=500(nori) gid=501(nori) 所属グループ=501(nori)次にGRANT_SUDOについては
を参考にすると
GRANT_SUDO=yesは
ユーザー権限なしにjupyterを利用できるするようにするオプションです。よくわからないけど他の人もみんなこうしてるから俺もこうしよう
できれば解説をコメントでお願いします ?♂️次にvolumeのmountについては
公式の
を参考にすると
docker run --rm -p 10000:8888 -e JUPYTER_ENABLE_LAB=yes -v "$PWD":/home/jovyan/work jupyter/datascience-notebook:9b06df75e445Example 3: This command pulls the jupyter/datascience-notebook image tagged 9b06df75e445 from Docker Hub if it is not already present on the local host. It then starts an ephemeral container running a Jupyter Notebook server and exposes the server on host port 10000. The command mounts the current working directory on the host as /home/jovyan/work in the container. The server logs appear in the terminal. Visiting http://:10000/?token= in a browser loads JupyterLab, where hostname is the name of the computer running docker and token is the secret token printed in the console. Docker destroys the container after notebook server exit, but any files written to ~/work in the container remain intact on the host.:
と書いてあるのでコンテナ側はどうやら
/home/jovyan/workらしい最後にuser: rootについては
を参考にすると
エラーとかの回避のためにとりあえずつけてる感じ?
できれば解説をコメントでお願いします ?♂️Dockerfileについて
これも簡単にコメント
FROM jupyter/datascience-notebook MAINTAINER kiwamizamurai # 名前<mail address> が慣習のよう RUN pip install jupyterlab RUN jupyter serverextension enable --py jupyterlabベースイメージに何が入っていんかの確認方法がわからんかったし
何を追加でpip installすればいいかわからんかったパスワード設定について(読み飛ばして良い)(設定したい人向け)
上では
command: start.sh jupyter lab --NotebookApp.token='' # passwordなし
としたが
command: start.sh jupyter lab
とすれば後からパスワードが設定できる上のリンクによると
$ docker-compose build $ docker-compose upでコンテナ起動させるとパスワード入力画面が現れて、入力しログインする、
その後、JupyterLab上で下記を実行してfrom IPython.lib import passwd passwd()SHA1の文字列が得られるのでこの文字列を起動時に渡すようにする、つまり
docker-compose.ymlversion: "3" services: jupyterlab: build: context: . user: root ports: - "8888:8888" volumes: - "./work:/home/jovyan/work" environment: NB_UID: $UID GRANT_SUDO: "yes" command: start.sh jupyter lab --NotebookApp.token='ここに貼り付ける'で、
# foregroundで起動していた場合 (-d なし) ターミナルの画面で Ctr + C をしてから $ docker-compose up -dここら辺は
を参考にどうぞ
おっけー
- 投稿日:2019-03-23T22:39:43+09:00
 
素人がDockerの理解度チェックとしてJupyterLabの環境構築
背景
Dockerをとりあえず勉強したけど
では、何か環境を構築できるのか?
つまり、理解に繋がっているのか?の確認対象読者
- 初めてDockerで環境構築してみたい人
 - Linuxにそもそも疎い人(ggrksの完全独学野郎)
 - Macユーザー
 完成品について
GitHubにあります。
kz-jpylb ├── Dockerfile ├── work ├── README.md └── docker-compose.yml使い方について
はじめに、Gitを使えるようにしておいてください。
例えば、
このリポをforkしてから
Clone with HTTPSってところをおして
出てきたやつをコピーする$ cd Desktop $ git clone ここにコピーしたやつです。これでDesktopにディレクトリができたと思うので
env.exampleUID=下の方で取得方法が観れるのでそれをここにで
.env.exampleを.envにrenameしてから$ docker-compose up -dでOKです
docker-composeで困ったこと
docker-compose.ymlを記述の際に次の点がわからなかった。
一応、その他のところも簡単にコメントを書くdocker-compose.ymlversion: "3" # docker-composeのバージョン、俺の時の最新は3 services: jupyterlab: # サービス名 build: # imageを直接とってもいいけどDockerfileを別で用意してるからいらない # pipで何か追加したいときはDockerfileにかこう context: . # Dockerfileがあるところ user: root ########### ← これよ, このuser ########### ports: - "8888:8888" # ホスト:コンテナ volumes: - "./work:/home/jovyan/work" ########### ← これよ, この/home/jovyan/work ########### environment: NB_UID: $UID ########### ← これよ, このUID ########### GRANT_SUDO: "yes" ########### ← これよ, このSUDO ########### command: start.sh jupyter lab --NotebookApp.token='' # passwordなし、これですぐ使えるまずUIDについては
を参考にすると
| ユーザーのユーザーID(uid)やグループID(gid)を調べるには、idコマンドを使用する。以下の例では、ユーザーIDが500、グループIDが501であることが分かる。また、所属グループが501となっていることから、ユーザー名と同じ名前のグループ名であることも分かる。 |
$ whoami unkoman $ id unkoman uid=500(nori) gid=501(nori) 所属グループ=501(nori)次にGRANT_SUDOについては
を参考にすると
GRANT_SUDO=yesは
ユーザー権限なしにjupyterを利用できるするようにするオプションです。よくわからないけど他の人もみんなこうしてるから俺もこうしよう
できれば解説をコメントでお願いします ?♂️次にvolumeのmountについては
公式の
を参考にすると
docker run --rm -p 10000:8888 -e JUPYTER_ENABLE_LAB=yes -v "$PWD":/home/jovyan/work jupyter/datascience-notebook:9b06df75e445Example 3: This command pulls the jupyter/datascience-notebook image tagged 9b06df75e445 from Docker Hub if it is not already present on the local host. It then starts an ephemeral container running a Jupyter Notebook server and exposes the server on host port 10000. The command mounts the current working directory on the host as /home/jovyan/work in the container. The server logs appear in the terminal. Visiting http://:10000/?token= in a browser loads JupyterLab, where hostname is the name of the computer running docker and token is the secret token printed in the console. Docker destroys the container after notebook server exit, but any files written to ~/work in the container remain intact on the host.:
と書いてあるのでコンテナ側はどうやら
/home/jovyan/workらしい最後にuser: rootについては
を参考にすると
エラーとかの回避のためにとりあえずつけてる感じ?
できれば解説をコメントでお願いします ?♂️Dockerfileについて
これも簡単にコメント
FROM jupyter/datascience-notebook MAINTAINER kiwamizamurai # 名前<mail address> が慣習のよう RUN pip install jupyterlab RUN jupyter serverextension enable --py jupyterlabベースイメージに何が入っていんかの確認方法がわからんかったし
何を追加でpip installすればいいかわからんかったパスワード設定について(読み飛ばして良い)(設定したい人向け)
上では
command: start.sh jupyter lab --NotebookApp.token='' # passwordなし
としたが
command: start.sh jupyter lab
とすれば後からパスワードが設定できる上のリンクによると
$ docker-compose build $ docker-compose upでコンテナ起動させるとパスワード入力画面が現れて、入力しログインする、
その後、JupyterLab上で下記を実行してfrom IPython.lib import passwd passwd()SHA1の文字列が得られるのでこの文字列を起動時に渡すようにする、つまり
docker-compose.ymlversion: "3" services: jupyterlab: build: context: . user: root ports: - "8888:8888" volumes: - "./work:/home/jovyan/work" environment: NB_UID: $UID GRANT_SUDO: "yes" command: start.sh jupyter lab --NotebookApp.token='ここに貼り付ける'で、
# foregroundで起動していた場合 (-d なし) ターミナルの画面で Ctr + C をしてから $ docker-compose up -dここら辺は
を参考にどうぞ
おっけー
- 投稿日:2019-03-23T16:41:34+09:00
 
systemdとdockerを組み合わせるときに気をつけること
topic
- dockerの標準出力の行方
 - docker logging driverでfluentdを利用する場合
 systemdとfluentdとdockerを利用した際に、標準出力の扱いに関して詰まったことがあったので下記に記載しておく。
dockerの標準出力の行方
コンテナでアプリを立ち上げたときに大体の人はdocker logsコマンドでコンテナの標準出力を見ると思う。
(アプリの設定で固定ファイルにログをすべて出力する設定等をしている場合は別だが、log4j2などを使っている場合)systemdからコンテナを立ち上げた際に、docker logsコマンドで表示される内容がすべてsyslogにも出力されているのをみて、えぇ!!と驚いたのでまとめておく。
コンテナの標準出力=プロセスの標準出力
当たり前の話だが、コンテナの標準出力=プロセスの標準出力なのでコンテナをsystemdで起動した場合コンテナの標準出力はsystemdによって拾われる。
そのため、systemdの設定で標準出力関連の設定をデフォルトにしている場合systemdで管理しているプロセスの標準出力(エラー出力を含む)はsystemd→journalログに拾われるため、結果的に/var/log/messages等のログにも同時出力される。勘違いした理由としては、docker logsコマンドの説明で、docker logging driverをデフォルトのjsonにしている場合は、コンテナIDごとに指定のファイルパスに標準出力のログファイルが蓄積してて、そこを見てるんだよ。
という旨の記載を見た気がして、じゃあプロセスとしての標準出力としては出なくてどっかで出力がうばわれてるんだなーと勝手に解釈してしまった(馬鹿)ためだ。よって、ログをjournalに拾われたくない場合はsystemdで下記の設定を行う必要がある。
StandardOutput=null
上記は標準出力のみで標準エラー出力に関しては、以前の通りjournalに出力されるので、必要であればエラー出力に関する設定も同様に存在するのでそちらもいじると良い。
そのまま、出力させるのであれば上記の設定は不要。
logging driverでfluentdを指定した場合に標準出力の行方
dockerの公式ドキュメントにも書いてあるが、docker logging driverでjson以外を設定した場合は、docker logsコマンドを利用することができない。
このため、ほほぉjson以外を設定するとコンテナの標準出力は吸い取られるのか!!(馬鹿)と勘違いしていた。
実際、logging driverをfluentdにしたあとはdocker logsコマンドが使えないので標準出力なくなったのかなーとか考えてたときにjournalログにも同じログが出てる!と気がついて、なんでこっちにもでてるのか散々悩んだ。結局、logging driverをどんな設定にしてもプロセスの標準出力自体はなくならないのでsystemd(upstart)等で管理する場合は通常と同じようにプロセスの標準出力の扱いに関する注意が必要と言うことである。(当たり前)
- 投稿日:2019-03-23T16:07:07+09:00
 
同一リポジトリでLaradock + Nuxt(SSRモード)の環境構築
前提
Docker version 18.09.2
docker-compose version 1.23.2
npm 6.9.0参考サイト
laradock と nuxt で開発環境構築
Laravel+Nuxt.js
LaravelとNuxt.jsを同一レポジトリで管理するときの構成
Laravel に Nuxt.js プロジェクトを入れたいLaradockの構築
Laradockをインストール用のディレクトリの作成
mkdir guild-test-environmentLaradockのプロジェクトをクローンする
cd guild-test-environment/ git clone https://github.com/Laradock/laradock.git作成したディレクトリに移動
cd laradock/.envファイルを作成する
cp env-example .envdocker-compose.ymlを編集し、Nuxt用のポートをマッピングする
ports: - "${WORKSPACE_SSH_PORT}:22" - "3000:3000".envファイル開発環境の構築をするのでルートディレクトリではなく以下のように変更を行う。
- DATA_PATH_HOST=~/.laradock/data + DATA_PATH_HOST=.laradock/dataDockerコンテナを立ち上げる
docker-compose up -d nginx mysql workspace指定のDockerコンテナが立ち上がる
Creating volume "laradock_mosquitto" with local driver Recreating laradock_mysql_1 ... done Recreating laradock_docker-in-docker_1 ... done Recreating laradock_workspace_1 ... done Recreating laradock_php-fpm_1 ... done Recreating laradock_nginx_1 ... doneworkspaceコンテナ内に入る
docker-compose exec workspace bash※ ちなみにコンテナから抜けるには、Ctrl + P + Q
laravel プロジェクト作成
workspaceに入ったままlaravelプロジェクトをインストール
composer create-project --prefer-dist laravel/laravel {プロジェクト名}インストール結構時間かかる。。。
.envファイルを編集する
#before # APP_CODE_PATH_HOST=../ #after APP_CODE_PATH_HOST=../{プロジェクト名} (option) #before #MYSQL_DATABASE=default #MYSQL_USER=default #MYSQL_PASSWORD=secret #after MYSQL_DATABASE=hogehoge MYSQL_USER=develop MYSQL_PASSWORD=developdockerを立ち上げ直す
docker-compose up -d nginx mysql workspace立ち上がって、laradockフォルダと同じ階層にLaravelプロジェクト名のディレクトリができていたらOK!!
TODO
php artisan maigrationの実行を入れるNuxtのインストール
Nuxt公式で展開してるtemplateにする
LaravelProjectの直下のclientディレクトリに配置
npx create-nuxt-app guild-test/client
初期設定で色々聞かれるのでとりあえず下記で設定
? Project name client ? Project description My ace Nuxt.js project ? Use a custom server framework none ? Choose features to install Linter / Formatter, Prettier, Axios ? Use a custom UI framework buefy ? Use a custom test framework jest ? Choose rendering mode Universal ? Author name ? Choose a package manager npmpackage.json と nuxt.config.jsの編集
package.json
laravel プロジェクトを作成した際に作られた package.json は捨てて、
nuxt の方と入れ替える。$ rm package.json # laravelインストール時に生成された方を削除 $ mv ./client/package.json package.json #nuxtの方と入れ替えるnuxt.config.js
$ mv ./client/nuxt.config.js nuxt.config.js内容編集
module.exports = { ~ 省略 ~ build: { ~ 省略 ~ }, srcDir: './client', <- nuxt プロジェクトディレクトリパス watchers: { <- nuxt コマンドでホットリロードを有効にするため webpack: { poll: true } } }パッケージをnpmでインストール
npm install完了後にpackge.jsonの編集を行う
なぜ必要なのかは要調査{ "name": "guild-test-nuxt", ~ 省略 ~ "scripts": { "dev": "nuxt", <- before "dev": "HOST=0.0.0.0 PORT=3000 nuxt", <- after "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate" }, ~ 省略 ~ }開発者モードで起動
npm run dev> client@1.0.0 dev /var/www/guild-test > HOST=0.0.0.0 PORT=3000 nuxt ℹ Preparing project for development 13:37:38 ℹ Initial build may take a while 13:37:38 ✔ Builder initialized 13:37:38 ✔ Nuxt files generated 13:37:38 ✔ Client Compiled successfully in 17.35s ✔ Server Compiled successfully in 15.14s ℹ Waiting for file changes 13:38:05 ╭─────────────────────────────────────────────╮ │ │ │ Nuxt.js v2.4.5 │ │ Running in development mode (universal) │ │ Memory usage: 157 MB (RSS: 295 MB) │ │ │ │ Listening on: http://172.31.0.2:3000 │ │ │ ╰─────────────────────────────────────────────╯LaravelのAPIからHellowoaldを取得する
client/pages/index.vue
<template> <div>{{ data }}</div> </template> <script> export default { async asyncData({ app }) { const data = await app.$axios.$get('/api') return { data } } } </script>routes/api.php
//APIテスト用 Route::get('/', function(){ return 'helloworld';});プロキシモジュールを追加
npm i @nuxtjs/proxy/nuxt.config.js
module.exports = { modules: [ '@nuxtjs/proxy' ], /* ** Axios module configuration */ axios: { // See https://github.com/nuxt-community/axios-module#options baseURL: '/' }, proxy:{ '/api' : "http://localhost:8000" } }workspaceコンテナ内でNuxt/Laravelサーバを立ち上げる
npm run dev php artisan serve画面にhelloworldが出てるはず
- 投稿日:2019-03-23T16:06:48+09:00
 
Java コンテナ化ツール「Jib」はどのくらい Docker のベストプラクティスを満たしているのか
はじめに
Java アプリケーションをコンテナ化するツールに jib があります。
GitHub の README には、Docker のベストプラクティスを知らなくても最適な Docker イメージを作ってくれると書かれています。
Jib builds optimized Docker and OCI images for your Java applications without a Docker daemon - and without deep mastery of Docker best-practices.
そんな Jib がどのくらい Docker イメージのベストプラクティスを満たしているのか調査してみました。
準備
検証には、Spring Initializr で作成した Maven プロジェクトを使います。
jib-maven-plugin の README の通り、pom.xml に以下の記述を追加します。
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>1.0.2</version> <configuration> <to> <image>myimage</image> </to> </configuration> </plugin>ビルドしてみます。
$ ./mvnw compile jib:dockerBuild : : : [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 18.444 s [INFO] Finished at: 2019-03-23T13:59:31+09:00 [INFO] ------------------------------------------------------------------------Docker イメージを確認すると ...
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE myimage latest 8ef0bcee6c5d 49 years ago 141MBDockerfile を一切書かず、イメージができました !
起動も通常通り成功しました。
$ docker run --rm myimage . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.3.RELEASE) 2019-03-23 05:01:06.902 INFO 1 --- [ main] s.SpringDockerExampleApplication : Starting SpringDockerExampleApplication on 072b9539cd19 with PID 1 (/app/classes started by root in /) : : :ここまでハマる点は一切なく、想像以上に簡単でした。
ベストプラクティスへの対応の調査
コンテナイメージをビルドするには、7 best practices for building containers のようなベストプラクティスがあります。
今回は、Jib で作成したイメージが以下のプラクティスを満たしているのか調査します。
- PID 1 で起動
 - ビルドキャッシュの最適化
 - 不要なツールの削除
 - イメージの最小化
 - レイヤー数の削減
 - 一般ユーザで実行
 PID 1 で起動
コンテナ停止時はコンテナ内の PID 1 のプロセスにシグナルが送られるため、PID 1 でアプリケーションを起動することが推奨されています。
Spring Boot 起動時のログを見ると ...
2019-03-23 05:01:06.902 INFO 1 --- [ main] s.SpringDockerExampleApplication : Starting SpringDockerExampleApplication on 072b9539cd19 with PID 1 (/app/classes started by root in /)
Starting SpringDockerExampleApplication on 072b9539cd19 with PID 1と出力されており、PID 1 で起動していることが分かります。ビルドキャッシュの最適化
Jib の README にビルドキャッシュの最適化を目指していることが書かれています。
Fast - Deploy your changes fast. Jib separates your application into multiple layers, splitting dependencies from classes. Now you don’t have to wait for Docker to rebuild your entire Java application - just deploy the layers that changed.
詳細は調べていませんが、これを自作の Dockerfile で再現するには、ある程度 Docker の知識が必要になってきそうです。
不要なツールの削除
コンテナには何が入っているのか調べるため docker exec で sh を実行しようとすると、以下のようにエラーとなりました。
$ docker exec -it $(docker container ls | grep myimage | awk '{print $1}') sh OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknownFAQ の where is bash によると ...
By default, Jib uses distroless/java as the base image. Distroless images contain only runtime dependencies. They do not contain package managers, shells or any other programs you would expect to find in a standard Linux distribution. Check out the distroless project for more information about distroless images.
If you would like to include a shell for debugging, set the base image to gcr.io/distroless/java:debug instead. The shell will be located at /busybox/sh. Note that :debug images are not recommended for production use.
実行に必要な依存関係しか入っておらず、デバッグ用にシェルがほしいならベースイメージを変更するようにとのことです。
ここまで不要なツールを削除した Java のイメージを自作するのは結構大変だと思います。ちなみに、Java についても、java コマンドは入っていましたが、javac コマンドは入っていませんでした。
$ docker run --rm --entrypoint java myimage -version openjdk version "1.8.0_181" OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-2~deb9u1-b13) OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode) $ docker run --rm --entrypoint javac myimage -version docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"javac\": executable file not found in $PATH": unknown. ~/Documents/src/os1ma/spring-docker-example (master) $イメージの最小化
イメージサイズを自作の Dockerfile からビルドした場合と比較します。
Dockerfile は以下の通りです。1
FROM openjdk:8u181-jre-alpine3.8 RUN addgroup -S -g 1000 app \ && adduser -D -H -S -G app -u 1000 app USER app WORKDIR /app COPY target/*.jar . # *.jar を展開するために sh -c を実行し、 # さらに PID 1 で java プロセスを起動するため exec を使用 CMD ["sh", "-c", "exec java -jar *.jar"]JAR と Docker イメージをビルドします。
$ ./mvnw clean package $ docker build -t myimage-openjdk .イメージサイズを比較すると ...
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE myimage-openjdk latest 262fd5db197f 9 seconds ago 99.8MB myimage latest 8ef0bcee6c5d 49 years ago 141MBopenjdk:8u181-jre-alpine3.8 をベースに自作した方が小さくなりました。
とはいえ、Alpine ベースで提供されていない2 Amazon Correto を利用した場合よりは小さくなっています。
REPOSITORY TAG IMAGE ID CREATED SIZE myimage-amazon latest dd6500aa12d0 4 minutes ago 542MBなお、Amazon Correto を使った場合の Dockerfile は以下です。
FROM amazoncorretto:8u202 RUN groupadd -r -g 1000 app \ && useradd -M -r -g app -u 1000 app USER app WORKDIR /app COPY target/*.jar . # *.jar を展開するために sh -c を実行し、 # さらに PID 1 で java プロセスを起動するため exec を使用 CMD ["sh", "-c", "exec java -jar *.jar"]レイヤー数の削減
Jib で作成したイメージと Dockerfile から作成したイメージのレイヤ数を比較すると ...
$ docker image inspect myimage | jq '.[0].RootFS.Layers' [ "sha256:44873b569cf340a616026da244ebee1bbd7d3f2bb7a0dbf7a6526c4416dea61a", "sha256:87c747af6dc3478b57493f1f3a2e0821696f8d56b86b1fef1128d1d74881cf7c", "sha256:6189abe095d53c1c9f2bfc8f50128ee876b9a5d10f9eda1564e5f5357d6ffe61", "sha256:cdfa1ce6eb7e772884aeab7a2560bee6988f7bba47addeedb636842d72a23702", "sha256:5e1ddec1ac755324b4489ba4030512f5f461ace13be7f9617982b0a12dcaec16", "sha256:edb7e86863542fc9cfaee3eb48af4678560b396dd5dcc18ee89e089aee23abf4", "sha256:769f5c896c76f8bf79881949a0d55cbd768405580f1ae87b4519b16da83d2387" ] $ docker image inspect myimage-openjdk | jq '.[0].RootFS.Layers' [ "sha256:7bff100f35cb359a368537bb07829b055fe8e0b1cb01085a3a628ae9c187c7b8", "sha256:dbc783c89851d29114fb01fd509a84363e2040134e45181354051058494d2453", "sha256:178e89c683ce4b8f572eb7d89c48a70e39f740b2c81274a58092e02a764732d6", "sha256:9f4e44fd5bdc31d8dbe3074d8db6b5ccc13504f65cc3e3bfac580f2f1710840b", "sha256:f5892329ace5f98e26db46cf436780fa28747a95303a2e283a9ae41be0246551", "sha256:426afce096026f233072c74b991ceec088b7278166096d364bf4db9f214cb238" ]自作した方が 1 つレイヤーが少なくなっています。
Jib ではビルド時にレイヤキャッシュを利用していることが関係しているのかもしれません。一般ユーザで実行
コンテナ内で root ユーザを使わないよう、Dockerfile で一般ユーザを作成するというプラクティスがあります。
しかし、Jib で作成したイメージを起動した際のログには
(/app/classes started by root in /)と書かれており、root ユーザで実行されていました。2019-03-23 05:01:06.902 INFO 1 --- [ main] s.SpringDockerExampleApplication : Starting SpringDockerExampleApplication on 072b9539cd19 with PID 1 (/app/classes started by root in /)一般ユーザで起動するイメージを作成するには、pom.xml に追記が必要でした。
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>1.0.2</version> <configuration> <to> <image>myimage</image> </to> <container> <user>1000:1000</user> </container> </configuration> </plugin>これで起動してみると ...
$ ./mvnw compile jib:dockerBuild $ docker run --rm myimage . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.3.RELEASE) 2019-03-23 06:24:42.445 INFO 1 --- [ main] s.SpringDockerExampleApplication : Starting SpringDockerExampleApplication on c864fdbdb6a7 with PID 1 (/app/classes started by ? in /)
(/app/classes started by ? in /)と表示されており、たしかに root ユーザでなくなりました。ちなみに、コンテナのユーザは以下のように起動時に設定することも可能です。
$ docker run --rm -u 1000:1000 myimageまとめ
Jib のセットアップは非常に簡単で、たしかに結構良いイメージを作ってくれました。
また、Jib はコンテナレジストリへのプッシュや Slaffold との連携も可能とのことなので、CI / CD の中で使うと面白そうです。
Java を Native バイナリとして動かす Quarkus にも対応してくれると嬉しいです。
マルチステージビルドでは .m2 のキャッシュが効かずビルドに時間がかかるため、マルチステージビルドは使っていません。マルチステージビルドで .m2 のキャッシュを利用する方法は「Buildkitを使ってMulti-stage BuildでMavenのキャッシュを効かせる」の通りです。 ↩
- 投稿日:2019-03-23T15:39:57+09:00
 
GitPitchをローカルでプレビューできるdocker imageを作った
どうも、うじまるです
皆さんGitPitch使ってますか? 僕はつい最近使い始めました。
Markdownで書くことができ、GitHub等のサービスにリモートリポジトリを作ってPITCHME.mdを置いておくとスライドにしてくれます。
詳しくは GitHubだけで超高機能なスライド資料が作れる「GitPitch」の使い方を徹底解説! - paiza開発日記作った経緯
ただこのサービス、GitHubにpushしないとスライドの状態にならないのです。
ちょっと編集してプレビューを見たい人間なのでそれだと面倒くさいなーっと思いgitpitchをローカルでプレビューしたいんだけどいい感じのができなさそう
— うじまる? (@uzimaru0000) 2019年3月20日というTweetをしたところ
To develop and preview your slide decks locally you need GitPitch Desktop - https://t.co/ftXUjSEZpR
— David Russell (@gitpitch) 2019年3月20日っと来たので「おーあるやんけー」って思ってリンクを見に行ったら
有料やんけ!!
っということで作りました。
構成
このoffline版はcorsとかの問題でhttpサーバに乗っけて配信しないとダメっぽいです。
なので、dockerでnginxを起動させそれに乗っけます。このoffline版はスライドの生成に
assets/md/PITCHME.mdを参照しているのでローカルのPITCHME.mdと共有するようにしました。しかし、
docker runでボリュームを設定するさいにnginxが配信するディレクトリ/usr/share/nginx/html/assets/md/PITCHME.mdを設定するのは面倒なので、/usr/share/nginx/html/assets/md/PITCHME.mdを/src/PITCHME.mdのシンボリックリンクにすることにしました。 これでボリュームを設定するときは-v $(pwd):/src:roみたいな感じで設定できます。どうしても別の場所に設定したいと言うときは、
docker runのcommandにPITCHME.mdを絶対パスで指定してください。使い方
上でゴチャゴチャ書いてあるものをまとめると
$ docker run -v $(pwd):/src -p 8080:80 -d uzimaru0000/gitpitch_localでサーバが起動します。
あとは、手元のPITCHME.mdを編集すれば反映されます。課題
即席で作ったのでいろいろと課題があって
---?code=pathで指定したときの挙動がダメ- スーパーリロードしないと更新されないときがある
 - styleの適応が未実装
 他にも本サイトで見るときと挙動が変わる部分が多々あると思います。
気がついた方は、リポジトリにissueを立てたり、PRを出してくれるとありがたいです。最後に
ライセンスとかよく分からないのでもしかしたらOUTかもしれないです。その時は言ってください。消します。
- 投稿日:2019-03-23T12:24:16+09:00
 
docker-composeでfirebase functionsのローカル実行を試してみたメモ
概要
- functionsをローカル実行したかった。
 - [Firebase] Cloud Functionsで消耗したくない人のために、開発環境のベストプラクティスをまとめていったらDockerに行き着いた話(随時更新)がdockerでfirebase functionsを使うサンプルをあげてくれているので、docker-composeで行った。
 - package.jsonが2重管理になってしまっているので、解決法が知りたい。知ってる方いたらコメントで教えていただけると。。。
 環境
- Windows10
 - virtualbox 6.0.4
 - vagrant 2.2.4
 - Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-29-generic x86_64)
 - Docker version 18.09.2, build 6247962
 - docker-compose version 1.23.2, build 1110ad01
 ファイル構成
- bin - firebase - serve-functions-local.sh # 実行用のコマンドを書いたシェル - docker - docker-compose.yml - firebase - Dockerfile - functions - package.json # backendフォルダと同じもの。2重管理やめたい。。 - backend - functions - tsconfig.json - tslint.json - package.json # dockerフォルダと同じもの。2重管理やめたい。。 - src - index.ts - app - firebase.jsonファイル
docker関係の設定
docker/docker-compose.ymlversion: '3' services: garden_firebase: build: ./firebase volumes: - ../backend/functions:/app/functions - /app/functions/node_modules # コンテナ内のnode_modulesを使用 - ../app/.firebaserc:/app/.firebaserc - ../app/firebase.json:/app/firebase.json ports: - 5000:5000 - 9005:9005
functions: Cannot start emulator. Error: Cannot find module '@google-cloud/functions-emulator/src/configとでたので、パッケージをグローバルに1つ追加している。docker/firebase/DockerfileFROM node:8.15.1-alpine # コンテナ上の作業ディレクトリ作成 WORKDIR /app # 後で確認出来るようにpackage.jsonを作成 RUN npm init -y # firebase RUN yarn global add firebase-tools RUN yarn add --dev firebase-tools RUN sed -i -e "s/\(\"scripts\": {\)/\1\n \"firebase\": \"firebase\", /g" /app/package.json # firebase function COPY functions /app/functions # functions用のモジュールをインストールしておく。 RUN cd /app/functions && NODE_ENV=development npm install -y # ローカルでfunctionを実行するために必要 RUN yarn global add @google-cloud/functions-emulator --ignore-enginesfirebase functionsの設定
以下のpackage.jsonは2重管理となってしまっている。ポイントは
firebase serve --only functions -p 5000 -o 0.0.0.0でホストをグローバルにしているところ。コンテナ外からアクセスするために必要。docker/firebase/functions/package.json{ "name": "functions", "scripts": { "lint": "tslint --project tsconfig.json", "build": "tsc", "serve": "npm run build && firebase serve --only functions -p 5000 -o 0.0.0.0", "shell": "npm run build && firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log" }, "main": "lib/index.js", "dependencies": { "firebase-admin": "~7.0.0", "firebase-functions": "^2.2.1" }, "devDependencies": { "tslint": "^5.12.0", "typescript": "^3.2.2" }, "engines": { "node": "8" }, "private": true }/app/firebase.json{ "functions": { "source": "functions", "predeploy": [ "npm --prefix \"$RESOURCE_DIR\" run lint", "npm --prefix \"$RESOURCE_DIR\" run build" ] } }functionsのソース
/backend/functions/src/index.tsimport * as functions from 'firebase-functions'; export const hello = functions.https.onRequest((request, response) => { response.status(200).send("Hello World") });実行コマンド
bin/firebase/local-functions-serve.sh#!/bin/bash # このシェルスクリプトのディレクトリの絶対パスを取得。 bin_dir=$(cd $(dirname $0) && pwd) # docker-composeの起動 cd $bin_dir/../../docker && docker-compose run -p 9005:9005 -p 5000:5000 garden_firebase sh -c 'cd /app/functions && npm run serve'実行
./bin/firebase/serve-functions-local.shで実行。
画面に以下のように出てきたら成功。✔ functions: hello: http://0.0.0.0:5000/{ここはそれぞれ違います}/us-central1/hellovagrantで起動しているならば、そこのIPに
http://{IPアドレス}:5000/{ここはそれぞれ違います}/us-central1/helloとアクセスすればHello Worldが表示されるはず。参考
[Firebase] Cloud Functionsで消耗したくない人のために、開発環境のベストプラクティスをまとめていったらDockerに行き着いた話(随時更新)
ローカルでのファンクションの実行
firebaseローカルサーバ起動時にfunctions: Cannot start emulator. Error: Cannot find module '@google-cloud/functions-emulator/src/configと返された。
Firebase Cloud Function をローカルで実行するときにはまった点
Cloud Functions for Firebaseが最高だった話
DockerでのNodeアプリ構築で学んだこと
firebase-functions-test を使って Firestore の offline テストを書いてみる
Cloud Functions for Firebaseを楽々デバッグするには

