I’ve followed the instructions here: Tutorial: Docker Compose update | Mender documentation to get a mender artifact that will bring my application up using docker compose. If I didn’t require any env vars this would be perfect, but unfortunately, I need to set some that are interpolated when the docker compose up command is run. Specifically, the main use case for it, is to dynamically set some labels for Traefik. However, there are a few other places where they’re used as well. Preferably I would like to use Mender’s configuration feature to do this, as the settings will vary for each of my devices.
My question is:is there a recommended way of setting env vars for docker compose? Docker documentation states that I can place a .env file alongside the docker compose file and variables in that file will be used. However, I haven’t found a “Mender” way of dynamically creating this .env file and having it be used properly. Any advice would be greatly appreciated.
My Setup:
Yocto image with the docker update pre reqs installed
Creating a config script that takes config variables, writes them to file and then copies the .env file to /data/mender-app/myapp. This doesn’t work because I need it to present prior to deployment, and the deploy itself seems to erase my .env file.
Creating a state script called ArtifactInstall_Enter_01.sh that copies over the .env file before docker compose is run. I believe in theory this could work, however, when following the instructions provided for creating the docker compose update artifact, that doesn’t seem to be an option/argument available to set the artifact state script (if I use --script, the app-gen command fails).
Setting env vars in /etc/environment and /etc/profile. Neither of these seem to be used by Mender.
thank you for using Mender for containerised applications!
how does it sound to use mender-app-docker-compose.conf which by default lives in /etc/mender/mender-app-docker-compose.conf and is loaded by the docker compose submodule?
there is also a global configuration file mender-app.conf with default location /etc/mender/mender-app.conf and loaded by the main Mender update module.
anything you set in those will get sourced and will populate the environment of the subsequent operations.
I’m happy to report that your response set me down the right path and I ended up with a solution. I’m not sure if there’s a better way, but I ended up breaking out our deploy into two separate artifacts:
A new, single-file artifact that I just called <our>-software-prep. This artifact contains a shell script that does two things. First, it creates my mender-config script that will later be used to set the env variables, next it modifies the aforementioned /etc/mender/mender-app-docker-compose.conf file to use a custom docker compose up command which includes the --env-file argument. This allows us to pass an arbitrary file to docker compose. The modification includes the file that is written to by our config script.
Our main docker compose artifact. This artifact is now properly deployable, with the caveat that the device must be configured before deployment in order for the env vars to be available. Saving or updating a device configuration writes the variables we want to an environment file which is now setup in the docker compose command from #1.
Hopefully someone else may find this response and find it useful.
Thanks for sharing! Just as a thought, it might be possible to fold such a preparatory script into the ArtifactInstall_Enter stage of a state script: State scripts | Mender documentation