Docker生产环境下的PHP-FPM和Nginx配置就绪

24

在Docker中,我使用php-fpm、nginx和应用程序代码的组合存在一个小的理论问题。我试图坚持这个模型:Docker镜像只做一件事情 - 我有单独的容器用于php-fpm和nginx。

php:
    image: php:5-fpm-alpine
    expose:
        - 9000:9000
    volumes:
        - ./:/var/www/app

nginx:
    image: nginx:alpine
    ports:
        - 3000:80
    links:
        - php
    volumes:
        - ./nginx/app.conf:/etc/nginx/conf.d/app.conf
        - ./:/var/www/app

注意: 在 app.conf 文件中,有 root /var/www/app;

来自Symfony的示例模式

这在开发中非常棒,但我不知道如何将其转换为生产就绪状态。在生产中挂载应用程序目录实际上是一种非常糟糕的做法(如果我没有弄错的话)。在最好的情况下,我会将应用程序源代码复制到容器中并使用此预构建代码(Dockerfile 中的 COPY . /var/www/app),但在这种情况下不可能或者我不知道如何做。

我需要在两个容器之间共享应用程序源代码(nginx 容器和 php-fpm 容器),因为两者都需要它。

当然,我可以创建自己的 nginx 和 php-fpm 容器,并在两个容器中添加 COPY . /var/www/app,但我认为这是错误的方式,因为我重复了代码,整个构建过程(安装依赖项、构建源代码等)必须在两个(nginx/php-fpm)容器中进行。

我尝试搜索,但我找不到任何解决此问题的想法。很多文章展示了如何使用 docker-compose 文件并使用 --volume 挂载代码,但我没有找到任何在生产中使用的示例(不使用卷)。

对我来说,唯一可接受的解决方案(目前)是制作一个包含 nginx 和 php-fpm 的容器,但我不确定这是否是一个好方法(我正在寻找最佳实践)。

你有任何经验或想法来解决这个问题吗?

感谢您的任何回应!


1
同样的问题 :( 我也需要帮助 - jerson
2个回答

6
我通过使用docker-compose文件创建共享卷来解决这个问题:
version: '3'

volumes:
 share_place:

services:
 php:
  image: php:5-fpm-alpine
  ports:
   - 9000:9000
  volumes:
   - share_place:/var/www/app
 nginx:
  image: nginx:alpine
  ports:
   - 3000:80
  volumes:
   - share_place:/var/www/app

这将创建一个名为share_place的卷,它将在两个容器之间共享数据。

4

现在我使用类似以下的方法:

Dockerfile:

FROM php:fpm
COPY . /var/www/app/
WORKDIR /var/www/app/
RUN composer install
EXPOSE 9000
VOLUME /var/www/app/web

Dockerfile.nginx

FROM nginx
COPY default /etc/nginx/default

docker-compose.yml

app:
  build:
    context: .
web:
  build:
    context: .
    dockerfile: Dockerfile.nginx
  volumes_from: app  

但是在5月17日的发布中,我们可以在一个Dockerfile文件中完成如下操作:

FROM php:cli AS builder
COPY . /var/www/app/
WORKDIR /var/www/app/
RUN composer install && bin/console assets:dump

FROM php:fpm AS app
COPY --from=builder /var/www/app/src /var/www/app/vendor /var/www/app/
COPY --from=builder /var/www/app/web/app.php /var/www/app/vendo /var/www/app/web/

FROM nginx AS web
COPY default /etc/nginx/default
COPY --from=builder /var/www/app/web /var/www/app/web

4
以这种方式使用多阶段构建不会解决问题。如果运行这个Dockerfile,只会创建一个镜像(最后一个FROM指令所在的镜像)。 - Jim Panse
@JimPanse 有 docker build --target 选项以及在 docker-compose 的 build 部分中的 target 键。 - VolCh
1
没错!我昨天发现了这个选项...有了这个选项,构建镜像变得非常棒! - Jim Panse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接