Two docker services depends_on the same service - docker

I am having two docker-compose files
/cfacing/docker-compose.yml
app-customer-facing:
build: .
depends_on:
- mysql-db
mysql-db:
container_name: staging-mysql-db
image: mysql:5.6
/afacing/docker-compose.yml
app-admin-facing:
build: .
depends_on:
- mysql-db
mysql-db:
container_name: staging-mysql-db
image: mysql:5.6
I want both customer-facing container and admin-facing container to depend on the same mysql-db container. This is currently not working, the app-customer-facing will start with mysql-db but app-admin-facing will not start throwing:
ERROR: for mysql-db Cannot create container for service mysql-db: Conflict. The container name "/staging-mysql-db" is already in use by container "fe63e1ab0c1fd19236551bfc5930544cb31e649a4c18421c05959dc1274eb600". You have to remove (or rename) that container to be able to reuse that name.

The error is that you are duplicating your mysql-db service, you are not re-using it. That's why you get an error telling that there is already a container named staging-mysql-db.
To resolve your use case, you'll have to extend your docker-compose file.
You can see an exemple here. See the block ADMINISTRATIVE TASKS which is basically what you are trying to do.

Related

Docker-compose expected container is up to date

I created docker-compose yaml file to run a docker image after it has been pulled locally and this yaml file contain another services (mysql and phpmyadmin) so when I run a command docker-composer up -d I found a conflict in creating a container as it been used by another container with the same name and I expected to show me that the container is already run and up to date, I know that the container must be removed or renamed before creating a new one but I aiming to get the newer version of image and check if mysql and phpmyadmin services is up or not if up gives me those container is up to date and if not create it as another environment bellow.
docker-compose.yml
version: '3.3'
services:
app-prod:
image: prod:1.0
container_name: app-prod
ports:
- "81:80"
links:
- db-prod
depends_on:
- db-prod
- phpmyadmin-prod
db-prod:
image: mysql:8
container_name: db-prod
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=laravel
- MYSQL_USER=user
- MYSQL_PASSWORD=secret
volumes:
- db-prod:/var/lib/mysql
phpmyadmin-prod:
image: phpmyadmin/phpmyadmin:5.0.1
restart: always
environment:
PMA_HOST: db-prod
container_name: phpmyadmin-prod
ports:
- "5001:80"
volumes:
db-prod:
Error
Creating phpmyadmin-prod ... error
Creating db-prod ...
ERROR: for phpmyadmin-prod Cannot create container for service phpmyadmin: Conflict. The container name "/phpmyadmin-prod" is already in use by container "5a52b27b64f7302bccb1c3a0eaeca8a33b3dfee5f1a279f6a809695Creating db-prod ... error
ERROR: for db-prod Cannot create container for service db: Conflict. The container name "/db-prod" is already in use by container "5d01c21efafa757008d1b4dbcc8d09b4341ac1457a0ca526ee57873cd028cf2b". You have to remove (or rename) that container to be able to reuse that name.
ERROR: for phpmyadmin Cannot create container for service phpmyadmin: Conflict. The container name "/phpmyadmin-prod" is already in use by container "5a52b27b64f7302bccb1c3a0eaeca8a33b3dfee5f1a279f6a809695f482500a9". You have to remove (or rename) that container to be able to reuse that name.
ERROR: for db Cannot create container for service db: Conflict. The container name "/db-prod" is already in use by container "5d01c21efafa757008d1b4dbcc8d09b4341ac1457a0ca526ee57873cd028cf2b". You have to remove (or rename) that container to be able to reuse that name.
ERROR: Encountered errors while bringing up the project.
Error: No such container: app-prod
Error: No such container: app-prod
While using another docker-compose file for test environment I got this which I expected
db-stage is up-to-date
phpmyadmin-stage is up-to-date
Creating app-stage ... done
docker-compose run command will create new containers. But in your case, 2 of them are already running, hence, you can use
docker-compose up -d
That specific error is easy to fix. You're trying to manually specify container_name: for every container, but the error message says you have existing containers with those same names already. Left to its own, Compose will assign non-conflicting names, and you can almost always just delete container_name: from the Compose file.
version: '3.8'
services:
app:
image: prod:1.0
ports:
- "81:80"
depends_on: [db, phpmyadmin]
# no container_name: or links:
db: { ... }
phpmyadmin: { ... }
The other obvious point of conflict for running the same Compose file in multiple places is the ports:; only one container or host process can listen on a given (first) port number. If you're trying to run the same Compose file multiple times on the same system you might need some way to replace the port numbers. This could be a place where using multiple Compose files fits in well: define a base docker-compose.yml that defines the services but not any of the ports, and an override file that assigns specific host ports.
As I have several docker-compose files and I run this command docker-composer -f <compose_file_path> -p <project_name> -d up and then I try to run docker-composer up -d in the same location without specify the project name -p <project_name> which gives me the conflict of the container as this make the compose-file up with a different project name and with the same container name.

What does volumes do in docker-compose

I am currently learning Docker. I am stucked at the idea of volumes. I assume that they made to store the data whenever we restart the container etc., but i do not understand what happens if we don't provide the ":" for the source:target.
Example:
- "/usr/src/my-app/frontend/node_modules"
- "/usr/src/my-app/backend/node_modules"
What do we store inside the container if we use volumes like above?
The whole docker-compose
version: '3'
services:
nginx:
image: nginx
container_name: nginx
ports:
- 80:80
restart: always
volumes:
- "./nginx/default.conf:/etc/nginx/conf.d/default.conf"
backend:
build:
dockerfile: Dockerfile.dev
context: ./backend
container_name: backend
volumes:
- "/usr/src/my-app/backend/node_modules"
- "./backend:/usr/src/my-app/backend"
frontend:
build:
dockerfile: Dockerfile.dev
context: ./frontend
container_name: frontend
environment:
CHOKIDAR_USEPOLLING: "true"
volumes:
- "/usr/src/my-app/frontend/node_modules"
- "./frontend:/usr/src/my-app/frontend"
It is an anonymous volume. It is managed by docker like a named volume, but it doesn't have a real name, only a GUID. Likewise, it's similar to the one you get when you use the VOLUME instruction in your Dockerfile without mounting a named volume or bind mount to that path when running the container.
See this for example (emphasis mine):
-v or --volume: Consists of three fields, separated by colon characters (:). The fields must be in the correct order, and the meaning of each field is not immediately obvious.
In the case of named volumes, the first field is the name of the volume, and is unique on a given host machine. For anonymous volumes, the first field is omitted.
https://docs.docker.com/storage/volumes/#choose-the--v-or---mount-flag
As long as you keep the container and only restart it, the same volume will be used. If you delete the container / create a new container, it will use a new volume.

Create multiple containers of the same service with Docker Compose

I am currently starting with Docker Compose, and I wanted to know how to create multiple containers of the same service 'Redis'. I've already tried with docker-compose up --scale redis=3, but it gives an error, I've been searching through Google the possible solution, but I could not find one.
Thank you in advance.
Here is my docker-compose.yml
version: '3'
services:
redis:
container_name: redis
hostname: redis
image: redis
redis-commander:
container_name: redis-dbms
hostname: redis-commander
image: rediscommander/redis-commander:latest
restart: always
environment:
- REDIS_HOSTS=local:redis:6379
ports:
- "8081:8081"
And here is the error it gives me.
docker-compose up --scale redis=3
Creating network "ex2_default" with the default driver
WARNING: The "redis" service is using the custom container name "redis". Docker requires each container to have a unique name. Remove the custom name to scale the service.
Creating redis-dbms ...
Creating redis ... done
Creating redis ...
Creating redis ...
Creating redis-dbms ... done
ERROR: for redis Cannot create container for service redis: Conflict. The container name "/redis" is already in use by container "d4c93ae4ca68da0b6430e5eddc657d9dda0f40002c7a81c89368535df05eae24". You have to remove (or rename) that container to be able to reuse that name.
ERROR: for redis Cannot create container for service redis: Conflict. The container name "/redis" is already in use by container "d4c93ae4ca68da0b6430e5eddc657d9dda0f40002c7a81c89368535df05eae24". You have to remove (or rename) that container to be able to reuse that name.
The error raise because the reason below:
Link: https://docs.docker.com/compose/compose-file/compose-file-v3/#container_name
Because Docker container names must be unique, you cannot scale a service beyond 1 container if you have specified a custom name. Attempting to do so results in an error.
You can read more add here: https://github.com/docker/compose/issues/3722

How can I store data with Docker Compose containers?

I have this docker-compose.yml, and I have a Postgres database and Grafana running over it to make queries on data.
version: "3"
services:
db:
image: postgres
container_name: db
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=my_secret_password
grafana:
image: grafana/grafana
container_name: grafana
depends_on:
- db
ports:
- "3000:3000"
I start this compose with the command docker-compose up, but then, if I want to not lose any data, I must run docker-compose stop instead of docker-compose down.
I also read about docker commit, but "the commit operation will not include any data contained in volumes mounted inside the container", so I guess it's no use for my needs.
What's the proper way to store the created volumes and reusing them with commands up/down, so even when recreating the containers? I must use some sort of backup methods provided by every image (so, for example, a DB export for Postgres, and some other type of export for Grafana), or there is a way to do this inside docker-compose.yml?
EDIT:
I also read about volumes, but is there a standard way to store everything?
In the link provided by #DannyB, setting volumes to ./postgres-data:/var/lib/postgresql instead of ./postgres-data:/var/lib/postgresql/data caused the container to not store the actual folder.
My question is: every image must follow a particular pattern like the one above? This path to data to store the volume underlying is present in every Docker image Readme? Or is there something like:
volumes:
- ./my_image_root:/
Docker provides for volumes as the way to persist volumes between container invocations and to share data between containers.
They are quite simple to declare and use in compose files:
volumes:
postgres:
grafana:
services:
db:
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=my_secret_password
volumes:
- postgres:/var/lib/postgresql/data
grafana:
image: grafana/grafana
depends_on:
- db
volumes:
- grafana:/var/lib/grafana
ports:
- "3000:3000"
Optionally, you can also set a local directory as your container volume
with the added convince of having the files easily accessible not only from inside the container. This is especially helpful for mounting specific config files to their location in the container, you can edit the file locally like any other file restart the container with the updated configuration (certificates and other similar files also make good use of this option). And you do that like so:
volumes:
- /home/myusername/postgres_data/:/var/lib/postgresql/data/
PS. I have omitted the container_name and version directives from this compose.yml because (as of docker 20.10), the docker compose spec determines version automatically, and docker compose exposes enough functionality that accessing the containers directly using short names isn't necessary usually.

How to configure docker-compose.yml to up a container as root

I'm trying to connect two containers with a docker-compose-yml, but it isn't working. This is my docker-compose.yml file:
version: "3"
services:
datapower:
build: .
ports:
- "9090:9090"
depends_on:
- db
db:
image: "microsoft/mssql-server-linux:2017-latest"
environment:
SA_PASSWORD: "your_password"
ACCEPT_EULA: "Y"
ports:
- "1433:1433"
When I make:
docker-compose up
This up my two containers. Then I stop one container and then I run the same container stoped independiently like:
docker-compose run -u root --name nameofcontainer 'name of container named in docker-compose.yml'
With this, the connection of the containers works. Exists a method to configure my docker-compose.yml to connect my containers like root without stop a container and run independently?
Update:
There exists the user property that can be set in the compose file. This is documented in docker-compose file reference.
...
services:
datapower:
build: .
user: root
ports:
- "9090:9090"
depends_on:
- db
...
Setting both a User AND a Group in docker-compose.yml:
Discovered another way to set not only the user but also the group in a docker-compose.yml file which is NOT documented in the Docker Compose File Reference #yamenk helpfully provides in the accepted answer.
I needed to raise a container expressly setting both a user AND a group and found that the user: parameter in docker-compose.yml can be populated as a UID:GID mapping delimited by a colon.
Below is a snippet from my docker-compose.yml file where this form was tested and found to work correctly:
services:
zabbix-agent:
image: zabbix/zabbix-agent2:ubuntu-6.0-latest
container_name: DockerHost1-zabbix-agent2
user: 0:0
<SNIP>
Reference:
https://github.com/zabbix/zabbix-docker/issues/710
Hope this saves others wasted cycles looking for this!

Resources