在多个php应用程序中使用Docker
我最近从Wamp(wampserver)转到Docker(Windows主机)。在使用wamp时,我可以有多个项目,如下面的文件结构在多个php应用程序中使用Docker,php,docker,docker-compose,lamp,Php,Docker,Docker Compose,Lamp,我最近从Wamp(wampserver)转到Docker(Windows主机)。在使用wamp时,我可以有多个项目,如下面的文件结构 - wamp64 - www/ - project1/ - project2/ - .... 在wamp的Apache上,我定义了两个虚拟主机,所有的项目都使用wamp的数据库,每个都有自己的模式 因此,在一天中,在必要时将上下文从project1切换到project2再切换到project3等是很常见的。。 通过访问像http:/
- wamp64
- www/
- project1/
- project2/
- ....
在wamp的Apache上,我定义了两个虚拟主机,所有的项目都使用wamp的数据库,每个都有自己的模式
因此,在一天中,在必要时将上下文从project1
切换到project2
再切换到project3
等是很常见的。。
通过访问像http://localhost/projectX
或相应的虚拟主机
在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停止我当前正在工作的项目,并将docker compose添加到我想要切换到的项目,反之亦然
我尝试了另一种方法,在单个ApachePHP容器(整个www文件夹)中运行所有项目
这会让我一次拥有所有项目,但采用这种方法,我面临两个严重问题
docker build花费的时间太长,可能是因为文件数量增加,而不是单个项目中的文件数量减少
我不能在mysql中初始化超过一个db模式,所以即使我设法运行了2到3个项目,也只有1个项目能够与相应的db通信李>
第一种方法中的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
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
第二种方法中的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
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 data persist我认为对您来说,最好的解决方案是在自己的容器中运行每个项目。由于容器是(应该)轻量级的,并且易于上下移动,所以这样做的开销应该是最小的
我将展示的与第一种方法的不同之处在于docker compose文件将为您编排容器。因此,它应该允许所有容器(项目)同时与数据库通信。(假设您的项目不会经常相互覆盖,并导致死锁)
文件夹结构:
- www/
docker-compose.yml
- project1/
Dockerfile
- project2/
Dockerfile
Docker Compose
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 build-t myphpdev:最新版本-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的文件夹,为每个站点创建一个名为data的文件夹。每个网站将在
根据需要调整/添加任何PHP_u;env变量。图像出现时将基于env变量更新PHP.ini
当以这种方式运行时,每个站点都必须使用相对链接而不是绝对链接进行设置,并且它们都将共享同一个db实例
资源密集度最低的配置是让每个站点共享同一个db实例,并让每个站点在实例上拥有自己的db。如果出于某种原因,所有站点都必须使用相同的db名称,那么也可以使用表前缀
如果您不介意额外的资源使用,您可以复制mysql块,确保每个站点都有一个唯一的端口号和数据文件夹,并为每个站点提供一个完全独立的db服务器
在容器中装载主机将允许您从主机端编辑站点文件夹的内容,并使用xdebug进行实时调试,而无需在每次需要迭代或上下文切换时重建docker环境
如果不想在站点中使用相对链接,也可以通过添加一些Apache配置来设置虚拟主机,方法是将配置装载到/opt/docker/etc/httpd/vhost.common.d中/
检查Dockerfile中引用的图像的文档。在php版本、web服务器和基本操作系统以及开发与生产设置方面,它们有很多不同之处。我在下面添加了他们文档的链接
对于凯尔的回答,我会非常小心。。考虑这个例子
./project1/Dockerfile
./project2/Dockerfile
./shared.php
通过使用他的建议,您将无法在/project1/Dockerfile
或/project2/Dockerfile
中使用shared.php
所以不是
build:
context: /project1 #automatically finds Dockerfile
照办
build:
context: .
dockerfile: ./project1/Dockerfile
这告诉系统,可能包含共享文件的上下文文件夹与Dockerfile所在的文件夹不同,这是一个非常有用的分离
关于上下文的更多详细信息此处您是否为每次代码更改重建Docker图像?如果是这样,您可以在开发中使用卷来缓解这种情况。为什么您必须停止一个Docker项目并开始另一个单端口冲突?您希望从使用Docker中获得哪些具体好处?您能否将您的非Docker工作设置用于日常开发,而仅将Docker设置用于生产部署?@DavidMaze我最初从Wamp迁移到Docker,因为我面临有关memcache扩展和PHP 7.3的不兼容问题。由于我的生产环境使用LAMP环境,我认为我的本地设置尽可能接近生产环境更合适setup@halfer似乎了解单个项目的Docker与在不同的项目中使用Docker是不同的。很明显,我做错了什么,这就是为什么我开始写这篇文章的原因,因为