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