目的
Windows上でgolang勉強用の環境を作成します。
golangだけでなく、DBも利用したいのでPostgrSQL環境も合わせて作成します。
環境
- ホスト
- Windows 10 Pro 64bit
- Docker for Windows(Docker Desktop Community) 2.0.0.3
- Docker Engine 18.09.2
- Compose 1.23.2
- コンテナイメージ
- CentOS:7
- golang 1.12.4
- vim latest
- PostgreSQL:latest
- CentOS:7
作成
Dockerfile(golang用)
Dockerfileで実行しようとしていることは、タイムゾーンの設定とyumのアップデート等、最新vimのインストール、golangのインストール、ホストとの共有用ディレクトリの作成(/share)です。
yumのアップデートやパッケージのインストールは、普通にやろうと失敗するので、先にrpm --rebuilddb
でRPM DBを修復します。
参考:Docker - Rpmdb checksum is invalid: dCDPT(pkg checksums): xxxx.amzn1 — u 対処法
最終行のCMD [ "/sbin/init" ]
は、このコンテナ上で起動するプロセス(dockerがコンテナ監視するプロセス?)です。このプロセスをコンテナ起動後にkillするとコンテナは瞬断しますし、逆にこの行がないとそもそも起動しません。
vimは個人的に使うので入れていますが、不要であれば削除しても問題ないです。
/shareが、ホストと共有できるディレクトリなので、ホストでプログラム等を作成して送ることもできるので。
# もちろんdocker cp
でできるから、共有用はいらないのであれば、/shareも削除しても問題ないです。
FROM centos:7
LABEL maintainer "@hirano00o"
ENV GO_INSTALL_DIR /usr/local
ENV HOME /root
ENV GO_VERSION 1.12.4
# set timezone
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# compile and install vim
RUN rpm --rebuilddb && yum update -y && \
yum -y install git gcc ncurses-devel make && \
yum -y install httpd which && \
rm -rf /var/cache/yum/* && \
yum clean all
WORKDIR /usr/local/src/
RUN git clone https://github.com/vim/vim.git && \
cd vim && \
make && make install && make clean && \
rm -rf vim
# Your .vimrc
# ADD .vimrc ~/
# get golang and set $GOPATH
WORKDIR ${GO_INSTALL_DIR}
RUN curl https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz > go.tar.gz && \
tar zxf go.tar.gz && \
rm go.tar.gz
WORKDIR ${HOME}
RUN echo 'export GOROOT=/usr/local/go' >> ${HOME}/.bashrc
RUN echo 'export GOPATH=${HOME}/go' >> ${HOME}/.bashrc
RUN echo 'export PATH=${GOROOT}/bin:${PATH}' >> ${HOME}/.bashrc
RUN mkdir -p ${HOME}/go/src
# make directory to share with host
RUN mkdir -p /share
CMD [ "/sbin/init" ]
Dockerfile(postgres用)
postgresqlイメージのデフォルトは、当然LANGやTIMEZONEはus、UTCなので、Dockerfileで設定しておきます。
参考:Docker Hub公式PostgreSQLで初期化ずみデータベースコンテナを作る
.sql
ファイルを/docker-entrypoint-initdb.d/に置いておくと、コンテナ起動時に自動的に実行してくれます。
とりあえずユーザやテスト用DB作成のsqlファイルを/sqlに作成しておきます。
FROM postgres:latest
LABEL maintainer "@hirano00o"
# set timezone
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8
ADD sql/* /docker-entrypoint-initdb.d/
docker-compose.ymlの作成
build
には、各々のDockerfileを格納しているディレクトリ名を指定しておきます。
また、postgersの/var/lib/postgresql配下は、作成したDBを保持しておきたいためホストと共有、golang側もホストとのファイル共有用に/shareをvolumesに指定しておきます。
golangからpostgresへは、サービス名(postgres)でアクセスしたいので、golangのdepends_on
にpostgresを指定します。
あとApacheを利用するかもしれないので、ホストの8080ポートとコンテナ内の80ポートをつなげておきます。
これくらいしておけば、大体のことはできるでしょう。
version: "3"
services:
postgres:
restart: always
build: postgres
container_name: postgres
volumes:
- db_data:/var/lib/postgresql
ports:
- 5432:5432
golang:
build: golang
container_name: golang
privileged: true
depends_on:
- postgres
volumes:
- host_share:/share
ports:
- 8080:80
volumes:
host_share:
driver: local
driver_opts:
type: none
device: /c/golang-container/share
o: bind
db_data:
driver: local
driver_opts:
type: none
device: /c/golang-container/db
o: bind
device
で指定したディレクトリは、ホスト上のディレクトリですが、コンテナ作成前に予め作成しておかないとエラーとなります。
Creating postgres ... error
ERROR: for postgres Cannot create container for service postgres: error while mounting volume with options: type='none' device='/c/golang-container/db' o='bind': no such file or directory
ERROR: for postgres Cannot create container for service postgres: error while mounting volume with options: type='none' device='/c/golang-container/db' o='bind': no such file or directory
ERROR: Encountered errors while bringing up the project.
実行
実行は、Windowsなので、コマンドプロントかPowerShell上で実行。(下記PowerShell上で実行)
vimのコンパイルが結構時間かかります。
PS C:\golang-container> docker-compose up -d
~省略~
PS C:\golang-container> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0480e929da66 golang-container_golang "/sbin/init" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp golang
cc4d612168ad golang-container_postgres "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp postgres
PS C:\golang-container> docker exec -it golang bash
[root@0480e929da66 ~]# go version
go version go1.12.4 linux/amd64
Apacheを使うなら、コンテナログインしていつもどおりのコマンドで実行。
PS C:\golang-container> docker exec -it golang bash
[root@0480e929da66 ~]# systemctl start httpd
コンテナを削除する場合は、upの反対を実行。
PS C:\golang-container> docker-compose down
Stopping golang ... done
Stopping postgres ... done
Removing golang ... done
Removing postgres ... done
Removing network golang-container_default
余談
コンテナ上で動いているプロセスはこんな感じです。
[root@0480e929da66 ~]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 00:45 ? 00:00:00 /sbin/init
root 24 1 0 00:45 ? 00:00:00 /usr/lib/systemd/systemd-journald
root 26 1 0 00:45 ? 00:00:00 /usr/lib/systemd/systemd-udevd
root 124 1 0 00:45 ? 00:00:00 /usr/lib/systemd/systemd-logind
dbus 125 1 0 00:45 ? 00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --root 192 1 0 00:45 tty1 00:00:00 /sbin/agetty --noclear tty1 linux
root 1970 0 0 00:51 pts/0 00:00:00 bash
root 1987 1 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1988 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1989 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1990 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1991 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1992 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
root 1994 1970 0 00:56 pts/0 00:00:00 ps -ef
/sbin/init
をkillしてみます。
[root@0480e929da66 ~]# kill -9 0
PS C:\golang-container> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0480e929da66 golang-container_golang "/sbin/init" 13 minutes ago Up 13 minutes 0.0.0.0:8080->80/tcp golang
cc4d612168ad golang-container_postgres "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 0.0.0.0:5432->5432/tcp postgres
一瞬で再起動したようですね。もう一度コンテナログインして確認しましたが、何も変わってないように見えます。。。
PS C:\golang-container> docker exec -it golang bash
[root@0480e929da66 ~]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 00:45 ? 00:00:00 /sbin/init
root 24 1 0 00:45 ? 00:00:00 /usr/lib/systemd/systemd-journald
root 26 1 0 00:45 ? 00:00:00 /usr/lib/systemd/systemd-udevd
root 124 1 0 00:45 ? 00:00:00 /usr/lib/systemd/systemd-logind
dbus 125 1 0 00:45 ? 00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --syst
root 192 1 0 00:45 tty1 00:00:00 /sbin/agetty --noclear tty1 linux
root 1987 1 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1988 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1989 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1990 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1991 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 1992 1987 0 00:51 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
root 2029 0 0 00:59 pts/0 00:00:00 bash
root 2042 2029 0 00:59 pts/0 00:00:00 ps -ef
最後に
今回のファイル等は、hirano00o/golang-devenv-dockerで公開しています。
コンテナは、いろいろ試したいけど環境汚したくないとき等に非常に便利ですね。