为何Systemd服务启动Docker容器时会触发镜像构建导致失败?
问题原因与解决方案
问题根源
你的docker-compose.yml中每个服务同时定义了image和build字段。当docker-compose up执行时,它会优先检查本地是否存在指定image的镜像:
- 如果镜像不存在,会自动触发构建流程;
- 即使镜像存在,若
build上下文目录(比如./dlnWebApplication)在部署环境中缺失,docker-compose仍可能尝试验证构建配置,导致报错。
而你的部署环境没有这些构建所需的上下文目录,所以systemd服务启动时会因构建失败而无法正常运行。
解决方法
方法一:移除docker-compose.yml中的build字段(推荐)
既然部署环境已经通过tar包加载了镜像,完全不需要构建步骤,直接删除每个服务下的build配置即可。修改后的docker-compose.yml如下:
services: web: image: dlnproject-web:latest container_name: ${WEB_CONTAINER_NAME} volumes: - ./db:/app/db # Mount the new db directory containing db.sqlite3 env_file: - .env environment: - DJANGO_SETTINGS_MODULE=dlnWebApplication.settings - DATABASE_PATH=/app/db/db.sqlite3 # Correct path for both services cron: image: dlnproject-cron:latest container_name: ${CRON_CONTAINER_NAME} volumes: - ./db:/app/db # Mount the new db directory containing db.sqlite3 - ./logs/dlnEquipmentSnooper:/var/log/dlnEquipmentSnooper # Map log directory to host depends_on: - web env_file: - .env environment: - DJANGO_SETTINGS_MODULE=dlnWebApplication.settings - DATABASE_PATH=/app/db/db.sqlite3 # Correct path for both services nginx: image: dlnproject-nginx:latest container_name: ${NGINX_CONTAINER_NAME} volumes: - ./dlnWebApplication/static:/app/static - ./dlnWebApplication/media:/app/media - ./logs:/var/log/nginx ports: - "80:80" depends_on: - web volumes: sqlite_data:
方法二:在systemd服务中添加--no-build参数
如果需要保留build字段(比如后续可能在其他环境复用该配置),可以修改systemd服务的ExecStart命令,加上--no-build参数,强制docker-compose不执行构建:
[Service] WorkingDirectory=/opt/dlnWebApplication ExecStart=/usr/bin/docker-compose -f /opt/dlnWebApplication/docker-compose.yml up -d --no-build ExecStop=/usr/bin/docker-compose -f /opt/dlnWebApplication/docker-compose.yml down Restart=always RestartSec=5 User=dlnwebapp Group=dlnserverusers
额外检查:用户权限
确保dlnwebapp用户拥有docker操作权限,执行以下命令将其加入docker组:
sudo usermod -aG docker dlnwebapp
修改后需要重新登录或重启systemd服务生效。
内容的提问来源于stack exchange,提问作者AeroClassics
相关产品推荐
相关产品推荐

