mirror of
https://github.com/rnvm9wjdtj-bot/myaps_api.git
synced 2026-06-02 05:54:40 +00:00
docker部署
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
venv/
|
||||
env/
|
||||
ENV/
|
||||
.venv/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
|
||||
# Logs (运行时生成)
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Local storage (运行时生成)
|
||||
storage/*.sqlite3
|
||||
storage/binlog_position.json
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
.cache/
|
||||
|
||||
# Test files
|
||||
tests/
|
||||
test_*.py
|
||||
*_test.py
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
|
||||
# Distribution
|
||||
dist/
|
||||
build/
|
||||
*.egg-info/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Other
|
||||
.arts/
|
||||
*.md
|
||||
!README.md
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# MyAPS API Dockerfile
|
||||
# 多阶段构建,优化镜像体积
|
||||
|
||||
# 构建阶段
|
||||
FROM python:3.12-slim AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN sed -i 's/deb.debian.org/mirrors.tencentyun.com/g' /etc/apt/sources.list.d/debian.sources \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
libpq-dev \
|
||||
default-libmysqlclient-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
|
||||
RUN pip config set global.index-url http://mirrors.tencentyun.com/pypi/simple \
|
||||
&& pip config set install.trusted-host mirrors.tencentyun.com \
|
||||
&& pip install --no-cache-dir --user -r requirements.txt
|
||||
|
||||
# 运行阶段
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN sed -i 's/deb.debian.org/mirrors.tencentyun.com/g' /etc/apt/sources.list.d/debian.sources \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends \
|
||||
libpq5 \
|
||||
libmariadb3 \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& mkdir -p /app/logs /app/storage /app/project_files
|
||||
|
||||
COPY --from=builder /root/.local /root/.local
|
||||
|
||||
ENV PATH=/root/.local/bin:$PATH
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:8000/docs || exit 1
|
||||
|
||||
CMD ["gunicorn", "-c", "scripts/deploy/gunicorn.conf.py", "main:app"]
|
||||
@@ -0,0 +1,65 @@
|
||||
# MyAPS API Docker Compose 配置
|
||||
# 使用方法: docker-compose up -d
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: myaps_redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass ${REDIS_PASSWORD}}
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- myaps_network
|
||||
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: myaps_api:latest
|
||||
container_name: myaps_api
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${PORT:-8000}:8000"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- REDIS_HOST=redis
|
||||
- GUNICORN_BIND=0.0.0.0:8000
|
||||
- APP_ROOT=/app
|
||||
volumes:
|
||||
- ./logs:/app/logs
|
||||
- ./project_files:/app/project_files
|
||||
- ./static:/app/static
|
||||
- ./storage:/app/storage
|
||||
- ./apps:/app/apps
|
||||
- ./core:/app/core
|
||||
- ./globalobjects:/app/globalobjects
|
||||
- ./scripts:/app/scripts
|
||||
- ./main.py:/app/main.py
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8000/docs"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
start_period: 10s
|
||||
retries: 3
|
||||
networks:
|
||||
- myaps_network
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
myaps_network:
|
||||
driver: bridge
|
||||
@@ -2,13 +2,17 @@
|
||||
import os
|
||||
import multiprocessing
|
||||
|
||||
# 设置工作目录为项目根目录
|
||||
chdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
working_dir = '/app'
|
||||
# 设置工作目录
|
||||
# Docker环境下使用/app,否则基于脚本位置计算
|
||||
if os.path.exists('/app/main.py'):
|
||||
chdir = '/app'
|
||||
else:
|
||||
chdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# 进程数
|
||||
workers = min(multiprocessing.cpu_count(), 4)
|
||||
worker_class = "uvicorn.workers.UvicornWorker"
|
||||
bind = "127.0.0.1:8000"
|
||||
bind = os.getenv("GUNICORN_BIND", "127.0.0.1:8000")
|
||||
timeout = 30
|
||||
|
||||
# 日志配置
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
# MyAPS API Docker 部署指南
|
||||
|
||||
## 环境要求
|
||||
|
||||
- Docker 20.10+
|
||||
- Docker Compose V2
|
||||
- Python 3.12(镜像内置)
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
# 构建镜像
|
||||
docker-compose build
|
||||
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
|
||||
# 查看状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
## 辅助脚本
|
||||
|
||||
```bash
|
||||
cd scripts/deploy_docker
|
||||
|
||||
./build.sh # 构建镜像 (默认 latest)
|
||||
./build.sh v1.0 # 构建指定版本
|
||||
|
||||
./start.sh # 启动服务
|
||||
./stop.sh # 停止服务
|
||||
./restart.sh # 重启服务
|
||||
./status.sh # 查看状态
|
||||
|
||||
./export_image.sh # 导出镜像 (离线部署用)
|
||||
./import_image.sh # 导入镜像
|
||||
```
|
||||
|
||||
## 环境配置
|
||||
|
||||
配置文件 `.env` 会被自动读取,以下变量会被容器环境覆盖:
|
||||
|
||||
| 变量 | 容器内值 | 说明 |
|
||||
|-----|---------|------|
|
||||
| `REDIS_HOST` | `redis` | 容器名访问 |
|
||||
| `GUNICORN_BIND` | `0.0.0.0:8000` | 容器内监听 |
|
||||
| `APP_ROOT` | `/app` | 容器工作目录 |
|
||||
|
||||
## 数据持久化
|
||||
|
||||
以下目录已配置持久化挂载:
|
||||
|
||||
- `logs/` - 应用日志
|
||||
- `project_files/` - 项目配置缓存
|
||||
- `static/` - 静态文件
|
||||
- `storage/` - 存储目录(SQLite、Binlog位置等)
|
||||
- `apps/` - 应用代码(开发模式热更新)
|
||||
- `core/` - 核心配置(开发模式热更新)
|
||||
- `globalobjects/` - 全局对象(开发模式热更新)
|
||||
- `scripts/` - 脚本文件(开发模式热更新)
|
||||
- `redis_data` - Redis数据卷
|
||||
|
||||
> 注意:生产环境建议移除代码目录挂载,使用镜像内置代码以获得更好隔离性。
|
||||
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
# 查看应用日志
|
||||
docker-compose logs -f app
|
||||
|
||||
# 进入容器
|
||||
docker exec -it myaps_api bash
|
||||
|
||||
# 重新构建并启动
|
||||
docker-compose up -d --build
|
||||
|
||||
# 停止并清理
|
||||
docker-compose down
|
||||
|
||||
# 停止并清理卷
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
## 版本更新
|
||||
|
||||
```bash
|
||||
# 拉取最新代码
|
||||
git pull
|
||||
|
||||
# 重新构建并启动(零停机)
|
||||
docker-compose up -d --build
|
||||
|
||||
# 或使用脚本
|
||||
./build.sh v2.0
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## 回滚操作
|
||||
|
||||
```bash
|
||||
# 回滚到指定版本
|
||||
docker tag myaps_api:v1.0 myaps_api:latest
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## 离线部署
|
||||
|
||||
```bash
|
||||
# 导出镜像
|
||||
./export_image.sh v1.0 /path/to/output
|
||||
|
||||
# 在目标机器导入
|
||||
./import_image.sh /path/to/myaps_api_v1.0.tar
|
||||
|
||||
# 启动服务
|
||||
./start.sh
|
||||
```
|
||||
|
||||
## 健康检查
|
||||
|
||||
- 应用健康检查: `curl http://localhost:8000/docs`
|
||||
- Redis健康检查: `docker exec myaps_redis redis-cli ping`
|
||||
- 查看容器健康状态: `docker ps --format "table {{.Names}}\t{{.Status}}"`
|
||||
|
||||
## 镜像信息
|
||||
|
||||
| 项目 | 值 |
|
||||
|-----|-----|
|
||||
| 基础镜像 | python:3.12-slim |
|
||||
| 镜像大小 | ~460MB |
|
||||
| 多阶段构建 | 是 |
|
||||
| 国内镜像源 | 已配置(腾讯云) |
|
||||
|
||||
## 故障排查
|
||||
|
||||
```bash
|
||||
# 查看应用日志
|
||||
docker-compose logs -f app
|
||||
|
||||
# 查看启动失败原因
|
||||
docker logs myaps_api 2>&1 | head -50
|
||||
|
||||
# 进入容器调试
|
||||
docker exec -it myaps_api bash
|
||||
|
||||
# 检查容器内文件
|
||||
docker exec myaps_api ls -la /app/
|
||||
```
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
# 构建Docker镜像
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "=========================================="
|
||||
echo " MyAPS API Docker 镜像构建"
|
||||
echo "=========================================="
|
||||
|
||||
VERSION="${1:-latest}"
|
||||
IMAGE_NAME="myaps_api:$VERSION"
|
||||
|
||||
echo ""
|
||||
echo "构建镜像: $IMAGE_NAME"
|
||||
echo ""
|
||||
|
||||
docker build -t "$IMAGE_NAME" .
|
||||
|
||||
echo ""
|
||||
echo "✅ 镜像构建完成: $IMAGE_NAME"
|
||||
echo ""
|
||||
docker images myaps_api
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# 导出Docker镜像(用于离线部署)
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "=========================================="
|
||||
echo " MyAPS API Docker 镜像导出"
|
||||
echo "=========================================="
|
||||
|
||||
VERSION="${1:-latest}"
|
||||
OUTPUT_DIR="${2:-$SCRIPT_DIR}"
|
||||
IMAGE_NAME="myaps_api:$VERSION"
|
||||
OUTPUT_FILE="$OUTPUT_DIR/myaps_api_$VERSION.tar"
|
||||
|
||||
echo ""
|
||||
echo "导出镜像: $IMAGE_NAME"
|
||||
echo "输出文件: $OUTPUT_FILE"
|
||||
echo ""
|
||||
|
||||
if ! docker images "$IMAGE_NAME" | grep -q "myaps_api"; then
|
||||
echo "❌ 镜像不存在,请先构建镜像"
|
||||
echo "运行: ./build.sh $VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker save -o "$OUTPUT_FILE" "$IMAGE_NAME"
|
||||
|
||||
echo ""
|
||||
echo "✅ 镜像已导出: $OUTPUT_FILE"
|
||||
ls -lh "$OUTPUT_FILE"
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
# 导入Docker镜像(用于离线部署)
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "=========================================="
|
||||
echo " MyAPS API Docker 镜像导入"
|
||||
echo "=========================================="
|
||||
|
||||
IMAGE_FILE="${1:-$SCRIPT_DIR/myaps_api_latest.tar}"
|
||||
|
||||
if [ ! -f "$IMAGE_FILE" ]; then
|
||||
echo "❌ 镜像文件不存在: $IMAGE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "导入镜像: $IMAGE_FILE"
|
||||
echo ""
|
||||
|
||||
docker load -i "$IMAGE_FILE"
|
||||
|
||||
echo ""
|
||||
echo "✅ 镜像已导入"
|
||||
docker images myaps_api
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# 重启Docker服务
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "=========================================="
|
||||
echo " MyAPS API Docker 服务重启"
|
||||
echo "=========================================="
|
||||
|
||||
echo ""
|
||||
echo "重启服务..."
|
||||
echo ""
|
||||
|
||||
docker-compose restart
|
||||
|
||||
echo ""
|
||||
echo "服务状态:"
|
||||
docker-compose ps
|
||||
|
||||
echo ""
|
||||
echo "✅ 服务已重启"
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
# 启动Docker服务
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "=========================================="
|
||||
echo " MyAPS API Docker 服务启动"
|
||||
echo "=========================================="
|
||||
|
||||
if [ ! -f ".env" ]; then
|
||||
echo "❌ 错误: .env 文件不存在"
|
||||
echo "请先创建 .env 配置文件"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "启动服务..."
|
||||
echo ""
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
echo ""
|
||||
echo "等待服务启动..."
|
||||
sleep 5
|
||||
|
||||
echo ""
|
||||
echo "服务状态:"
|
||||
docker-compose ps
|
||||
|
||||
echo ""
|
||||
echo "✅ 服务已启动"
|
||||
echo ""
|
||||
echo "访问地址: http://localhost:${PORT:-8000}"
|
||||
echo "查看日志: docker-compose logs -f"
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# 查看Docker服务状态
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "=========================================="
|
||||
echo " MyAPS API Docker 服务状态"
|
||||
echo "=========================================="
|
||||
|
||||
echo ""
|
||||
docker-compose ps
|
||||
|
||||
echo ""
|
||||
echo "容器健康状态:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "NAMES|myaps"
|
||||
|
||||
echo ""
|
||||
echo "日志查看命令:"
|
||||
echo " 全部日志: docker-compose logs -f"
|
||||
echo " 应用日志: docker-compose logs -f app"
|
||||
echo " Redis日志: docker-compose logs -f redis"
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# 停止Docker服务
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "=========================================="
|
||||
echo " MyAPS API Docker 服务停止"
|
||||
echo "=========================================="
|
||||
|
||||
echo ""
|
||||
echo "停止服务..."
|
||||
echo ""
|
||||
|
||||
docker-compose down
|
||||
|
||||
echo ""
|
||||
echo "✅ 服务已停止"
|
||||
Reference in New Issue
Block a user