modify: docker 支持
This commit is contained in:
@@ -16,3 +16,6 @@ output.md
|
|||||||
|
|
||||||
# resources
|
# resources
|
||||||
uploads/
|
uploads/
|
||||||
|
|
||||||
|
# docker
|
||||||
|
*.tar
|
||||||
|
|||||||
@@ -56,3 +56,29 @@ build
|
|||||||
cd build
|
cd build
|
||||||
chongming # windows chongming.exe
|
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
@@ -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"]
|
||||||
+24
-12
@@ -5,10 +5,12 @@ FastAPI chongming 示例
|
|||||||
主入口文件,适配 chongming 打包系统
|
主入口文件,适配 chongming 打包系统
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
|
import platform
|
||||||
from utils.launch import launch
|
from utils.launch import launch
|
||||||
from multiprocessing import freeze_support
|
from multiprocessing import freeze_support
|
||||||
import server
|
import server
|
||||||
|
|
||||||
|
use_shell = platform.system() == "Windows"
|
||||||
|
|
||||||
def app_run(app_config: dict, default_config: dict):
|
def app_run(app_config: dict, default_config: dict):
|
||||||
"""
|
"""
|
||||||
@@ -18,7 +20,6 @@ def app_run(app_config: dict, default_config: dict):
|
|||||||
app_config: 应用配置
|
app_config: 应用配置
|
||||||
default_config: 默认配置
|
default_config: 默认配置
|
||||||
"""
|
"""
|
||||||
import uvicorn
|
|
||||||
from app.core.logger import get_logger # type: ignore
|
from app.core.logger import get_logger # type: ignore
|
||||||
|
|
||||||
logger = get_logger("app")
|
logger = get_logger("app")
|
||||||
@@ -47,17 +48,28 @@ def app_run(app_config: dict, default_config: dict):
|
|||||||
logger.info(f"👥 Workers: {workers}")
|
logger.info(f"👥 Workers: {workers}")
|
||||||
logger.info("=" * 50)
|
logger.info("=" * 50)
|
||||||
|
|
||||||
uvicorn.run(
|
if use_shell:
|
||||||
"server:app",
|
import uvicorn
|
||||||
host=host,
|
uvicorn.run(
|
||||||
port=port,
|
"server:app",
|
||||||
reload=reload,
|
host=host,
|
||||||
workers=workers,
|
port=port,
|
||||||
log_level="debug" if app_config.get("debug", False) else "info",
|
reload=reload,
|
||||||
access_log=False,
|
workers=workers,
|
||||||
timeout_keep_alive=timeout_keep_alive,
|
log_level="debug" if app_config.get("debug", False) else "info",
|
||||||
)
|
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():
|
def main():
|
||||||
freeze_support()
|
freeze_support()
|
||||||
|
|||||||
@@ -48,3 +48,5 @@ packages = ["src/chongming"]
|
|||||||
[project.scripts]
|
[project.scripts]
|
||||||
build = "chongming.scripts.build:build"
|
build = "chongming.scripts.build:build"
|
||||||
serve = "chongming:serve"
|
serve = "chongming:serve"
|
||||||
|
# gunicorn = "gunicorn chongming.app:app -k uvicorn.workers.UvicornWorker -w 4 -b 0.0.0.0:8000"
|
||||||
|
gunicorn = "chongming:gunicorn_serve"
|
||||||
|
|||||||
@@ -13,6 +13,23 @@ def serve():
|
|||||||
logget.info(f"启动日志: {log_config}")
|
logget.info(f"启动日志: {log_config}")
|
||||||
uvicorn.run("chongming.app:app", **server_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__":
|
if __name__ == "__main__":
|
||||||
serve()
|
serve()
|
||||||
|
|||||||
+161
-75
@@ -1,3 +1,5 @@
|
|||||||
|
import platform
|
||||||
|
|
||||||
from module_bank import PythonToSQLite
|
from module_bank import PythonToSQLite
|
||||||
from module_bank.encryption import Encryption
|
from module_bank.encryption import Encryption
|
||||||
import os
|
import os
|
||||||
@@ -10,6 +12,8 @@ from sqlite_vfs.core import SQLiteVFS
|
|||||||
from sqlite_vfs.folder_packer import FolderPacker
|
from sqlite_vfs.folder_packer import FolderPacker
|
||||||
|
|
||||||
|
|
||||||
|
is_windows = platform.system() == "Windows"
|
||||||
|
|
||||||
def build_vue_web():
|
def build_vue_web():
|
||||||
"""打包 Vue Web"""
|
"""打包 Vue Web"""
|
||||||
# 构建 Vue Web 命令
|
# 构建 Vue Web 命令
|
||||||
@@ -26,26 +30,37 @@ def build_vue_web():
|
|||||||
cwd="./src/chongming-web",
|
cwd="./src/chongming-web",
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
shell=True,
|
shell=is_windows,
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
errors="replace",
|
errors="replace",
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
print("打包 Vue Web 失败")
|
print("打包 Vue Web 失败")
|
||||||
print(result.stderr)
|
print("标准输出:", result.stdout)
|
||||||
|
print("错误输出:", result.stderr)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
vfs = SQLiteVFS(output_db, compress=False)
|
print("Vue Web 打包成功")
|
||||||
packer = FolderPacker(
|
if result.stdout:
|
||||||
sqlite_vfs=vfs,
|
print(result.stdout)
|
||||||
exclude_patterns=[],
|
|
||||||
fs_name=fs_name,
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
# 检查 dist 目录是否存在
|
||||||
packer.pack_folder(dist_dir)
|
if not os.path.exists(dist_dir):
|
||||||
print(f"✅ 打包完成,文件保存为 {output_db}")
|
print(f"错误: dist 目录不存在: {dist_dir}")
|
||||||
finally:
|
return
|
||||||
vfs.close()
|
|
||||||
|
vfs = SQLiteVFS(output_db, compress=False)
|
||||||
|
packer = FolderPacker(
|
||||||
|
sqlite_vfs=vfs,
|
||||||
|
exclude_patterns=[],
|
||||||
|
fs_name=fs_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
packer.pack_folder(dist_dir)
|
||||||
|
print(f"✅ 打包完成,文件保存为 {output_db}")
|
||||||
|
finally:
|
||||||
|
vfs.close()
|
||||||
|
|
||||||
|
|
||||||
def run_pyarmor_obfuscate():
|
def run_pyarmor_obfuscate():
|
||||||
@@ -77,68 +92,139 @@ def run_pyinstaller():
|
|||||||
"""运行 PyInstaller 打包成可执行文件"""
|
"""运行 PyInstaller 打包成可执行文件"""
|
||||||
try:
|
try:
|
||||||
# 构建 PyInstaller 命令
|
# 构建 PyInstaller 命令
|
||||||
cmd = [
|
if is_windows:
|
||||||
sys.executable,
|
cmd = [
|
||||||
"-m",
|
sys.executable,
|
||||||
"PyInstaller",
|
"-m",
|
||||||
"--onefile",
|
"PyInstaller",
|
||||||
"--name",
|
"--onefile",
|
||||||
"chongming",
|
"--name",
|
||||||
"--distpath",
|
"chongming",
|
||||||
".",
|
"--distpath",
|
||||||
"--workpath",
|
".",
|
||||||
"./build_temp",
|
"--workpath",
|
||||||
"--specpath",
|
"./build_temp",
|
||||||
"./specs",
|
"--specpath",
|
||||||
"--clean",
|
"./specs",
|
||||||
# 隐藏导入
|
"--clean",
|
||||||
"--hidden-import",
|
# 隐藏导入
|
||||||
"utils",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"utils",
|
||||||
"utils.launch",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"utils.launch",
|
||||||
"utils.config",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"utils.config",
|
||||||
"server",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"server",
|
||||||
"module_bank",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"module_bank",
|
||||||
"fastapi",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"fastapi",
|
||||||
"fastapi.staticfiles",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"fastapi.staticfiles",
|
||||||
"fastapi.middleware.cors",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"fastapi.middleware.cors",
|
||||||
"uvicorn",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"uvicorn",
|
||||||
"sqlmodel",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"sqlmodel",
|
||||||
"aiosqlite",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"aiosqlite",
|
||||||
"aiofiles",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"aiofiles",
|
||||||
"apscheduler",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"apscheduler",
|
||||||
"diskcache",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"diskcache",
|
||||||
"passlib",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"passlib",
|
||||||
"passlib.context",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"passlib.context",
|
||||||
"passlib.handlers.bcrypt",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"passlib.handlers.bcrypt",
|
||||||
"sqlite_vfs",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"sqlite_vfs",
|
||||||
"python_multipart",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"python_multipart",
|
||||||
"sqlite_vfs.core",
|
"--hidden-import",
|
||||||
"--hidden-import",
|
"sqlite_vfs.core",
|
||||||
"jwt",
|
"--hidden-import",
|
||||||
# 其他选项
|
"jwt",
|
||||||
"--icon",
|
# 其他选项
|
||||||
"../../public/chongming.ico",
|
"--icon",
|
||||||
"main.py",
|
"../../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)}")
|
print(f"正在运行 PyInstaller: {' '.join(cmd)}")
|
||||||
result = subprocess.run(cmd, cwd="./build", capture_output=True, text=True)
|
result = subprocess.run(cmd, cwd="./build", capture_output=True, text=True)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ def generate_markdown_from_py_files(directory, output_file):
|
|||||||
or file.endswith(".ts")
|
or file.endswith(".ts")
|
||||||
or file.endswith(".json")
|
or file.endswith(".json")
|
||||||
or file.endswith(".html")
|
or file.endswith(".html")
|
||||||
|
or file == "dockerfile"
|
||||||
):
|
):
|
||||||
file_path = os.path.join(root, file)
|
file_path = os.path.join(root, file)
|
||||||
if file == "output.md" or file == "package-lock.json":
|
if file == "output.md" or file == "package-lock.json":
|
||||||
|
|||||||
Reference in New Issue
Block a user