使用docker-compose部署时应用异常及多问题排查求助
问题总结
我有一个包含前端(React 19 + Vite)和后端(FastAPI)的项目,开发阶段能通过VSCode数据库客户端正常连接。现在把docker-compose移到根目录准备部署到VPS,本地测试时遇到三个问题:
- 访问
localhost:5173提示无法访问 localhost:80能显示登录页,但刷新后跳转至localhost/auth/login出现Nginx 404错误,直接访问该路径也失败- 无法通过
127.0.0.1:5432连接PostgreSQL数据库
尝试过修改.env中PostgreSQL主机为localhost、调整前端端口映射为5173:80,均无效。以下是相关配置文件:
后端Dockerfile
FROM python:3.13-alpine # Set environment variables ENV PYTHONUNBUFFERED=1 \ PYTHONPATH=/app \ CARGO_HOME=/root/.cargo \ RUSTUP_HOME=/root/.rustup \ PATH="/root/.cargo/bin:$PATH" WORKDIR /app # Install system dependencies for psycopg2 and build tools RUN apk update && apk add --no-cache \ gcc \ musl-dev \ libpq-dev \ postgresql-dev \ python3-dev \ libffi-dev \ cargo \ rust \ openssl-dev \ make \ curl # Copy and install Python dependencies COPY requirements.txt /app/ RUN pip install --no-cache-dir -r requirements.txt # Copy the rest of the app COPY . /app # Expose the port EXPOSE 8000 # Run the application CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
根目录docker-compose.yml
version: "3.8" services: app: build: context: ./backend dockerfile: Dockerfile dns: - 8.8.8.8 # Google's public DNS container_name: fastapi-app env_file: - ./backend/.env ports: - "8000:8000" environment: - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - CELERY_BROKER_URL=${REDIS_URL} - CELERY_RESULT_BACKEND=${REDIS_URL} depends_on: - db - redis networks: - backend volumes: - ./backend:/app # Mount the app directory to the container for live updates command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload # Enable hot-reloading celery_worker: build: context: ./backend dockerfile: Dockerfile container_name: celery-worker env_file: - ./backend/.env environment: - REDIS_PASSWORD=${REDIS_PASSWORD} - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - CELERY_BROKER_URL=${REDIS_URL} - CELERY_RESULT_BACKEND=${REDIS_URL} - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - AWS_REGION=${AWS_REGION} - AWS_BUCKET_NAME=${AWS_BUCKET_NAME} depends_on: - app - db - redis volumes: - ./backend:/app command: celery -A app.worker worker --loglevel=info networks: - backend db: image: pgvector/pgvector:pg16 env_file: - ./backend/.env environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data networks: - backend redis: image: redis:alpine ports: - "6379:6379" env_file: - ./backend/.env environment: REDIS_PASSWORD: ${REDIS_PASSWORD} command: [ "redis-server", "--appendonly yes", "--requirepass", "${REDIS_PASSWORD}", ] # Enforces Redis password volumes: - redis_data:/data networks: - backend networks: backend: volumes: postgres_data: redis_data:
前端Dockerfile
# Step 1: Build the React app using Vite FROM node:22-alpine AS build # Set the working directory WORKDIR /app # Copy package.json and package-lock.json COPY frontend/package*.json ./ # Install dependencies RUN npm install # Copy all source code COPY frontend/ ./ # Build the production version of the app RUN npm run build # Step 2: Serve the app using Nginx FROM nginx:alpine # Copy the build files from the build stage to Nginx's html directory COPY --from=build /app/dist /usr/share/nginx/html # Expose port 80 for Nginx EXPOSE 80 # Start Nginx in the foreground CMD ["nginx", "-g", "daemon off;"]
前端docker-compose.yml
version: "3.8" services: frontend: build: context: . dockerfile: frontend/Dockerfile # Referencing the Dockerfile in frontend folder env_file: - ./frontend/.env container_name: react-frontend ports: - "80:80" # Nginx exposes the app on port 80 networks: - frontend depends_on: - app # React app depends on the backend networks: frontend:
nginx.conf
server { listen 80; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; # This line handles SPA routing! } # API proxy configuration (if needed) location /api/ { proxy_pass http://app:8000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
解决方案
1. localhost:5173无法访问问题
- 前端容器映射的是
80:80,5173是开发环境Vite的默认端口,但生产构建后用Nginx跑在80端口,直接访问localhost:80即可 - 若要保留5173访问,修改前端docker-compose的端口映射为
5173:80,需确保本地5173端口未被占用
2. SPA路由刷新404问题
- 现有
nginx.conf的try_files配置逻辑正确,但未替换容器内默认Nginx配置,导致规则未生效 - 修复步骤:
- 将
nginx.conf移动到前端目录下(如frontend/nginx.conf) - 修改前端Dockerfile,添加复制配置的命令:
# 在COPY --from=build命令后添加 COPY frontend/nginx.conf /etc/nginx/conf.d/default.conf - 重新构建前端容器:
docker-compose -f frontend/docker-compose.yml up --build
- 将
3. 无法连接PostgreSQL问题
- 排查方向:
- 本地端口冲突:检查本地是否有PostgreSQL服务占用5432端口,停止本地服务后重试
- 数据库连接配置错误:后端容器需通过Docker内部网络连接数据库,将.env中的
DATABASE_URL改为postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}(db是docker-compose中数据库服务名) - 容器状态异常:用
docker ps查看db容器是否正常启动,用docker logs <db-container-name>查看启动日志排查错误
额外优化建议
- 将前后端docker-compose合并为根目录下的单一配置,避免多网络导致的服务互通问题(当前前端在
frontend网络,后端在backend网络,前端无法访问app服务),合并后统一使用backend网络:version: "3.8" services: # 保留原app、celery_worker、db、redis配置 frontend: build: context: . dockerfile: frontend/Dockerfile env_file: - ./frontend/.env container_name: react-frontend ports: - "80:80" networks: - backend depends_on: - app networks: backend: volumes: postgres_data: redis_data:
内容的提问来源于stack exchange,提问作者HUY PHAM MINH
相关产品推荐
相关产品推荐

