Docker Compose入门 简介 一般一个宿主机中会生成多个容器,容器与容器之间需要协调工作,有时多个容器之间也需要进行环境的隔离,而Docker Compose就是用来定义和运行多个容器的工具。可以通过一个yaml文件来配置应用程序的服务,并通过命令来管理所有服务的生命周期。
安装步骤 一般可以在Compose repository release page on GitHub 获取到最新版的Docker Compse。
下载 执行以下命令:
1 sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 
如果需要其他版本的Docker Compse,只需要把命令中的1.29.2替换成需要的版本即可。
如果curl安装有问题,可以参照Alternative Install Options  进行安装。
赋予执行权限 1 sudo chmod +x /usr/local/bin/docker-compose 
检查是否安装成功 1 2 >  docker-compose --version docker-compose version 1.29.2, build 5becea4c 
如何使用 基本配置 在docker compose下,存在服务的概念,一个compose配置可以由多个服务来组成,参考如下yaml配置:
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 40 41 42 43 44 45 46 47 version:  "3.9" services:   db_mysql:      image:  mysql      restart:  always      container_name:  my-mysql      ports:        -  10001 :3306      environment:        MYSQL_ROOT_PASSWORD:  new_password_xxx      command:         --default-authentication-plugin=mysql_native_password        --character-set-server=utf8mb4        --collation-server=utf8mb4_unicode_ci      volumes:         -  /usr/local/docker/mysql/data/:/var/lib/mysql        -  /usr/local/docker/mysql/conf.d:/etc/mysql/conf.d       redis:       image:  redis      hostname:  redis-server      restart:  always      container_name:  my-redis      ports:        -  10002 :6379      command:  redis-server  /etc/redis/redis.conf  --appendonly  yes      volumes:         -  /usr/local/docker/redis/conf/redis.conf:/etc/redis/redis.conf       nginx:      image:  nginx      restart:  always      container_name:  my-nginx      ports:        -  80 :80      volumes:         -  /usr/local/docker/nginx/nginx.conf:/etc/nginx/nginx.conf           redis-commander:      container_name:  redis-commander      hostname:  redis-commander      image:  rediscommander/redis-commander:latest      restart:  always      environment:        -  REDIS_HOSTS=local:redis-server:6379      ports:        -  11002 :8081  
存在一个services节点,该节点下定义了三个服务。每个服务会对应到一个镜像,当执行docker-compose up之后,会根据每个服务对应的镜像,生成对应的容器。服务的名称可以自行定义,无强制要求。
在yaml所在目录下执行
1 2 3 4 5 >  docker-compose up -d Creating network "docker-compose_default" with the default driver Creating my-mysql ... done Creating my-nginx ... done Creating my-redis ... done 
up为创建并启动所有容器,-d表示守护态运行。这里不指定配置文件名称,则默认当前目录下的名为docker-compose.yml的文件。不指定项目名称,则默认该配置文件所在的目录名称作为项目名称。
可以看到配置文件所定义的所有服务均正常启动。
1 2 3 4 5 >  docker ps CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                                    NAMES ea6c7d60903d   redis     "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   0.0.0.0:10002->6379/tcp, :::10002->6379/tcp              my-redis 49062f5891e7   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp                        my-nginx d63a6ed103f5   mysql     "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   33060/tcp, 0.0.0.0:10001->3306/tcp, :::10001->3306/tcp   my-mysql 
常用命令 对于docker-compose有如下选项。
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 Commands:   build              Build or rebuild services   config             Validate and view the Compose file   create             Create services   down               Stop and remove resources   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 version information and quit 
讲一些比较常用的。
up命令,用于创建并启动compose项目。
然后就是start、stop等,仅进行启动和停止服务。
如果是执行down命令,在停止所有服务容器的同时,也会删除所有容器以及网络。
如果改变了一个服务的Dockerfile或者构建目录的内容,可以使用build命令对其进行重建。
ps的用法都差不多,查看所有正在运行的容器。
每个命令具体用法,还是要参见--help。
容器与容器间的访问 一般创建容器 当docker创建一个容器时,会将它纳入一个网络。如果是单独创建容器,则会纳入默认的bridge网络中(默认为bridge模式),如:
新建一个tomcat容器:
1 2 >  docker pull tomcat >  docker run --name my-tomcat --rm  -p 8080:8080 -d tomcat 
通过dockers network命令查看
1 2 3 4 5 6 >  docker network ls  NETWORK ID     NAME                     DRIVER    SCOPE 3d18fe44fe65   bridge                   bridge    local de7157fb3e93   docker-compose_default   bridge    local da3cd2189967   host                     host      local 098d7dd513d5   none                     null      local 
可以看到,有一个name为brideg的网络,查看详细信息:
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 40 41 42 43 44 45 46 >  docker network inspect bridge [     {         "Name": "bridge",         "Id": "3d18fe44fe65f8d4f370adc558ce41a92897ce58288fa2f16aa2787dcebd9e0c",         "Created": "2021-07-11T17:04:49.64883344+08:00",         "Scope": "local",         "Driver": "bridge",         "EnableIPv6": false,         "IPAM": {             "Driver": "default",             "Options": null,             "Config": [                 {                     "Subnet": "172.17.0.0/16",                     "Gateway": "172.17.0.1"                 }             ]         },         "Internal": false,         "Attachable": false,         "Ingress": false,         "ConfigFrom": {             "Network": ""         },         "ConfigOnly": false,         "Containers": {             "e42b6c1b108d756cc266cb29d0f6d779c396d62fbc5eef556ad42356ec275b9e": {                 "Name": "my-tomcat",                 "EndpointID": "00e0c410554cb08d4c4c65861d844fc98297f32ca9be628087c934f44bccb82b",                 "MacAddress": "02:42:ac:11:00:02",                 "IPv4Address": "172.17.0.2/16",                 "IPv6Address": ""             }         },         "Options": {             "com.docker.network.bridge.default_bridge": "true",             "com.docker.network.bridge.enable_icc": "true",             "com.docker.network.bridge.enable_ip_masquerade": "true",             "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",             "com.docker.network.bridge.name": "docker0",             "com.docker.network.driver.mtu": "1500"         },         "Labels": {}     } ] 
其中Containers有刚刚创建的my-tomcat容器。
docker-compose创建的网络 在使用docker-compose创建一个项目后,会将该项目中所有的服务(services)都纳入到同一个网络当中,默认的网络名称为项目名加上_default,如上面的docker-compose_default网络。
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 >  docker network inspect docker-compose_default [     {         "Name": "docker-compose_default",         "Id": "de7157fb3e937908299c17cd3d21380a5dca2960a93bcb9da0ed392f5a4d74d7",         "Created": "2021-08-01T10:46:49.281728229+08:00",         "Scope": "local",         "Driver": "bridge",         "EnableIPv6": false,         "IPAM": {             "Driver": "default",             "Options": null,             "Config": [                 {                     "Subnet": "172.19.0.0/16",                     "Gateway": "172.19.0.1"                 }             ]         },         "Internal": false,         "Attachable": true,         "Ingress": false,         "ConfigFrom": {             "Network": ""         },         "ConfigOnly": false,         "Containers": {             "49062f5891e7d12eccbefb19875bcc0bd16b8e79906abb4952bb0420c1d09d72": {                 "Name": "my-nginx",                 "EndpointID": "c3e9773c7cb20222762f37784a24d35912e48edaf332408f61c6be19033382c2",                 "MacAddress": "02:42:ac:13:00:04",                 "IPv4Address": "172.19.0.4/16",                 "IPv6Address": ""             },             "d63a6ed103f525148402f57919648e2e7caadd43d51a36597b058a7ecfedf8e4": {                 "Name": "my-mysql",                 "EndpointID": "391283e8835fa8107c6eb95ef946ffabaff8daa9ac5f6325274224f40925cead",                 "MacAddress": "02:42:ac:13:00:03",                 "IPv4Address": "172.19.0.3/16",                 "IPv6Address": ""             },             "ea6c7d60903ded82d4c26d5fa47cdcdb005eba94ff5ff825e65e3815e44aab88": {                 "Name": "my-redis",                 "EndpointID": "1dc8f641e6599117fbc9ba605a0940ed1f71b630646db2553670d64fd361d853",                 "MacAddress": "02:42:ac:13:00:02",                 "IPv4Address": "172.19.0.2/16",                 "IPv6Address": ""             }         },         "Options": {},         "Labels": {             "com.docker.compose.network": "default",             "com.docker.compose.project": "docker-compose",             "com.docker.compose.version": "1.29.2"         }     } ] 
其中包含了我们创建的三个服务容器。
容器与容器间需要进行网络通信,使用的是CONTAINER_IP:CONTAINER_PORT,而不是映射到宿主机的ip和端口。
举个例子,新加入一个服务到上面的docker-compose.yml中。
1 2 3 4 5 6 7 8 9 10 11 12 version:  3.9 services:   redis-commander:      container_name:  redis-commander      hostname:  redis-commander      image:  rediscommander/redis-commander:latest      restart:  always      environment:        -  REDIS_HOSTS=local:redis:6379      ports:        -  11002 :8081  
environment需要配置redis容器的地址,这里使用local:redis:6379,其中的redis为compose中定义的服务名,通过服务名,docker可以自己获取该服务的当前ip。端口使用的是6379,而非映射的10002。
保存yml后,重新执行docker-compose up -d,会更新有变化的容器。
1 2 3 4 5 6 7 8 9 10 11 12 13 >  docker-compose up -d Pulling redis-commander (rediscommander/redis-commander:latest)... latest: Pulling from rediscommander/redis-commander 339de151aab4: Pull complete f732fa32fc61: Pull complete ef60bb667d5a: Pull complete 4f50fa5032a4: Pull complete Digest: sha256:19cd0c49f418779fa2822a0496c5e6516d0c792effc39ed20089e6268477e40a Status: Downloaded newer image for rediscommander/redis-commander:latest my-redis is up-to-date my-nginx is up-to-date Creating redis-commander ...  Creating redis-commander ... done 
访问11002端口,可以看到redis-commander已成功部署,并正常连接到了我们所配置的redis服务。