之前写过一个文档 《从源代码构建 Go 开发环境》, 今天增加一个使用 Docker
构建 golang
环境的文档。
文章目录:
- 安装 Docker
- 配置
Docker
镜像仓库的地址
- 配置
- 下载
golang
的Docker
镜像
- 下载
- 使用
golang
镜像
- 使用
golang
的Docker
镜像的一种使用方式
- 一个例子
- 方便以后查阅和直接使用,完整命令如下
1. 安装 Docker
我当前使用的系统环境是 CentOS7
,安装 Docker
使用的命令是 yum install docker*
。至于其它系统,可以到百度查找其对应的安装方式。
2. 配置 Docker
镜像仓库的地址
目前来说,直接访问 Docker
官网的 DockerHub
会比较慢, 不过幸好现在国内出现了一些 DockerHub
的加速网站。 下面使用 ustc
加速器。
修改文件 /etc/docker/daemon.json
,将其内容修改为
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
配置完成后,重启 Docker
服务:systemctl restart docker
这样就可以使用 https://docker.mirrors.ustc.edu.cn
加速器了。
如果 ustc
的加速器速度不够快,还可以尝试一下其它的加速器,具体请参考这里 Docker 镜像加速器
3. 下载 golang
的 Docker
镜像
现在就可以下载 golang
的 Docker
镜像了。
执行命令 docker search golang
就可以查询 golang
镜像的信息了。
$ docker search golang
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/golang Go (golang) is... 1649 [OK]
docker.io docker.io/circleci/golang Go (golang) is... 8
docker.io docker.io/resin/artik710-golang Go (golang) is... 1
docker.io docker.io/resin/artik10-golang Go (golang) is... 0
可以看到,在查询结果中排名第一的,STARS
数量最多, 并且 OFFICIAL
选项下面是 OK
,说明是官方的,所以理论上应该是更可信的。 所以我们就选择使用第一个了。
执行命令 docker pull docker.io/golang
来下载 golang
的官方镜像吧。
[root@fengbo golang]$ docker pull docker.io/golang
Using default tag: latest
Trying to pull repository docker.io/library/golang ...
latest: Pulling from docker.io/library/golang
723254a2c089: Extracting [===============================> ] 40.83 MB/45.12 MB
abe15a44e12f: Download complete
409a28e3cc3d: Download complete
503166935590: Download complete
abe52c89597f: Download complete
ce145c5cf4da: Downloading [===============> ] 31.36 MB/104.3 MB
96e333289084: Download complete
39cd5f38ffb8: Download complete
39cd5f38ffb8: Pulling fs layer
下载好了之后,查看一下镜像的信息 docker images golang
[root@fengbo golang]$ docker images golang
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/golang latest 138bd936fa29 4 weeks ago 733.3 MB
4. 使用 golang
镜像
执行命令 docker run -it --rm golang bash
,测试一下刚刚下载的 golang
镜像
[root@fengbo golang]$ docker run -it --rm golang bash
root@9e46b1255f4b:/go# go version
go version go1.9.2 linux/amd64
可以看到,最新的是 1.9.2
版本的。
查看进到容器后的默认目录
root@9e46b1255f4b:/go# pwd
/go
看来是在 /go
目录下面。
不过因为我们在创建容器的时候加了 --rm
参数,所以当我们执行 exit
命令退出容器的时候,这个临时容器会被删除。
那我们如何使用这个 golang
的镜像来工作呢?
5. golang
的 Docker
镜像的一种使用方式
首先,如果我们把文件直接写在 Docker
容器里面的话,那么数据是无法持久化的。 即使可以使用 docker cp
命令这样的方式把我们的文件复制到容器内部, 或者把文件从容器中复制出来,但是在操作的时候仍会有很多不方便的地方。
而且,在 golang
的镜像中进行 build
操作的时候,程序依赖的第三方包, 会被下载到容器的 /go
目录下面。如果每次容器都删除, 或者每次创建新的容器的时候,都需要从网络上拉取一次第三方包。 如果网速快的话还好,否则时间浪费的有点儿严重。
所以,我们要把主机的目录映射到容器中,这样就可以把文件进行持久化了。
我们可以使用 docker
命令的 -v
参数,把主机的目录映射到容器中。 不过只使用 -v
参数的话,在容器内部操作目录会有权限限制, 所以还需要增加 --privileged
参数给容器放权。
[root@fengbo golang]$ pwd # 查看当前所在的目录
/root/golang
[root@fengbo golang]$ ls -l # 查看当前目录下的子目录和文件等
total 0
drwxrwxrwx. 2 root root 6 Jan 10 01:19 code
drwxrwxrwx. 2 root root 6 Jan 10 01:20 go
[root@fengbo golang]$ docker run \ # 执行 docker 命令,创建一个新的容器并运行这个容器
> -it \ # 使用交互模式
> --rm \ # 当退出这个容器时,系统自动删除这个容器
> -v /root/golang/go:/go \ # 把主机的目录 '/root/golang/go' 映射为容器内的目录 '/go'
> -v /root/golang/code:/code \ # 把主机的目录 '/root/golang/code' 映射为容器内的目录 '/code'
> --privileged \ # 给这个容器超级权限,否则无法操作上面映射进去的两个目录
> docker.io/golang \ # 基于镜像 'docker.io/golang' 创建容器
> bash # 在容器内执行命令 'bash'
> root@fe6be9f3b22d:/go# # 已经进入容器了
我们可以在容器的两个目录 /go
和 /code
里面创建一些文件, 然后返回主机查看。
root@bb2942f33960:/go# echo "hello" > /go/h.txt # 在容器内,创建文件 '/go/h.txt' 并写入数据
root@bb2942f33960:/go# echo "world" > /code/w.txt # 在容器内,创建文件 '/code/w.txt' 并写入数据
root@bb2942f33960:/go# exit # 退出容器
exit
[root@fengbo golang]# find # 已经回到主机了。在主机的 '/root/golang' 目录下查看文件
.
./code
./code/w.txt # 可以看到文件 'w.txt'
./go
./go/h.txt # 以及文件 'h.txt'
[root@fengbo golang]# cat go/h.txt
hello
[root@fengbo golang]# cat code/w.txt
world
使用上面的方法,每次创建了容器,都会把主机上指定的目录映射到容器中,修改的数据也会反映到主机上。
6. 一个例子
在主机的目录 /root/golang/code
里面创建一个 go
源码文件:aha.go
,其内容如下:
package main
import "fmt"
func main() {
fmt.Println("Hello Docker !")
}
接下来启动容器:
[root@fengbo code]$ docker run \
> -it \
> --rm \
> -v /root/golang/go:/go \
> -v /root/golang/code:/code \
> --privileged \
> docker.io/golang bash
root@de6baf248f0c:/go# # 进入容器内了
现在已经进入容器中了。接下来进入目录 /code
,查看文件:
root@de6baf248f0c:/go# cd /code/ # 进入容器内的目录 '/code'
root@de6baf248f0c:/code# ls
aha.go # 可以看到在主机上创建的文件 'aha.go'
使用 go build
命令编译我们刚刚的源码文件;
root@de6baf248f0c:/code# go build aha.go # 编译 'aha.go'
[root@fengbo code]# ls # 查看编译命令执行后的文件状态,多了一个 'aha'
aha aha.go
说明正确编译了。现在回到主机上,执行以下这个编译完成的二进制文件:
root@de6baf248f0c:/code# exit # 退出容器
exit
[root@fengbo code]# ls # 此时已经回到了主机,查看主机目录 '/root/golang/code' 下的文件
aha aha.go # 多了一个 'aha',这个就是在容器中编译的文件了
[root@fengbo code]# ./aha # 在主机上执行编译完成的文件
Hello Docker ! # 执行结果
[root@fengbo code]#
有了 Docker
就是方便不少,前提是网速要快。
7. 方便以后查阅和直接使用,完整命令如下
开启容器
docker run -it --rm -v /root/golang/go:/go -v /root/golang/code:/code --privileged docker.io/golang bash