docker容器部署示范


连接宿主机使用host.docker.internal:

bash
DATABASE_ASYNC_URL=postgresql+asyncpg://postgres:123456@host.docker.internal:5432/test
DATABASE_URL=postgresql://postgres:123456@host.docker.internal:5432/test

docker-compose.yml:
创建一个名为web的服务,使用Dockerfile文件构建,指定了环境变量文件,并执行命令(因为是启动命令,所以不止是在构建文件中要写),把容器的8001映射到本地8001

yml
services:
	db: # 写了这个db服务,那么容器之间.env写成db代表主机连接到这个库
    image: postgres:17-alpine
    container_name: db
    restart: always
    environment:
      POSTGRES_USER: postgres          # 用户名,可放到 .env
      POSTGRES_PASSWORD: 123456  # 密码,优先取 .env
      POSTGRES_DB: duola               # 初始数据库
	  TZ: Asia/Singapore
    ports:
      - "5432:5432"                   # 宿主机也能访问
    volumes:
      - pgdata:/var/lib/postgresql/data
	  
  web:
    build:
      context: .
      dockerfile: Dockerfile
	# 如果是linux,则需要添加extra_hosts这一行,才可使用host.docker.internal访问到宿主机
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      - "8001:8001"
    volumes:
      - .:/app
    env_file:
      - .env
    command: uvicorn main:app --host 0.0.0.0 --port 8001 --reload

# 创建一个pgdata的卷,用于存储数据库数据
volumes:
  pgdata:

Dockerfile:

bash
# 使用官方 Python 运行时作为父镜像
FROM python:3.11.12-slim
# 也可以使用第三方仓库源,防止hub限流
#ARG BASE_IMAGE="public.ecr.aws/docker/library/python:3.11.12-slim"
#FROM ${BASE_IMAGE}

# 设置环境变量,防止 Python 写入 .pyc 文件
ENV PYTHONDONTWRITEBYTECODE 1
# 设置环境变量,确保 Python 输出是无缓冲的
ENV PYTHONUNBUFFERED 1

# 安装 PostgreSQL 客户端
RUN apt-get update \
 && apt-get install -y --no-install-recommends libpq5 \
 && rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /app

# 将依赖文件复制到工作目录
COPY requirements.txt ./

# 安装项目依赖
# --no-cache-dir: 不缓存包,减少镜像大小
# 使用国内的清华镜像源加速下载
RUN pip install --no-cache-dir -r requirements.txt  -i https://pypi.tuna.tsinghua.edu.cn/simple/

# 将当前目录内容复制到容器的 /app 目录
COPY . .

# 暴露端口,让容器外部可以访问
EXPOSE 8001

# 容器启动时运行的命令
# 使用 uvicorn 启动 FastAPI 应用
# host="0.0.0.0" 让服务可以被外部访问
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001", "--reload"] 

docker compose up -d 启动并运行容器,也可以作为重启
sudo docker compose up -d --build 启动并构建
docker compose down # 停止并移除现有的容器
docker compose logs -f 输出所有容器错误日志
docker compose logs -f web 输出web服务容器的日志

如果不是在同一个运行

多个容器之间的通信方案:
docker network create backend 创建一个网络,只需执行一次

其他容器加入这个网络:

bash
docker run -d \
  --name postgres \
  --network backend \
  -e POSTGRES_DB=crowdpulse \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=123456 \
  -e TZ=Asia/Singapore \
  -p 5432:5432 \
  -v pg-data:/var/lib/postgresql/data \
  --shm-size=1g \
  --restart unless-stopped \
  postgres:17-alpine \
  -c max_connections=500
yaml
networks:
  backend:
    external: true      # 告诉 compose:用已存在的网络
    name: backend       # 可省
services:
  # 构建应用镜像的服务(只构建一次)
  app:
    # 其他配置
    networks: [backend]

让已存在的容器加入网络:

arduino
sudo docker network connect backend redis
sudo docker network connect backend postgre
sudo docker network connect backend weaviate

如果更新了依赖,需重新构建,停止容器后执行
sudo docker compose build --no-cache

容器挂载本地时区

yml
# FastAPI 应用 - 使用共享镜像
  fastapi-app:
    image: crowdpulse-lee:latest  # 使用上面构建的镜像
    environment:
      - TZ=Asia/Singapore             # 设置时区
    # 让uvicorn 监听代理转发的真实ip
    command: uvicorn fastapi_ser.main:app --host 0.0.0.0 --port 8001 --workers 1 --proxy-headers --forwarded-allow-ips='*'
    ports:
      - "8001:8001"
    restart: always
    env_file:
      - .env
    volumes:
      - /etc/localtime:/etc/localtime:ro  # 宿主的本地时区文件挂进容器
      - /etc/timezone:/etc/timezone:ro    # Debian/Ubuntu 常见;有则挂(Alpine 可能没有)
      - ./logs:/app/logs
      - .:/app
    networks: [backend]

容器内运行长命令

bash
docker exec -i crowdpulse_lee-celery-io-worker-1 sh <<'SH'
set -e
date
echo "$TZ"
cat /etc/timezone 2>/dev/null || true
python - <<'PY'
from datetime import datetime, timezone
print("python now()        :", datetime.now())
print("python now(UTC)     :", datetime.now(timezone.utc))
try:
    from zoneinfo import ZoneInfo
    print("now Asia/Singapore :", datetime.now(ZoneInfo("Asia/Singapore")))
except Exception as e:
    print("zoneinfo not available:", e)
PY
SH

查看哪个容器在哪个网络】

docker network ls 列出网络列表
docker inspect postgre | grep -A5 Networks 查容器网络