Rename a project by keeping containers - docker

I decided to change the project name of a docker composition:
$ docker-compose -p old_name up -d # Before
Starting old_name_web_1
$ docker-compose -p new_name up -d # After
Creating new_name_web_1
But I don't wanted to delete my containers, so I renamed them:
$ docker rename old_name_web_1 new_name_web_1
...
I thought docker-compose was based on container names, but it does not seem to be the case:
$ docker-compose -p new_name up -d
ERROR: for web Cannot create container for service web: Conflict. The name "/new_name_web_1" is already in use by container 4930deaabb[...]. You have to remove (or rename) that container to be able to reuse that name.
ERROR: Encountered errors while bringing up the project.
How can I relink my old containers to the new composition ?

It looks like you are using one of the newer versions of docker compose which tracks containers by labels assigned to them rather than by their names. That is why renaming the container didn't work.
Updating labels
You can check container's labels through the docker inspect command.
$ docker inspect --format='{{json .Config.Labels }}' container_name
The project name is the value of the 'com.docker.compose.project' label.
Moving an existing container to a new project is as easy as changing the value of that label. However it is not yet supported by Docker CLI. There is an open issue requesting that feature.
Workaround
It still can be achieved by directly editing the configuration file of that particular container. There you will find labels currently assigned to that container.
$ nano /var/lib/docker/containers/$container_id/config.v2.json
Assign the new project name to the 'com.docker.compose.project' label and save the file. Next you have to restart the daemon. Otherwise the changes will not be visible to docker.
$ systemctl daemon-reload

While it is true docker-compose reuse existing containers, this comment mentions:
docker-compose by default uses the folder name of the yml file as the project name, and prefix that name to all container names.
This could explain why docker-compose up did not pick up the new container name.

Related

Docker Desktop with Docker Compose usage

All we have such a dashboard in Docker Desktop, where we can look at containers that were started with Docker-Compose.
At the picture below I have 3 containers that were started with one docker-compose1.yml (frontend, backend, db).
The fourth container db-v4 that was created via another docker-compose2.yml file.
So my question is -- How can I separate then into this dashboard? I have tried to use different networks, but this didn't work out.
For example, first container will be in one group and other three are in another group
Normally it is sorted by project name. Per default the project name is the folder name where the yml-file is located. You may:
Use different folders for yml-files
Or set name by env:
#.env.1 listing:
COMPOSE_PROJECT_NAME=MyProject1
#.env.2 listing:
COMPOSE_PROJECT_NAME=MyProject2
# Run with
docker-compose --env-file .env.1 -f project1.yml up
docker-compose --env-file .env.2 -f project2.yml up
or using the --project-name flag, short -p
# Run with
docker-compose -p MyProject1 -f project1.yml up
docker-compose -p MyProject2 -f project2.yml up
By the way: It is not just optics. Docker uses this project name to share resources and handles it as one bundle. If they are separate logical units you SHOULD use different names.

Completely reset a single service in Docker Compose, including deleting the volumes?

I want to recreate a service, including its volumes. The closest I got was the following commands:
docker-compose stop foo
docker-compose rm -f foo
docker-compose up --renew-anon-volumes -d foo
docker-compose start foo
The issue here is --renew-anon-volumes recreates all services that have anonymous volumes, not just foo's volumes. If I don't use --renew-anon-volumes, then I think I need a named volume to do docker volume rm myvolume. However, with named volumes, Docker Compose always prepends a project name. Since my script doesn't know the project name, I can't programmatically delete the volume. I can't enforce that the user uses a particular project name. I know I can set the project name using an environment variable, but there's no guarantee that the user won't run Docker Compose with a different project name.
I think there are 2 potential solutions:
Make --renew-anon-volumes only recreate the volumes for the service I specified
Use a named volume and somehow figure out the correct prefix
Are either of these doable, or is there another solution?
Many roads leading to Rome, depending on your prerequisites:
Do docker volume ls and regex the result for your named volume (just working if volume name is unique)
Use external volumes and volume create them with known names by bootstrap script before running docker-compose up (not working if volumes must be instantiated)
Set project name to a known value. Normally it takes the folder name, but can explicitly given in docker-compose command (-p NAME) or by environment variable (COMPOSE_PROJECT_NAME=NAME).
Setup a dummy compose-file just containing this single service with its volumes for your script. Doing a docker-compose -f 'your-down-file.yml' down -v which removes all named and anonymous volumes belonging to this service and docker-compose -f .. up on this file.
Edit (#DavidMaze):
You're right, docker compose recognizes that fact. But it does NOT remove it, just warning. If you want to remove all "orphans" you need the flag --remove-orphans.
But for some reasons the down does not remove volumes then, even if flag -v is given. This could be reported because it is not behaving like described.
And errata: the flag -f must go before up/down and not after!
docker-compose rm has a -v option to delete anonymous volumes attached to a container, and also a -s option to stop the container. For your particular use case it should be enough to:
docker-compose rm -s -f -v foo
docker-compose up -d foo
This will only help for anonymous volumes, that is, where the Compose file has volumes: with only a container path and there is no corresponding top-level volumes: entry. I don't immediately see a Compose option to list, remove, or otherwise manage named volumes that Compose created.

How to change Docker config of an already running container?

I have installed Sentry onpremise and after some time tinkering I got it to work and changed the system.url-prefix option to the correct URL using the command line. However there are 2 problems still:
This option is not persistant
You cannot do the same for the mail.from option, which can only be set before running.
There are 3 config files at play, but not all of them register and that makes it confusing.
sentry.conf.py
Containing
SENTRY_OPTIONS['system.url-prefix'] = 'https://sentry.mydomain.com'
SENTRY_OPTIONS['mail.from'] = 'sentry#mydomain.com'
config.yml
Containing
mail.from: 'sentry#mydomain.com'
system.url-prefix: 'https://sentry.mydomain.com'
docker-compose.yml
Restarting the containers does not load the new config.
Related issue. However I don't know what to do after changing the config like in the comment (SENTRY_OPTIONS['mail.from'])
You need to make your modified config files visible inside the container.
If they are built into the image (possibly via COPY or ADD in the Dockerfile), then restarting your container does not help, because you're doing it on an old image. You should be rebuilding the image, stopping the old one and starting the new. Rather annoying and error-prone way.
Better way is to "mount" your files via volumes. Docker volumes can be single files, not only directories. You can add the section volumes in your docker-compose.yml:
my_container:
image: my_image
volumes:
sentry.conf.py:/full/path/to/sentry.conf.py/in/the/container
config.yml:/similar/full/path/to/config.yml
ports:
...
command: ...
There's a chance you already have some volumes defined for this particular container (to hold persistent data for example), then you need to simply add volume mappings for your config files.
Hope this helps. All the best in the New Year!
This is how you can edit an existing docker container config:
stop container:
docker stop <container name>
edit config:
docker run -it -v /var/lib/docker:/var/lib/docker alpine vi $(docker inspect --format='/var/lib/docker/containers/{{.Id}}/config.v2.json' <container name>)
restart docker
if the configuration files are stored as docker configs, then I found this guide to work...
https://medium.com/#lucjuggery/about-using-docker-config-e967d4a74b83
Basically add update as a NEW config
tell service to remove the old and then add the new config as the one to use. Service will be restarted
now you can remove the old docker config
this is not very nice, and if you want to name the new config with the old config identifier, you have to repeat it again!
Arrggghhh....

Docker-Compose Issue with container name

I have created a docker image with required packages. I have run the docker image specifying the host and guest port along with the required volume mounting
Example:
sudo docker run -it --name CONTAINERNAME -v /host:/guest -p
hostportno:guestportno
My container is up and running fine.
I am trying to migrate my container to a new docker image using docker-compose.
I have created docker-compose.yml file and specified the required parameters as shown below:
image: test1
ports
- "1234:123"
- "2000:223"
volumes:
- /home:/test
-container_name: dockercomposetest
working_dir: /test
command: /bin/bash
I am unable to migrate it using docker-compose.
I am getting issue as stated below:
Conflict. The name "test" is already in use by container eeedac72bb25.
You have to delete (or rename) that container to be able to reuse that
name.
Work around currently is I have to stop and remove the container and perform docker-compose up.
Can I not restart/migrate a container using docker-compose with same name as I have started in normal docker run process.
No, you can't have two containers with the same name. You'll have to pick a different name for the container_name field. The previous container needs to be removed before you can re-use the name.
If you wanted Compose to treat the container as if it had created it, you have to set the container labels as Compose does. The easiest way to find these would be to have compose create a container (probably by removing the container_name field), then using docker inspect to view the labels.

Docker.IO Filesystem Consistancy

I created a docker container, and then I created a file and exited the container.
When I restart the container with:
docker run -i -t ubuntu /bin/bash
the file is nowhere to be found. I checked /var/lib/docker/ and there is another folder created which has my file in it. I know it's something to do with Union FS.
How do I start the same container again with my file in it?
How do I export a container with file change?
I don't know if this will answer your question completely, but...
Doing
docker run -i -t ubuntu /bin/bash
will not restart any container. Instead, it will create and start a new container based on the ubuntu image.
If you started a container and stopped it you can use docker start ${CONTAINER_ID}. If you did not stop it yet you can use restart.
You can also commit (export) the container to a new image: see http://docs.docker.io/en/latest/commandline/command/commit/ for the correct syntax. docker export is a option as well, but all that will do is archive your container. By creating a new image using docker commit you can create multiple instances (containers) of it afterwards, all having your file in it.

Resources