docker-compose进行水平扩展和负载均衡flask应用,环境变量的配置,redis做数据库同时设置密码,使用nginx做反向代理,支持健康检查

  1. 项目目录结构:

  2. docker-compose.yml文件:

点击查看代码
version: "3.8"

services:
    flask:
        # 构建镜像
        build:  # 指定包含构建上下文的路径,或作为一个对象,该对象具有context和指定的dockerfile,以及args参数
            context: .  # 指定Dockerfile文件所在路径
            dockerfile: Dockerfile  # context指定目录下dockerfile的文件名称
        image: flask-demo
        # container_name: flask-demo  # 需要使用--scale启动多个flask应用,所以不能设置容器名称
        # command:  # 覆盖默认镜像里执行的命令,支持shell格式和exec格式
        environment:
            - REDIS_PASS=${REDIS_PASSWORD}
            - REDIS_HOST=redis-server
            - FLASK_DEBUG=debug
        healthcheck:
            test: ["CMD", "curl", "-f", "http://localhost:5000"]
            interval: 5s
            timeout: 3s
            retries: 3
            start_period: 40s
        # volumes:
        #    - ./app:/usr/src/app
        networks:
            - backend
            - frontend
        # ports:
        #    - 8008:5000
        depends_on:
            redis-server:
                condition: service_healthy
        restart: on-failure:10

    redis-server:
        image: redis:latest
        command: redis-server --requirepass ${REDIS_PASSWORD}
        container_name: redis-server
        healthcheck:
            test: ["CMD", "redis-cli", "ping"]
            interval: 1s
            timeout: 3s
            retries: 15
        networks:
            - backend
        restart: on-failure:10

    nginx:
        image: nginx:stable-alpine
        container_name: nginx_server
        networks:
            - frontend
        volumes:
            - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
            - ./var/log/nginx:/var/log/nginx
        ports:
            - 80:80
        depends_on:
            flask:
                condition: service_healthy

networks:  # 相当于 docker network create demo-network
    backend:  # 指定网络名称
        external: false  # 为true表示从外部去找,没有就报错,为false是优先从外部找,没有就创建,默认值也是false
        name: backend
        ipam:
            driver: default
            config:
                - subnet: 192.168.1.0/24
    frontend:  # 指定网络名称
        external: false  # 为true表示从外部去找,没有就报错,为false是优先从外部找,没有就创建,默认值也是false
        name: frontend
        ipam:
            driver: default
            config:
                - subnet: 192.168.2.0/24

2.1 docker-compose读取环境变量的时候会从当前目录的.env文件中读取,所以我们需要先创建.env文件

REDIS_PASSWORD=abc132

2.2 为了不让.env文件被提交到github中去,可以在当前目录创建.gitignore文件

.env

2.3 检测docker-compose使用的.env环境变量是否生效的命令:
sudo docker-compose config
2.4 如果我们不想叫.env文件,想自定义环境变量文件名:myenv, 那么我们执行命令的时候需要这样写
sudo docker-compose --env-file myenv config
sudo docker-compose --env-file myenv up -d
完整命令

sudo docker-compose --env-file myenv up -d --scale flask=3
sudo docker-compose restart  // 如果应用程序数量变了,有nginx做反向代理的话,需要重启一下。
  1. Dockerfile文件
FROM python:3.9-slim

COPY app /usr/src/app

WORKDIR /usr/src/app

RUN bash run.sh

EXPOSE 5000

ENV FLASK_APP=app.py REDIS_HOST=redis

ENTRYPOINT ["flask", "run"]
CMD ["-h", "0.0.0.0"]
  1. nginx/nginx.conf文件
server {
    listen 80;
    server_name 域名或公网IP;

    location / {
        proxy_pass http://flask:5000;
    }
}
  1. app/app.py文件
import socket
import os

from redis import StrictRedis
from flask import Flask

redis = StrictRedis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379, password=os.environ.get("REDIS_PASS"))

app = Flask(__name__)

@app.route("/")
def hello():
    redis.incr("hits")
    return f"hello container world, I have been seen 【{redis.get('hits').decode('utf-8')}】 times and myhostname is {socket.gethostname()} 哈哈哈\n"
  1. app/requirements.txt文件
flask
redis
  1. app/run.sh文件
#!/usr/bin/env bash
pip install --no-cache-dir -U -r requirements.txt -i https://pypi.douban.com/simple
apt-get update
apt-get install -y curl
  1. 使用水平扩展的方式启动3个flask应用,同时docker engine有dns解析功能和负载均衡功能
    启动命令:
    sudo docker-compose up -d --scale flask=3

打开浏览器访问nginx配置文件中的server_name试试吧,大功告成。
而且redis-server增加了密码验证功能,flask应用中增加了REDIS_PASS的密码环境变量,应用中通过环境变量获取密码,链接redis-server。
同时flask应用服务和redis服务都开启了健康检查的功能。

posted @ 2022-05-30 14:13  专职  阅读(200)  评论(0编辑  收藏  举报