How to change Docker config of an already running container? - docker

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....

Related

Making a local bind mount in docker-compose

My team is using docker-compose for our project's container.
Previously, while we were learning how Docker works, we were just using docker. In docker, I could instantly see my local changes on my local deployment by attaching a bind mount to the container when I run it on the command line.
Now, using docker-compose, there doesn't seem to be any such option - my workflow is docker-compose up with little opportunity for deviation. I believe I can specify a bind mount as a volume in our docker-compose.yaml. But that's not really what I'm looking for.
I'd like to be able to specify a local, personal, temporary bind mount without having to modify my team's docker-compose.yaml or commit my personal preferences to vc. How can I specify my bind mount from command line, or equivalent?
Looking at the docs, there doesn't seem to be such an option from the commandline.
One way to get similar behavior to what you want is to make a second docker-compose file with the personal options. If you name it docker-compose.override.yaml, it will be picked up automatically. Otherwise, you can use the -f flag to load it, like so
docker-compose -f docker-compose.yaml -f docker-compose.user.yaml up -d
More details for using multiple docker-compose files are documented here (thanks #Sysix).
You could put this filename into gitignore.

Docker compose: change docker compose file without removing the container

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.

Problem with reopening of the project in container

I have ran into this problem when opening the project in container.
Setting up container for folder or workspace: c:\Work\playground\moodle\lms_administrace
Run: docker-compose -f c:\Work\playground\moodle\lms_administrace\docker\docker-compose-dev.yml config --services
app
redis
db
phpmyadmin
Run: docker-compose --project-name docker -f c:\Work\playground\moodle\lms_administrace\docker\docker-compose-dev.yml up -d --build
Creating volume "docker_mysql_data_volume" with default driver
Pulling app (nodejs:)...
ERROR: The image for the service you're trying to recreate has been removed. If you continue, volume data could be lost. Consider backing up your data before continuing.
Continue with the new image? [yN]
The problem is that I cannot press y or N. I know why I'm having this problem - because I have used that docker compose file before and containers and volumes were created with the directory prefix (docker).
There's a way how to change the compose project name through .env file, but it does not work (I put the file in the root directory, in the directory where compose file is, and in the .devcontainer folder). And also there is -p parameter, but the MS GitHub page does not provide any information.
I can probably fix it by renaming everything, but this may be a serious issue since you can't continue in the process ...
Did anybody experienced similar problem and fixed that?
Thanks,
Karel
You probably mistyped service docker image name in docker-compose.yml.
You are trying to pull nodejs image instead of node
Also, there is could be same error with case postgresql and postgres.
I had the same problem,My problem is using the wrong mirror name.

Drupal folders within docker

I succesfully installed drupal 7 with docker.
Using docker4drupal, now my question when I start editing my drupal site is, where are the folders containing drupal?
Let's say I installed a new theme and want to swap the images for the banner, how do I access the drupal folder containing the images, or would it be preciser to ask : Where does Docker storage them?
My docker compose line is :
-codebase : /var/www/html
I know that installing it using :
./:/var/www/html
Would install drupal in the same directory my docker-compose.yml is, but for some reason it doesn't work and still doesn't show me where the files are.
Any help is welcome!
If you are not using volumes to mount your existing code, the code resides inside the docker container. You can access it only by getting inside the container using docker exec. If you are using the default docker-compose.yml that came with the repo, then the name of the container will be "docker4drupal_nginx_1" (since nginx is the default).
Run this code to get inside the container:
docker exec -it docker4drupal_nginx_1 /bin/bash
exec allows you to execute commands inside the container.
-it allows you to start an interactive terminal
/bin/bash allows you to start the bash terminal inside the container
Once you are inside container run ls and you will see drupal files including "web".
MORE USEFUL
However, this is not a useful way if you want to work on the files and probably use an editor. Instead, mount a directory on host machine. First make a new directory where your docker-compose.yml file is with the name "codebase".
Then, update the docker-compose.yml so that:
- codebase:/var/www/html
becomes
- ./codebase:/var/www/html
Do this in both php and nginx service definisions. Of course, you should do this after you run docker-compose down with your previous set up. Then restart containers using docker-compose up -d.
Then, you will notice that the Drupal files are present in the codebase directory.
If you see at the bottom of the yml file, you will see that "codebase" is defined as a Docker volume. This implies the storage is managed by Docker and it will get stored somewhere in /var/lib/docker/ along with the container itself.
Hope this helps.

How can I mount a file in a container, that isn't available before first run?

I'm trying to build a Dockerfile for a webapp that uses a file-based database. I would like to be able to mount the file from the host*
The file is in the root of the complete software install, so it's not really ideal to mount that complete dir.
Another problem is that before the first use, the database-file isn't created yet. A first time user won't have a database, but another user might. I can't 'mount' anything during a build** I believe.
It could probably work like this:
First/new database start:
Start the container (without mount).
The webapp creates a database.
Stop the container
subsequent starts:
Start the container using a -v to mount the file
It would be better if that extra start/stop isn't needed for a user. Even if it is, I'm still looking for a way to do this userfriendly, possibly having 2 'methods' of starting it (maybe I can define a first-boot thing in docker-compose as well as a 'normal' method?).
How can I do this in a simpel way, so that it's clear for any first time users?
* The reason is that you can copy your Dockerfile and the database file as a backup, and be up and running with just those 2 elements.
** How to mount host volumes into docker containers in Dockerfile during build
One approach that may work is:
Start the database in the build file in such a way that it has time to create the default file before exiting.
Declare a VOLUME in the Dockerfile for the file after the above instruction. This will cause the file to be copied into the volume when a container is started, assuming you don't explicitly provide a host path
Use data-containers rather than volumes. So the normal usage would be:
docker run --name data_con my_db echo "my_db data container"
docker run -d --volumes-from data_con my_db
...
The first container should exit immediately but set up the volume that is used in the second container.
I was trying to achieve something similar and managed to do it by mounting a folder, instead of the file, and creating a symlink in the Dockerfile, initially pointing to a non-existing file:
docker-compose.yml
version: '3.0'
services:
bash:
build: .
volumes:
- ./data:/data
command: ['bash']
Dockerfile
FROM bash:latest
RUN ln -s /data/.bash_history /root/.bash_history
Then you can run the container with:
docker-compose run --rm bash
With this setup, you can push an empty "data" folder into the repository for example (and exclude its content with .gitignore). In the first run, inside the container /root/.bash_history will be a "broken" symlink, pointing to a file that does not exist. When you exit the shell, bash will write the history to /root/.bash_history, which will end up in /data/.bash_history.
This is probably not the correct approach.
If you have multiple containers that are trying to share some information through the file-system, you should probably let them share some directory.
That way, the flow is simple and very hard to get wrong.
You simply mount the same directory, say /data (from the host's perspective) into all the containers that are trying to use it.
When an application starts and it can't find anything inside that directory, it can gracefully stop and exit with a code that says: "Cannot start, DB not initialized yet".
You can then configure some mechanism with a growing timeout to try and restart that container until you're successful.
On the other hand, the app that creates the DB can start and create it inside the directory or find an existing file to use.

Resources