この記事はDocker超初心者(脳筋)向けです
とあるツール(Ginza)の環境構築の際に、クロスプラットフォームに対応するためDockerを使うことにしたが、コンテナとホストマシンのディレクトリをどう同期させているのかが微妙だったので記録しておく。
自分は身体で覚えるスタイルなので、チュートリアルとかはやらず(よくない)、最小の要素(なるべくシンプルなとこ)から段々欲しいものを追加してツールを学んでいく。そういった脳筋向けの人はきっと同じとこで困っている気がするので、そのための記録でもある。
Dockerfileを書いて、dockerコマンドのみで使うところから
vol.1
一番初めに書いたもの
# ベースイメージ
FROM python:3.9-slim
# 作業ディレクトリ作成
WORKDIR /app
# ライブラリのインストール
RUN apt-get update && \\
apt-get install -y --no-install-recommends \\
build-essential \\
&& rm -rf /var/lib/apt/lists/*
# spaCyとGiNZAをインストール
RUN pip install --no-cache-dir spacy ginza ja_ginza
# spaCyの日本語モデルをダウンロード
RUN python -m spacy download ja_core_news_lg
# ginza_testディレクトリをコピー
COPY ./ginza_test /app/ginza_test
# スクリプトを実行
ENTRYPOINT ["python", "/app/ginza_test/gingin.py"]
最初はこれをbuildし、runさせることでなんとかpyファイルを実行していた。
が、これではgingin.py以外のpyファイルを実行したい時にいちいち書き換えなければいけない。
めんどうなので、シェルを起動する形にしてみる。
vol.2
# ginza_testディレクトリをコピー
COPY ./ginza_test /app/ginza_test
# デフォルトでシェルを起動する
CMD ["bash"]
Dockerfile内でスクリプトを実行するのではなく、シェルを起動した後に、コマンドでpythonファイルを実行する。
これならばginza_test/にあるpyファイルを好きなだけ実行できる。
しかし、COPYでホストマシンのディレクトリをコンテナの作業環境によっこいしょしているので、ファイルの編集内容を同期させるにはいちいちbuildし直さなくてはいけない。
世のDockerユーザーがこんなに面倒なことをしているわけはないと確信しさらに調べると、volumeという概念(ではないと思う)を見つける。
volumeでできること
- コンテナ内のデータを永久保持させる
- ホストとコンテナでディレクトリ同期
- コンテナとコンテナでディレクトリを同期
これやん、ということで、ホストとコンテナでディレクトリを同期させてみる。
docker-compose.ymlに気が付く
volumeを使ってみようと思い立ったところで、dockerコマンドで実行してみようとすると、ふとめんどくさいことに気が付く。
今後同じように追加していきたい時、全部コマンドでやるの?
そこでもしやdocker-composeが活躍するのかと思って調べると、どうやらそうらしい。
Docker Compose 概要 — Docker-docs-ja 24.0 ドキュメント
要するに、
- 複数のコンテナを定義し、同時に管理
- コンテナの設定をコードで一元管理
ができると言っているような気がしたので、docker-composeを導入。
vol.3
FROM python:3.9-slim
WORKDIR /app
RUN apt-get update && \\
apt-get install -y --no-install-recommends \\
build-essential \\
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir spacy ginza ja_ginza
services:
app:
build: .
volumes:
- ./ginza_test:/app/ginza_test
working_dir: /app
command: tail -f /dev/null
ports:
- "8000:8000"
volumes:- ./ginza_test:/app/ginza_test
で、ホストとコンテナのディレクトリを同期している。
実際にこれを
docker compose up
docker compose exec app bash
とすることで、先ほどのvol.2のようにコンテナのbashを使えるようにしつつ、ローカルの編集をそのままコンテナにリアルタイム同期できるようになった。
command: tail -f /dev/null
は、docker-composeにそのままbashと書くとなぜか一瞬で切れてしまうので(なんでなんだろう)gptに聞いたら、これで持続的にコンテナを実行できると教えてくれた。よくわかっていないけど動いているのでいいことにする。
まとめ
せっかく数時間をDocker理解に費やしたので、忘れないように記事にした。
絶対に働き始めたら使うので、もっと理解していこう。
最初からチュートリアルを見ていたらこんなに時間はかからなかったのかもしれないし、あるいは脳筋方法をとったから仕組みが体験として理解できたような気もする。
畢竟、好きな方法で勉強したらいい。