modify: aarch64 设备docker部署
This commit is contained in:
+56
-29
@@ -1,48 +1,75 @@
|
|||||||
# FROM debian:bookworm-slim AS builder
|
# 架构参数:可选值 x86_64 或 aarch64
|
||||||
|
ARG TARGETARCH=x86_64
|
||||||
|
|
||||||
FROM ubuntu:24.04 AS builder
|
FROM ubuntu:24.04 AS builder
|
||||||
|
|
||||||
RUN apt-get update && \
|
ARG TARGETARCH
|
||||||
apt-get install -y --no-install-recommends ca-certificates tzdata && \
|
|
||||||
|
# 跳过 GPG 签名验证(兼容 BM1684 等系统时间不准的设备)
|
||||||
|
RUN apt-get update -o Acquire::AllowInsecureRepositories=yes \
|
||||||
|
-o Acquire::AllowDowngradeToInsecureRepositories=yes \
|
||||||
|
--allow-unauthenticated 2>/dev/null || true && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
-o Acquire::AllowInsecureRepositories=yes \
|
||||||
|
--allow-unauthenticated \
|
||||||
|
ca-certificates tzdata 2>/dev/null || true && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY build/chongming /tmp/chongming
|
COPY build/chongming /tmp/chongming
|
||||||
|
|
||||||
RUN mkdir -p /tmp/rootfs/app && \
|
# 构建最小 rootfs
|
||||||
# === 临时目录 ===
|
RUN \
|
||||||
mkdir -p /tmp/rootfs/tmp && \
|
if [ "$TARGETARCH" = "aarch64" ]; then \
|
||||||
chmod 1777 /tmp/rootfs/tmp && \
|
LIB_PATH="/lib/aarch64-linux-gnu"; \
|
||||||
# === 数据目录 ===
|
LD_LINKER="/lib/ld-linux-aarch64.so.1"; \
|
||||||
mkdir -p /tmp/rootfs/app/data && \
|
LD_LINKER_TARGET="/tmp/rootfs/lib/ld-linux-aarch64.so.1"; \
|
||||||
chmod 777 /tmp/rootfs/app/data && \
|
else \
|
||||||
# === 解释器目录 ===
|
LIB_PATH="/lib/x86_64-linux-gnu"; \
|
||||||
mkdir -p /tmp/rootfs/lib64 && \
|
LD_LINKER="/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2"; \
|
||||||
mkdir -p /tmp/rootfs/lib/x86_64-linux-gnu && \
|
LD_LINKER_TARGET="/tmp/rootfs/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2"; \
|
||||||
cp /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
fi && \
|
||||||
ln -s /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /tmp/rootfs/lib64/ld-linux-x86-64.so.2 && \
|
mkdir -p /tmp/rootfs/app && \
|
||||||
|
mkdir -p /tmp/rootfs/tmp && chmod 1777 /tmp/rootfs/tmp && \
|
||||||
|
mkdir -p /tmp/rootfs/app/data && chmod 777 /tmp/rootfs/app/data && \
|
||||||
|
# === aarch64 链接器路径特殊处理 ===
|
||||||
|
if [ "$TARGETARCH" = "aarch64" ]; then \
|
||||||
|
mkdir -p /tmp/rootfs/lib && \
|
||||||
|
cp /lib/ld-linux-aarch64.so.1 /tmp/rootfs/lib/ && \
|
||||||
|
mkdir -p /tmp/rootfs/lib64 && \
|
||||||
|
ln -s /lib/ld-linux-aarch64.so.1 /tmp/rootfs/lib64/ld-linux-aarch64.so.1; \
|
||||||
|
else \
|
||||||
|
mkdir -p /tmp/rootfs/lib64 && \
|
||||||
|
mkdir -p /tmp/rootfs${LIB_PATH} && \
|
||||||
|
cp ${LIB_PATH}/ld-linux-x86-64.so.2 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
|
ln -s ${LIB_PATH}/ld-linux-x86-64.so.2 /tmp/rootfs/lib64/ld-linux-x86-64.so.2; \
|
||||||
|
fi && \
|
||||||
# === 依赖库 ===
|
# === 依赖库 ===
|
||||||
cp /lib/x86_64-linux-gnu/libdl.so.2 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
mkdir -p /tmp/rootfs${LIB_PATH} && \
|
||||||
cp /lib/x86_64-linux-gnu/libz.so.1 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
cp ${LIB_PATH}/libdl.so.2 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
cp /lib/x86_64-linux-gnu/libpthread.so.0 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
cp ${LIB_PATH}/libz.so.1 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
cp ${LIB_PATH}/libpthread.so.0 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
cp /lib/x86_64-linux-gnu/librt.so.1 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
cp ${LIB_PATH}/libc.so.6 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
cp /lib/x86_64-linux-gnu/libm.so.6 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
cp ${LIB_PATH}/librt.so.1 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
cp /lib/x86_64-linux-gnu/libutil.so.1 /tmp/rootfs/lib/x86_64-linux-gnu/ && \
|
cp ${LIB_PATH}/libm.so.6 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
cp /lib/x86_64-linux-gnu/libnss_dns.so.2 /tmp/rootfs/lib/x86_64-linux-gnu/ 2>/dev/null || true && \
|
cp ${LIB_PATH}/libutil.so.1 /tmp/rootfs${LIB_PATH}/ && \
|
||||||
cp /lib/x86_64-linux-gnu/libnss_files.so.2 /tmp/rootfs/lib/x86_64-linux-gnu/ 2>/dev/null || true && \
|
cp ${LIB_PATH}/libnss_dns.so.2 /tmp/rootfs${LIB_PATH}/ 2>/dev/null || true && \
|
||||||
cp /lib/x86_64-linux-gnu/libresolv.so.2 /tmp/rootfs/lib/x86_64-linux-gnu/ 2>/dev/null || true && \
|
cp ${LIB_PATH}/libnss_files.so.2 /tmp/rootfs${LIB_PATH}/ 2>/dev/null || true && \
|
||||||
|
cp ${LIB_PATH}/libresolv.so.2 /tmp/rootfs${LIB_PATH}/ 2>/dev/null || true && \
|
||||||
# === 时区数据 ===
|
# === 时区数据 ===
|
||||||
mkdir -p /tmp/rootfs/usr/share/zoneinfo && \
|
mkdir -p /tmp/rootfs/usr/share/zoneinfo && \
|
||||||
cp -r /usr/share/zoneinfo/Asia /tmp/rootfs/usr/share/zoneinfo/ && \
|
cp -r /usr/share/zoneinfo/Asia /tmp/rootfs/usr/share/zoneinfo/ 2>/dev/null || true && \
|
||||||
cp /usr/share/zoneinfo/UTC /tmp/rootfs/usr/share/zoneinfo/ && \
|
cp /usr/share/zoneinfo/UTC /tmp/rootfs/usr/share/zoneinfo/ 2>/dev/null || true && \
|
||||||
# === 证书和 DNS ===
|
# === 证书和 DNS ===
|
||||||
mkdir -p /tmp/rootfs/etc/ssl/certs && \
|
mkdir -p /tmp/rootfs/etc/ssl/certs && \
|
||||||
cp /etc/ssl/certs/ca-certificates.crt /tmp/rootfs/etc/ssl/certs/ && \
|
cp /etc/ssl/certs/ca-certificates.crt /tmp/rootfs/etc/ssl/certs/ 2>/dev/null || true && \
|
||||||
echo "hosts: files dns" > /tmp/rootfs/etc/nsswitch.conf && \
|
echo "hosts: files dns" > /tmp/rootfs/etc/nsswitch.conf && \
|
||||||
# === /proc /sys /dev ===
|
# === /proc /sys /dev ===
|
||||||
mkdir -p /tmp/rootfs/proc /tmp/rootfs/sys /tmp/rootfs/dev
|
mkdir -p /tmp/rootfs/proc /tmp/rootfs/sys /tmp/rootfs/dev
|
||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
|
|
||||||
|
ARG TARGETARCH
|
||||||
|
|
||||||
COPY --from=builder /tmp/rootfs/ /
|
COPY --from=builder /tmp/rootfs/ /
|
||||||
|
|
||||||
COPY build/chongming /app/chongming
|
COPY build/chongming /app/chongming
|
||||||
@@ -55,4 +82,4 @@ WORKDIR /app
|
|||||||
|
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
|
||||||
CMD ["./chongming"]
|
CMD ["./chongming"]
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ chongming/
|
|||||||
### 运行原理
|
### 运行原理
|
||||||
|
|
||||||
开发时通过 `uv run serve` 直接启动 uvicon。
|
开发时通过 `uv run serve` 直接启动 uvicon。
|
||||||
打包后,`chongming` 可执行文件内嵌了经过混淆的引导程序,引导程序从加密的 Module-Bank 文件 (`app.mbank`, `plugins.mbank`) 中动态加载应用模块,同时从 SQLite VFS (`static.svfs`) 提供前端静态文件。所有 Python 业务代码不暴露与明文磁盘。
|
打包后,`chongming` 可执行文件内嵌了经过混淆的引导程序,引导程序从加密的 Module-Bank 文件 (`app.mbank`, `plugins.mbank`) 中动态加载应用模块,同时从 SQLite VFS (`static.svfs`) 提供前端静态文件。所有 Python 业务代码不暴露于明文磁盘。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -197,12 +197,23 @@ build/
|
|||||||
|
|
||||||
## Docker 部署
|
## Docker 部署
|
||||||
|
|
||||||
Docker 镜像采用多角度构建 + `scratch` 基础镜像,真正做到最小化。
|
Docker 镜像采用多阶段构建 + `scratch` 基础镜像,真正做到最小化。同时支持 **x86_64** 与 **aarch64 (ARM64)** 双架构。
|
||||||
|
|
||||||
### 构建镜像
|
### 构建镜像
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# 默认构建 x86_64 架构
|
||||||
docker build -t chongming:latest .
|
docker build -t chongming:latest .
|
||||||
|
|
||||||
|
# 在 ARM64 设备上构建
|
||||||
|
docker build --build-arg TARGETARCH=aarch64 -t chongming:arm64 .
|
||||||
|
|
||||||
|
# 使用 Docker Buildx 构建多架构镜像(推送到仓库)
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--build-arg TARGETARCH \
|
||||||
|
-t your-registry/chongming:latest \
|
||||||
|
--push .
|
||||||
```
|
```
|
||||||
|
|
||||||
### 执行部署脚本
|
### 执行部署脚本
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ host = "0.0.0.0"
|
|||||||
port = 8000
|
port = 8000
|
||||||
reload = false
|
reload = false
|
||||||
workers = 4
|
workers = 4
|
||||||
|
# 对于嵌入式设备(如 BM1684),建议启用环境变量覆盖:
|
||||||
|
# docker run -e APP_WORKERS=2 ...
|
||||||
|
# 可减少线程数,避免 "can't start new thread" 错误
|
||||||
|
|
||||||
[production.logging]
|
[production.logging]
|
||||||
backup_count = 5 # 最多保存 10 个日志文件
|
backup_count = 5 # 最多保存 10 个日志文件
|
||||||
|
|||||||
@@ -12,8 +12,25 @@ log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|||||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||||
|
|
||||||
# 配置
|
# 检测架构
|
||||||
IMAGE="chongming:latest"
|
ARCH=$(uname -m)
|
||||||
|
case "$ARCH" in
|
||||||
|
x86_64|amd64)
|
||||||
|
DEFAULT_IMAGE="chongming:latest"
|
||||||
|
ARCH_FLAG="x86_64"
|
||||||
|
;;
|
||||||
|
aarch64|arm64)
|
||||||
|
DEFAULT_IMAGE="chongming:arm64"
|
||||||
|
ARCH_FLAG="aarch64"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "不支持的架构: $ARCH"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 配置:可通过环境变量覆盖镜像标签,例如: IMAGE=chongming:arm64 ./deploy.sh
|
||||||
|
IMAGE="${IMAGE:-$DEFAULT_IMAGE}"
|
||||||
CONTAINER="chongming"
|
CONTAINER="chongming"
|
||||||
PORT=8000
|
PORT=8000
|
||||||
DATA_DIR="${HOME}/chongming-data"
|
DATA_DIR="${HOME}/chongming-data"
|
||||||
@@ -60,13 +77,27 @@ if ss -tlnp | grep -q ":${PORT}"; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 根据架构设置默认 worker 数
|
||||||
|
case "$ARCH" in
|
||||||
|
aarch64|arm64)
|
||||||
|
DEFAULT_WORKERS=2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
DEFAULT_WORKERS=4
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# 4. 启动容器
|
# 4. 启动容器
|
||||||
log_info "启动容器..."
|
log_info "启动容器..."
|
||||||
|
log_info "架构: $ARCH, workers: ${APP_WORKERS:-$DEFAULT_WORKERS}, 端口: $PORT"
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-p "$PORT:8000" \
|
-p "$PORT:8000" \
|
||||||
-v "$DATA_DIR/data:/app/data" \
|
-v "$DATA_DIR/data:/app/data" \
|
||||||
-v "$DATA_DIR/uploads:/app/uploads" \
|
-v "$DATA_DIR/uploads:/app/uploads" \
|
||||||
-v "$DATA_DIR/logs:/app/logs" \
|
-v "$DATA_DIR/logs:/app/logs" \
|
||||||
|
-e "APP_WORKERS=${APP_WORKERS:-$DEFAULT_WORKERS}" \
|
||||||
|
--ulimit nproc=65535 \
|
||||||
|
--ulimit nofile=65535 \
|
||||||
--restart unless-stopped \
|
--restart unless-stopped \
|
||||||
--name "$CONTAINER" \
|
--name "$CONTAINER" \
|
||||||
"$IMAGE"
|
"$IMAGE"
|
||||||
@@ -92,4 +123,4 @@ else
|
|||||||
log_error "容器启动失败,查看日志:"
|
log_error "容器启动失败,查看日志:"
|
||||||
docker logs "$CONTAINER" 2>/dev/null || true
|
docker logs "$CONTAINER" 2>/dev/null || true
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,7 @@
|
|||||||
FastAPI chongming 示例
|
FastAPI chongming 示例
|
||||||
主入口文件,适配 chongming 打包系统
|
主入口文件,适配 chongming 打包系统
|
||||||
"""
|
"""
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import platform
|
import platform
|
||||||
from utils.launch import launch
|
from utils.launch import launch
|
||||||
@@ -37,7 +38,9 @@ def app_run(app_config: dict, default_config: dict):
|
|||||||
# 打包环境强制禁用重载
|
# 打包环境强制禁用重载
|
||||||
is_frozen = getattr(sys, "frozen", False)
|
is_frozen = getattr(sys, "frozen", False)
|
||||||
reload = False if is_frozen else server_config.get("reload", False)
|
reload = False if is_frozen else server_config.get("reload", False)
|
||||||
workers = server_config.get("workers", 4)
|
# 支持通过环境变量 APP_WORKERS 覆盖 worker 数量(方便嵌入式设备调优)
|
||||||
|
default_workers = server_config.get("workers", 4)
|
||||||
|
workers = int(os.environ.get("APP_WORKERS", str(default_workers)))
|
||||||
|
|
||||||
# 显示启动信息
|
# 显示启动信息
|
||||||
env = app_config.get("env", "development")
|
env = app_config.get("env", "development")
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ async def init_database():
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||||
|
|
||||||
from ..app.core.config import get_config
|
from ..app.core.config import get_config
|
||||||
from ..app.task.dev_init_db import init_permission, dev_init_admin
|
from ..app.task.dev_init_db import init_permission, init_default_roles, dev_init_admin
|
||||||
|
|
||||||
database = get_config()["database"]
|
database = get_config()["database"]
|
||||||
database_type = database["type"]
|
database_type = database["type"]
|
||||||
@@ -333,6 +333,9 @@ async def init_database():
|
|||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
# await UserService.create_user(session, "admin", "admin", is_superuser=True) # type: ignore
|
# await UserService.create_user(session, "admin", "admin", is_superuser=True) # type: ignore
|
||||||
await init_permission(session)
|
await init_permission(session)
|
||||||
|
# 再初始化默认角色及权限关联
|
||||||
|
await init_default_roles(session)
|
||||||
|
# 最后初始化管理员用户
|
||||||
await dev_init_admin(session)
|
await dev_init_admin(session)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user