The Problem:
You have a service running on Rancher managed by docker-compose. You desire to set a password after the container has been deployed. Rancher secrets allow you to mount a volume on your container with a file containing the secret. You want to execute a script to retrieve this secret and set it as a password in your configuration file. However, you do not want the secret to be stored in your Git repository and are looking for a solution to achieve this through docker-compose.
The Solutions:
Solution 1: Use a “bash” entry point and `restart: no`
In this solution, a second service is created named "mongosetup" that uses a "bash" entry point and restart: no
. This service depends on the "mongo" service, ensuring that it starts only after the "mongo" service is up and running.
The entry point for the "mongosetup" service is configured as follows:
entrypoint: [ "bash", "-c", "sleep 10 && mongo --host mongo:27017 --eval 'rs.initiate()'" ]
This entry point effectively executes a bash script that sleeps for 10 seconds and then uses the mongo client to connect to the "mongo" service and initialize the replica set using the rs.initiate()
command.
The restart: no
setting ensures that the "mongosetup" service is not automatically restarted if it exits. This prevents the initialization script from being executed multiple times.
The result is a setup where the "mongo" service is started first, and then the "mongosetup" service is executed to initialize the replica set. This approach allows you to run a script after the "mongo" container has started.
Solution 2: Docker Compose Custom Script Execution
To execute a script after a container has started using Docker Compose, follow these steps:
- Create an Initialization Script:
Create a script, let’s call itinit.sh
, that will perform the desired actions after the container startup. - Add the Script to the Image:
Copy theinit.sh
script to the image usingCOPY
instruction in the Dockerfile.Dockerfile
FROM sourceimage:tag
COPY init.sh /usr/local/bin/
ENTRYPOINT []
- Override the Entrypoint:
TheENTRYPOINT
defined in the base image (sourceimage
) is overridden with an empty array[]
. This allows us to specify a custom command in thedocker-compose.yml
file. - Specify the Custom Command:
In thedocker-compose.yml
file, under thecommand:
key, specify the custom command that will execute theinit.sh
script and then start the main executable. Use the following syntax:docker-compose.yml
services:
myservice:
image: something:tag
...
command: sh -c "/usr/local/bin/init.sh && exec myexecutable"
- Use
exec
:
It’s crucial to useexec
before calling the main executable (myexecutable
in the example). This ensures that the main executable becomes the first process (PID1) and correctly receives signals like STOP, KILL (Ctrl-C), or HUP.
Solution 3: Using Docker Volumes
You can also leverage Docker volumes to accomplish this task. Here’s how you can do it:
services:
example:
image: <whatever>
volume: ./init.sh:/init.sh
entrypoint: sh -c "/init.sh"
-
Create an Initialization Script:
- Start by creating an initialization script named
init.sh
. - The script should contain the commands you need to perform after the container has started.
- Start by creating an initialization script named
-
Define the Docker Compose Service:
- In your
docker-compose.yml
file, define a service calledexample
or any other name you prefer. - Specify the
image
that you want to use for the container. - Define a
volume
to map your localinit.sh
script to a specific path within the container. In this case, it’s mapped to/init.sh
.
- In your
-
Specify the Entrypoint:
- Set the
entrypoint
property to the following command:sh -c "/init.sh"
- This command tells Docker to run the
init.sh
script as the container’s entrypoint when it starts.
- Set the
-
Volume Considerations:
- Keep in mind that using volumes mounts the host’s file system inside the container. Changes made to the files внутри контейнера will be reflected on the host’s file system.
-
Test and Verify:
- After setting up the
docker-compose.yml
file, you can rundocker-compose up
to start the container. - Once the container starts, the
init.sh
script will be executed, and the necessary actions (such as setting passwords) will be performed.
- After setting up the
Solution 4: Use Rancher secret and rebuild container
Docker-compose is used to launch containers, not modify running ones. Rancher secrets can be referenced in the docker-compose.yml
file, which creates a volume containing the secret. The default permissions for the secret file are User ID and Group ID 0 with File Mode 0444. Setting external
to true
in the secrets part indicates that the secret has already been created.
To update a running container, use the following steps:
docker-compose up -d --no-deps --build <service_name>
This command builds the container, stops the old one, and starts the new one.
References: