docker-compose shared volumes between service - docker

I would like to shared files from one service to an other.
I make a short exemple.
Docker-compose.yml
mobile:
dockerfile
app.apk
web:
dockerfile
docker-compose.yml
version: "3.7"
services:
web:
build: ./web
depends_on:
- mobile
volumes:
- data-volume:/var/lib/shared
mobile:
build: ./mobile
volumes:
- data-volume:/var/lib/shared
volumes:
data-volume:
Dockerfile.yml (mobile)
FROM node:alpine AS mobile
COPY app.apk /var/lib/shared
RUN ls /var/lib/shared
Dockerfile.yml (web)
FROM node:alpine AS web
RUN ls /var/lib/shared
So I want to see app.apk from mobile service in web service.
I try to use volumes in docker-compose but it's not working. I have tried to figure out for hours.
Someone know how to do that ?

the dockerfile is executed first. The compose-file then overrides the shared folder. You can't access volumes in dockerfiles.
When you first built the docker-container, your app.apk gets copied into the docker-image.
Then compose starts the container and mounts the new (and probably empty) folder to /var/lib/shared.
Then the old content of /var/lib/shared is "overshadowed" by the new content and you can't access the old content anymore.
solution: copy the app into the volume after starting the container.
using docker exec -it <container_name> bash you can start a shell in the container after it has started. You can find the name with docker ps.

Related

docker-compose change name of main container

I have a simple frontend and backend app. And I have a docker-compose file but it's inside frontend folder. So when I run it both frontend and backend containers are under frontend container (it takes name of the folder) how can I rename this main container? I am using version 3.9
version: "3.9"
services:
be_service:
container_name: backend
build:
context: ../backend
dockerfile: ./Dockerfile
ports:
- "8089:8080"
fe_service:
container_name: frontend
build:
context: ./
dockerfile: ./Dockerfile
ports:
- "8088:80"
depends_on:
- be_service
When refering to your main container, you are probably refering to the project name, which you could usually set via the -p flag. (See other answers)
For docker-compose, you can set the top level variable name to your desired project name.
docker-compose.yml file:
version: "3.9"
name: my-project-name
services:
myService:
...
If you are using Docker Desktop, make sure Use Docker Compose V2 is enabled there.
Related to Docker Compose docs you can set your project name with:
docker-compose -p app up --build
with -p app to set your compose container name to app.
I think that your docker compose file is right and to change the co you can use the containe_name instruction but I think you should run this command when you want to run your application :
docker-compose up --build
Use -p to specify a project name
Each configuration has a project name. If you supply a -p flag, you can specify a project name. If you don’t specify the flag, Compose uses the current directory name.
Calling docker-compose --profile frontend up will start the services with the profile frontend and services without specified profiles. You can also enable multiple profiles, e.g. with docker-compose --profile frontend --profile debug up the profiles frontend and debug will be enabled
Also refer https://docs.docker.com/compose/profiles/

How to copy files inside container with docker-compose

I have a simple image that runs a jar file. That jar file inside the image needs a special configuration file in order to run.
In the location with the docker-compose.yml I have a folder named "carrier" and under this folder I have that file.
The docker-compose.yml:
version: "3.3"
services:
web:
image: "myimage:1.80.0.0"
ports:
- "61003:61003"
volumes:
- ./carrier:/var/local/Config/
When I hit docker-compose up it complains that the file is not there, so it doesn't copy it.
If I do another option like I did in the .sh command, something like this:
volumes:
- ./carrier:/var/local/Config/:shared
It complains about another error:
C:\Tasks\2246>docker-compose up
Removing 2246_web_1
Recreating 1fbf5d2bcea4_2246_web_1 ... error
ERROR: for 1fbf5d2bcea4_2246_web_1 Cannot start service web: path /host_mnt/c/Tasks/2246/carrier is mounted on / but it is not a shared mount
Can someone please help me?
Copy the files using Dockerfile, use below;
FROM myimage:1.80.0.0
RUN mkdir -p /var/local/Config/
COPY carrier /var/local/Config/
EXPOSE 61003
docker-compose.yml
version: "3.3"
services:
web:
build:
dockerfile: Dockerfile
context: '.'
ports:
- "61003:61003"
In the end, run below command to build new image and start container
docker-compose up -d --build
You can use Dockerfile if it does not copy.
Dockerfile;
FROM image
COPY files /var/local/Config/
EXPOSE 61003
Docker-compose;
version: "3.3"
services:
web:
build: . (path contains Dockerfile)
ports:
- "61003:61003"
volumes:
- ./carrier:/var/local/Config/
Remove the last /
volumes:
- ./carrier:/var/local/Config
I'm not sure but you can try to set full access permissions for all user to /carrier:
chmod -R 777 /carrier
Thanks all for all your answers.
Seems like finally docker warned me with some comparisons over the windows files vs Linux files when building the image. (Not with docker compose but with Dockerfile).
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Tried it on linux and works.

Deploy with docker-compose.yml

Not sure if it will be a duplicate question but i tried to find out stuff but not sure if i have similar situation like others.
So i am new to docker and trying to setup a deployment for a small website.
So far i have a folder which has 3 files.
index.html - has basic html
Dockerfile - which has
FROM ubuntu:16.04
COPY . /var/www/html/
docker-compose.yml - which has
version: '2.1'
services:
app:
build: .
image: myname/myapp:1.0.0
nginx:
image: nginx
container_name: nginx
volumes:
- ./host-volumes:/cont-volumes
network_mode: "host"
phpfpm56:
image: php-fpm:5.6
container_name: phpfpm56
volumes:
- ./host-volumes:/cont-volumes
network_mode: "host"
mysql:
image: mysql:5.7
container_name: mysql
ports:
- "3306:3306"
volumes:
- mysql:/var/lib/mysql
volumes:
mysql:
Now i am using jenkins to create build, putting my all codes to host volumes to make it available to container and then i would run
docker-compose build
Now it creates an image and i push it to docker hub.
Then i login to remote server and pull the image and run. But that wont work because i still need to run docker-compose up inside the container.
Is this the right approach or i am missing something here?
The standard way to do this is to copy your code into the image. Do not bind-mount host folders containing your code; instead, use a Dockerfile COPY directive to copy in the application code (and in a compiled language, use a RUN command to build it). For example, your PHP container might have a corresponding Dockerfile that looks like (referencing this base Dockerfile)
FROM php-fpm:5.6
# Base Dockerfile defines a sensible WORKDIR
COPY . .
# Base Dockerfile sets EXPOSE 9000
# Base Dockerfile defines ENTRYPOINT, CMD
Then your docker-compose.yml would say, in part
version: '3'
service:
phpfpm56:
build: .
image: me/phpfpm56:2019-04-30
# No other settings
And then your nginx configuration would say, in part (using the Docker Compose service name as a hostname)
fastcgi_pass phpfpm56:9000
If you use this in production you need to comment out the build: lines I think.
If you're extremely set on a workflow where there is no hostname other than localhost and you do not need to rebuild Docker images to update code, you at least need to restart (some of) your containers after you've done the code push.
docker-compose stop app phpfpm56
docker-compose up -d
You might look into a system-automation tool like Ansible or Chef to automate the code-push mechanism. Those same tools can also just install nginx and PHP, and if you're trying to avoid the Docker image build sequence, you might have a simpler installation and deployment system running servers directly on the host.
docker-compose up should not be run inside a container but on a docker host. So this could be run via sh on a host but you need to have access to the composefile wherever you run the command.

Docker / Docker-compose volume fill & share issue

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

Docker ADD folder during build and then expose to VOLUME

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

Resources