技術書をハンズオンするための最低限の環境をdockerで作る[Ubuntu]!!
こんにちは、あと一年で社会人になるので今のうちにいろいろ勉強しているhagaahiroです!
最近の趣味は技術書を積むことです。
最近の思いとして、
「dockerとかの仕組みを低レイヤから理解したいからLinux系の本を買ってハンズオンしてるんだけど、結局環境がubuntuがほとんど
dockerで環境作ってからやることが多い。。。😂」
というのがあります。
技術書にはハンズオンがついているものも多くあります。
ただ、そのハンズオンの環境構築に詰まることも往々にしてあります。
自分はMacOSを使用しているのですが、技術書はUbuntuを使われていることが非常に多いです。
vagrantを立ち上げるのも時間がかかるので、ちょっとめんどくさいということもあります。
そこでこの記事では、
さっさと技術書に書いてある環境構築を終わらせて、本の本題に入りたい人向けに、dockerを使った環境構築方法
をメモがてら書いていきます。
ゴールとしては、技術書に書いてある環境をdockerで気軽にさくっと構築できるようになることとします。
なお、「そもそもコンテナとは」「dockerとは」のような話は他の記事に譲ることとします。
記事の最後に参考にさせていただいた記事リストも載せておきます。
前提(私の環境)
- MacOSを使用
- dockerアプリはダウンロード済み
この記事では例として『[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識』で使用される環境を作成していきます。
dockerを使って環境構築をしてみる
今回は下記のような環境を作成することをゴールとします。
- Ubuntuを使用する
- binutils、buildessential、sysstatをパッケージとして入れる
- straceコマンド、macコマンドを使えるようにする
ここまでをやります。
最終的にはとても簡単なファイルになります。
Dockerfileからdocker imageを作成
まずはDockerfileからdocker imageを作成してみようと思います。
Dockerfile -> build -> docker imageというのが流れになります。
docker imageとは
docker imageとはdockerコンテナを立ち上げる元となるものです。
詳しくはこちらの記事を!
Dockerfileとは
Dockerfileとはdocker imageの設計図となるものです。
このファイルに記述した情報を元にimageを作成します。
下記の例のようにINSTRUCTION arguments
の形で記述します。
FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
ではここまでを実際に自分の環境でやってみましょう。dockerアプリ自体はダウンロードしておいて下さい。
$ mkdir linux-docker-practice # 任意のディレクトリを作成
$ cd linux-docker-practice
$ touch Dockerfile # Dockerfileを作成
実際にDockerfileを開いて、コードを記述します。
今回だと下記のようなコードが出来上がります。
FROM ubuntu:latest
RUN apt-get update && \
apt-get install git binutils build-essential \
sysstat strace man -y \
&& mkdir /workdir
このファイルは下記のことをしています。
- ベースイメージとしてUbuntuの最新版を指定
-
apt-get
でパッケージをインストール- git, binutils, build-essential, sysstat, strace, manをインストールしています。
- ちなみにMacでは
homebrew
がよく使われます。
-
-y
はinstall中に聞かれる質問を全てYesで回答するために指定 -
mkdir /workdir
でリモートコンテナ内にworkdirというディレクトリを作成- 後述する「ホストをコンテナにマウント」するためにやっています。
コードの内容を見ていきましょう。
FROM
まず、ファイルの1行目にFROMという記述があり、ubuntu:latest
と指定されています。
FROMはベースイメージを指定するものです。
ベースイメージとは、イメージレイヤーの一番下になるものです。
ここが基本となって後続の処理が走ることになります。
例えば、Linuxコマンドを実行するには当然ながらLinux(Linuxの種類としてUbuntuなどがある)が必要です。
apt-get
やtouch
などのLinuxコマンドを指定するにはUbuntuが入っている必要があります。
MacOSだとapt-getは使えません。
FROMはDockerfileの1行目に記述するようにしましょう。
RUN
RUNは指定したアクションをimageが実行するためのものです。
RUNごとにレイヤーが作られるので、基本的には分けて書くのではなく、つなげて書く方が良いです。
レイヤーが増えてイメージが大きくなるとそれだけ非効率なコンテナになってしまいます。
例えば、下記の二種類の書き方だと後者の方が良いです。
# NG
FROM ubuntu:latest
RUN touch test
RUN echo 'ohayo' > test
RUN cat test
# OK
FROM ubuntu:latest
RUN touch test && echo 'ohayo' > test \
cat test
&&
でコマンドをつなぐことができます。
\
で改行ができます。
ここまででざっくりとDockerfileの中身について解説しました。
では、作成したDockerfileをビルドしてdocker imageを作成しましょう。
$ cd linux-docker-practice # Dockerfileがあるディレクトリに移動
$ docker build -t ubuntu-latest . # ubuntu-imageという名前をつけてカレンとディレクトでビルド
$ docker images
docker build <Dockerfileがあるディレクトリ>
とすることでdocker imageを作成できます。
この時に、-t <name>
とすることでdocker imageに名前をつけて管理することができます。
実行してみます。
[~/Desktop/tameshite-linux] $ docker build -t ubuntu-latest .
[+] Building 4.0s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 3.8s
=> [auth] library/ubuntu:pull token for registry-1.docker.io 0.0s
=> [1/2] FROM docker.io/library/ubuntu:latest@sha256:3c9c713e0979e9bd6061ed52ac1e9e1f246c9495aa063619d9d695 0.0s
=> CACHED [2/2] RUN apt-get update && apt-get install git binutils build-essential sysstat strace m 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:fd94075efd8f2f56454f55c953b2a35068e989c5846c9f657650cc326140e5df 0.0s
=> => naming to docker.io/library/ubuntu-latest 0.0s
[~/Desktop/tameshite-linux]
docker images
で作成したイメージを確認してみましょう。
[~/Desktop/tameshite-linux] $ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu-latest latest fd94075efd8f 1 hours ago 381MB
さてここまでで、Dockerfileを作成し、そのDockerfileからdocker imageを構築することができました。
ただしこのままでは実際にコードを動かしたりできないので、実行環境であるコンテナを起動する必要があります。
docker imageからコンテナを立ち上げる
まずはコードを実行していきましょう。
$ docker run -it -v ~/Desktop/linux-docker-practice:/workdir ubuntu-latest bash
root@d374440bc52b:/# cd workdir
root@d374440bc52b:/workdir# ls
Dockerfile
ここまでで下記のことをしました。
- コンテナを作成し、起動。ホストのフォルダをコンテナにマウント
- コンテナにアクセスし、workdirに移動
- lsコマンドを実行し、Dockerfileがあることを確認
コマンドを確認していきましょう。
$ docker run -it -v <hostのディレクトリpath>:<コンテナのファルパス> <name or image id> bash
-
docker run
- コンテナを作成し、起動する
-
-i
- キーボードからの入力をホストからコンテナに繋ぐことができる。これを指定しないとコンテナアクセス後に
cd
とかしても動かない
- キーボードからの入力をホストからコンテナに繋ぐことができる。これを指定しないとコンテナアクセス後に
-
-t
- 出力を整理する。補完なども効くようになる
-
-it
としてにdocker run時にはほぼ全ての場合で指定しておくと良い
-
-v <hostのディレクトリpath>:<コンテナのファルパス>
- 立ち上げたコンテナ内から自分のPC上にあるフォルダにアクセスできるようにする
-
:
前後は順不同なので注意
ここでやっているようにわざわざホストのファイルにアクセスしなくても、コンテナ内でフォルダを作ればいいじゃんということになりますよね。
- コンテナ内にファイルをおくと、コンテナが大きくなってしまう
- コードはホストに置いておいて、実行する時にコンテナを使うのが良い
という理由があるのでマウントをするようにしています。
さてこれで環境構築が完了しました。
Macだとcommand not found
となるようなsar
やstrace
も使えるようになっていると思います。
まとめ
私自身、dockerをしっかりと使ったことがないので、説明が不十分だったりする箇所もあるかと思います。
気になる点がございましたら、コメント欄で教えていただけると幸いです🙇♀️
これで心置きなく、技術書のハンズオンができますね!!
ここまで読んでいただきありがとうございました!
Discussion