将 Docker 用于多个 php 应用程序

Using Docker for multiple php applications

我最近从 Wamp(wampserver)搬到了 Docker(Windows 主机)。在使用 wamp 时,我能够拥有多个项目,如以下文件结构

- wamp64
  - www/
    - project1/ 
    - project2/
    - ....

在 wamp 的 Apache 上,我定义了几个虚拟主机,所有项目都使用 wamp 的数据库,每个都有自己的模式。

因此,在一天之内,必要时从 project1project2project3 等切换上下文是很常见的。 通过访问 http://localhost/projectX 之类的 url 或相应的虚拟主机。

这在 Docker 上似乎并不那么直接,正如我目前所见。 我的第一个方法是在每个项目

上设置不同的 Docker
- www/
  - project1/
       - dockerfile & docker-compose
  - project2/
       - dockerfile & docker-compose
  - projectX/
       - dockerfile & docker-compose
- data // this is where mysql data lie

我认为与我过去使用 wamp 相比,这似乎不太有效,因为每次我想更改上下文时,我都必须使用 docker-compose stop 我当前正在工作的项目和 docker-compose up 到我想切换到的项目,反之亦然。

我尝试了另一种方法,将所有项目 运行 放在一个 apache-php 容器(整个 www 文件夹)中

- www/
    dockerfile & docker-compose
    - project1/
    - project2/

这可以让我同时拥有所有项目,但是使用这种方法,我面临两个严重的问题。

  1. docker 构建花费的时间太长,可能是因为文件数量增加,而不是单个项目的数量减少
  2. 我无法在 mysql 中初始化一个以上的数据库模式,所以即使我设法获得 2 或 3 个项目 运行ning,也只有 1 个能够与相应的通信D b。

我的 docker-compose 文件在第一种方法中看起来像这样

version: '3'

services:

  project1:
    build:
      context: . // contents of specific project directory
      dockerfile: .docker/Dockerfile

    image: project1

    ports:
      – 80:80

    volumes:
      – .:/app/project1

   links:
      – mysql

  mysql:

    image: mysql:5.7

    ports:
      – 13306:3306

    environment:

      MYSQL_DATABASE: docker
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      MYSQL_ROOT_PASSWORD: docker

    volumes:
      - ../data:var/lib/mysql

而我的 docker-compose 文件在第二种方法中看起来像这样

version: '3'

services:

  web-project:
    build:
      context: . // contents of www directory
      dockerfile: .docker/Dockerfile

    image: web-project

    ports:
      – 80:80

    volumes:
      – /project1:/app/project1
      – /project2:/app/project2
      – /projectX:/app/projectX

   links:
      – mysql

  mysql:

    image: mysql:5.7

    ports:
      – 13306:3306

    volumes:
      - /data:var/lib/mysql

ref for mysql 数据持续

我认为对您来说最好的解决方案是 运行 每个项目都在它自己的容器中。由于容器(应该)是轻量级的并且易于上下移动,因此这样做的开销应该是最小的。

我将展示的内容与第一种方法的区别在于 docker-compose 文件将为您编排容器。因此,它应该允许您的所有容器(项目)同时与您的数据库进行通信。 (鉴于您的项目不会不断地相互覆盖,并导致死锁)

文件夹结构:

- www/
    docker-compose.yml
    - project1/
      Dockerfile
    - project2/
      Dockerfile

Docker撰写

version: '3'
services:
  project1:
    build:
      context: /project1 #automatically finds Dockerfile
    container_name: project1
    ports:
      – 8081:80
    volumes:
      – .:/app/project
   links:
      – mysql
  project2:
    build:
      context: /project2 #automatically finds Dockerfile
    container_name: project2
    ports:
      – 8082:80
    volumes:
      – .:/app/project
   links:
      – mysql
  ...
  mysql:
    image: mysql:5.7
    ports:
      – 13306:3306
    volumes:
      - /data:var/lib/mysql

然后当您 运行 docker-compose up 时,它将在同一网络中调出两个项目容器和一个数据库容器。请注意,每个项目都在其自己的端口上 运行。所以你需要记住哪个端口链接到哪个容器。

创建一个顶级文件夹并将其放入 Dockerfile在里面

FROM webdevops/php-apache-dev:7.2

# Add microsoft SQL support to PHP

# add microsoft packages to apt sources
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/9/prod.list > /etc/apt/sources.list.d/mssql-release.list
# install needed system packages as well as a few nice to have utils
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
  DEBIAN_FRONTEND=noninteractive apt-get -y upgrade && \
  ACCEPT_EULA=Y apt-get -y install msodbcsql17 unixodbc-dev less joe iputils-ping traceroute telnet && \
  apt-get purge -y --auto-remove && \
  rm -rf /var/lib/apt/lists/*
# install sqlsrv php extensions
RUN pecl install sqlsrv pdo_sqlsrv
# load the pdo extension 
RUN echo extension=pdo_sqlsrv.so >> `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/30-pdo_sqlsrv.ini
# load the mssql extension 
RUN echo extension=sqlsrv.so >> `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/20-sqlsrv.ini

# our docroot
WORKDIR /app

在顶级文件夹 运行 中执行以下命令:

docker 构建 -t myphpdev:latest 。 -f Dockerfile

现在在同一个顶级文件夹中创建一个 docker-compose.yml 并将以下内容放入其中:

version: '3'
services:
  web_debug:
    image: myphpdev:latest
    ports:
      - 1080:80
    volumes:
      - .:/app
    environment:
      - PHP_XDEBUG_ENABLED=1
      - PHP_DATE_TIMEZONE="America/Los_Angeles"
      - PHP_MEMORY_LIMIT="512M"
      - PHP_MAX_EXECUTION_TIME="600"
      - PHP_MAX_INPUT_TIME="60"
      - PHP_POST_MAX_SIZE="512M"
      - PHP_UPLOAD_MAX_FILESIZE="512M"
      - PHP_ERROR_REPORTING="E_ALL & ~E_DEPRECATED & ~E_STRICT"
      - PHP_DISPLAY_ERRORS="1"
      - PHP_DISPLAY_STARTUP_ERRORS="1"
      - PHP_DEBUGGER="xdebug"
      - XDEBUG_CONFIG=remote_host=host.docker.internal

  mysql:
    image: mysql:5.7
    ports:
      - 13306:3306
    volumes:
      - ./data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=password

# if you get errors about invalid or needing to use absolute paths
# you may need to down your stack then run the next line then up the stack
# SET COMPOSE_CONVERT_WINDOWS_PATHS=1

在同一个顶级文件夹中,为您的数据库持久性创建一个名为 data 的文件夹,并为您的每个站点创建一个文件夹。每个站点将在 http://localhost:1080/site_folder

根据需要调整/添加任何 PHP_ env vars 图片将在出现时根据 env vars 更新 php.ini。

当 运行以这种方式设置时,每个站点都必须使用相对 link 而不是绝对设置,并且它们将共享同一个数据库实例。

资源占用最少的配置是让每个站点共享同一个数据库实例,并让每个站点在该实例上拥有自己的数据库。如果由于某种原因所有站点都必须使用相同的数据库名称,您也可以使用 table 前缀。

如果您不介意额外的资源使用,您可以复制 mysql 块,确保每个都有唯一的端口号和数据文件夹,并为每个站点启动一个完全独立的数据库服务器。

在容器内安装 host 将允许您从 host 端编辑站点文件夹的内容以及使用 xdebug 实时调试,而无需每次您想迭代或上下文切换时重建您的 docker 环境。

如果您不想在站点中使用相对 links,您也可以通过添加一些 Apache 配置来设置虚拟 hosts,方法是将配置安装到 /opt/docker/etc/httpd/vhost .common.d/

查看 Dockerfile 中引用的图像的文档。他们在 php 版本 Web 服务器和基础 os 以及开发与生产设置方面有很多变化。我在下面的文档中包含了 link。

WebDevOps ApachePHP Docker Docs

对于 Kyle 的回答,我会非常小心..考虑这个例子

./project1/Dockerfile
./project2/Dockerfile
./shared.php

通过使用他的建议,您将无法在 ./project1/Dockerfile./project2/Dockerfile

中使用 shared.php

所以不用

build:
  context: /project1 #automatically finds Dockerfile

随心所欲

build:
  context: .
  dockerfile: ./project1/Dockerfile

这告诉系统可能包含共享文件的 context 文件夹与 Dockerfile 所在的文件夹不同,这是一个非常有用的分隔。

这里有更多关于上下文的详细信息