Dockerfile实战(翻译)

首先我们用一个老外写来认识或入门

1、编写一个golang web app
# 建一个示例工程目录
$ 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)
}
2、编写Dockerfile
$ 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
3、创建镜像

$ 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"

浏览器测试

Dockerfile实战(翻译)_第1张图片

5、Dockerfile 参数说明

FROM

指定基础镜像, FROM 可以出现多次

FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]

RUN

执行 shell 命令,linux 环境下默认shell环境是/bin/sh -c,命令过长是或执行多条shell命令时可以反斜杠\ 链接

  • RUN
  • RUN ["executable", "param1", "param2"]

CMD

CMD 命令在Dockerfile 中只能有一个,多个时值最后一个生效,它有一下三种格式,但是当省略了executablecommand 时,也就是说在第二种格式下必须定义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

EXPOSE 其实并没有将指定的端口暴露给客户,上面例子中你去掉 docker run 中的 -p 参数,然后访问http://127.0.0.1:8080, 你会发现服务不能用,为了使服务能用必须用-p 参数做端口映射

  • EXPOSE 端口号/协议tcp、udp:若不指定协议,默认为TCP

ENV

设置环境变量,它设置的变量存在于容器的整个生命过程中,有两种格式

  • ENV key value: 用于设置单个变量
  • ENV key=value kye1=value1 ...: 用于一次设置多个变量

ADD

将多个本地或网络源文件(目录)复制到容器的一个绝对路径下,它有两种格式,src 可以使用类似于linux 命令 cp 一样的通配符,linux 环境下可以通过 --chown 来授权用户和组

  • ADD [--chown=:] ...
  • ADD [--chown=:] ["",... ""]

COPY

将多个本地或网络源文件(目录)复制到容器的一个绝对路径下,它有两种格式,src 可以使用类似于linux 命令 cp 一样的通配符,linux 环境下可以通过 --chown 来授权用户和组

  • COPY [--chown=:] ...
  • COPY [--chown=:] ["",... ""]

ENTRYPOINT

ENTRYPOINT 可以将容器配置的像一个命令一样,docker run 后面的参数都将传给ENTRYPOINT, 而且这些参数将覆盖CMDENTRYPOINT 提供的参数,Dockerfile 中只能含一个 ENTRYPOINT

  • ENTRYPOINT ["executable", "param1", "param2"]
  • ENTRYPOINT command param1 param2

ENTRYPOINT 和 CMD 的区别

Dockerfile实战(翻译)_第2张图片

你可能感兴趣的:(微服务)