【发布时间】:2019-11-03 12:49:31
【问题描述】:
上下文
我最近设置了一个 PHP 应用程序,以便在连接到不同容器中的数据库的 docker 容器中工作。
在生产中,我们使用的是单一容器环境,因为它只是连接到托管在其他地方的数据库。尽管如此,为了简化开发工作流程,我们还是决定在本地使用两个容器和 docker-compose。
问题
我们遇到的问题是,我们第一次通过docker-compose up --build Composer 的vendor 目录构建和运行应用程序在容器中不可用,即使我们在@ 中有一个特定的RUN composer install 行987654328@。一旦容器运行,我们就必须在容器内执行composer install。
找到解决方案
经过大量谷歌搜索,我们认为我们有两种可能的解决方案:
- 将我们的 Docker 镜像的默认命令更改为:
bash -c "composer install && /usr/sbin/apache2ctl -D FOREGROUND"
- 或者简单地通过docker-compose的
command覆盖容器的默认命令到上面。
不同之处在于,如果我们通过 docker-compose 覆盖该命令,那么在将应用程序部署到我们的服务器时,它将无缝运行,这是应该的,但是当更改 Dockerfile 中的默认命令时,它将遭受 1每次我们部署的时候都会有几分钟的停机时间。
这在此过程中有所帮助:
一些(可能是错误的)结论
我的结论是,那一分钟的停机时间是由于容器必须在运行 Apache 服务器之前通过 composer 安装所有依赖项,而不是简单地运行服务器。
此外,我从所有的探索中得出的另一个结论是,docker-compose up --build 不会安装作曲家依赖项的原因是因为我们在docker-compose.yml 中指定了一个卷,它覆盖了容器中的目录。
这些帮助:
实际问题
我希望有人能对这一切有所了解,因为我并不完全了解发生了什么——为什么运行 docker-compose 不会安装 PHP 依赖项,但在默认命令中包含 composer install 会以及为什么将composer install 添加到docker-compose.yml 更好。此外,卷是如何影响这一切的,这是否是所有麻烦的真正原因。
我们当前的 docker 文件如下所示:
FROM php:7.1.27-apache-stretch
ENV DEBIAN_FRONTEND=noninteractive
# install some stuff, PHP, Apache, etc.
WORKDIR /srv/app
COPY . .
RUN composer install
RUN service apache2 restart
EXPOSE 80
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
我们现在的docker-compose.yml 是这样的:
version: '3'
services:
database:
image: mysql:5.7
container_name: container-cool-name
command: mysqld --user=root --sql_mode=""
ports:
- "3306:3306"
volumes:
- ./db_backup.sql:/tmp/db_backup.sql
- ./.docker/import.sh:/tmp/import.sh
environment:
MYSQL_DATABASE: my_db
MYSQL_USER: my_user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: test
app:
build:
context: .
dockerfile: Dockerfile
image: image-name
command: bash -c "composer install && /usr/sbin/apache2ctl -D FOREGROUND"
ports:
- 8080:80
volumes:
- .:/srv/app
links:
- database:db
depends_on:
- database
environment:
DB_HOST: db
DB_PORT: 3306
DB_DATABASE: my_db
DB_USER: my_user
DB_PASSWORD: password
【问题讨论】:
标签: php docker docker-compose composer-php dockerfile