6.3.1. 前言

其实在之间的 Docker 服务 篇就已经使用过 Docker Compose。不过实现的是集群服务(swarm service), 这里就从一个简单的示例开始介绍 Docker Compose 的使用。

6.3.2. 构建单机服务

由于之间构建的是集群服务(即 docker swarn initdocker swarm join ... 环境),在实际中并没有构建单机应用。其实单机应用同集群应用一样, docker compose 语法并没有什么差别,只是有些语法不通用,这个后续作说明。下面就开始从无到有的构建一个单机应用。

  • 进入任何目录创建文件夹 stand-alone
$ mkdir stand-alone

hello-world-1.0.0.jar 拷贝至该目录(右键 - 在新标签页中打开链接 实现下载)。该 jar 文件运行后访问 8080 端口会返回 HelloWorld 信息,并且每次访问都会加一。

  • 编写 Dockerfile 文件
$ ls
hello-world-1.0.0.jar

$ touch Dockerfile

$ cat Dockerfile

FROM itumate/jdk:8.0.0
RUN mkdir /app
ADD hello-world-1.0.0.jar /app
WORKDIR /app
CMD ["java","-jar","/app/hello-world-1.0.0.jar","--server.port=8080"]

FROM 指定的基础镜像 itumate/jdk:8.0.0 是笔者构建 jdk1.8 基础镜像。你也可以直接使用官方提供的 openjdk 镜像。当然,笔者构建的镜 像你也可以直接进行拉取。

RUN 指令创建一个文件夹 /app

ADD 指令将当前目录下的 hello-world-1.0.0.jar 文件拷贝至 /app 目录,当然你也可以直接使用 CP 指令。

WORKDIR 指令指定工作目录

CMD 指令指定运行容器时运行 hello-world-1.0.0.jar 并指定端口号 8080

Dockerfile 文件就五个指令,共创建五个层。当然实际可以简写,不过笔者为了清晰所以这样写。

  • 编写 docker-compose.yml 文件
$ ls
hello-world-1.0.0.jar Dockerfile

$ touch docker-compose.yml

$ cat docker-compose.yml

version: "3"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "80:8080"

version 指定版本号,这个后续做说明。

services 定义服务。

web 定义服务下的其中一个应用,名称为 web

build 指令同 docker build 指令。

context 指定指令 Dockerfile 所在文件夹,. 表示当前目录。

dockerfile 指定 Dockerfile 文件。

ports 指令指定了服务启动时使用主机 80 端口映射容器 8080 端口。

这样,一个简单的 docker-compose 就定义完成。

6.3.3. 启动单机服务

在当前目录下执行 docker-compose up 指令启动服务。注意,docker-compose 会使用默认服务名称,你也可以使用 -p 参数指定项目名称。

$ ls
hello-world-1.0.0.jar Dockerfile docker-compose.yml

$ docker-compose up

# 输出信息如下:
docker-compose up
Building web
Step 1/5 : FROM itumate/jdk:8.0.0
 ---> 8d8678770f0e
Step 2/5 : RUN mkdir /app
 ---> Running in 13ce9b2567f2
Removing intermediate container 13ce9b2567f2
 ---> 889213b22b13
Step 3/5 : ADD hello-world-1.0.0.jar /app
 ---> dc6355ab2c1a
Step 4/5 : WORKDIR /app
 ---> Running in 79b133a4af3f
Removing intermediate container 79b133a4af3f
 ---> ed4f734f6e87
Step 5/5 : CMD ["java","-jar","/app/hello-world-1.0.0.jar","--server.port=8080"]
 ---> Running in f44ca9233608
Removing intermediate container f44ca9233608
 ---> 5dc7a6e85260
Successfully built 5dc7a6e85260
Successfully tagged docker_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating docker_web_1 ... done
Attaching to docker_web_1
web_1  | 
web_1  |   .   ____          _            __ _ _
web_1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
web_1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
web_1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
web_1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
web_1  |  =========|_|==============|___/=/_/_/_/
web_1  |  :: Spring Boot ::        (v2.1.3.RELEASE)
web_1  | 
web_1  | 2019-03-20 16:55:30.363  INFO 1 --- [           main] c.m.helloworld.HelloWorldApplication     : Starting HelloWorldApplication v1.0.0 on 5467cdbe3346 with PID 1 (/app/hello-world-1.0.0.jar started by root in /app)
web_1  | 2019-03-20 16:55:30.381  INFO 1 --- [           main] c.m.helloworld.HelloWorldApplication     : No active profile set, falling back to default profiles: default
web_1  | 2019-03-20 16:55:32.648  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
web_1  | 2019-03-20 16:55:32.693  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
web_1  | 2019-03-20 16:55:32.693  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.16]
web_1  | 2019-03-20 16:55:32.721  INFO 1 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
web_1  | 2019-03-20 16:55:32.893  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
web_1  | 2019-03-20 16:55:32.894  INFO 1 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2404 ms
web_1  | 2019-03-20 16:55:33.339  INFO 1 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
web_1  | 2019-03-20 16:55:33.688  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
web_1  | 2019-03-20 16:55:33.694  INFO 1 --- [           main] c.m.helloworld.HelloWorldApplication     : Started HelloWorldApplication in 4.017 seconds (JVM running for 4.632)

从输出的信息中可看到,构建项目时使用的名称是 web,然后使用 Dockerfile 构建一个镜像。镜像构建完成后输出服务的日志信息。

你可以使用如下命令查看服务状态:

$ docker-compose ps

    Name                  Command               State          Ports        
----------------------------------------------------------------------------
docker_web_1   java -jar /app/hello-world ...   Up      0.0.0.0:80->8080/tcp

$ docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
5467cdbe3346        docker_web          "java -jar /app/hell…"   3 minutes ago       Up 3 minutes        0.0.0.0:80->8080/tcp   docker_web_1

可以从服务和容器输出信息看出,项目已将主机 80 端口映射到容器 8080 端口。访问 localhost 看输出信息:

$ curl localhost
Hello World - 0

$ curl localhost
Hello World - 1

$ curl localhost
Hello World - 2

.......

看到每访问一次就会增加一次访问次数。这样一个简单的单机服务就启动成功。

6.3.4. 重构服务

修改原 docker-compose.yml 内容,修改后如下:

version: "3"

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    volumes:
      - .:/app

volumes:
  web-data:

再次运行 docker-compose up 命令启动服务:

$ docker-compose up

Creating volume "docker_web-data" with default driver
Creating docker_web_1 ... done
Attaching to docker_web_1
web_1  | 
web_1  |   .   ____          _            __ _ _
web_1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
web_1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
web_1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
web_1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
web_1  |  =========|_|==============|___/=/_/_/_/
web_1  |  :: Spring Boot ::        (v2.1.3.RELEASE)

从输出的日志信息中可以看到,在修改部分内容之后再次使用 docker-compose up 命令启动服务并没有像第一次构建镜像。现在不做任何修改再次执行命令 docker-compose up 命令:

$ docker-compose up

docker_web_1 is up-to-date
Attaching to docker_web_1
web_1  | 
web_1  |   .   ____          _            __ _ _
web_1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
web_1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
web_1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
web_1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
web_1  |  =========|_|==============|___/=/_/_/_/
web_1  |  :: Spring Boot ::        (v2.1.3.RELEASE)

看到,这次的输出信息更加直接。原因是在使用 docker-compose 启动服务时会将信息进行缓存,当下载再起启动服务时会将两次的内容信息做对比。如果信息 做了修改那么进行修改容器信息并重新运行,否则不做任何修改。

这是 docker-compose 的一大优势。

另外,由于使用卷将当前目录下的内容挂载到容器中。当你写的应用程序有使用到这些文件时并且这些文件做了修改。那么你每次修改的文件信息都会在程序中体现出来。

6.3.5. 关闭、下线单机服务

关闭服务如下命令:

# 停止服务
$ docker-compose stop
 or
# 停止服务并删除容器、网络、镜像和卷
$ docker-compose down

6.3.6. 命令说明

  • 后台运行服务

在上面的示例中看到,每次启动服务时都会在控制台上输出日志信息。如果你退出日志那么响应的服务也会被杀死,所以,如果你想要服务在后台运行可以使用 -d 参数:

$ docker-compose up -d

docker-compose up -d
docker_web_1 is up-to-date

查看服务是否运行状态:

$ docker-compose ps
    Name                  Command               State           Ports         
------------------------------------------------------------------------------
docker_web_1   java -jar /app/hello-world ...   Up      0.0.0.0:8080->8080/tcp
  • 运行一次性命令

如果你想使用一次性命令可以使用 run 命令,例如,要查看Web服务可用的环境变量:

$ docker-compose run web env
  • 停止服务
$ docker-compose stop
  • 下线服务并删除卷、网络和容器信息

注意:当前版本如果要同时删除卷信息需要增加 --volumes 参数:

$ docker-compose down

# 同时删除卷增加 --volumes 参数
$ docker-compose --volumes

另外,除了这些命令外。docker-compose 单机服务还有一些可使用命令。你可以使用 --help 命令查询所有命令及命令的相信信息。示例:

# 查看全部命令(只列出部分信息,具体自己使用命令查看)
$ docker-compose --help

...
Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

# 查看某命令信息(只列出部分信息,具体自己使用命令查看)
$ docker-compose build --help

...
Options:
    --compress              Compress the build context using gzip.
    --force-rm              Always remove intermediate containers.
    --no-cache              Do not use cache when building the image.
    --pull                  Always attempt to pull a newer version of the image.
    -m, --memory MEM        Sets memory limit for the build container.
    --build-arg key=val     Set build-time variables for services.
    --parallel              Build images in parallel.
Copyright © MinGRn 2018 Base On Docker v18.09 all right reserved,powered by Gitbook最近修订时间: 2019-03-30

results matching ""

    No results matching ""