I have got a docker-compose.yml file and there I define:
extra_hosts:
- "localhost:${MY_MACHINE_IP}"
It works if I define MY_MACHINE_IP as environment var earlier.
What I want to achieve is to perform action like:
extra_hosts:
- "localhost:<get MY_MACHINE_IP from env if it exists, if not set MY_MACHINE_IP env variable with value <docker-machine-ip>>"
In other words: I want to define it in extra_hosts section, if MY_MACHINE_IP is already specified, get it, if not - set this env. variable with value = my docker machine ip.
Is it possible?
Yes in according to docker documentation
docker-compose run SERVICE env
So i think the variables are not global as you may think. You have to pass them as parameters.
Read this.
You can use the package ruamel.dcw for that (dcw for Docker Compose Wrapper, disclaimer: I am the author of that package). It allows you to create a section with key user-data in your docker-compose.yaml file, which is stripped out before handing the file to the normal docker-compose. That section can look like:
user-data:
author: Your Name <your-name#youremail.com>
description: container for postfix/submission
env-defaults:
PORT: 587 # override during development
NAME: submission
DOCKER_BASE: /data0/DATA
and then you can use {PORT}, {NAME} and {DOCKER_BASE} in the rest of the file, with the option of overriding these default values with environment variables.
The utility also write out a file .dcw_env_vars.inc which you can copy into your container and source to get the appropriate values into scripts you RUN from within the Dockerfile
Related
So I have been tasked with taking an existing dockerized version of a service, and creating docker images from this repository.
Creating the images is not the problem however, since the build command starts it up no problem. The issue is that this dockerfile copies an .env file during build, that holds variables that must be customizable after the build process is done (expected db and other endpoint info).
Is there some way to set that file to automatically be changed to reflect the environmental variables used in the docker run command? (I do want to note, that the docker image does copy the .env file into the working directory, it is not docker-compose reading that .env file)
I am sure that there has to be an easy way to do this, but all the tutorials I am pulling up just show you how to declare these variables, not how to get the files in docker to use them! Most of the code being run is javascript, and uses npm and yarn if that makes any difference...
docker does not provide any way to update files from environment variables on container start. But I don't think this is what you need anyway:
As I understand a .env file with default values is copied into the image at build time and you want to be able to change some of the values at runtime via container environment variables?
Usually such an .env file is read by the application and complemented by any variables set in the environment, i.e. you can override values from the file with environment variables. For javascript projects dotenv is a popular module to do this.
So to override say an API_ENDPOINT variable specified in .env you simply need to pass an environment variable with the same name and desired value to the container:
docker run -e API_ENDPOINT=/other/endpoint ...
If for some reason your applications do not work according to this convention and you actually need to change the values in the .env file you will need to write a custom script that updates/generates .env from the values of passed environment variables and use this script as ENTRYPOINT
I tried to get the variable in docker-compose.yml like ${NODE_ENV} but doesn't work.
Also I don't want to send any param on my commands. I have defined already an environment variable on my system and I'd like to take that one from either one of these 2 files.
the solution was running export NODE_ENV=development again. I was losing this env var every time I was closing the terminal
I want to know where can I see the variables I have defined. For example, I have three files:
.env
BLA=1
docker-compose.xml
IS_ONE=${BLA}
Dockerfile
RUN echo "$BLA" >> file.txt
I want to know the relation, for example:
Do I need the variable defined in all files? or there a relation like
docker-compose.xml can only see .evn variables?
Dockerfile can only see docker-compose.xml variables?
And, where do I need to declare a variable to use in a bash script automatically triggered in Dockerfile (if it's possible), or use later in the console of the container.
Lots of examples here: https://docs.docker.com/compose/environment-variables/
If you need to customize docker-compose itself then .env file is used.
For example, I want to include build id in my container name, my .env file would have
BUILD_ID=20
and docker-compose.yml would have
containername: "foo-${BUILD_ID}"
If I want to pass environment vars into container when it runs, I use
environment:
- FOO_VAR=bar
If I want to pass in multiple environment vars into container,
docker-compose.yml would have
env_file: my_container_env
is the easy way if the values of the FOO_VAR are going to be dynamically generated.
Whether to use set env values in docker-compose directly or use file depends on:
Are the values dynamic? If yes, use file and populate correct values
in the file with some script (like jenkins could set my BUILD_ID in
my .env file)
Are they 'secret'? If yes, use file and don't checkin the .env or my_container_env file into the repo - you have to manage those files
separately
I have the following .env file:
# ENV
ENVIRONMENT=local
SITENAME=reo
I have the following docker-compose.yml (part of it) file:
volumes:
${SITENAME}-sync:
external: true
I get the following error:
volumes value '${SITENAME}-sync' does not match any of the regexes: u'^[a-zA-Z0-9._-]+$'
Is it possible to have a variable as a key in a Yaml file?
I noticed that: key: ${SITENAME} does work.
Environment variables are not possible for keys in docker-compose.yml, only for values. See here
Since docker-compose doesn't support interpolation in keys, you'd need to add another level of indirection, e.g. use a templating tool like mustache or handlebars, and generate the docker-compose.yml file yourself from env vars.
I have several containers that I run together with docker-compose.
One of them, is mysql, which requires some variables to be set. I have those in a .env file:
MYSQL_USER='my_user'
MYSQL_PASSWORD='my_password'
MYSQL_ROOT_PASSWORD='supersecretpassword'
MYSQL_DATABASE='my_database'
And I am able to start the mysql container successfully.
The problem comes when I want to use another service for db migrations, which require the following variables set in the .env file:
SERVICE_DBUSER='my_user'
SERVICE_DBPASSWORD='my_password'
SERVICE_DBNAME='my_database'
And what I would like to write (this doesn't work), to avoid repetition, is something like:
SERVICE_DBUSER="$MYSQL_USER"
SERVICE_DBPASSWORD="$MYSQL_PASSWORD"
SERVICE_DBNAME="$MYSQL_DATABASE"
But docker doesn't recognize that and doesn't perform the substitution. In the docker docs, it also states that expects each line in an env file to be in VAR=VAL format.
My question is, is it possible to avoid the repetition?
Many thanks.
Compose will substitute environment variables into the YAML compose file when you reference them with $VARIABLE or ${VARIABLE}.
You can still use the .env file to set a default environment. But when you want to reference a variable, put it in the environment: section of the compose yaml:
environment:
SERVICE_DBUSER: "${MYSQL_USER}"
SERVICE_DBPASSWORD: "${MYSQL_PASSWORD}"
SERVICE_DBNAME: "${MYSQL_DATABASE}"
Then if you set, or source an alternate environment when running docker-compose you will get the new values substituted in.
$ MYSQL_USER="other" MYSQL_PASSWORD="opass" docker-compose start