O'REILLYの『Docker』をこれから読む人のために
こんにちは、Docker初学者です。
勉強のためO'REILLYの『Docker』を読み進めていますが、サンプルコードをそのまま使うとめちゃくちゃエラーが出て困った && ググってもなかなかヒットしない(公式の正誤表にも載ってない)(オライリーを入門書として使う私は変人なのかもしれない)ので、現時点(第6章まで)までに対応したエラーの解決方法を取り急ぎまとめました。謎の使命感駆動ライティングです。
『Docker』をこれから読む方のお役に立てれば幸いです!
Chapter3.3 Dockerfileからcowsayイメージを構築する回
FROMで指定しているベースイメージdebianのバージョンが古いせいでエラーが出ました。wheezy
はサポートが終了しているので、現在の安定版buster
に変更します。
# 誤
FROM debian:wheezy
RUN apt-get update && apt-get install -y cowsay fortune
# 正
FROM debian:buster
RUN apt-get update && apt-get install -y cowsay fortune
このDockerfile
からビルドしたcowsayイメージ
の実行コマンドもパスが通っていないとエラーが返ってきます。
$ # 誤
$ docker run test/cowsay-dockerfile "Moo"
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:367: starting container process caused: exec: "Moo": executable file not found in $PATH: unknown.
$ # 正
$ docker run test/cowsay-dockerfile /usr/games/cowsay "Moo"
_____
< Moo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Chapter5.1 "Hello, World!"出力する回
そのまま書き写すと、2行目でIndentationError
が出ます。Python
は括弧(){}の代わりにインデントでコードをグルーピングする言語なので、タブ・スペースのズレは気を付けないとあかんです。
# 誤
from flask import Flask
app = Flask(__name__) #ここのインデント
@app.route('/')
def hello_world():
return 'Hello World!\n'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
# 正
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!\n'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
Chapter5.1 "Hello, World!"出力する回 その2
コンテナにアプリケーションサーバuWSGI(Web Server Gateway Interface)を導入する際、サンプルの通り古いバージョンを指定してしまうとエラーが出ます。最新版の2.0.19に直しましょう。
# 誤
FROM python:3.4
RUN pip install Flask==0.10.1 uWSGI==2.0.8
WORKDIR /app
COPY app /app/
CMD ["uwsgi", "--http", "0.0.0.0:9090", "--wsgi-file", "/app/identidock.py", \ "--callable", "app", "--stats", "0.0.0.0:9191"]
# 正
FROM python:3.4
RUN pip install Flask==0.10.1 uWSGI==2.0.19
WORKDIR /app
COPY app /app/
CMD ["uwsgi", "--http", "0.0.0.0:9090", "--wsgi-file", "/app/identidock.py", \ "--callable", "app", "--stats", "0.0.0.0:9191"]
おまけ その1
せっかくDocker版cowsayを起動したので、cow以外のcowsayを出力させてみました。
$ docker run -it --name cowsay --hostname cowsay debian bash #インタラクティブセッションを要求
root@cowsay:/# apt-get update
root@cowsay:/# apt-get install -y cowsay fortune
root@cowsay:/# /usr/games/fortune | /usr/games/cowsay -l #-lオプションでcow以外のファイルを確認
Cow files in /usr/share/cowsay/cows:
apt bud-frogs bunny calvin cheese cock cower daemon default dragon
dragon-and-cow duck elephant elephant-in-snake eyes flaming-sheep
ghostbusters gnu hellokitty kangaroo kiss koala kosh luke-koala
mech-and-cow milk moofasa moose pony pony-smaller ren sheep skeleton
snowman stegosaurus stimpy suse three-eyes turkey turtle tux unipony
unipony-smaller vader vader-koala www
root@cowsay:/# /usr/games/fortune | /usr/games/cowsay -f dragon #-fオプションで選択
_________________________________________
/ Truth will out this morning. (Which may \
\ really mess things up.) /
-----------------------------------------
\ / \ //\
\ |\___/| / \// \\
/0 0 \__ / // | \ \
/ / \/_/ // | \ \
@_^_@'/ \/_ // | \ \
//_^_/ \/_ // | \ \
( //) | \/// | \ \
( / /) _|_ / ) // | \ _\
( // /) '/,_ _ _/ ( ; -. | _ _\.-~ .-~~~^-.
(( / / )) ,-{ _ `-.|.-~-. .~ `.
(( // / )) '/\ / ~-. _ .-~ .-~^-. \
(( /// )) `. { } / \ \
(( / )) .----~-.\ \-' .~ \ `. \^-.
///.----..> \ _ -~ `. ^-` ^-_
///-._ _ _ _ _ _ _}^ - - - - ~ ~-- ,.-~
/.-~
root@cowsay:/# /usr/games/fortune | /usr/games/cowsay -f tux
_______________________________________
/ He was part of my dream, of course -- \
| but then I was part of his dream too. |
| |
\ -- Lewis Carroll /
---------------------------------------
\
\
.--.
|o_o |
|:_/ |
// \ \
(| | )
/'\_ _/`\
\___)=(___/
おまけ その2
ポケモンバージョンのPokemonsay in Dockerがあったので、やってみました。
$ docker run --rm -it xaviervia/pokemonsay 'Hello World!'
Chapter6 シンプルWebアプリケーションを作成する回
第5章と同じく、Pythonファイルのインデントと導入するライブラリのバージョンに気を付けないとエラーが出ます。あと個人的にredisとradisのスペルミス沼にハマってしまいました。(どっちもあってややこしいね!)
# 誤
RUN pip install Flask==0.10.1 uWSGI==2.0.19 requests==2.0.8 redis==2.5.1
# 正
RUN pip install Flask==0.10.1 uWSGI==2.0.19 requests==2.10.0 redis==3.0.0
# 誤
redis:
image: redis:3.0
# 正
redis:
image: redis:6.2.4
なんで指定しているバージョンが違うの?
Dockerfile
とdocker-composer.yml
でライブラリのバージョン表記が違うのは、前者はPython用のクライアントライブラリ、後者はコンテナ(サービス)とそれぞれインストールしているものが違うからです。
latestタグは非推奨?
Dockerは何も指定しない場合デフォルトでlatest
タグがつきます。しかしこれはバージョンの自動更新を強制するものではないため、イメージをpullする際もpushする際もバージョンを明示することが推奨されています。
出力結果
入力情報から一意にモンスターを生成してくれるAPI、dnmonsterを使用したサンプルでした。かわいい
教訓
オライリー本が難易度的な意味で入門書として適切かどうかは個人差あるとして、発行年が比較的古い(今回は5年前)ものを参照するにはそれなりの覚悟が必要。
参考