使用Compose基本是一个三步过程
Dockerfile
文件保证我们的项目在任何地方都可以运行docker-compose.yml
文件定义组成应用程序的服务,以便它们在隔离的环境中一起运行docker compose up
,然后Docker compose命令启动并运行整个应用程序。也可以docker-compose up
使用docker-compose二进制文件运行。作用:
批量容器编排
docker-compose.yml 就是这种:
version: "3.9" services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redis volumes: logvolume01: {}
下载安装compose curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 423 100 423 0 0 315 0 0:00:01 0:00:01 --:--:-- 315 100 16.7M 100 16.7M 0 0 3672k 0 0:00:04 0:00:04 --:--:-- 5250k 授权 chmod +x /usr/local/bin/docker-compose 查看版本 docker-compose version docker-compose version 1.25.5, build 8a1c60f6 docker-py version: 4.1.0 CPython version: 3.7.5 OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
mkdir -p /home/compose/python-redis cd /home/compose/python-redis 写python应用 vim app.py #! /usr/bin/python3 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) 编写依赖包文件 vim requirements.txt flask redis
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"]
vim docker-compose.yml version: "3" services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
目前有四个文件 [root@docker python-redis]# ls app.py docker-compose.yml Dockerfile requirements.txt 启动compose项目 docker-compose up Creating python-redis_web_1 ... done Creating python-redis_redis_1 ... done
最后构建镜像
[root@docker python-redis]# docker-compose build redis uses an image, skipping Building web Step 1/10 : FROM python:3.7-alpine ---> c46f62f378d7 Step 2/10 : WORKDIR /code ---> Using cache ---> 3d09c3c9e5f7 Step 3/10 : ENV FLASK_APP=app.py ---> Using cache ---> 5401ce448bf0 Step 4/10 : ENV FLASK_RUN_HOST=0.0.0.0 ---> Using cache ---> cd3cf06ed26e Step 5/10 : RUN apk add --no-cache gcc musl-dev linux-headers ---> Using cache ---> 5b887aadaeb6 Step 6/10 : COPY requirements.txt requirements.txt ---> Using cache ---> 24c8b54c831f Step 7/10 : RUN pip install -r requirements.txt ---> Using cache ---> e26516cdef01 Step 8/10 : EXPOSE 5000 ---> Using cache ---> 2ffe08dae8ee Step 9/10 : COPY . . ---> Using cache ---> e1299046671d Step 10/10 : CMD ["flask", "run"] ---> Using cache ---> ecc8f48e18e5 Successfully built ecc8f48e18e5 Successfully tagged python-redis_web:latest 再次启动会发现 docker-compose up 项目迅速启动 保证启动之后有两个容器 [root@docker ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e92f6c104c29 redis:alpine "docker-entrypoint.s…" 9 minutes ago Up About a minute 6379/tcp python-redis_redis_1 ad9ab1f0220d python-redis_web "flask run" 9 minutes ago Up About a minute 0.0.0.0:5000->5000/tcp, :::500 0->5000/tcp python-redis_web_1
测试
[root@docker ~]# curl localhost:5000 Hello World! I have been seen 1 times. [root@docker ~]# curl localhost:5000 Hello World! I have been seen 2 times.
我们查看网络,会发现compose会单独创建一个网络
查看网络详情 docker network inspect python-redis_default [ { "Name": "python-redis_default", "Id": "0e1cc417dc99dc66c337823ed1cbda0b680e7543732444d1120d54a50b72989c", "Created": "2021-04-25T03:03:35.019219454-04:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": true, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "ad9ab1f0220dda2638747f03852e547a0154514574b65930720ead939fc66048": { "Name": "python-redis_web_1", "EndpointID": "8c23797f7d6e4ea8464cddc12a0757c119a41381a45d936b8d8c5beeb2978e85", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, "e92f6c104c29e79459e0c5eaebbd0d98c674c273cc1354bd4e18704f0c41e2b2": { "Name": "python-redis_redis_1", "EndpointID": "68c762f33ebf63a77cbde1bc6af15484f1458a43c50d7384a748cbdfe1033a33", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": { "com.docker.compose.network": "default", "com.docker.compose.project": "python-redis", "com.docker.compose.version": "1.25.5" } } ] 里面包含python-redis_redis_1、python-redis_web_1,因为在同一个网络就可以通过容器名直接访问
app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) 这里host='redis' 没有写host=‘localhost’或者127.0.0.1 就是因为docker容器在同一个网络里面可以通过容器名访问
官方详解
耐心查看官方的教程,会有很大收获的
3层 第一层:版本 第二层:服务 第三层:其他配置 version: # 版本 services: # 服务 服务1:web # 服务配置 images build netwokr ..... 服务2:redis 服务3:redis ... # 其他配置 网络/卷、全局规则 volumes: networks: configs:
如以下一个样本
version: "3.9" services: redis: image: redis:alpine ports: - "6379" networks: - frontend deploy: replicas: 2 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure db: image: postgres:9.4 volumes: - db-data:/var/lib/postgresql/data networks: - backend deploy: placement: max_replicas_per_node: 1 constraints: - "node.role==manager" vote: image: dockersamples/examplevotingapp_vote:before ports: - "5000:80" networks: - frontend depends_on: - redis deploy: replicas: 2 update_config: parallelism: 2 restart_policy: condition: on-failure result: image: dockersamples/examplevotingapp_result:before ports: - "5001:80" networks: - backend depends_on: - db deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend deploy: mode: replicated replicas: 1 labels: [APP=VOTING] restart_policy: condition: on-failure delay: 10s max_attempts: 3 window: 120s placement: constraints: - "node.role==manager" visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" stop_grace_period: 1m30s volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: - "node.role==manager" networks: frontend: backend: volumes: db-data:
depends_on
version: "3.9" services: web: build: . depends_on: web依赖于db和redis - db - redis redis: image: redis db: image: postgres 容器运行顺序就是1.db 2.redis 3.web
deploy
version: "3.9" services: redis: image: redis:alpine deploy: replicas: 6 placement: max_replicas_per_node: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure replicas是副本
mkdir /home/wordpress cd /home/wordpress 编写yaml vim docker-compose.yml version: '3.3' services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: 123 MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: 123 wordpress: depends_on: - db image: wordpress:latest ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: 123 WORDPRESS_DB_NAME: wordpress volumes: db_data: {} docker-compose up
package com.example.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @Autowired StringRedisTemplate redisTemplate; @GetMapping("/hello") public String hello(){ Long views = redisTemplate.opsForValue().increment("views"); return "hello,xiaotian,thank you,views:"+views; } }
application.properties
# 应用名称 spring.application.name=demo # 应用服务 WEB 访问端口 server.port=8080 spring.redis.host=redis
dockerfile
FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
docker-compose.yml
version: '3.8' services: tianapp: build: . image: tianapp depends_on: - redis ports: - "8080:8080" redis: image: "library/redis:alpine"
将jar包上传至服务器后启动项目
[root@docker javaapp]# ls docker-compose.yml Dockerfile maomao-0.0.1-SNAPSHOT.jar
测试
[root@docker python-redis]# curl localhost:8080/hello hello,xiaotian,thank you,views:1 [root@docker python-redis]# curl localhost:8080/hello hello,xiaotian,thank you,views:2