Help us understand the problem. What is going on with this article?

docker-composeで勉強用のgolang環境を作ってみる

目的

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

作成

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で公開しています。
コンテナは、いろいろ試したいけど環境汚したくないとき等に非常に便利ですね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした