之前讲了很多原理性的东西,基本上已经把Docker的大概原理阐述了一遍,这次我们就通过运行一个实例,把Docker容器用起来。
我们先自己用Go语言写一个简单的web服务器程序hello.go,然后再用Docker把它跑起来,Go程序源码如下:
package main import ( "io" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello world!") } func main() { http.HandleFunc("/", hello) http.ListenAndServe(":8000", nil) }
这个程序非常简单,就是启动一个简单的web服务器程序并监听8000端口,当使用浏览器访问IP:8000/
这个地址的时候,程序会给浏览器返回Hello world!
想把上面的程序通过Docker的方式运行起来,就需要制作一个Docker镜像,而制作Docker镜像非常方便的方式就是使用Dockerfile,Dockerfile在这里应该做的事主要是两个:
上面说到的两个步骤,是可以直接通过一个Dockerfile来实现的,也就是Dockerfile的多阶段构建功能(multi-stage), Dockerfile内容如下:
# 使用官方提供的 GO 镜像来编译我们的程序 FROM golang:1.17 # 将工作目录切换为 /compile WORKDIR /compile # 将 hello.go 程序复制到镜像中的/compile目录下 COPY hello.go /compile # 编译生成 hello 可执行程序 RUN GOOS=linux go build hello.go # 使用alpine作为基础镜像 FROM alpine:3.15.0 # 将工作目录切换为 /app WORKDIR /app # alpine 执行 Go 程序需要先安装一下依赖 RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 # 从第一阶段复制 hello 可执行程序到当前目录 COPY --from=0 /compile/hello ./ # 允许外界访问容器的 8000 端口,不写也会默认暴露端口,写上相当于起一个注释的作用 EXPOSE 8000 # 启动 hello 可执行程序 CMD ["./hello"]
在本机工作目录中,执行Dockerfile构建以生成新的镜像:
$ ls Dockerfile hello.go $ docker build -t hello .
-t 是给镜像起一个可读的名字,注意最后还有一个 . 代表Dockerfile所在的目录。
docker build正确执行成功后,就可以看到新的镜像已经生了:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello latest 56173fb23f12 15 minutes ago 11.7MB
下面使用docker run命令将此镜像运行起来:
$ docker run -d -p 8000:8000 56173fb23f12
我们的Go程序监听的是容器的8000端口,这里使用-p指定把容器的8000端口映射到宿主机的8000端口,这样就可以直接使用我本机的浏览器进行访问了。
使用浏览器进行访问:
这样我们的镜像就已经测试完成了,通常我们制作的镜像希望分享给其它人使用,一般公司内部会使用Harbor搭建镜像仓库供内部人员使用,这里我们可以把镜像传到DockerHub公共镜像仓库上去,这样我们的镜像可以被互联网上所有人看到并下载使用,如果没有DockerHub帐号,则先要去官网创建帐号和自己的仓库:DockerHub
使用docker login命令登录到DockerHub上:
$ docker login 输入用户名和密码 Login Succeeded
我的Docker仓库的名字是hackercracker/test
,要根据这个仓库名称给本地的镜像改个名字:
$ docker tag hello hackercracker/test:v1
把镜像推到DockerHub上:
$ docker push hackercracker/test:v1 The push refers to repository [docker.io/hackercracker/test] 24ba23593bae: Pushed 639949c6c224: Pushed c282b654e2d7: Pushed 8d3ac3489996: Mounted from library/alpine v1: digest: sha256:0d45ef82dd579e51fe81b30f7e43071a745a485fcef51867e018970ec205a73d size: 1153
至此,镜像就成功推到DockerHub上了。