试着使用docker-compose搭建一个用于学习golang的环境

目的 – 目标

我将在Windows上创建一个用于学习Golang的环境。除了Golang,我还希望使用数据库,因此也将创建一个PostgreSQL环境。

环境

    • ホスト

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

制作 (zuò

用于golang的Dockerfile

在Dockerfile中,我们要做的是进行一些操作,包括设置时区、更新yum等,安装最新的vim和golang,并创建一个与主机共享的目录(/share)。

由于通常直接尝试进行yum的更新和软件包的安装会失败,所以要首先通过rpm –rebuilddb命令修复RPM数据库。参考:Docker – Rpmdb checksum is invalid: dCDPT(pkg checksums): xxxx.amzn1 — u解决方法。

在最后一行的 CMD [“/sbin/init”] 是在此容器上启动的进程(Docker 监视容器的进程?)。如果在容器启动后杀死此进程,容器将会中断,而没有此行则容器根本就不会启动。

我个人使用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/目录下,容器启动时会自动执行。
暂时先在/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文件

在构建过程中,您需要指定包含每个Dockerfile的目录名称。此外,由于我们想要保存创建的数据库,所以需要将/var/lib/postgresql目录共享给主机,同时还需要指定volumes中的/share选项以便与主机进行文件共享。

由于我希望通过服务名(postgres)从Golang访问到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。

[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上公开的。
当想要尝试各种东西但又不想弄脏环境时,容器非常方便呢。

广告
将在 10 秒后关闭
bannerAds