modify: docker 支持

This commit is contained in:
2026-04-26 15:26:01 +08:00
parent 871b7abf02
commit 450be84020
8 changed files with 257 additions and 87 deletions
+3
View File
@@ -16,3 +16,6 @@ output.md
# resources
uploads/
# docker
*.tar
+26
View File
@@ -56,3 +56,29 @@ build
cd build
chongming # windows chongming.exe
```
## docker镜像
打包镜像
```shell
docker build -t chongming:latest .
```
导出镜像
```shell
docker save -o chongming_v1.0.tar chongming:v1.0
```
导入镜像
```shell
docker load -i chongming_v1.0.tar
```
运行镜像
```shell
mkdir -p /data/chongming
docker run -d -p 8000:8000 \
-v /data/chongming/database.db:/app/database.db \
-v /data/chongming/uploads:/app/uploads \
--name chongming chongming:v1.0
```
+23
View File
@@ -0,0 +1,23 @@
# 使用 Debian 的极简版,确保有基础的 glibc(推荐)
FROM debian:bookworm-slim
# 可选:设置时区、安装 ca-certificates 等
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# 复制打包好的可执行文件
COPY build/chongming /app/
# 复制运行时需要的静态资源、配置文件、.mbank 等
COPY build/config.toml /app/
COPY build/resources/ /app/resources/
COPY build/static.svfs /app/
# 暴露端口
EXPOSE 8000
# 启动
CMD ["./chongming"]
+14 -2
View File
@@ -5,10 +5,12 @@ FastAPI chongming 示例
主入口文件,适配 chongming 打包系统
"""
import sys
import platform
from utils.launch import launch
from multiprocessing import freeze_support
import server
use_shell = platform.system() == "Windows"
def app_run(app_config: dict, default_config: dict):
"""
@@ -18,7 +20,6 @@ def app_run(app_config: dict, default_config: dict):
app_config: 应用配置
default_config: 默认配置
"""
import uvicorn
from app.core.logger import get_logger # type: ignore
logger = get_logger("app")
@@ -47,6 +48,8 @@ def app_run(app_config: dict, default_config: dict):
logger.info(f"👥 Workers: {workers}")
logger.info("=" * 50)
if use_shell:
import uvicorn
uvicorn.run(
"server:app",
host=host,
@@ -57,7 +60,16 @@ def app_run(app_config: dict, default_config: dict):
access_log=False,
timeout_keep_alive=timeout_keep_alive,
)
else:
from gunicorn.app.wsgiapp import run
sys.argv = [
"gunicorn",
"server:app",
"-k", "uvicorn.workers.UvicornWorker",
"-w", str(workers),
"-b", f"{host}:{port}"
]
run()
def main():
freeze_support()
+2
View File
@@ -48,3 +48,5 @@ packages = ["src/chongming"]
[project.scripts]
build = "chongming.scripts.build:build"
serve = "chongming:serve"
# gunicorn = "gunicorn chongming.app:app -k uvicorn.workers.UvicornWorker -w 4 -b 0.0.0.0:8000"
gunicorn = "chongming:gunicorn_serve"
+17
View File
@@ -13,6 +13,23 @@ def serve():
logget.info(f"启动日志: {log_config}")
uvicorn.run("chongming.app:app", **server_config)
def gunicorn_serve():
"""使用 gunicorn 启动服务"""
import sys
from gunicorn.app.wsgiapp import run
config = load_config()
env = config["default"]["env"]
server_config = config[env]["server"]
# 设置 gunicorn 参数
sys.argv = [
"gunicorn",
"chongming.app:app",
"-k", "uvicorn.workers.UvicornWorker",
"-w", f"{server_config.get('workers', 4)}",
"-b", f"{server_config.get('host', '0.0.0.0')}:{server_config.get('port', 8000)}"
]
run()
if __name__ == "__main__":
serve()
+88 -2
View File
@@ -1,3 +1,5 @@
import platform
from module_bank import PythonToSQLite
from module_bank.encryption import Encryption
import os
@@ -10,6 +12,8 @@ from sqlite_vfs.core import SQLiteVFS
from sqlite_vfs.folder_packer import FolderPacker
is_windows = platform.system() == "Windows"
def build_vue_web():
"""打包 Vue Web"""
# 构建 Vue Web 命令
@@ -26,14 +30,25 @@ def build_vue_web():
cwd="./src/chongming-web",
capture_output=True,
text=True,
shell=True,
shell=is_windows,
encoding="utf-8",
errors="replace",
)
if result.returncode != 0:
print("打包 Vue Web 失败")
print(result.stderr)
print("标准输出:", result.stdout)
print("错误输出:", result.stderr)
return
else:
print("Vue Web 打包成功")
if result.stdout:
print(result.stdout)
# 检查 dist 目录是否存在
if not os.path.exists(dist_dir):
print(f"错误: dist 目录不存在: {dist_dir}")
return
vfs = SQLiteVFS(output_db, compress=False)
packer = FolderPacker(
sqlite_vfs=vfs,
@@ -77,6 +92,7 @@ def run_pyinstaller():
"""运行 PyInstaller 打包成可执行文件"""
try:
# 构建 PyInstaller 命令
if is_windows:
cmd = [
sys.executable,
"-m",
@@ -139,6 +155,76 @@ def run_pyinstaller():
"../../public/chongming.ico",
"main.py",
]
else:
cmd = [
sys.executable,
"-m",
"PyInstaller",
"--onefile",
"--name",
"chongming",
"--distpath",
".",
"--workpath",
"./build_temp",
"--specpath",
"./specs",
"--clean",
# 隐藏导入
"--hidden-import",
"utils",
"--hidden-import",
"utils.launch",
"--hidden-import",
"utils.config",
"--hidden-import",
"server",
"--hidden-import",
"module_bank",
"--hidden-import",
"fastapi",
"--hidden-import",
"fastapi.staticfiles",
"--hidden-import",
"fastapi.middleware.cors",
"--hidden-import",
"uvicorn",
"--hidden-import",
"sqlmodel",
"--hidden-import",
"aiosqlite",
"--hidden-import",
"aiofiles",
"--hidden-import",
"apscheduler",
"--hidden-import",
"diskcache",
"--hidden-import",
"passlib",
"--hidden-import",
"passlib.context",
"--hidden-import",
"passlib.handlers.bcrypt",
"--hidden-import",
"sqlite_vfs",
"--hidden-import",
"python_multipart",
"--hidden-import",
"sqlite_vfs.core",
"--hidden-import",
"jwt",
# gunicorn
"--hidden-import",
"gunicorn.glogging",
"--hidden-import",
"gunicorn.app",
"--hidden-import",
"gunicorn.app.wsgiapp",
# 其他选项
"--icon",
"../../public/chongming.ico",
"main.py",
]
print(f"正在运行 PyInstaller: {' '.join(cmd)}")
result = subprocess.run(cmd, cwd="./build", capture_output=True, text=True)
+1
View File
@@ -22,6 +22,7 @@ def generate_markdown_from_py_files(directory, output_file):
or file.endswith(".ts")
or file.endswith(".json")
or file.endswith(".html")
or file == "dockerfile"
):
file_path = os.path.join(root, file)
if file == "output.md" or file == "package-lock.json":