This commit is contained in:
Rzy 2026-08-11 16:41:45 +08:00
parent 4c37bfdeae
commit 90f1bd69e4
3 changed files with 14 additions and 35 deletions

View File

@ -14,19 +14,9 @@ RUN python scripts/generate_supervisor_conf.py
# 创建所有需要的目录 # 创建日志目录
RUN mkdir -p /var/log/supervisor /app/logs /app/model_cache /tmp/gunicorn && \ RUN mkdir -p /var/log/supervisor /app/logs /app/model_cache
chmod 777 /var/log/supervisor /app/logs /app/model_cache /tmp /tmp/gunicorn
# 创建非root用户并加入必要的组
RUN groupadd -g 1000 appuser && \
useradd -m -u 1000 -g appuser appuser && \
usermod -aG root appuser && \
chown -R appuser:appuser /app && \
chown -R appuser:appuser /var/log/supervisor
# 切换到非root用户
USER appuser
# 启动命令 # 启动命令
CMD ["sh", "-c", "mkdir -p /tmp/gunicorn && python scripts/download_models.py && supervisord -c ./supervisor.conf"] CMD ["sh", "-c", "mkdir -p /tmp/gunicorn && python scripts/download_models.py && supervisord -c ./supervisor.conf"]

View File

@ -4,6 +4,7 @@ services:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: bert-all-services container_name: bert-all-services
user: "0:0" # 显式使用 root
ports: ports:
- "5002-5010:5002-5010" - "5002-5010:5002-5010"
env_file: env_file:
@ -15,13 +16,6 @@ services:
- NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES:-all} - NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES:-all}
- NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES:-all} - NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES:-all}
- MODEL_CACHE_DIR=/app/model_cache - MODEL_CACHE_DIR=/app/model_cache
# 传递代理环境变量(如果构建时使用了代理)
- HTTP_PROXY=${HTTP_PROXY:-}
- HTTPS_PROXY=${HTTPS_PROXY:-}
- http_proxy=${http_proxy:-}
- https_proxy=${https_proxy:-}
- NO_PROXY=${NO_PROXY:-}
- no_proxy=${no_proxy:-}
volumes: volumes:
- ./logs:/app/logs - ./logs:/app/logs
- ./models:/app/models - ./models:/app/models

View File

@ -11,12 +11,16 @@ def discover_models():
for key, value in os.environ.items(): for key, value in os.environ.items():
if key.endswith('_MODEL_ID'): if key.endswith('_MODEL_ID'):
prefix = key[:-9] prefix = key[:-9]
service_name = os.getenv(f'{prefix}_SERVICE_NAME', f'{prefix.lower()}_classifier')
service_folder = service_name.replace('_classifier', '')
models[prefix.lower()] = { models[prefix.lower()] = {
'prefix': prefix, 'prefix': prefix,
'model_id': value, 'model_id': value,
'port': os.getenv(f'{prefix}_PORT', '5002'), 'port': os.getenv(f'{prefix}_PORT', '5002'),
'service_name': os.getenv(f'{prefix}_SERVICE_NAME', f'{prefix.lower()}_classifier'), 'service_name': service_name,
'model_dir': os.getenv(f'{prefix}_MODEL_DIR', f'/app/services/{prefix.lower()}/model') 'model_dir': os.getenv(f'{prefix}_MODEL_DIR', f'/app/services/{service_folder}/model'),
'service_folder': service_folder,
} }
return models return models
@ -25,7 +29,6 @@ def generate_supervisor_conf(models):
"""生成supervisor配置文件""" """生成supervisor配置文件"""
conf = [] conf = []
# supervisor全局配置
conf.append("""[supervisord] conf.append("""[supervisord]
nodaemon=true nodaemon=true
logfile=/var/log/supervisor/supervisord.log logfile=/var/log/supervisor/supervisord.log
@ -34,14 +37,14 @@ childlogdir=/var/log/supervisor
""") """)
# 为每个模型生成program配置
programs = [] programs = []
for name, config in models.items(): for name, config in models.items():
program_name = config['service_name'] program_name = config['service_name']
service_folder = config['service_folder']
programs.append(program_name) programs.append(program_name)
conf.append(f"""[program:{program_name}] conf.append(f"""[program:{program_name}]
command=gunicorn --bind 0.0.0.0:{config['port']} --workers %(ENV_MAX_WORKERS)s --threads 2 --timeout 120 services.{name}.app:app command=gunicorn --bind 0.0.0.0:{config['port']} --workers %(ENV_MAX_WORKERS)s --threads 2 --timeout 120 services.{service_folder}.app:app
directory=/app directory=/app
autostart=true autostart=true
autorestart=true autorestart=true
@ -50,12 +53,10 @@ stdout_logfile=/app/logs/{program_name}.log
stdout_logfile_maxbytes=50MB stdout_logfile_maxbytes=50MB
stderr_logfile=/app/logs/{program_name}_error.log stderr_logfile=/app/logs/{program_name}_error.log
stderr_logfile_maxbytes=50MB stderr_logfile_maxbytes=50MB
environment=SERVICE_NAME="{program_name}",SERVICE_PORT="{config['port']}",MODEL_ID="{config['model_id']}" environment=SERVICE_NAME="{program_name}",SERVICE_PORT="{config['port']}",MODEL_ID="{config['model_id']}",MODEL_DIR="{config['model_dir']}"
user=appuser
""") """) # 注意:移除了 user=appuser
# 生成group配置
conf.append(f"""[group:bert_services] conf.append(f"""[group:bert_services]
programs={','.join(programs)} programs={','.join(programs)}
""") """)
@ -66,12 +67,9 @@ programs={','.join(programs)}
def main(): def main():
supervisor_conf_path = './supervisor.conf' supervisor_conf_path = './supervisor.conf'
# 检查文件是否已存在
if os.path.exists(supervisor_conf_path): if os.path.exists(supervisor_conf_path):
print("=" * 50) print("=" * 50)
print("supervisor.conf already exists, skipping generation...") print("supervisor.conf already exists, skipping generation...")
print(f"File: {os.path.abspath(supervisor_conf_path)}")
print("=" * 50)
sys.exit(0) sys.exit(0)
print("=" * 50) print("=" * 50)
@ -81,22 +79,19 @@ def main():
models = discover_models() models = discover_models()
if not models: if not models:
print("⚠️ No models found, generating empty config") print("⚠️ No models found")
sys.exit(1) sys.exit(1)
print(f"Found {len(models)} model(s):") print(f"Found {len(models)} model(s):")
for name, config in models.items(): for name, config in models.items():
print(f" - {name}: {config['model_id']} (port {config['port']})") print(f" - {name}: {config['model_id']} (port {config['port']})")
# 生成配置
conf_content = generate_supervisor_conf(models) conf_content = generate_supervisor_conf(models)
# 写入文件
with open(supervisor_conf_path, 'w') as f: with open(supervisor_conf_path, 'w') as f:
f.write(conf_content) f.write(conf_content)
print(f"\n✓ supervisor.conf generated successfully!") print(f"\n✓ supervisor.conf generated successfully!")
print(f" File: {os.path.abspath(supervisor_conf_path)}")
print("=" * 50) print("=" * 50)