Docker Compose。
v. 组成,构成(一个整体);作曲;创作(音乐);撰写(信函、讲稿、诗歌等)
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
Using Compose is basically a three-step process:
- Define your app’s environment with a
Dockerfile
so it can be reproduced anywhere.- Define the services that make up your app in
docker-compose.yml
so they can be run together in an isolated environment.- Run
docker-compose up
and Compose starts and runs your entire app.
https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec
理解。
Docker Compose 是官方开源的项目,需要另外安装。
Dockerfile 让程序在任何地方运行。Web 服务、Redis、MySQL、Nginx…多个容器。批量容器编排。
-
服务 services ~ 容器,应用。(Web 服务、Redis、MySQL、Nginx…等)。
-
项目。project。~ 一组关联的容器。
单机 ~ Docker Compose。集群 ~ Docker Swarm。
安装 Docker Compose。
https://docs.docker.com/compose/install/
Install Compose on Linux systems
On Linux, you can download the Docker Compose binary from the Compose repository release page on GitHub. Follow the instructions from the link, which involve running the curl command in your terminal to download the binaries. These step-by-step instructions are also included below.
For alpine, the following dependency packages are needed: py-pip, python-dev, libffi-dev, openssl-dev, gcc, libc-dev, and make.
Run this command to download the current stable release of Docker Compose:
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
To install a different version of Compose, substitute 1.27.4 with the version of Compose you want to use.
If you have problems installing with curl, see Alternative Install Options tab above.
Apply executable permissions to the binary:
sudo chmod +x /usr/local/bin/docker-compose
Note: If the command docker-compose fails after installation, check your path. You can also create a symbolic link to /usr/bin or any other directory in your path.
For example:
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Optionally, install command completion for the bash and zsh shell.
Test the installation.
$ docker-compose --version
docker-compose version 1.27.4, build 1110ad01
[geek@192 ~]$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
[sudo] password for geek:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 651 100 651 0 0 224 0 0:00:02 0:00:02 --:--:-- 224
100 11.6M 100 11.6M 0 0 111k 0 0:01:47 0:01:47 --:--:-- 205k
[geek@192 ~]$ sudo chmod +x /usr/local/bin/docker-compose
[geek@192 ~]$ docker-compose --version
docker-compose version 1.27.4, build 40524192
Hello World。
[geek@192 geek]$ mkdir composetest
[geek@192 geek]$ cd composetest/
[geek@192 composetest]$ sudo vim app.py
[sudo] password for geek:
[geek@192 composetest]$ cat app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
In this example, redis is the hostname of the redis container on the application’s network. We use the default port for Redis, 6379.
Handling transient errors
Note the way the get_hit_count function is written. This basic retry loop lets us attempt our request multiple times if the redis service is not available. This is useful at startup while the application comes online, but also makes our application more resilient if the Redis service needs to be restarted anytime during the app’s lifetime. In a cluster, this also helps handling momentary connection drops between nodes.
Create another file called requirements.txt
in your project directory and paste this in:
[geek@192 composetest]$ sudo vim requirements.txt
flask
redis
Step 2: Create a Dockerfile
In this step, you write a Dockerfile that builds a Docker image. The image contains all the dependencies the Python application requires, including Python itself.
In your project directory, create a file named Dockerfile
and paste the following:
[geek@192 composetest]$ sudo vim Dockerfile
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
This tells Docker to:
Build an image starting with the Python 3.7 image.
Set the working directory to /code.
Set environment variables used by the flask command.
Install gcc and other dependencies
Copy requirements.txt and install the Python dependencies.
Add metadata to the image to describe that the container is listening on port 5000
Copy the current directory . in the project to the workdir . in the image.
Set the default command for the container to flask run.
For more information on how to write Dockerfiles, see the Docker user guide and the Dockerfile reference.
- Step 3: Define services in a Compose file
Create a file calleddocker-compose.yml
in your project directory and paste the following:
[geek@192 composetest]$ sudo vim docker-compose.yml
version: "3.8"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
This Compose file defines two services: web
and redis
.
-
Web service
The web service uses an image that’s built from the Dockerfile in the current directory. It then binds the container and the host machine to the exposed port, 5000. This example service uses the default port for the Flask web server, 5000. -
Redis service
The redis service uses a public Redis image pulled from the Docker Hub registry.
Step 4: Build and run your app with Compose
From your project directory, start up your application by running docker-compose up.
$ docker-compose up
[geek@192 ~]$ sudo docker service ls
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
默认的服务名:文件名_服务名_num。
如果有多个服务器,集群,_num 就表示副本数量。
通过 docker_compose 启动的项目会自动创建网络 composetest_default。所以这些应用都会在同一网络下。
docker-compose ~ https://docs.docker.com/compose/wordpress/。
自己搭建 docker-compose 项目。
package com.geek.demo_docker.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@RequestMapping("/hello")
public String hello() {
Long views = stringRedisTemplate.opsForValue().increment("view", 1);
return "hello, geek, views: " + views;
}
}
- application.properties。
server.port=8088
spring.redis.host=redis
- docker-compose.yml。
version: '3.8'
services:
geekapp:
build: .
# dockerfile: Dockerfile
image: geekapp
depends_on:
- redis
ports:
- "8080:8080"
redis:
image: "library/redis:alpine"
- Dockerfile。
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
放入服务器文件夹。
[geek@192 geekapp]$ ls
demo_docker-0.0.1-SNAPSHOT.jar docker-compose.yml Dockerfile
docker-compose up
version: "3.8"
services:
mysql:
image: mysql
container_name: mysql
ports:
- "3306:3306"
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123
volumes:
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
- "./mysql/init:/docker-entrypoint-initdb.d"
networks:
- hm-net
hmall:
build:
context: .
dockerfile: Dockerfile
container_name: hmall
ports:
- "8080:8080"
networks:
- hm-net
depends_on:
- mysql
nginx:
image: nginx
container_name: nginx
ports:
- "18080:18080"
- "18081:18081"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf"
- "./nginx/html:/usr/share/nginx/html"
depends_on:
- hmall
networks:
- hm-net
networks:
hm-net:
name: hmall
compose.yaml。
模板文件是 Compose 的核心,涉及的指令关键字比较多,但是大部分的指令与 docker run 相关的参数的含义是类似的。
默认的模板名是 docker-compose.yml。
# 语法 3 层。
version: "3.8"
services: # 定义很多服务。
服务 1:
# 当前的服务配置。
服务 2:
# 当前服务配置。
# 服务要用的网络、卷、等其他全局规则。
volumes:
networks:
configs:
.....
官网链接:https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
Compose 和 Docker 兼容性。
Compose 文件格式有 3 个版本,分别为1, 2.x 和 3.x。
目前主流的为 3.x,其支持 docker 1.13.0 及其以上的版本。
# 常用参数:
version # 指定 compose 文件的版本。
services # 定义所有的 service 信息,services 下面的第一级别的 key 既是一个 service 的名称。
服务
build # 指定包含构建上下文的路径,或作为一个对象,该对象具有 context 和指定的 dockerfile。
context # context: 指定 Dockerfile 文件所在的路径。
dockerfile # dockerfile: 指定 context 指定的目录下面的 Dockerfile 的名称(默认为 Dockerfile)
args # args: Dockerfile 在 build 过程中需要的参数 。
command # 覆盖容器启动后默认执行的命令,支持 shell 格式和 [] 格式。
container_name # 指定容器的名称(等同于 docker run --name 的作用)。
deploy # v3 版本以上, 指定与部署和运行服务相关的配置。
# deploy 部分是 docker stack 使用的,docker stack 依赖 docker swarm。
depends_on # 定义容器启动顺序(此选项解决了容器之间的依赖关系)。
dns # 设置 DNS 地址(等同于 docker run --dns 的作用)。
entrypoint # 覆盖容器的默认 entrypoint 指令。
env_file # 从指定文件中读取变量设置为容器中的环境变量,可以是单个值或者一个文件列表。
environment # 设置环境变量,environment 的值可以覆盖 env_file 的值。
expose # 暴露端口,但是不能和宿主机建立映射关系,类似于 Dockerfile 的 EXPOSE 指令。
external_links # 连接不在 docker-compose.yml 中定义的容器或者不在 compose 管理的容器。
extra_hosts # 添加 host 记录到容器中的 /etc/hosts 中。
healthcheck # v2.1 以上版本, 定义容器健康状态检查。
image # 指定 docker 镜像, 可以是远程仓库镜像、本地镜像。
labels # 使用 Docker 标签将元数据添加到容器。
logging # 设置容器日志服务。
network_mode # 指定网络模式(等同于 docker run --net 的作用,在使用 swarm 部署时将忽略该选项)。
networks # 将容器加入指定网络(等同于 docker network connect 的作用。
# networks 可以位于 compose 文件顶级键和 services 键的二级键。
pid: 'host' # 共享宿主机的 进程空间(PID)。
ports # 建立宿主机和容器之间的端口映射关系, ports 支持两种语法格式。
- "8000:8000" # 容器的 8000 端口和宿主机的 8000 端口建立映射关系。
volumes # 定义容器和宿主机的卷映射关系。
- /var/lib/mysql # 映射容器内的 /var/lib/mysql 到宿主机的一个随机目录中。
- /opt/data:/var/lib/mysql # 映射容器内的 /var/lib/mysql 到宿主机的 /opt/data。
- ./cache:/tmp/cache # 映射容器内的 /var/lib/mysql 到宿主机 compose 文件所在的位置。
- ~/configs:/etc/configs/:ro # 映射容器宿主机的目录到容器中去,权限只读。
- datavolume:/var/lib/mysql # datavolume 为 volumes 顶级键定义的目录,在此处直接调用。
.....
# 对于值为时间的可接受的值。
2.5s
10s
1m30s
2h32m
5h34m56s
时间单位: us, ms, s, m, h
# 对于值为大小的可接受的值:
2b
1024kb
2048k
300m
1gb
单位: b, k, m, g 或者 kb, mb, gb
# depends_on 示例。
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
ports:
- "6379:6379"
environment:
- root_pwd: "123456"
db:
image: postgres
# docker compose up 以依赖顺序启动服务,下面例子中 redis 和 db 服务在 web 启动前启动。
# 默认情况下使用 docker compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。
# network 示例。
version: '3.7'
services:
test:
image: nginx:1.14-alpine
container_name: mynginx
command: ifconfig
networks:
app_net: # 调用下面 networks 定义的 app_net 网络。
ipv4_address: 172.16.238.10
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
- getaway: 172.16.238.1