I do a Symfony project with Docker. In development, I mount my source folder in Nginx and PHP-FPM containers. But for the production, I want to put the code in the PHP-FPM container to do an app container, and share the code with the Nginx container.
In my Dockerfile, I use a VOLUME /var/www/html, but how can I permit the nginx container to access this volume (in docker-compose file) ?
Before the v3, I know there was a volumes_from, but not anymore.
I want place the code inside the container like say here (https://docs.docker.com/compose/production/)
Removing any volume bindings for application code, so that code stays inside the container and can’t be changed from outside
Thanks a lot for your help
Finally, it appear we can use a named volume to do it, remove the VOLUME from the Dockerfile, then just define a name volume, and it takes the value of the first container.
version: '3'
services:
nginx:
build: ./docker/nginx
volumes:
- app_data:/var/www/html:ro
depends_on:
- app
app:
build: ./
volumes:
- app_data:/var/www/html:rw
networks:
- default
volumes:
app_data:
driver: local
Related
This is docker compose file looks like
version: '3.3'
services:
portal:
ports:
- '8080:8080'
- '8000:8000'
environment:
- 'revcycle.portal.logger.root=C:/tomcat/logs/'
volumes:
- /src/main/webapp/sampleFiles:/usr/local/tomcat/webapps/portal/sampleFiles:rw
container_name: portal
image: 'portal:latest'
docker-compose up is creating container successfully by when i check the content of the tomcat webapp All the other sibling folder of the sampleFiles are deleted.
Am i missing something with the volumn commands
Same happen when I use Intellji Idea docker plugin Bind mounts in Configuration
It should be like this:
volumes:
- /src/main/webapp/sampleFiles:/usr/local/tomcat/webapps/portal/sampleFiles
as far as i know rw is for cases when you use drivers stuff...
and make sure that /src/main/webapp/sampleFiles is the host folder which have what you need in docker container. Because essentially it will be mapped into docker container. and will replace target folder.
this way siblings for /usr/local/tomcat/webapps/portal/sampleFiles should stay intact. If no, try starting without volumes part and verify that you see siblings.
don't forget to do docker-compose down and docker-compose up -d when you change anything in docker-compose.yaml file
I have 2 containers in a compose files,that i want to serve app static files through nginx.
I have read this: https://stackoverflow.com/a/43560093/7522096 and want to use host dir to share between app container and nginx container, for some reason I dont want to use named volume.
===
Using a host directory Alternately you can use a directory on the host
and mount that into the containers. This has the advantage of you
being able to work directly on the files using your tools outside of
Docker (such as your GUI text editor and other tools).
It's the same, except you don't define a volume in Docker, instead
mounting the external directory.
version: '3'
services:
nginx:
volumes:
- ./assets:/var/lib/assets
asset:
volumes:
- ./assets:/var/lib/assets
===
My docker-compose file:
version: "3.7"
services:
app:
container_name: app
restart: always
ports:
- 8888:8888
env_file:
- ./env/app.env
image: registry.gitlab.com/app/development
volumes:
- ./public/app/:/usr/app/static/
- app-log:/root/.pm2
nginx:
container_name: nginx
image: 'nginx:1.16-alpine'
restart: always
ports:
- 80:80
- 443:443
volumes:
- /home/devops/config/:/etc/nginx/conf.d/:ro
- /home/devops/ssl:/etc/nginx/ssl:ro
- ./public/app/:/etc/nginx/public/app/
depends_on:
- app
volumes:
# app-public:
app-log:
Yet when i do this in my compose, the dir always come up empty on nginx, and the static files in my app container got disappear too.
Please help, I tried a lot of ways but can not figure it out.
Thanks.
During the initialization of the container docker will bind the ./public/app directory on the host with the /usr/app/static/ directory in the container.
If the ./public/app does not exist it will be created. The bind is from the host to the container, meaning that the content of ./public/app folder is
reflected (copied) into the container and not viceversa. That's why after the initialization the static app directory is empty.
If my understanding is correct your goal is to share the application files between the app container and nginx.
Taken into consideration the above the only solution is to create the files in the volume after the volume is created. Here is an example for the relevant parts:
version: "3"
services:
app:
image: ubuntu
volumes:
- ./public/app/:/usr/app/static_copy/
entrypoint: /bin/bash
command: >
-c "mkdir /usr/app/static;
touch /usr/app/static/shared_file;
mv /usr/app/static/* /usr/app/static_copy;
rm -r /usr/app/static;
ln -sfT /usr/app/static_copy/ /usr/app/static;
exec sleep infinity"
nginx:
image: 'nginx:1.16-alpine'
volumes:
- ./public/app/:/etc/nginx/public/app/
depends_on:
- app
This will move the static files to the static_copy directory and link back those files to /usr/app/static. Those files will be shared with the host (public/app director)
and nginx container (/etc/nginx/public/app/). Adapt it to fit your needs.
In alternative you can of course use named volumes.
Hope it helps
I have a few questions about Docker volumes. I have installed Docker and docker-compose on a fresh host running debian stretch. I managed to get a docker-compose file running for a simple nginx/php-fpm project, both containers mounted on the directory containing the source code. I wanted to try to create a single volume that would be shared across my containers but I have a few issue, and my understanding of the official documentation is not helping.
So this is an idea of what I'm trying to achieve :
Question 1 : Trying to create a volume from a dockerfile on a directory mounted from host
docker-compose.yml :
version: '3'
services:
php:
build:
context: .
dockerfile: php.dockerfile
volumes:
- ./host-project-directory:/project
php.dockerfile :
FROM php:7-fpm
VOLUME project
from my understanding, when running docker-compose we should have a volume created on host containing all files from /project from container. And /project from container should contain all files from ./host-project-directory from host.
If I ls the content of /project on container I can see the files from host, but using docker volume list, there are no volumes created on host, why ?
Question 2 : How to populate and use this volume from another container ?
version: '3'
services:
php:
build:
context: .
dockerfile: php.dockerfile
volumes:
- named-volume:/project
web:
image: nginx
links:
- php
volumes:
- named-volume:/project
volumes:
named-volume:
This should create a volume called 'named-volume' and bind it to /project directories on both containers php and web.
Now, how to populate this volume with content from ./host-project-directory ?
I've tried adding a dockerfile like
ADD ./host-project-directory /project
But nothing changed and the volume remained empty.
I'm sorry if this is due to my lack of experience using Docker but I can't figure out how to make this simple thing work.
Thank you for your time !
For the first question, I try a simple docker file like this:
FROM php:7-fpm
COPY ./project /project
And a docker-compose like this:
version: '3'
services:
php:
build: .
volumes:
- named-volume:/project
web:
image: nginx
links:
- php
volumes:
- named-volume:/project
volumes:
named-volume:
Since you create the volume on docker-compose you don't need to create that in the Dockerfile.
Running docker volume list, I'm able to see the volume created with a local driver. Making ls inside the folder I'm also able to see the file. It's important to note, that the file present in you local directory it's not the same that the file inside the container. So if you edit the files in the host this will not change the files in container. That's because you have your volume created in another path, probably at: /var/lib/docker/volumes/...
This happens because you map the volume to the path, but you not specifies where you want the volume. To do that just make your docker-compose like this:
version: '3'
services:
php:
build: .
volumes:
- ./project:/project
web:
image: nginx
links:
- php
volumes:
- ./project:/project
Making this I'm still able to see the volume with the volume list command but without a name.
So I don't know why you are not able to see the volume in the list.
For question 2:
Doing the example above I have the files inside the container that exists in my local "project" folder.
Please check that the path to the local folder is correct.
A bind mount is not the same thing as a volume. You're defining a named volume here, but wanting the functionality of a bind mount.
Try this
version: '3'
services:
php:
build:
context: .
dockerfile: php.dockerfile
volumes:
- ./host-project-directory:/project
web:
image: nginx
links:
- php
volumes:
- ./host-project-directory:/project
I have a docker compose file in a local folder on my mac. I have also another folder /src which should act as the root element. The docker-compose file looks like this:
version: '2'
services:
fpm:
image: sbusso/php-fpm-ion
nginx:
image: nginx:stable
ports:
- "80:80"
links:
- fpm
- db
db:
image: orchardup/mysql
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: myproject
I understand what we are doing here, but I am missing the solution that /src is taken as the root and I think I need to set up an lsync service which syncs between local and my docker container. So I found this one, but it is not working properly - the root /src is not taken into account. I just want to type localhost in my browser and it should open the /src folder.
version: '2'
services:
fpm:
image: sbusso/php-fpm-ion
links:
- sync
volumes_from:
- sync
db:
image: orchardup/mysql
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: myproject
links:
- sync
volumes_from:
- sync
nginx:
image: nginx:stable
ports:
- "80:80"
links:
- sync
volumes_from:
- sync
sync:
image: zeroboh/lsyncd
volumes:
- /var/www/html
- ./src:/src:Z
- ./docker-config/nginx:/etc/nginx/conf.d
- /var/lib/php/session
- ./docker-config/lrsync/lrsync.lua:/etc/lrsync/lrsync.lua
- ./sync:/sync
What I do understand is that every image that is loaded links the sync service into it. What I do not understand is why every image needs a volumes_from and that the syntax in sync explicitly says - can somebody help me, setting this up correctly?
Thanks
volumes_from imports volumes from another container
By default, each container has no volumes. You can define local volumes using the volumes attribute, but the volumes are only used in that container. In order for other containers to make use of them, those containers must import the volumes using volumes_from, pointing to the name of one or more containers. All volumes in those named containers are then made available in the current container.
The Z volume label indicates a private volume
You are mounting the /src volume using this:
volumes:
- ./src:/src:Z
That's fine, except you are also using volumes_from, and your question indicates that you specifically wanted to share /src. But by using the Z label, you have told Docker to make this a private volume.
From the documentation:
Volume labels
Labeling systems like SELinux require that proper labels are placed on volume content mounted into a container. Without a label, the security system might prevent the processes running inside the container from using the content. By default, Docker does not change the labels set by the OS.
To change a label in the container context, you can add either of two suffixes :z or :Z to the volume mount. These suffixes tell Docker to relabel file objects on the shared volumes. The z option tells Docker that two containers share the volume content. As a result, Docker labels the content with a shared content label. Shared volume labels allow all containers to read/write content. The Z option tells Docker to label the content with a private unshared label. Only the current container can use a private volume.
In this case, "current container" is sync, so only that container may use the volume. The others may not use it.
I am using docker-compose for a basic web app. When the image is built, it copies the static JS files in (ADD) and then builds them.
I then want to expose that directory to other containers, using VOLUME.
E.g.
Dockerfile
ADD ./site/static /site/static
WORKDIR /site/static
RUN gulp
docker-compose.yml
app:
build: .
volumes:
- /site/static
http:
image: nginx
volumes_from:
- app
nginx.conf
location /static {
alias /site/static
}
(Note, this is just an example)
The problem is that it seems to work the first time (i.e. when the volume does not exist), but is then never overwritten by the modified image. If I was using purely a Dockerfile, I could achieve this by putting VOLUME after ADD.
Is there a way to allow this, or am I approaching it completely wrong?
Thanks
Possible solution 1
I might be wrong, but I think the trouble is that when (and if) you do
docker-compose down && docker-compose up
your containers are recreated, and new "anonymous" volume is created.
You can check my guess running:
docker volume ls
I would try to use named volume, like so:
version: "2"
volumes:
app-volume: ~
services:
app:
build: .
volumes:
- app-volume:/site/static
http:
image: nginx
volumes:
- app-volume:/site/static
You need docker-compose 1.6.0+ and require a Docker Engine of version 1.10.0+ for usinng version 2 of docker-compose file.
Possible solution 2
just
app:
build: .
volumes:
- ./site/static:/site/static # maps host directory `./site/static` (relative to docker-compose.yml) to /site/static inside container
http:
image: nginx
volumes_from:
- app
And remove
ADD ./site/static /site/static
from your Dockerfile