Docker で django 環境

Dockerほんとに便利。

環境構築に手間取らない、ローカルが汚れない。
勉強が、とまらねぇ、、

本題

作りたいwebappのアイデアができたのでDockerを学びながら開発することにしました。
nginx+django+gunicornでサービスを作ってみた経験から、今回はそれを拡張し、 docker+nginx+django+gunicorn+postgresqlでの開発。Dockerとデータベースを追加。 色々探していたらドンピシャでブログ記事があったので、こちらを写経。

testdriven.io

英語ですが、内容はとても丁寧で、随所の補足資料もわかりやすかった。
例えばでいうと、Docker のベストプラクティスについての補足資料。 Docker for Python Developers

内容をつまむと、

  • alpineを使おう。軽いし、パッケージが少ない分安全
  • 多段階ビルドを活用しよう。例えば最初のコンパイルだけフルのpythonを使って、結果だけalpineにコピーするなど。
  • RUN, COPY, ADDはレイヤーを積むのでできるだけ後ろの方で実行
  • latestとタグづけるのではなく、$SHA1でバージョニング
  • imageにいかなる秘密の情報も含めてはいけない

などなど。

基本的に書いてある通りに沿って、疑問に思ったところはさかのぼったり調べたり、すんなり理解できた。

つまった部分 volumeの権限問題

startappでアプリを追加する段階で、コンテナ内でstartappで作成したファイルにホスト側からアクセスできないという権限からみの問題が発生。参考サイトではそんなことは起きてないので調べると、docker for macでは生じない問題らしい。私はWSLのLinux, Ubuntu環境で、これは個別に対処しないといけなかった。

問題の本質は、コンテナ内のコマンドで作成されたファイルはコンテナのユーザーの持ち物になること。

dockerでvolumeをマウントしたときのファイルのowner問題 - Qiita

こちらの記事が頻繁に参照されており、私もお世話になったので引いておく。

まず「うまくいく方法1」を試したのだが、私のコードだとコンテナのイメージがpythonをベースにしてあり

/usr/src/app/entrypoint.sh: line 22: useradd: not found
/usr/src/app/entrypoint.sh: line 23: groupmod: not found
/usr/src/app/entrypoint.sh: exec: line 26: /usr/sbin/gosu: not found

と言われた。 そんなコマンドは入っていないと。しかしbashファイルであるentrypoint.sh自体は実行できてると文句を言いたくなる。Docker側にbashファイルを実行するシステムが入っているのだろうか。使ってるだけの側の人間なのでその辺はわからない。またゆっくり勉強する。

つぎに「うまくいく方法2」。こちらは毎回打つコマンド長くなるとぼやきたくなるが、どうせ後でalias設定するしと自分を納得させる。

docker-compose run -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro -u $(id -u $USER):$(id -g $USER) web python manage.py startapp upload

やっぱり長い。
とはいえ、この方法で作成したuploadというアプリの中のファイルは書き込み可能になっている。これで解決。

drwxr-xr-x 3 ***** ****** 4096 *** ** 11:29 upload

おわり

良記事だった。

その他参考にした記事

nginx
nginxについてまとめ(設定編) - Qiita (logの設定が少し違うかも?) Module ngx_http_log_module