Docker-compose复杂使用

目录结构

docker-compose-denpends                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       ├── backend                                                                                                                                                                                                                                                                             │   ├── app.py                                                                                                                                                                                                                                                                          │   └── requirements.txt                                                                                                                                                                                                                                                                ├── docker-compose.yml                                                                                                                                                                                                                                                                  └── frontend                                                                                                                                                                                                                                                                                └── html                                                                                                                                                                                                                                                                                    └── index.html      

包含:

  • 两个服务:backend和 frontend
  • backend 是一个 Python Flask API,监听 5000 端口
  • frontend 是一个 Nginx,监听 8080 端口,并展示一个页面,同时调用后端 API
  • 使用 depends_on控制启动顺序(但注意:仅控制启动顺序,不保证服务就绪)
  • 使用简易的 healthcheck来更可靠地控制服务依赖(高级用法,可选)

✅ 简单版本(带依赖顺序,使用 depends_on)

📄 docker-compose.yml

version: '3.8'

services:
  backend:
    image: python:3.10-slim
    container_name: flask-backend
    working_dir: /app
    volumes:
      - ./backend:/app
    command: python app.py
    ports:
      - "5000:5000"
    expose:
      - "5000"  # 仅容器间可访问

  frontend:
    image: nginx:latest
    container_name: nginx-frontend
    ports:
      - "8080:80"
    volumes:
      - ./frontend/html:/usr/share/nginx/html
    depends_on:
      - backend  # 保证 backend 先启动

📁 backend/app.py(Python Flask 后端 API)

在项目目录下创建文件夹 backend/,然后创建文件 app.py

# backend/app.py
from flask import Flask, jsonify
from flask_cors import CORS

app = Flask(__name__)
# ✅ 允许所有来源访问所有路由(开发阶段推荐)
CORS(app)  # 这一行是关键!

@app.route('/api/hello')
def hello():
    return jsonify({"message": "Hello from the backend!"})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

📁 backend/requirements.txt

flask
flask-cors

虽然这个例子中我们直接用了 python:3.10-slim镜像并运行 python app.py,但如果你想用 pip install -r requirements.txt,可以改用 Dockerfile构建自定义镜像。为了简化,这里直接运行脚本。


📁 frontend/html/index.html(前端页面,调用后端 API)

在项目目录下创建文件夹 frontend/html/,然后创建文件 index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Frontend + Backend Demo</title>
  <script>
    async function fetchData() {
      try {
        const response = await fetch('http://172.18.214.132:5000/api/hello');
        const data = await response.json();
        document.getElementById('message').innerText = data.message;
      } catch (error) {
        document.getElementById('message').innerText = '无法连接到后端 API: ' + error;
      }
    }
    fetchData();
  </script>
</head>
<body>
  <h1>🚀 前端调用后端 API 示例</h1>
  <p id="message">加载中...</p>
</body>
</html>

然后运行:

docker compose up --build -d

如果你没有自定义 Dockerfile,其实不需要 --build,但加上也无害。

然后打开浏览器访问:

http://宿主机ip:8080

你应该会看到页面显示:

🚀 前端调用后端 API 示例

​Hello from the backend!​

关键点解释

1. 两个服务:backend 和 frontend

  • backend​​:使用官方 Python 镜像,运行一个 Flask API,监听 5000 端口,提供一个 /api/hello接口
  • ​frontend​​:使用 Nginx 镜像,展示一个静态 HTML 页面,该页面通过 JavaScript 调用后端 API

2. 服务间通信

  • 在 Docker Compose 网络中,每个 service(如 backendfrontend)都有一个 ​​服务名​​,可以作为 ​​主机名​​ 被其他容器访问
  • 所以前端页面中的 JavaScript 也可以直接访问:http://backend:5000/api/hello,Docker 会自动将 backend解析为对应的容器 IP, 但是部署后,通过客户机访问是不行的, 因为浏览器运行在客户机,是不在docker网络中的,所以只能用ip, 但是使用服务名可以在docker中的容器的浏览器中访问

3. 端口映射

  • backend:将容器内 5000 端口映射到宿主机 5000 端口(可选,这里映射出来你可以用 Postman 等工具直接测试)
  • frontend:将容器内 Nginx 的 80 端口映射到宿主机 8080 端口,浏览器访问 localhost:8080

4. 服务依赖:depends_on

depends_on:
  - backend
  • 表示 ​​frontend 服务会等 backend 服务先启动后,再启动​
  • ⚠️ 但注意:depends_on​只控制容器启动顺序​​,​​不保证后端服务已经完成初始化、可以接受请求!​
Previous Post Next Post

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注