Reputation: 21
I would like to start NGINX and PHP-FPM in two different containers sharing a volume to let NGINX serve the app. All solutions I've found include sharing the source directly as a volume in the docker-composer file.
volumes:
- ./:/var/www
I don't want to implement this solution as I believe is just for the developing phase. I have a private Docker image that contains the source code and exposes php-fpm
on port 9000. The solution I have in mind consists in adding the following parameter to both nginx and php-fpm containers.
volumes:
- code:/var/www/html
code
is a volume already specified in the docker-composer file. Thus, the final result should be something like:
version: "3.6"
networks:
inside:
external: false
volumes:
code:
driver: local
services:
server:
image: nginx:1.17-alpine
ports:
- "80:80"
volumes:
- code:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- inside
restart: always
app:
image: PRIVATE_IMAGE
volumes:
- code:/var/www/html
networks:
- inside
restart: always
The issue is about permissions: when I try to load the app since the cache
folder inside the app is not writable, I receive Permission denied
.
Do you know the clearest way to solve this issue?
Upvotes: 2
Views: 2064
Reputation: 158647
Named volumes, on their own, are not a reliable way to publish files from one container to another. The easiest way to see this is to make some change in your html
directory and run docker-compose build; docker-compose up -d
. What you'll see in this case is that the old contents of the code
volume are used in the Nginx container without updates, and in fact the old contents of the volume hide the updated code in your application container. For things that aren't Docker named volumes, including Docker bind-mounts and Kubernetes volumes, you'll just get an empty directory with nothing copied into it.
The absolute easiest way to address this is to let the application serve its own static assets. The mechanism to do this is framework-specific (and I'm not well-versed in PHP), but if you can do this then your Nginx configuration just has a proxy_pass
or fastcgi_pass
directive, and it doesn't have any files on its own to serve. That eliminates the need for this volume.
If that's not an option, then you can create a second image for the reverse proxy that includes the static assets.
FROM nginx:1.17-alpine
COPY ./html/ /usr/share/nginx/html/
# use the CMD from the base image, no need to repeat it
Now you're not "sharing files" per se, but the application and the reverse proxy both contain the same static files built from the same source tree. This means you don't need volumes:
in the Compose setup, except maybe to do things like inject configuration. (It's likely reasonable to COPY
this into the image as well.)
version: "3.8"
services:
server:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
restart: always
app:
build: .
restart: always
Upvotes: 2