Docker 实战(四):Docker Compose

之前都是单个 Docker 容器,现在,基于 Docker Compose,你可以同时控制多个相关联的 Docker 容器。
比如典型的 Nginx + Tomcat + MySQL 的 Web 架构,只需要几个简单的配置,敲击几个命令,原来可能需要好几个小时的工作,现在几分钟就可以搞定。

使用 Compose 主要由以下三步组成:

  • 定义 Dockerfile;
  • 定义 docker-compose.yml;
  • 运行 docker-compose up 启动所有容器。

这里会构造一个 HAProxy + 两个 Tomcat 负载均衡的架构。

目录

1
2
3
4
5
6
7
compose-haproxy-web
- docker-compose.yml
+ haproxy
- haproxy.cfg
+ web
- Dockerfile
- index.html

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
weba:
build: ./web
expose:
- 8080

webb:
build: ./web
expose:
- 8080

haproxy:
image: haproxy:latest
volumes:
- ./haproxy:/haproxy-override
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- weba
- webb
ports:
- "80:80"
- "70:70"
expose:
- "80"
- "70"

haproxy.cfg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
daemon

defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000

frontend balancer
bind 0.0.0.0:80
mode http
default_backend servers

backend servers
option httpchk OPTIONS /
option forwardfor
cookie JSESSIONID prefix
server tomcat1 weba:8080 cookie JSESSIONID_SERVER_1 check inter 5000
server tomcat2 webb:8080 cookie JSESSIONID_SERVER_2 check inter 5000

listen status
mode http
default_backend servers
bind 0.0.0.0:70
stats enable
stats hide-version
stats uri /stats
stats auth admin:password
stats admin if TRUE

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
FROM batizhao/java:8

# 创建者信息
MAINTAINER batizhao <zhaobati@gmail.com>

# Install dependencies
RUN apt-get update && \
apt-get install -y wget tar && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Define commonly used JAVA_HOME variable
ENV TOMCAT_VERSION 8.5.8

# Get Tomcat
RUN wget --no-cookies http://ftp.jaist.ac.jp/pub/apache/tomcat/tomcat-8/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz -O /tmp/tomcat.tgz && \
tar xzvf /tmp/tomcat.tgz -C /opt && \
mv /opt/apache-tomcat-${TOMCAT_VERSION} /opt/tomcat && \
rm /tmp/tomcat.tgz && \
rm -rf /opt/tomcat/webapps/examples && \
rm -rf /opt/tomcat/webapps/docs && \
rm -rf /opt/tomcat/webapps/manager && \
rm -rf /opt/tomcat/webapps/host-manager && \
rm -rf /opt/tomcat/webapps/ROOT/*

ADD index.html /opt/tomcat/webapps/ROOT

ENV CATALINA_HOME /opt/tomcat
ENV PATH $PATH:$CATALINA_HOME/bin

EXPOSE 8080
WORKDIR /opt/tomcat

# Launch Tomcat
CMD ["/opt/tomcat/bin/catalina.sh", "run"]

index.html

1
Hello, Docker.

启动容器

1
2
3
4
5
6
7
8
9
$ docker-compose up
Creating composehaproxyweb_webb_1
Creating composehaproxyweb_weba_1
Creating composehaproxyweb_haproxy_1
Attaching to composehaproxyweb_weba_1, composehaproxyweb_webb_1, composehaproxyweb_haproxy_1
haproxy_1 | <7>haproxy-systemd-wrapper: executing /usr/local/sbin/haproxy -p /run/haproxy.pid -f /usr/local/etc/haproxy/haproxy.cfg -Ds
webb_1 | 30-Nov-2016 12:50:21.524 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.8
weba_1 | 30-Nov-2016 12:50:21.531 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.8
...

访问 http://localhost
可以看到 Hello, Docker.

访问 http://localhost:70/stats

后台运行

增加 -d 参数

1
2
3
4
$ docker-compose up -d
Starting composehaproxyweb_webb_1
Starting composehaproxyweb_weba_1
Starting composehaproxyweb_haproxy_1

查看 compose 进程

1
2
3
4
5
6
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------------------
composehaproxyweb_haproxy_1 /docker-entrypoint.sh hapr ... Up 0.0.0.0:70->70/tcp, 0.0.0.0:80->80/tcp
composehaproxyweb_weba_1 /opt/tomcat/bin/catalina.s ... Up 8080/tcp
composehaproxyweb_webb_1 /opt/tomcat/bin/catalina.s ... Up 8080/tcp

在 weba 上执行命令,比如 env

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ docker-compose run weba env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/tomcat/bin
HOSTNAME=4fd738ffc9b2
TERM=xterm
COMPOSEHAPROXYWEB_WEBA_1_PORT=tcp://172.17.0.2:8080
COMPOSEHAPROXYWEB_WEBA_1_PORT_8080_TCP=tcp://172.17.0.2:8080
COMPOSEHAPROXYWEB_WEBA_1_PORT_8080_TCP_ADDR=172.17.0.2
COMPOSEHAPROXYWEB_WEBA_1_PORT_8080_TCP_PORT=8080
COMPOSEHAPROXYWEB_WEBA_1_PORT_8080_TCP_PROTO=tcp
COMPOSEHAPROXYWEB_WEBA_1_NAME=/composehaproxyweb_weba_run_1/composehaproxyweb_weba_1
COMPOSEHAPROXYWEB_WEBA_1_ENV_TOMCAT_VERSION=8.5.8
COMPOSEHAPROXYWEB_WEBA_1_ENV_CATALINA_HOME=/opt/tomcat
WEBA_PORT=tcp://172.17.0.2:8080
WEBA_PORT_8080_TCP=tcp://172.17.0.2:8080
WEBA_PORT_8080_TCP_ADDR=172.17.0.2
WEBA_PORT_8080_TCP_PORT=8080
WEBA_PORT_8080_TCP_PROTO=tcp
WEBA_NAME=/composehaproxyweb_weba_run_1/weba
WEBA_ENV_TOMCAT_VERSION=8.5.8
WEBA_ENV_CATALINA_HOME=/opt/tomcat
WEBA_1_PORT=tcp://172.17.0.2:8080
WEBA_1_PORT_8080_TCP=tcp://172.17.0.2:8080
WEBA_1_PORT_8080_TCP_ADDR=172.17.0.2
WEBA_1_PORT_8080_TCP_PORT=8080
WEBA_1_PORT_8080_TCP_PROTO=tcp
WEBA_1_NAME=/composehaproxyweb_weba_run_1/weba_1
WEBA_1_ENV_TOMCAT_VERSION=8.5.8
WEBA_1_ENV_CATALINA_HOME=/opt/tomcat
TOMCAT_VERSION=8.5.8
CATALINA_HOME=/opt/tomcat
HOME=/root

停止后台进程

1
2
3
4
$ docker-compose stop
Stopping composehaproxyweb_haproxy_1 ... done
Stopping composehaproxyweb_webb_1 ... done
Stopping composehaproxyweb_weba_1 ... done

问题

No such image

这是缓存造成的一个问题,可能由于你直接手动删除了 compose 生成的 image。
你可以通过 docker-compose ps 查看,也通过 docker-compose rm 直接清除。
想要避免这个问题,你需要 docker-compose down