はじめに
業務でLinuxプログラミングに手を出すことになりました。長年、Windowsプログラミングの世界にいたのでプログラミング環境構築というとWindowsマシーンにVisual Studioをインストールしてツール上でポチポチやって終わりだったのですが、Linuxプログラミングはそうもいかないようです。ということで、まずはLinuxとビルドできる環境を用意することにしました。また、今回は同じ開発環境を開発チーム内で使い回すことを考えて、dockerを用いることにしました。
というわけで、私自身が初心者ということもあり、記事の内容や表現も初心者向けになっています。間違いがありましたらご指摘いただけるとありがたいです。
環境
ホストPC
- macOS Catalina
- Docker version 19.03.2
- docker for macを https://hub.docker.com/ からダウンロードしてインストールしました。
構築したい開発環境
- Linuxディストリビューション Debian 9.2
- gcc, g++などのC/C++コンパイル環境
- zshとテーマ(oh-my-zsh)
Dockerイメージの作成
Dockerは、上記のような開発環境に必要なものを”コンテナ”と呼ばれる箱に入れておき、コンテナをホストPC上で動かす仕組み、というのがざっくりした説明です。
コンテナの素になるのがDockerイメージです。このコンテナの素であるDockerイメージをコピーしてコンテナが作られます。
Dockerイメージはdocker hubから取得したり、"Dockerfile"というイメージの設計図を作成して作ることもできます。
イメージの設計図 Dockerfileの作成する
今回は、Dockerfileでイメージを構築することにしました。理由はDockerfileをメンテしていくことで今後チーム内で環境を改善していきやすいと考えたためです。
今回Dockerfile作成の際にこちらをお手本にしました。ZSH_THEMEを"robbyrussell"からoh-my-zshのテーマである"candy"に置き換えるということを行っています。
FROM debian:9.2
と記載すると、docker hubにあるdebian 9.2をベースにします。docker hubには様々なOfficial imageが用意されていて、ユーザはそれらを利用することができます。
FROM debian:9.2
MAINTAINER miyatada
WORKDIR /home/projects
# Install basic packages.
RUN apt-get update
RUN apt-get install -y gcc g++ make
RUN apt-get install -y software-properties-common zsh curl wget git htop unzip vim telnet less
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install oh-my-zsh and define zsh as default shell
RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true &&\
chsh -s /bin/zsh
# Apply custom theme, disable auto-update and fix backspace displaying space in the prompt
RUN sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="candy"/g' /root/.zshrc &&\
sed -i 's/# DISABLE_AUTO_UPDATE=true/DISABLE_AUTO_UPDATE=true/g' /root/.zshrc &&\
echo TERM=xterm >> /root/.zshrc
CMD ["/bin/zsh"]
Mac上でDockerfileをビルドしてイメージを作成する
Dockerfileが出来上がったら、ファイルがあるディレクトリ内で以下のコマンドを実行します。
$ docker image build -t debian-ccpp .
Sending build context to Docker daemon 2.56kB
Step 1/10 : FROM debian:9.2
---> 6d83de432e98
Step 2/10 : MAINTAINER miyatada
...
Successfully built a48bc5610306
Successfully tagged debian-ccpp:latest
debian-ccppという名前のdockerイメージが出来上がりました。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian-ccpp latest a48bc5610306 4 minutes ago 634MB
Dockerイメージからコンテナを起動しよう
コンテナの起動
先ほど作成したdockerイメージdebian-ccpp
からコンテナを起動してみます。docker run オプション image名 シェル
で起動できます。
-v
オプションをつけるとホストPC上のディレクトリをコンテナ上のディレクトリにマウントできます。今回はホストPC上の/Users/usr1/Documents/GitHub/
をコンテナ上の/home/projects
にマウントしています。
シェルは/bin/bash
でも問題ありません。お好みです。
$ docker run -itv /Users/usr1/Documents/GitHub/:/home/projects debian-ccpp /bin/zsh
root@720295dcd1ee [01:57:42] [/home/projects]
-> #
どんなコンテナが起動しているかはdocker ps
で確認できます。
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
720295dcd1ee debian-ccpp "/bin/zsh" 3 minutes ago Up 3 minutes elegant_faraday
ちなみに、同じイメージでdocker runをもう一度実行すると、同じイメージから異なるコンテナが作成されます。IMAGEは同じですが、CONTAINER IDとNAMESが異なりますね。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7a880e5792a debian-ccpp "/bin/zsh" 7 seconds ago Exited (0) 3 seconds ago busy_ptolemy
720295dcd1ee debian-ccpp "/bin/zsh" 24 minutes ago Up 4 minutes elegant_faraday
コンテナを抜ける
exit
でコンテナを抜けます。
root@720295dcd1ee [02:07:46] [/var/tmp]
-> # exit
抜けると、STATUSが"Exited"になります。この状態ではコンテナは残っているので、再度入ることができます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
720295dcd1ee debian-ccpp "/bin/zsh" 11 minutes ago Exited (0) 50 seconds ago elegant_faraday
抜けたコンテナにもう一度入るには
以下のようにdocker startとdocker attachコマンドでもう一度入りたいコンテナのCONTAINER IDを指定してあげます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
720295dcd1ee debian-ccpp "/bin/zsh" 14 minutes ago Exited (0) 4 minutes ago elegant_faraday
$ docker start 720295dcd1ee
720295dcd1ee
$ docker attach 720295dcd1ee
root@720295dcd1ee [02:13:00] [/home/projects]
-> #
コンテナを削除しなければ、コンテナ内で編集したり追加したファイルは保持されます。
以下はそれを確認するための実験です。timestampファイルを作ってから、exitで抜けて再度コンテナに入ってtimestampファイルがあることを確認できました。
root@720295dcd1ee [02:16:42] [/var/tmp]
-> # ls
root@720295dcd1ee [02:16:43] [/var/tmp]
-> # date > timestamp
root@720295dcd1ee [02:17:00] [/var/tmp]
-> # cat timestamp
Mon Oct 14 02:17:00 UTC 2019
root@720295dcd1ee [02:17:03] [/var/tmp]
-> # ls -ltr
total 4
-rw-r--r-- 1 root root 29 Oct 14 02:17 timestamp
root@720295dcd1ee [02:17:15] [/var/tmp]
-> # exit
$ docker start 720295dcd1ee
720295dcd1ee
root@720295dcd1ee [02:17:25] [/home/projects]
-> # cd /var/tmp
root@720295dcd1ee [02:17:42] [/var/tmp]
-> # ls -ltr
total 4
-rw-r--r-- 1 root root 29 Oct 14 02:17 timestamp
root@720295dcd1ee [02:17:45] [/var/tmp]
-> # cat timestamp
Mon Oct 14 02:17:00 UTC 2019
コンテナの削除
ps rmコマンドでコンテナを削除します。削除すると、コンテナ内で編集したファイルも削除されます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7a880e5792a debian-ccpp "/bin/zsh" 7 seconds ago Exited (0) 3 seconds ago busy_ptolemy
720295dcd1ee debian-ccpp "/bin/zsh" 24 minutes ago Up 4 minutes elegant_faraday
$ docker rm e7a880e5792a
e7a880e5792a
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
720295dcd1ee debian-ccpp "/bin/zsh" 28 minutes ago Up 8 minutes elegant_faraday
まとめ
Mac上にDockerで Debian, C/C++開発環境を構築しました。また、その際に使うdockerコマンドの使い方を記載しました。今後はこれをベースに開発環境をブラッシュアップしていきたいと思っています。