Docker-Compose无法维持LAMP基础容器运行的问题求助
其实你的问题核心在于Docker容器的运行逻辑:容器的生命周期完全绑定它的主进程——只要主进程退出,容器就会立刻停止。
你单独用docker run时能正常运行,是因为Debian镜像默认的启动命令是bash,再加上你加了-it参数(开启交互模式并分配终端),bash会一直等着输入,所以容器不会退出。但在Docker Compose里,你自定义了启动命令,最后虽然加了bash,但Compose默认不会给容器分配终端也不会打开标准输入,bash在没东西可做的情况下就直接退出了,容器自然跟着停了。
我推荐第一种更贴合Docker设计思路的方案:
方案1:让Apache成为容器的主进程
Apache支持前台运行模式,只要用apache2ctl -D FOREGROUND启动它,它就会一直占据主进程位置,容器也就会持续运行。你可以先把MySQL启动、执行完初始化脚本,最后让Apache前台跑起来:
修改docker-compose.yaml里lamp服务的command部分:
command: > /bin/sh -c "service mysql start && \ mysql < migrations/migrations.sql && \ mysql < migrations/development.sql && \ apache2ctl -D FOREGROUND"
这样一来,MySQL会在后台保持运行,而Apache作为主进程前台运行,容器就不会随便退出了——哪怕后续Apache意外挂了,容器还能根据你的重启策略自动重启,更利于服务稳定性。
方案2:给容器分配交互终端(不推荐)
如果你非要用bash来维持容器运行,可以在lamp服务里加上tty: true和stdin_open: true,模拟出和docker run -it一样的交互终端环境,让bash不会自动退出:
lamp: container_name: lamp-stack build: . ports: - 80:80 volumes: - .:/var/www/html tty: true stdin_open: true command: > /bin/sh -c "service apache2 start && \ service mysql start && \ mysql < migrations/migrations.sql && \ mysql < migrations/development.sql && \ bash"
但这个方案不太推荐,因为容器的生命周期和bash绑定,而不是和你的核心服务Apache绑定——要是Apache挂了,容器还会继续运行,你很难及时发现服务故障。
其实在一个容器里同时跑Apache和MySQL并不是Docker的最佳实践,更规范的做法是把MySQL拆成独立的服务,用官方的mysql镜像来运行。这样每个容器只负责一个服务,不管是版本管理、资源隔离还是故障排查都会更方便。给你个示例参考:
version: "3.2" services: lamp: container_name: lamp-stack build: . ports: - 80:80 volumes: - .:/var/www/html command: apache2ctl -D FOREGROUND depends_on: - mysql mysql: container_name: mysql-db image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: your_root_password MYSQL_DATABASE: your_db_name volumes: - ./migrations:/docker-entrypoint-initdb.d - mysql-data:/var/lib/mysql node: container_name: node-builder image: node:12-alpine3.9 depends_on: - lamp working_dir: /var/www/html volumes: - .:/var/www/html command: > /bin/ash -c "npm run build:dev > ./.logs/npm/npm-build.log && \ npm run watch:sass > ./.logs/npm/sass-watch.log" volumes: mysql-data:
这里MySQL服务独立运行,你的初始化SQL脚本会被官方镜像自动执行;lamp容器只负责跑Apache和PHP,完全符合容器“单一职责”的设计原则。
内容的提问来源于stack exchange,提问作者n1md7

