こんにちは,米国データサイエンティストのかめ(@usdatascientist)です.
Docker超入門も3回目に突入しました!今回の記事ではDockerのコンテナに入って,作業をしてみようと思います.
前回の記事では,Docker Hubに登録し,hello-worldのDocker imageをpullしてrunするところまでをやりました.
(まだ前回の記事を読んでない人は是非読んでくださいね!)
しかし,hello-worldのimageにはOSが入っていないので,テキスト出力して終わりでした.
今回はubuntuのDocker imageを使って,コンテナに入ってみようと思います!
大丈夫です.今回と次回の記事でなんとなーくわかってくるはず!Dockerはエンジニア必須ツールな上にできる人が少ないので,このスキルは絶対重宝されます.頑張りましょう!
(追記:Docker動画講座作りました.Dockerについてもっと学びたい人は是非!14時間にも及ぶ超壮大講座です.
目次
UbuntuのDocker imageをrunしてみる
今回はhello-worldではなくて,ubuntuのDocker imageを使います.
前回に記事ではpullしてrunしましたよね? 実はDockerは,指定されたimageをrunする時にローカルのimageを見にいきます.
そこで,ローカルのimageがない場合,指定されたレジストリ(今回のケースだとDocker Hub)にそのimageを取りに行き,runします.
つまり,わざわざpullしなくても,runを実行すれば勝手にpullしてくれるのです.
てことでいきなりrunしてみよう!ubuntuのDocker image名は ubuntu です.
1 |
$docker run -it ubuntu bash |
runした結果をみてみると,確かにpullしてるのがわかると思います.
この4つpullされているのは,ubuntuのDocker imageを構成するDocker image layerです.
帰らないでーーーww
なにも難しいことはございません.Docker imageというのはOSが入ってpythonが入って,Rubyが入って・・・と,それぞれのパッケージごとに定義されたlayerの塊なのです.
↑こんな感じ. なんでLayerごとに別れているかというと,例えばこのimageに機能を追加した新しいDocker imageをつくったとき,共通の部分は新しく作る必要がなくなるからです.
同じ部分は複製せず,共有することでストレージが節約できます.
Docker imageをpullする時も,すでに同じlayerがローカルにあったらpullしなくて済むので時間が短縮されるのです.素晴らしい!
それは,コンテナに入ってなにか更新することで,その都度新しいlayerが追加されます.
正確には更新後commitというコマンドでsaveする必要があります.Gitみたいですね!(Gitについてまだ勉強していない人はこちらに連載しております.)
ちなみに,’2746a4a261c9’などの乱数時はlayer IDです.
先ほどの $docker run -it ubuntu bash コマンドで,もうコンテナに入っているはずです.
それでは,なにかコンテナを更新してみます.まずTerminalをみてみましょう.
コンテナを実行しbashを起動したので,コンテナの中に入ることができました.rootというのはコンテナ内のuserで,デフォルトだとroot権限での実行になります.
これは連載の後半でまた話しますが,非常に重要なことなので覚えておきましょう.
デフォルトだとroot権限になってしまうので,実際の業務ではセキュリティ問題になるケースが多いです.
試しに $pwd して $ls してみましょう.
$pwd: カレントディレクトリのPATH表示
$ls: カレントディレクトリのファイル一覧
1 2 3 4 5 |
root@e8d053a58c8a:/# pwd / root@e8d053a58c8a:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@e8d053a58c8a:/# |
また,
$ls の結果をみてわかる通り,自分のローカルPCとは全く違うものになっています.
そうです.コンテナ内は別のファイルシステムになっており,実行時に指定しない限りローカルPC(ホストOSといいます)のファイルシステムにはアクセスできません.これも重要なので覚えておきましょう!
それでは,コンテナ内にファイルを作成してみます. $touch {ファイル名} でファイルを作成できます.
1 2 3 |
$touch test root@e8d053a58c8a:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var |
test が作成されていますね.これでもとのubuntuコンテナを更新したことになります.
それでは,コンテナを出て再度入り直してちゃんと
test が保存されているか確認します.
コンテナを出るにはexitするかdetachの2通りあります.
その通り,今回はどちらの方法も例にしてやってみます.
まずはexitから!$exitでコンテナからexitしてみよう!
1 |
$exit |
1 2 3 4 5 |
$ exit exit $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8d053a58c8a ubuntu "bash" About an hour ago Exited (0) 5 seconds ago dreamy_herschel |
今回のコンテナの名前はdreamy_herschelってついてますね.
Dockerは特に指定がなければ勝手にコンテナに名前をつけます. ubuntu はあくまでもimage名です.コンテナには別の名前がつき,今回の場合は dreamy_herschel です.これはランダムなのであなたのコンテナ名は違うはず
ちなみにコンテナ名を指定するときは --name {コンテナ名} というoptionをつけてrunしましょう. $ docker run --name {コンテナ名} -it {IMAGE名:TAG名} bash みたいな感じです.常に動かしておくコンテナを作る場合はnameを指定したほうがいいです.IDだと乱数文字なのでわかりにくいですからね.
それではコンテナをrestartさせます.restartさせずにrunしてしまってエラーに悩むことが多いので注意ですw(私はよくやりますw)
1 2 3 4 5 |
$ docker restart dreamy_herschel dreamy_herschel $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8d053a58c8a ubuntu "bash" 2 hours ago Up 26 seconds dreamy_herschel |
STATUSがUpになっているのを確認し,再度コンテナに入ります.
$docker run コマンドはDocker imageからコンテナを作るコマンドでした.すでにあるコンテナに入るには $docker exec {コンテナ名} を使います.今回もbashを起動してInteractiveに操作したいので -it と bash をつけて実行しましょう.
1 2 3 4 |
$ docker exec -it dreamy_herschel bash root@e8d053a58c8a:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var root@e8d053a58c8a:/# |
コンテナからdetachする
「コンテナを動かしたままにしたい」「止めたくない」という場合はdetachするという方法があります.
ctrl +p+qでdetachできます.(ここままさかのショートカットw コマンドではありません.)
1 2 3 4 |
root@e8d053a58c8a:/# read escape sequence $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8d053a58c8a ubuntu "bash" 2 hours ago Up 12 minutes dreamy_herschel |
detach後, $docker ps -a でSTATUSがUpになってますね.再度 $docker exec コマンドでコンテナに入ってみましょう!
1 2 3 |
$ docker exec -it dreamy_herschel bash root@e8d053a58c8a:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var |
ちゃんとtestがあります♪
detachすると,そのプロセスは残ります.detach後に再度$docker execでコンテナに入ってexitしても,前にdetachしたプロセスは残り続けます.なのでExitedになりません.
detachした時のそのプロセスに戻るには$docker attach コンテナ名/IDを実行します.するとそこでexitするとちゃんとStatusがExitedになります.
実務ではあまりattachすることはないと思いますが,覚えておくといいです.
まとめ
今回はubuntuイメージを使って実際にコンテナを作成,更新,exit&detachをしてみました.
新しいコマンドがたくさん出てきますが,これからの記事でたくさん使うため反復練習で自然に身につくと思います!
- runしたとき,ローカルのimageを探してなければレジストリからpullする
- Docker imageはImage layerから構成される.
- コンテナ間でImage layerを共有することでストレージが節約されている
- コンテナを実行するとデフォルトでroot権限になる
- 指定しない限りコンテナからホストのファイルシステムにはアクセスできない
- コンテナ名は指定しないとランダムにつけらる
- $exit はコンテナを止める
- $docker restart {コンテナ名} でコンテナを再起動
- ctrl + p + q でdetachしてコンテナから抜ける(コンテナは起動したままになる)
- $docker exec -it {コンテナ名} bash で動いているコンテナに入る
こうみると盛りだくさんでしたね!
ここまでくれば,業務で使えるようになるまでもう一息です!Dockerを使えるようになると開発が楽になりますし,プロジェクトに新しい人が入ったときにDocker imageを渡すだけで開発環境を構築できるようになります.
逆に,新しくプロジェクトに入るとき,もしDockerをみんながDockerを使っていたら・・・
Dockerはここ数年で一気に業界標準になりましたので,絶対に基本操作をマスターしましょう!
次回はDockerコンテナをcommitしてdocker imageにするところを記事にしたいと思います!
それでは!
追記:第4回書きました