在docker中写个Hello World

Hello World Docker

示例

  1. 准备hello.cpp
#include<stdio.h>

int main(){
  printf("Hello World Docker\n");
  return 0;
}
  1. 新建Dockerfile文件(不区分大小写,默认指令全大写)
FROM gcc:9.3
# this is in docker filesystem, not host
WORKDIR /usr/src/app
COPY hello.cpp .
RUN g++ hello.cpp -o test
CMD [ "./test" ]

Dockerfile里的指令是按序且相互独立执行的,但第一个指令必须是FROM指令,该指令用于指定基础image(比如示例基于gcc9.3 image)。

WORKDIR指定的是docker daemon处程序运行的位置,非客户端处。

COPY将文件拷贝到WORKDIR中。

RUN在daemon上运行指令。

CMD在daemon上运行cmd命令。

  1. 对docker的操作都是以docker命令开头,在当前目录构建docker并tag为hello:1.0
docker build -t hello:1.0 .

docker会在本目录下搜寻Dockerfile文件,用户也可以通过-f选项指定Dockerfile文件。

显示的构建信息:

Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM gcc:9.3
 ---> e2a33649a4fc
Step 2/5 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 6e517536c8a4
Step 3/5 : COPY hello.cpp .
 ---> Using cache
 ---> 94a4f0ecfe1b
Step 4/5 : RUN g++ hello.cpp -o test
 ---> Using cache
 ---> 92e3862f7e1e
Step 5/5 : CMD [ "./test" ]
 ---> Running in 1e7ffb943e31
Removing intermediate container 1e7ffb943e31
 ---> c0cef7d15884
Successfully built c0cef7d15884
Successfully tagged hello:1.0

构建完成。

  1. 以交互式方式(-i)运行hello:1.0 并别名(--name)为hello
docker run -it --name hello hello:1.0

docker开始运行./test程序,打印:

Hello World Docker
  1. 查看docker当前状态
docker ps -all

显示:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
03fb0b671849        hello:1.0           "./test"            8 seconds ago       Exited (0) 7 seconds ago                       hello

Exited的原因是hello程序运行太快,在ps前就已经退出。

  1. 停止docker运行
docker stop hello
  1. 最后删除docker
docker rm --force hello

此时再ps会发现名为hello的docker已经消失不见。

docker build过程中发生的事

build命令

docker build [OPTIONS] PATH | URL | -
  1. docker build命令是由daemon而非客户端运行的。

  2. docker会首先将PATH(本地目录)下的所有目录和文件,或URL(git仓库)下的所有模块递归的发送到daemon中。

  3. 接着docker会在本目录下搜寻·文件,用户也可以通过-f选项指定Dockerfile文件。

  4. 在运行Dockerfile文件里的指令之前,docker会先验证Dockerfile文件是否有语法问题并报错。

  5. 验证正确后,docker将一个个执行Dockerfile里的指令,每条指令相互独立(也就是说上一条指令的结果不会影响下一条指令,比如cd /tmp并不会让下一条指令在/tmp目录下运行)。若指令执行成功,则将结果提交到一个新的image中(每条指令都将生成一个新的image)。

  6. 当然,docker会将可能重复利用中间生成的临时image(cache)来加速build速度,是否用了cache可以通过(—> Using cache)信息判断。

  7. 在得到最终的imgae时,docker还会自动清理掉最初发过来的文件。

  8. -t选项可以给构建成功后的image指定库或tag(可以有多个)。

Tags: