I want to update the docker-compose.yml file for a service of mine to change restart: "no" for restart: unless-stopped.
I used restart: "no" originally to debug the container, but now it's working I had data that I don't won't to erase; so I would like to edit the docker-compose.yml file to keep the change reflected in it (for future reference) and apply the change.
Can I just stop the container without removing it and then apply a docker-compose up? Or docker-compose up is only meant for "fresh created" containers and I have to use another docker command after editing docker-compose.yml?
Deleting and recreating containers is extremely routine, and there are many settings you can only change by deleting and recreating a container. If nothing else you'll have to delete and recreate a container to update the image it runs on, when there is inevitably a bug fix or security update.
You should reconfigure your container to use some sort of volume, either a named volume or a bind mount, to hold your application data. Anything that's not in a volume will get lost.
For this particular change, it looks like the docker container update command can modify the restart policy. You'll have to find the Docker name of the container from docker ps, it will be named something like directory_service_1. But you can't use this command to change the image, environment variables, command, port mappings, or volume mounts; changing any of these things requires deleting and recreating the container.
Related
I've seen some similar questions but found no solution for myself.
I have 2 docker-compose files, I have created a named volume and I'm currently using it like this:
app:
...
volumes:
- volume_static:/path/to/container
...
...
volumes:
...
volume_static:
external:
name: static
...
...
During the build process, it happens that the script adds some new file to this volume, but then, the second docker-compose, which mount the volume in the exact same manner, have no access to the new data, I need to restart it to make it work.
Is this the right approach?
I just need to push some new file in the volume from one docker-compose, and see them directly on the second docker-compose (yeah I know, docker, but saying specifying compose give a better idea on what is my problem) without restarting and building the service
Is this possible?
Thanks!
Docker believes named volumes are there to hold user data, and other things that aren't part of the normal container lifecycle.
If you start a container with an empty volume, only the very first time you run it, Docker will load content from the image into the volume. Docker does not have an update mechanism for this: since the volume presumably holds user data, Docker can't risk corrupting it by overwriting files with content from the updated image.
The best approach here is to avoid sharing files at all. If the files are something like static assets for a backend application, you can COPY --from those files from the backend image into a proxy image, using the image name and tag of your backend application (COPY --from=my/backend ...). That avoids the need for the volume altogether.
If you really must share files in a volume, then the container providing the files needs to take responsibility for copying in the files itself when it starts up. An entrypoint script is the easiest place to do this; it gives you a hook to run things as the container starts (and volumes exist and are mounted) but before running the main container process.
#!/bin/sh
set -e
# Populate (or update) the shared static tree
cp -r ./app/assets /static
# Now run the image CMD
exec "$#"
Make this script be the ENTRYPOINT in your Dockerfile; it must use the JSON-array syntax. You can leave your CMD unchanged. If you've split an interpreter and filename into separate ENTRYPOINT and CMD you can combine those into a single CMD line (and probably should anyways).
...
ENTRYPOINT ["entrypoint.sh"]
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
In terms of build lifecycle, images are built without any of the surrounding Compose ecosystem; they are not aware of the network environment, volumes, environment variables, bind mounts, etc.; so when you rebuild the image you build a new changed image but don't modify the volume at all. The very first time you run the whole file, since the named volume is empty, it is populated with content from the volume, but this only happens the very first time you run it.
Rebuilding images and restarting containers is extremely routine in Docker and I wouldn't try to avoid that. (It's so routine that re-running docker-compose up -d will delete and recreate an existing container if it needs to in order to change settings.)
Can I update labels on a container using docker-compose without restarting the container?
Ideal scenario:
- change labels in docker-compose.yml
- save docker-compose.yml
- run a command to update the labels without restarting the container
As a general rule, changing the settings or code running inside a container involves deleting and restarting the container. This is totally normal, and docker-compose up will do it for you when necessary. (Remember to make sure any data you care about is stored outside the container.)
At a Docker API level, there are only a limited set of things that can be changed in the Update a container call, and labels aren’t one of those. That means anything that manages a container, whether direct docker commands or Docker Compose, must always delete and recreate a container to change its labels.
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....
I'm confused about common consensus that one shouldn't use data containers. I have specific use case that I want to accomplish.
I want to have docker nginx container and behind it some other container with application. To run newest version of my app I want to download ready container from my private docker registry. The application is for now purely static html, javascript something.
So my plan is to create docker image which will hold the files, and will specify a named volume in some /webapp folder. The nginx container will serve this volume. I do not see any other way how to move bunch of files to remote system the "docker containerized" way. Am I not actually creating cursed data container?
Anyway what happens during app containers exchange? When I stop the app container the volume remains accesible, as it is placed on host. When I pull and start new version of app container. The volume will be created again and prefiled with image files stored at the same location, replacing the content on host so the nginx container will server from now new version of the application.Right? What happens when I will reference volume that does not exist yet from the nginx container.
It seem that named values are not automatically filed with the content of the image. As well I'm not sure how to create named volume in docker file as this syntax taken from here doesn't work
FROM training/webapp
VOLUME webapp:/webapp
I think you might want what i have described here https://stackoverflow.com/a/41576040/3625317
The problem with volumes is, that when a container is recreated, not docker-compose down but rather docker-compose pull + up, the new container will not have your "new code stored in the volume" but rather, due to the recycled volume, still the old anon volume. The point is, you will need a anon-volume for the code anyway, since you want it redeployable, not a named volume since you want the code to be exchangeable.
On re-create the anon-volume is not removed, that said, lets say you have the image:v1 right now and you pull image:v2 and then do a docker-compose up. It will recreate your container based on image:v2 - when this finished, you will have a new container, but the code is still from the old container, which was based on image:v1, since the anon-volume has not been replaced, it was re-assigned. docker-compose down && docker-compose up will resolve that for you - but you have to keep this in mind when dealing with your idea. (down removes anon-volumes)
In general, there is a pro / con, see my other post.
Data-containers in general have a other meaning and have been replaced by so called named volumes. Data-containers have been used to establish a volume-mount which is "named" and not based on a anon-volume.
In the past, you had to create a container with a volume, and later use a container-name based mount of this volume ( the container would be the static / name part ), today, you just create a named volume name and mount by this volume-name, no need for a busybox killed after start based container-name based volume mount.
I'm trying to teach myself about Docker and using the docker-compose.yml to play around with images and the compose file. I've got the Wordpress image up and running using successfully docker-compose.yml up -d via the tutorial here... https://docs.docker.com/compose/wordpress/), but as soon as I make changes to the compose file and docker-compose.yml up -d again I can't access the changes again and have to completely delete images/containers/docker machine's to get my changes to work.
What am I doing wrong, what's the process to restart/delete the minimum amount to see my docker-compose.yml changes so I can play around with docker-compose.yml?
docker-compose stop to stop the stack
docker-compose start to start the stack
Both above will not remove your container, but rather shutdown and start them again, without any loses, even on the container filesystem, not only the volumes
docker-compose down will remove the containers of your services and all anonymous volumes assigned to them.
Be aware, not all changes in the docker-compose file can be applied using start/stop, rather most of the time, you have to do a down/up. Things like volumes/ports cannot be hot-applied like this.