Docker - 将代码交付给nginx和php-fpm

4

如何在独立的NGINX和PHP-FPM容器之间传递仅包含代码,基于busybox的容器化PHP应用程序的代码?我使用了docker compose的第三个版本。

包含代码的镜像的Dockerfile如下:

FROM busybox

#the app's code
RUN mkdir /app

VOLUME /app

#copy the app's code from the context into the image
COPY code /app

docker-compose.yml文件应该是这样的:
version: "3"
services:
  #the application's code
  #the volume is currently mounted from the host machine, but the code will be copied over into the image statically for production
  app:
   image: app
   volumes:
    - ../../code/cms/storage:/storage
   networks:
    - backend

  #webserver
  web:
   image: web
   depends_on:
    - app
    - php
   networks:
    - frontend
    - backend
   ports:
    - '8080:80'
    - '8081:443'

  #php
  php:
   image: php:7-fpm
   depends_on:
    - app
   networks:
    - backend

networks:
 cms-frontend:
   driver: "bridge"
 cms-backend:
   driver: "bridge"

我想到的解决方案都不太合适:
1)在PHP和NGINX容器中使用应用程序容器的卷,但compose v3不允许volumes_from指令。无法使用。
2)将代码放在命名卷中并将其连接到容器。这样做,我无法将代码容器化。无法使用。(我还需要在群集中的每个节点上手动创建此卷吗?)
3)将代码直接复制两次到基于NGINX和PHP-FPM的图像中。这是个坏主意。我必须保持它们保持一致性。
陷入困境了。还有其他选项吗?我可能误解了什么,毕竟才刚开始用Docker。

好的,我第一个可能的解决方案是使用Bind mounts进行开发,并将文件(通过Dockerfile指令)复制到生产中的php镜像中,同时创建一个卷暴露这些文件。接下来,我将使用命名卷在docker-compose.yml中与nginx容器共享此卷。不确定它是否会奏效,但至少文档确认:https://docs.docker.com/engine/admin/volumes/#tips-for-using-bind-mounts-or-volumes - super.t
它能正常工作吗?我和你一样,如何分享代码? - RafaelQm
1
@RafaelQm 我已经放弃了 PHP,不确定它是否适用。但在此之前,我一直在尝试将代码挂载到 Nginx 容器中。想想看,你可能只需要在那里放置前端控制器,因此你可以尝试在那里创建一个空的 index.php 文件,并玩弄 Nginx 配置。 - super.t
2个回答

3

我也一直在寻找解决类似问题的方法,似乎Nginx + PHP-FPM是生产环境下最好两个服务运行在一个容器中的例外情况之一。在开发过程中,您可以将项目文件夹绑定到nginx和php容器中。按照Bret Fisher的指南,为php提供良好的默认设置:

php-docker-good-defaults

到目前为止,Nginx + PHP-FPM组合是我唯一建议使用多服务容器的场景。这是一个相当独特的问题,不总是适合“一个容器,一个服务”的模型。您可以使用两个单独的容器,一个带有nginx,一个带有php:fpm,但我曾尝试在生产环境中使用此方法,并且存在许多缺点。每个容器中都必须有一份PHP代码的副本,它们必须通过TCP进行通信,这比在单个容器中使用Linux套接字要慢得多,而且由于它们之间通常存在一对一的关系,因此单独的服务控制论点相当无意义。

你可以在这里阅读有关在Docker上设置多个服务容器的更多信息(它也列在上面的链接中):Docker在一个容器中运行多个服务

0

在我看来,你有两个选择:

(1) 使用Docker-compose:(这适用于非常简单的开发环境)

你需要从nginx和php-fpm镜像构建两个独立的容器。然后只需从php-fpm上的web文件夹中提供app文件夹即可。

# The Application
  app:
    build:
      context: ./
      dockerfile: app.dev.dockerfile
    working_dir: /var/www
    volumes:
      - ./:/var/www
    expose:
      - 9000
  # The Web Server
  web:
    build:
      context: ./
      dockerfile: web.dev.dockerfile
    working_dir: /var/www
    volumes_from:
      - app
    links:
       - app:app
    ports:
      - 80:80
      - 443:443

(2) 使用单个Dockerfile构建其中的所有内容。

  • 从某种Linux或PHP镜像开始
  • 安装nginx
  • 构建您的自定义镜像
  • 并使用supervisord提供多服务docker容器

1
为什么在简化的开发环境中使用docker-compose并将代码从php-fpm容器挂载到nginx容器中?我打算在生产环境中采用这种方法(不过会使用stack代替compose)。 - super.t
请仔细检查...您需要找到一种方法将代码从应用程序容器提供给Web容器(应用程序容器应完全封闭)。使用上述代码,您正在创建一个可以从主机访问的卷(运行Docker容器的主机)。因此,任何可以访问您的主机的人都可以修改代码,然后容器内的应用程序也会受到影响。此外,该机制正在使用Docker容器链接...我认为为了使您的应用程序具有未来性,您应该使用Docker网络...并且如果可能的话,应该使用最新版本的Docker Compose语法。 - Andy
1
我不会从主机上挂载代码,如果你是指这个的话,这只是用于开发。在生产环境中,代码将被复制到应用程序镜像中,并以只读模式暴露给Web容器。尽管我不确定这是否可行,以及它是否需要废弃的链接。另外,我可以将代码复制到应用和Web镜像中,但这需要太多的维护工作。Docker网络如何帮助我在容器之间共享代码? - super.t
我的设置是使用后端网络,通过该网络nginx和php-fpm进行通信。我没有故意使用任何链接。我阅读了文档并进行了大量的谷歌搜索,现在似乎只有两个选择,如果我想要这些服务在单独的容器中 - 从php容器挂载代码或在镜像构建阶段将代码复制到两个容器中。 - super.t

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