I'm currently looking for a way to define ENV variables in CI with Gitlab Secrets so I can override defaults values at build time when I need to deploy my containers.
From what I could find, there is no such way if I don't specify the -e
in the build command. However, this is not very practical for a certain number of arguments.
My current commands are currently looking like this :
# In .gitlab-ci
docker build -t $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/production:${CI_COMMIT_REF_SLUG} -f .docker/production/Dockerfile .
# In Dockerfile
ENV MAILER_URL=${MAILER_URL:-"null://localhost"}
I know I could just use build args, but I have a good number of settings and I would like to avoid putting them in CI
As of today there is no direct way to read from file during the build process however you can add all of your arguments to a file then use bash to construct the build command.
# In Dockerfile
ARG MAILER_URL http://localhost
ENV MAILER_URL=${MAILER_URL}
This means that by default the value of MAILER_URL
will be http://localhost
but you can override it during the build by using --build-arg
2- Export Gitlab CI variables to file e.g (arguments.txt) in before_script
or any other section that works better:
echo "MAILER_URL=$CI_MAILER_URL" >> arguments.txt
# echo other variables to arguments.txt
3- Read arguments.txt
and save it in a variable then pass it to docker build
export BUILD_ARGS=$(for arg in $(cat arguments.txt); do echo "--build-arg $arg ";done | tr -d '\n');
docker build -t $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/production:${CI_COMMIT_REF_SLUG} $BUILD_ARGS -f .docker/production/Dockerfile .
For more details you can check Set build-time variables (--build-arg) in Docker and ARG usage in Dockerfile
Also you need to consider that variables like MAILER_URL
or MAILER_PASSWORD
from a security standpoint you should pass them when you deploy only and also to be able to deploy your image to multiple environment.
You can take a look at The Twelve Factor App: Config section:
Env vars are easy to change between deploys without changing any code;