首先我们用一个老外写来认识或入门
# 建一个示例工程目录
$ mkdir goEampleDocker
$ cd goEampleDocker
# go 工程放到 app 下面
$ mkdir app
$ vi app/app.go
app.go 源码如下
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"log"
"net/http"
"os"
)
func indexHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprintf(w, "This is the RESTful api")
}
func main() {
router := httprouter.New()
router.GET("/", indexHandler)
// print env
env := os.Getenv("APP_ENV")
if env == "production" {
log.Println("Running api server in production mode")
} else {
log.Println("Running api server in dev mode")
}
http.ListenAndServe(":8080", router)
}
$ pwd
/Users/dk/goEampleDocker
$ vi Dockerfile
Dockerfile 内容如下
# FROM 基础镜像
FROM golang
# ARG 参数
ARG app_env
# ENV 环境变量
ENV APP_ENV $app_env
# WORKDIR 工作目录
WORKDIR $GOPATH/src/github.com/user/myProject/app
# COPY 拷贝本地app文件夹到容器
COPY ./app $GOPATH/src/github.com/user/myProject/app
# RUN 执行命令,下载app依赖的包,这是在 WORKDIR 下面进行的
RUN go get ./
# RUN 执行golang工程编译,这是在 WORKDIR 下面进行的,最后编译出app执行文件
RUN go build .
# EXPOSE 容器向外暴露端口号为:8080
EXPOSE 8080
# CMD 容器启动后执行的命令
CMD app
$ pwd
/Users/dk/goEampleDocker
# -t 指定镜像的TAG
$ docker build -t goweb-image ./
Sending build context to Docker daemon 4.096kB
Step 1/9 : FROM golang
---> 4e611157870f
Step 2/9 : ARG app_env
---> Using cache
---> e3cf43a6b9b7
Step 3/9 : ENV APP_ENV $app_env
---> Using cache
---> 0ffc293b29bd
Step 4/9 : WORKDIR $GOPATH/src/github.com/user/myProject/app
---> Using cache
---> 52ccfe541b8b
Step 5/9 : COPY ./app $GOPATH/src/github.com/user/myProject/app
---> Using cache
---> ec8d35bb2426
Step 6/9 : RUN go get ./
---> Using cache
---> a6b1a5cbe050
Step 7/9 : RUN go build .
---> Using cache
---> 33fb154015e8
Step 8/9 : EXPOSE 8080
---> Using cache
---> 7a4f93bd1d93
Step 9/9 : CMD app
---> Using cache
---> 49ebb205b113
Successfully built 49ebb205b113
Successfully tagged goweb-image:latest
创建并运行容器
$ docker run --name goWebEx -p 8888:8080-d goweb-image
ab7f925131f6325858c75fd6711430feafbb39d0fd370c924a2b29b37d18fc7b
$ docker ps -a
CONTAINER ID IMAGE COMMAND
ab7f925131f6 goweb-image "/bin/sh -c app"
浏览器测试
指定基础镜像, FROM 可以出现多次
FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]
执行 shell
命令,linux
环境下默认shell
环境是/bin/sh -c
,命令过长是或执行多条shell
命令时可以反斜杠\
链接
RUN
RUN ["executable", "param1", "param2"]
CMD 命令在Dockerfile
中只能有一个,多个时值最后一个生效,它有一下三种格式,但是当省略了executable
或 command
时,也就是说在第二种格式下必须定义ENTRYPOINT
指令
CMD ["executable","param1","param2"]
: 执行一个程序CMD ["param1","param2"]
: 将作为ENTRYPOINT
的默认参数CMD command param1 param2
:shell 模式执行命令注意1:当CMD使用第二种格式时,CMD 和 ENTRYPOINT 都应该以数组形式定义
注意2:数组模式提供参数的情况下,参数必须用双引号
注意3:执行shell命令时若没有提供shell程序,命令将不会正常运行,比如你要执行 echo $HOME, 必须 CMD [ “sh”, “-c”, “echo $HOME” ]
EXPOSE 其实并没有将指定的端口暴露给客户,上面例子中你去掉 docker run
中的 -p
参数,然后访问http://127.0.0.1:8080
, 你会发现服务不能用,为了使服务能用必须用-p
参数做端口映射
EXPOSE 端口号/协议tcp、udp
:若不指定协议,默认为TCP
设置环境变量,它设置的变量存在于容器的整个生命过程中,有两种格式
ENV key value
: 用于设置单个变量ENV key=value kye1=value1 ...
: 用于一次设置多个变量将多个本地或网络源文件(目录)复制到容器的一个绝对路径下,它有两种格式,src
可以使用类似于linux
命令 cp
一样的通配符,linux
环境下可以通过 --chown
来授权用户和组
ADD [--chown=:] ...
ADD [--chown=:] ["",... ""]
将多个本地或网络源文件(目录)复制到容器的一个绝对路径下,它有两种格式,src
可以使用类似于linux
命令 cp
一样的通配符,linux
环境下可以通过 --chown
来授权用户和组
COPY [--chown=:] ...
COPY [--chown=:] ["",... ""]
ENTRYPOINT 可以将容器配置的像一个命令一样,docker run
后面的参数都将传给ENTRYPOINT
, 而且这些参数将覆盖CMD
为 ENTRYPOINT
提供的参数,Dockerfile
中只能含一个 ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2