连接宿主机使用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 查容器网络