在Docker环境中使用Symfony进行生产
I am looking to implement a symfony application on Docker using Docker-Compose. I will have at least the following containers :
- Nginx
- Rabbitmq server
- PHP-FPM
- MySQL
- Solr
Currently we have a development environment using the above setup too.
The Symfony application is stored locally (host) and then a volume is used on the PHP-FPM container so that it can read the application - this works well. We bash
into the php-fpm container to run composer / app/console commands.
We also manually run the consumers (Symfony commands) that consume messages from the rabbitmq server.
What are my options in production ?
1) Can i create a single container running the application and then allow other containers to use it ? i see that the php-fpm container needs access to the application code - but i would also like to create a container to run a consumer - passing in the name of the service to run to the container - meaning i can have a single image that can be flexibly launched to process messages from any queue. What happens with logs / cache in this option ?
2) Have the application stored within each image that needs it ? this is my least favourite option as then to update the application i need to build each image
3) Something i haven't yet explored ?
I would like to allow easy updates to the application - something scripted perhaps, but i would also like to minimise downtime - i can do that using haproxy or something similar - has anyone else got any experiences with running a multi container symfony application in production ?
我希望使用Docker-Compose在Docker上实现一个symfony应用程序。 我将至少拥有以下容器: p>
- Nginx li>
- Rabbitmq服务器 li>
- PHP-FPM
- MySQL li>
- Solr li>
ul>
目前我们还有一个使用上述设置的开发环境。 p>
Symfony应用程序存储在本地(主机),然后在PHP-FPM容器上使用卷,以便它可以读取应用程序 - 这很有效。 我们
bash code>进入php-fpm容器运行composer / app / console命令。 p>
我们还手动运行使用消息的消费者(Symfony命令) rabbitmq服务器。 p>
我在生产中有哪些选择? p>
1)我可以创建一个运行应用程序的单个容器,然后允许其他容器使用 它? 我看到php-fpm容器需要访问应用程序代码 - 但我还想创建一个容器来运行一个消费者 - 传递服务的名称来运行到容器 - 这意味着我可以有一个单独的图像 可以灵活地启动以处理来自任何队列的消息。 此选项中的日志/缓存会发生什么? p>
2)是否将应用程序存储在需要它的每个图像中? 这是我最不喜欢的选项,然后更新我需要构建每个图像的应用程序 p>
3)我还没有探索过的东西? p>
我想允许对应用程序进行简单的更新 - 也许是脚本化的,但我也希望最大限度地减少停机时间 - 我可以使用haproxy或类似的东西 - 有其他人有任何经验在生产中运行多容器symfony应用程序吗? p> div>
I run a container for each service. Remember that one of the Docker principles is "separation of concern".
You may have Nginx + PHP-FPM on the same container, though.
To launch all the services (in dev or prod environment) you can use docker-compose and the magic "SYMFONY_ENV=dev" environment variable to launch everything. I suggest to launch the consumers in a separate conainer, but with different project / log /cache paths, possibly. Consider that consumers, on production, may affect online performances if they are running with shared CPU/memory/disk.
I am currently investigating alternatives to deploy/postdeploy the webapp, the suboptimal solution is now a simple entrypoint bash script (which is passed to "docker run -d myimage php_entrypoint.sh" that:
- prepares the environment
- downloads and updates vendors
- syncs resources to cdn, updates db schema, etc
- runs the applications server (php-fpm in this case, i use supervisord to do the task)
It results in something like this:
#$OPTIMIZE is an ENV-propagated or a calulated variable
su -c "php composer.phar install $OPTIMIZE" webmgr
cp -f web/HTACCESS_${SYMFONY_ENV} web/.htaccess
/usr/bin/supervisord -c /etc/supervisord/supervisord.conf
The reason why I am using supervisord is that I have to copy/mount the [program:] sections that I need to run, thus maintaining a single php image that is good both for php-fpm and CLI/consumer work. I can also restart the php appserver without killing the container. Moreover, supervisord is quite clever at managing "daemonized" processes.
UPDATED
The webapp is mounted as a volume, and docker-compose.yml is in the project root directory, which contains docker image configurations and the symfony project. This is an excerpt of docker-compose.yml
webapp_fpm:
image: ...
volumes:
- ./symfony:/var/www/html
- ./docker-conf/supervisord:/etc/supervisord
- /var/log/appname/symfony:/var/log/symfony
entrypoint: "/bin/bash php_entrypoint.sh"