カテゴリー: FreeBSDとLinux
参照数: 2034

序章

在宅をしていると、たまに暇な時間が出来ますよね。

そんな時間は、新スキルを身に付けるのに有効です。

ということで、Linuxネタですが、Dockerでも勉強します。

 

基本

Dockerとは、説明するのが面倒なので、詳しいことは、ググって調べて下さい。

簡単に説明すると、仮想マシンほどではないけど、お手軽に仮想化を実現するLinuxです。

kvmのように仮想ハードウェア定義をする程でもないけど、各アプリの依存関係は隔離して使いたいなっていう場合に理想的なツールとなり得ます。

Dockerは、イメージとコンテナという概念があるようで、イメージというのが、コンテナの元で、イメージを元に実行しているのがコンテナで良いと思います。

イメージというのは、仮想ファイルシステムといった考えでも良いと思います。

例えば、Ubuntuイメージからコンテナを作成起動(bash等を起動)して、このコンテナにアプリ(apt install ..)を追加します。

で、bashから抜けるとコンテナが停止します。

停止した後は、起動の仕方で動作が変わるのですが、変更した記録を破棄するような起動の場合、元のイメージに戻ってしまいます。

変更した記録を残しておく起動の場合、変更差分を記録して停止します。

で、この変更差分を永続化したい場合、コミットすることで、新たなイメージとすることが出来ます。

この作成起動とコミット作業を繰り返すこで、理想のイメージに近づき、出来上がったイメージからコンテナを起動して、実現したいことがすぐに使えるような環境を構築することが可能となります。

 

使い方

まー、御託を書いても読んでくれないでしょうから、実技に行きましょう。

dockerのインストールは、よそのサイトを参考にしてセットアップを完了させて下さい。

それでは、みんな大好きUbuntuでも作成してみましょう。

 docker run -it --name testbox ubuntu bash

これは、ubuntuイメージをDockerハブから取ってきて、testboxという名前のコンテナを作成して、bashを起動しろと書いていますよ。

-itは、ホストの標準入出力とくっ付けろということです。これを指定しないと、bashに何も出来なくなりますよ。

実行すると、rootプロンプトが表示されるはずです。

root@hogehoge:/#

この状態が、ubuntuコンテナ内でbashを実行している状態です。

uname -a とかやると、何buntuかわかるはずです。

とりあえず、定番のupdate & upgrade でもやってみて下さい。

ifconfig等がインストールされていないので、

apt install net-tools

を実行してインストールしておきましょう。

飽きたら exitしてしまいましょう。

bashが終了することで、コンテナは、停止することになります。

 

色々やったコンテナをもう一回使いたいからって、docker run させても出来ませんよ。

docker run は、コンテナ作成のコマンドなので、別のコンテナを作ってしまいます。

コンテナを起動するには、docker start を使います。

docker start testbox

とやっても、さっきのrootプロンプトが出て来ませんよね。

実は、起動はしているのですが、ホストの標準入出力とくっついていない状態なのです。

コンテナの起動状態は、以下のコマンドで確認します。

docker ps

STATUSに Up となっていることがわかると思います。

停止しているコンテナも見たい場合、-a を付けることで見れますよ。

では、改めて以下のコマンドを実行します。

docker attach testbox

すると、今度は、rootプロンプトが出て来ますよね。

ということで、基本操作はこんなもんです。

ちなみに、以下のコマンドで、startとattachを一気に出来るので、普段使いは、こちらを使いましょう。

docker start -i testbox


さて、こうやって作っていったコンテナを永続化したい時がやって来ると思います。

永続化することで、イメージとなってくれるので、このイメージから色々なコンテナをさらに作成することが出来るようになるからですね。

docker commit testbox ubuntubox

このコマンドは、testboxコンテナをubuntubox:latestイメージとして構築しろということです。

構築出来たのでしょうが、よくわかりませんよね。

以下のコマンドで確認が出来ますよ。

docker image ls

すると、REPOSITORYにubuntuboxが存在しているはずです。

で、testboxは、どうなったかというと、別にどうにもなっておらず、単に停止しているだけです。

もし、お役御免で、必要無いなら消してしまいましょう。

docker rm testbox

これで、消えました。

作成したubuntuboxイメージから、新たにコンテナを作って色々なアプリをインストールしたくなりましたよね。

では、早速

docker run -it --name testbox2 ubuntubox bash

さぁ、どうでしょうか

rootプロンプトが表示されましたよね。

testboxの子孫としてtestbox2が生まれ変わってくれました。

Dockerって、このようにイメージからコンテナを作成して、コンテナで色々やった結果をイメージにして、さらにコンテナを作る。

この繰り返しで、必要な環境を構築していくわけです。

 


Dockerfile

Dockerの使い方は、わかってもらえたかと思います。

しかし、実際使っていくと、あの時作ったイメージって、どうやったっけ等が発生します。

または、いつも同じようなイメージを作るけど、元のイメージは、最新OSがほしいな等です。

そんな時は、Dockerfileという物を作成することで、解決出来ます。

Dockerfile

FROM ubuntu

RUN apt update

2行だけですけど、立派なDockerfileです。

これは、ubuntuイメージをDockerハブから取ってきてくれって書いていますよ。

ついでに、apt updateコマンドを実行しといてくれってことです。

そして、以下を実行します。

docker build -t ubuntubox2 .

docker run -it --name testbox ubuntubox2 bash

すると、rootプロンプトが表示されましたよね。

まずは、一行目から、Dockerfileの内容で、ubuntubox2イメージを作成してくれ。

2行目は、お馴染みのubuntubox2イメージから、testboxコンテナを作成起動し、bashを実行してくれ。

です。

後は、普通のdockerコマンドを使いこなして作業開始です。

Dockerfileは、もっと色々なことが出来ます。

この辺りは、よそのサイトを参考に実験を繰り返して下さいませ。


docker-compose.yml

いよいよ、佳境に入ってきました。

docker-compose.ymlです。

本来、複数のDockerコンテナを一気に起動したりする為の仕組みのようです。

自分の感覚では、コンテナの起動方法を記述しているようなファイルなのかなって思っています。

このファイルを使うことで、個別のコンテナの起動を、シェルに記述してごにょごょする必要が軽減されます。

ネットワークや仮想ボリューム等も構成する必要がある場合、ここに記述したりもします。

ちょっと、複雑なんで、よそのサイトに丸投げしておきますね。

詳しいことを知りたい方は、ググって下さい。

とりあえず、起動は、以下となります。

docker-compose up

停止は、以下です。

docker-compose down

完璧なdocker-compose.ymlを記述出来れば、こんぐらいで用を足せます。


PostgreSQL

やっと、本題に入れそうです。

途中、手抜きどころもありましたが、ご容赦ください。

早速、Dockerfileとdocker-compose.ymlとinit.shとstart.shを公開しましょう。

Dockerfile

FROM alpine
EXPOSE 5432
RUN apk update
ENV TZ=Asia/Tokyo
RUN apk --update add tzdata
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN apk --update add pcre-dev openssl-dev bash
RUN apk add postgresql
RUN mkdir /run/postgresql && chown postgres:postgres /run/postgresql
RUN su - postgres -c "echo 'export PGDATA=/pgdata/db' >> /var/lib/postgresql/.profile"
WORKDIR /startup

 

docker-compose.yml

version: "3" 
services: 
 db1:
  build:
   context: .
  ports:
   - "5432:5432"
  expose:
   - "5432"
  hostname: pgtest1
  volumes:
   - ./data:/pgdata
   - ./startup:/startup
  tty: true
  working_dir: /startup
  command: bash /startup/start.sh

networks:
 app-tier:
  driver: host

 

startup/init.sh

#/bin/bash
initdb -D /pgdata/db --no-locale -E utf-8 -k
echo listen_addresses = \'0.0.0.0\' >> /pgdata/db/postgresql.conf
echo 'host all all 0.0.0.0/0 trust' >> /pgdata/db/pg_hba.conf
exec

 

startup/start.sh

#/bin/bash
if [ ! -e /pgdata/db ]; then
 mkdir /pgdata/db && chown postgres:postgres /pgdata/db
 su - postgres -c 'bash /startup/init.sh'
fi
su - postgres -c 'pg_ctl start'
bash

 

フォルダ構成

project

├Dockerfile

├docker-compose.yml

└startup

  ├init.sh

  └start.sh

 

この構成で、

docker-compose up

すると、postgresqlサーバが起動し、TCP 5432番へ外部から接続することが出来ます。

このイメージは、alpineという小さいOSを使って作りました。

init.shで、postgresqlの初期設定を行っているので、カスタムしたい方は、ここを改造して下さいませ。

データは、ホストのdataフォルダに残るので、このフォルダだけ持ち出せば、すぐに使うことが出来ますよ。

もし、バージョンを固定して維持しつづけたい場合、イメージをメタデータ毎、バックアップしておけば、外部のDockerシステムでも同じ環境を構築することが可能です。

Dockerって、便利ですね