-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathDockerfile
More file actions
194 lines (155 loc) · 6.12 KB
/
Dockerfile
File metadata and controls
194 lines (155 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# 多阶段构建:前端 + 后端
# ============ 阶段 1: 构建前端 ============
# 使用阿里云 Node.js 镜像加速下载
FROM alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/node:20.16 AS frontend-builder
# 切换到 root 用户以创建目录
USER root
# 创建所需目录并设置权限
RUN mkdir -p /app/frontend /app/dist && \
chown -R node:node /app/frontend /app/dist
# 设置工作目录
WORKDIR /app/frontend
# 切换到 node 用户
USER node
# 设置 Node.js 环境变量(构建时需要 devDependencies,所以不设置 NODE_ENV=production)
ENV NODE_OPTIONS="--max-old-space-size=4096"
# 仅复制依赖文件以利用缓存
COPY --chown=node:node frontend/package*.json ./
# 安装依赖(包括 devDependencies,因为 vite 在 devDependencies 中)
RUN npm config set registry https://registry.npmmirror.com && \
npm install --legacy-peer-deps && \
npm cache clean --force
# 复制剩余前端代码并构建
COPY --chown=node:node frontend/ ./
# 构建生产版本(输出到 /app/dist)
RUN npm run build
# ============ 阶段 2: Python 后端基础镜像 ============
# 使用阿里云 Python 镜像加速下载
FROM registry.cn-shanghai.aliyuncs.com/51jbm/docker:27.2.0-cli AS backend-base
# ✅ 替换 apk 源为阿里云镜像(关键!提速 5–10×)
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache \
python3 \
python3-dev \
py3-pip \
py3-setuptools \
curl \
jq \
git \
make \
gcc \
musl-dev \
linux-headers \
docker-compose
# ✅ 创建软链接 python → python3(适配多数脚本)
RUN ln -sf python3 /usr/bin/python && \
ln -sf pip3 /usr/bin/pip
# ✅ 【关键修复】用户级升级 pip + 当前 shell 立即生效
# (注意:用 `sh -c` 显式执行,避免 shell 解析歧义)
# 使用国内镜像源并增加超时时间,避免网络超时
RUN python -m pip install --upgrade --break-system-packages \
--index-url https://mirrors.aliyun.com/pypi/simple/ \
--timeout 300 \
--retries 5 \
pip
# ✅ 验证 Python 环境
RUN echo "✅ Python version:" && python --version && \
echo "✅ pip version:" && pip --version && \
echo "✅ docker version:" && docker --version && \
echo "✅ buildx version:" && docker buildx version && \
echo "✅ QEMU arm64 registered:" && ls /proc/sys/fs/binfmt_misc/qemu-arm64 2>/dev/null || echo "⚠️ QEMU not found (should not happen)"
#设置时区
# 1. 安装 tzdata(Alpine 官方时区数据包)
RUN apk add --no-cache tzdata
# 2. 设置默认时区(影响 date 命令 & 大多数应用)
ENV TZ=Asia/Shanghai
# 3. (可选)让 `date` 命令显示正确本地时间(软链接 localtime)
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && \
echo "$TZ" > /etc/timezone
WORKDIR /app
# 复制 Python 依赖文件
COPY requirements.txt .
# 安装 Python 依赖
# 创建软链接(可选)
RUN ln -sf python3 /usr/bin/python && \
ln -sf pip3 /usr/bin/pip
# ✅ 创建虚拟环境并激活安装
RUN python -m venv .venv && \
.venv/bin/pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && \
.venv/bin/pip config set global.timeout 300 && \
.venv/bin/pip config set global.retries 5 && \
.venv/bin/pip install --upgrade pip && \
.venv/bin/pip install --no-cache-dir -r requirements.txt && \
echo "✅ docker-compose version:" && docker-compose --version || echo "⚠️ docker-compose not found"
# ✅ 设置 PATH,让 .venv/bin 优先(等效于 source .venv/bin/activate)
ENV PATH="/app/.venv/bin:$PATH"
# 复制后端代码(含 backend/VERSION,供运行时版本号与更新检查)
COPY backend/ ./backend/
# ============ 阶段 3: Agent 镜像 ============
FROM backend-base AS app2docker-agent
# Agent 不需要前端和模板,只需要后端代码(已在 backend-base 阶段复制)
# ✅ 设置 Python 无缓冲输出,确保日志立即输出到控制台
ENV PYTHONUNBUFFERED=1
# ✅ 设置 PYTHONPATH,确保可以正确导入 backend 模块
ENV PYTHONPATH="/app"
# 说明:
# - Agent 需要访问 Docker daemon(通过 /var/run/docker.sock 卷映射)
# - Agent 需要访问主机信息(通过 /proc 和 /sys 卷映射)
#
# 构建 Agent 镜像:
# docker build --target app2docker-agent -t app2docker-agent:latest .
#
# 运行 Agent 容器:
# docker run -d \
# --name app2docker-agent \
# --restart=always \
# -e AGENT_TOKEN=<token> \
# -e SERVER_URL=http://<server_host>:<port> \
# -v /var/run/docker.sock:/var/run/docker.sock \
# -v /proc:/host/proc:ro \
# -v /sys:/host/sys:ro \
# app2docker-agent:latest
# 复制启动脚本
COPY backend/agent/start.sh /app/backend/agent/start.sh
RUN chmod +x /app/backend/agent/start.sh
# 启动 Agent 程序(使用启动脚本捕获错误)
CMD ["/app/backend/agent/start.sh"]
# ============ 阶段 4: 主程序镜像(默认) ============
FROM backend-base AS app2docker
# 从第一阶段复制构建好的前端文件(vite.config.js 中 outDir 设置为 '../dist')
COPY --from=frontend-builder /app/dist ./dist
# 复制内置模板
COPY templates/ ./templates/
# 说明:
# - templates/ 目录包含内置模板(按项目类型分类)
# - data/ 目录在运行时通过卷映射提供
# - favicon.ico 已包含在前端构建产物(dist/)中
#
# 构建主程序镜像(默认,不指定 --target 时构建此镜像):
# docker build -t app2docker:latest .
#
# 或显式指定:
# docker build --target app2docker -t app2docker:latest .
#
# 运行容器:
# docker run -d \
# -v $(pwd)/data:/app/data \
# -v /var/run/docker.sock:/var/run/docker.sock \
# -p 8000:8000 \
# app2docker:latest
#
# 自定义端口:
# docker run -d \
# -e APP_PORT=9000 \
# -v $(pwd)/data:/app/data \
# -v /var/run/docker.sock:/var/run/docker.sock \
# -p 9000:9000 \
# app2docker:latest
# 设置默认服务端口(可通过环境变量覆盖)
ENV APP_PORT=8000
ENV APP_HOST=0.0.0.0
# 暴露服务端口
EXPOSE ${APP_PORT}
# 启动后端服务(后端会服务前端构建文件)
# 端口可通过环境变量 APP_PORT 设置
CMD ["python", "backend/app.py"]