dream0776 2016-04-30 11:51
浏览 93

使用docker的多个nginx / php应用程序的体系结构

I've been running most of my apps on single nginx/php-fpm installation directly on vps. I've decided to try out docker, and have been playing with it for a week now. I've read everything possible and believe I understand its concepts.

But I cannot wrap my head around having so many instances of nginx, php and db.

One thing I settled with is that I want to have 1 db, so that's easy:

  image: mariadb:latest
  container_name: mariadb
    - ""
  restart: always
    - /srv/mysql:/var/lib/mysql

I also found nginx-proxy together with nginx-certs work like charm:

  image: jwilder/nginx-proxy
  container_name: nginx-proxy
    - "80:80"
    - "443:443"
  restart: always
    - /srv/certs:/etc/nginx/certs:ro
    - /var/run/docker.sock:/tmp/docker.sock:ro
    - ./vhost.d:/etc/nginx/vhost.d
    - /usr/share/nginx/html

  image: jrcs/letsencrypt-nginx-proxy-companion
  container_name: nginx-certs
    - /srv/certs:/etc/nginx/certs:rw
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - nginx-proxy

This is all dandy. But how do I handle actual app containers?

I want to keep ram usage to minimum, so what is recommended:

  1. 1 php-fpm container with multiple volumes inside and multiple nginx servers
  2. 1 nginx server and multiple php-fpm containers?
  3. have 1 container per project and keep nginx/php-fpm inside that container
  4. X nginx containers + X php-fpm containers. X amount of apps.

Any ideas?

  • 写回答

2条回答 默认 最新

  • dongyi7041 2016-04-30 12:16

    You should only need 1 nginx container per host, and use that to load balance between your php containers. If you set the restart policy correctly on the nginx container, it should always be running, and nginx can handle a lot of load, so only one should be fine.

    It also gets harder to manage when you have more than one nginx, since only one container can bind to ports 80 and 443 at a time, and you would need something in front of the two nginx containers to load balance between them in that case. If you want redundancy you can add another host with that same exact setup, the load balance between the hosts.

    1 db container with volumes for the data is good.

    At least 1 php container, ideally more than one, but depends on your load. If you plan on changing the data(php files) in the containers (not recommended) when running, then make sure you use a volume, and share between all php containers.

    Have nginx load balance between the php containers, and make sure the restart policy for the php containers are setup correctly.

    If you need to update the php container images, it makes it easier if you have more than one, then you can do a rolling upgrade with no downtime.

    1. Pull down new image
    2. Stop php1 container, start with new image
    3. Stop php2 container, start with new image

    Done, rolling upgrade with no downtime.

    This setup works with one site, or many. The only difference is that nginx would be handling the proxying to the correct php containers based on the hostname.

    So you would always have 1 nginx, but the php containers would grow based on the number of sites you are hosting.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
  • dps43378 2016-04-30 14:23

    I never used php-fpm but the doc here would help you I think: https://hub.docker.com/r/bitnami/php-fpm/ They explain how to setup a nginx in a separate container to server content from a "naked" php-fpm container, you only have to repeat the step for each php-fpm container but keeping the same nginx container. Solution 2 seems to be the way to go, nginx-proxy can be both the proxy and the frontend (keeping the conf in one place), so nginx-proxy + nginx-certs + N php-fpm.

    On a side note, you should use alpine based images, they're ridiculously small and come only with what you need, like this: https://hub.docker.com/r/yavin/alpine-php-fpm/


    I did some tests. You can define a custom conf per virtual host for nginx-proxy. The php container received the request but then I got a 502 error. The custom conf is placed in the /etc/nginx/vhost.d folder and named myphp.local (myphp.local being a virtual host of your php container), it contains only a location directive:

    location ~ \.php$ {
       fastcgi_pass myphp.local:9000;
       fastcgi_index index.php;

    The auto-generated default.conf of nginx-proxy looks like:

    upstream myphp.local {
    server {
        server_name myphp.local;
        listen 80;
        include /etc/nginx/vhost.d/myphp.local;
        location / {
            proxy_pass http://myphp.local;

    For me, the php container should receive the requests on port 9000. But I'm not familiar with php so I don't know what the issue could be. My index.php is a simple <?php echo "hello world!" ?>.




  • ¥30 电脑画面同步投屏,通过同wifi的方式投屏方法,接收投屏端不需要安装第三方软件,
  • ¥15 有偿拼接大疆精灵4RGB影像
  • ¥15 Arduino实现音频混响
  • ¥15 cuda.jit加速报错
  • ¥15 Octave 安装工具箱出错 Only Win32 target is supported!
  • ¥15 docker save的不能在另一台设备运行
  • ¥15 Unity Animation Rigging使用问题
  • ¥15 mbedtls握手返回-7200
  • ¥30 c++ http服务器
  • ¥15 express连接mssql,每条额外附加了语句