Servir conteúdo estático usando o docker + nginx + php-fpm

9

Estou tentando configurar uma aplicação web php usando o docker. A ideia é executar o aplicativo usando php-fpm em um contêiner independente e ter outro contêiner que executará o nginx. A idéia para essa configuração é usar o mesmo contêiner nginx para solicitações de proxy para outros aplicativos da web que já estão trabalhando na mesma máquina. O problema é que não posso obter nginx para processar corretamente os arquivos estáticos (js, css, etc), pois as solicitações para eles continuam indo para fpm .

É assim que o sistema de arquivos se parece:

/
├── Makefile
├── config
│   └── webapp.config
└── webapp
    └── web
        ├── index.php
        └── static.js

Estou executando a coisa toda usando um Makefile que se parece com isso (não estou interessado em docker-compose para isso):

PWD:=$(shell pwd)
CONFIG:='/config'
WEBAPP:='/webapp'

run: | run-network run-webapp run-nginx

run-network:
    docker network create internal-net

run-webapp:
    docker run --rm \
    --name=webapp \
    --net=internal-net \
    --volume=$(PWD)$(WEBAPP):/var/www/webapp:ro \
    -p 9000:9000 \
    php:5.6.22-fpm-alpine

run-nginx:
    docker run --rm \
    --name=nginx \
    --net=internal-net \
    --volume=$(PWD)$(CONFIG)/webapp.conf:/etc/nginx/conf.d/webapp.domain.com.conf:ro \
    -p 80:80 \
    nginx:1.11.0-alpine

É assim que meu config/webapp.conf se parece.

server {
    listen 80;
    server_name webapp.domain.com;

    # This is where the index.php file is located in the webapp container
    # This folder will contain an index.php file and some static files that should be accessed directly
    root /var/www/webapp/web;

    location / {
        try_files $uri $uri/ @webapp;
    }

    location @webapp {
        rewrite ^(.*)$ /index.php$1 last;
    }

    location ~ ^/index\.php(/|$) {
        include fastcgi_params;

        fastcgi_pass webapp:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}

Qualquer ação que precise ser processada usando esse arquivo index.php funcionará. No entanto, os arquivos estáticos não serão exibidos, resultando em 404s desagradável (já que a webapp do php não tem rotas configuradas para isso). Eu acredito que o nginx tenta carregá-los de seu próprio sistema de arquivos contêiner, quando eles estão realmente no contêiner webapp , falhando de volta em @webapp .

Existe uma maneira de eu configurar o nginx para servir esses arquivos que residem em outro contêiner?

    
por ThisIsErico 05.06.2016 / 20:14

2 respostas

0

Consegui resolver o problema montando o volume webapp no contêiner nginx . É assim que a tarefa run-nginx se parece agora:

run-nginx:
    docker run --rm \
    --name=nginx \
    --net=internal-net \
    --volume=$(PWD)$(CONFIG)/webapp.conf:/etc/nginx/conf.d/webapp.domain.com.conf:ro \
    --volume=$(PWD)$(WEBAPP)/web:/var/www/webapp/web:ro \
    -p 80:80 \
    nginx:1.11.0-alpine

E esse é o arquivo webapp.conf , que tentará carregar os arquivos estáticos do contêiner e, se isso não for possível, fará o proxy da solicitação para o fpm worker:

server {
    listen 80;
    server_name webapp.domain.com;

    root /var/www/webapp/web;

    location ~ \.(js|css|png) {
        try_files $uri $uri/;
    }

    location / {
        rewrite ^(.*)$ /index.php$1 last;
    }

    location ~ ^/index\.php(/|$) {
        include fastcgi_params;

        fastcgi_pass webapp:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}

No entanto, gostaria de saber se existe uma maneira melhor de fazer isso em vez de compartilhar o mesmo volume duas vezes. Muito obrigado!

    
por 06.06.2016 / 18:40
0

Talvez isso possa ser feito usando NFS

Um contêiner do Docker que executa o NFS pode ser feito onde o código reside, que pode ser vinculado aos contêineres que executam o nginx e o php. Os arquivos seriam armazenados em apenas um contêiner. Isso também poderia fornecer outra camada de isolamento.

    
por 28.08.2016 / 19:28