【问题标题】:docker-compose overrides directories in the containerdocker-compose 覆盖容器中的目录
【发布时间】:2019-11-03 12:49:31
【问题描述】:

上下文

我最近设置了一个 PHP 应用程序,以便在连接到不同容器中的数据库的 docker 容器中工作。

在生产中,我们使用的是单一容器环境,因为它只是连接到托管在其他地方的数据库。尽管如此,为了简化开发工作流程,我们还是决定在本地使用两个容器和 docker-compose。

问题

我们遇到的问题是,我们第一次通过docker-compose up --build Composer 的vendor 目录构建和运行应用程序在容器中不可用,即使我们在@ 中有一个特定的RUN composer install 行987654328@。一旦容器运行,我们就必须在容器内执行composer install

找到解决方案

经过大量谷歌搜索,我们认为我们有两种可能的解决方案:

  1. 将我们的 Docker 镜像的默认命令更改为:
bash -c "composer install && /usr/sbin/apache2ctl -D FOREGROUND"
  1. 或者简单地通过docker-compose的command覆盖容器的默认命令到上面。

不同之处在于,如果我们通过 docker-compose 覆盖该命令,那么在将应用程序部署到我们的服务器时,它将无缝运行,这是应该的,但是当更改 Dockerfile 中的默认命令时,它将遭受 1每次我们部署的时候都会有几分钟的停机时间。

这在此过程中有所帮助:

  1. Running composer install within a Dockerfile

一些(可能是错误的)结论

我的结论是,那一分钟的停机时间是由于容器必须在运行 Apache 服务器之前通过 composer 安装所有依赖项,而不是简单地运行服务器。

此外,我从所有的探索中得出的另一个结论是,docker-compose up --build 不会安装作曲家依赖项的原因是因为我们在docker-compose.yml 中指定了一个卷,它覆盖了容器中的目录。

这些帮助:

  1. https://stackoverflow.com/a/38817651/4700998

  2. https://stackoverflow.com/a/48589910/4700998

实际问题

我希望有人能对这一切有所了解,因为我并不完全了解发生了什么——为什么运行 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


    【解决方案1】:

    Dockerfile 中的第一个 composer install 工作正常,生成的图像具有 vendor/ 等。

    但是稍后您从该映像创建一个容器,并且执行该容器时将整个目录替换为主机目录安装:

    volumes:
          - .:/srv/app
    

    因此,您的 docker 映像既有您的文件,也有安装的供应商文件,但随后您将项目目录替换为主机上没有供应商文件的目录,最终结果看起来好像从未完成构建。

    我的建议是:

    • 不要将第二个命令构建添加到Dockerfile
    • 在您的容器中挂载单个文件夹,即不是.:/srv/app,而是./src:/srv/app/src等。
    • 或者,映射整个文件夹,但将供应商文件从映像/容器复制到您的主机
    • 或使用一些 3rd 方实用程序来解决这个问题,例如http://docker-sync.io 或其他许多人

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      • 2020-03-26
      相关资源
      最近更新 更多