将 Docker 用于多个 php 应用程序
Using Docker for multiple php applications
我最近从 Wamp(wampserver)搬到了 Docker(Windows 主机)。在使用 wamp 时,我能够拥有多个项目,如以下文件结构
- wamp64
- www/
- project1/
- project2/
- ....
在 wamp 的 Apache 上,我定义了几个虚拟主机,所有项目都使用 wamp 的数据库,每个都有自己的模式。
因此,在一天之内,必要时从 project1
、project2
到 project3
等切换上下文是很常见的。
通过访问 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/
这可以让我同时拥有所有项目,但是使用这种方法,我面临两个严重的问题。
- docker 构建花费的时间太长,可能是因为文件数量增加,而不是单个项目的数量减少
- 我无法在 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。
对于 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 所在的文件夹不同,这是一个非常有用的分隔。
这里有更多关于上下文的详细信息
我最近从 Wamp(wampserver)搬到了 Docker(Windows 主机)。在使用 wamp 时,我能够拥有多个项目,如以下文件结构
- wamp64
- www/
- project1/
- project2/
- ....
在 wamp 的 Apache 上,我定义了几个虚拟主机,所有项目都使用 wamp 的数据库,每个都有自己的模式。
因此,在一天之内,必要时从 project1
、project2
到 project3
等切换上下文是很常见的。
通过访问 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/
这可以让我同时拥有所有项目,但是使用这种方法,我面临两个严重的问题。
- docker 构建花费的时间太长,可能是因为文件数量增加,而不是单个项目的数量减少
- 我无法在 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。
对于 Kyle 的回答,我会非常小心..考虑这个例子
./project1/Dockerfile
./project2/Dockerfile
./shared.php
通过使用他的建议,您将无法在 ./project1/Dockerfile
或 ./project2/Dockerfile
所以不用
build:
context: /project1 #automatically finds Dockerfile
随心所欲
build:
context: .
dockerfile: ./project1/Dockerfile
这告诉系统可能包含共享文件的 context 文件夹与 Dockerfile 所在的文件夹不同,这是一个非常有用的分隔。
这里有更多关于上下文的详细信息