Why Use Docker Compose, Build Argument and Environment Variable
Nov 09, 2019 · 5 Min Read · 6 Likes · 0 CommentImagine, you have some microservices and you want to use API from one service to another, how can you do that if all of them are running in different docker container? Docker Compose has a solution for you.
Suppose you want to deploy a project in test, stage and production environment with same Dockerfile
for all of them through a single Dockerfile. You can do that through Build Argument and Environment Variable.
Supercharge your containers using docker-compose
docker-compose
is a great tool for orchestrating multiple docker instances. But it is not like kubernetes or docker swarm. Rather, its a simple application which allows you to communicate between docker containers, allow you to easily configure things, even help you generate service
, route
, build config
etc for kubernetes if you use kompose
.
Example
Here is an example of docker-compose.yml
:
version: 3
services:
web:
build: .
container_name: dz01
db:
image: postgres:alpine
container_name: pz01
Use multiple compose file in same project
If you want to have different compose files for building the same project(like one for test server, another for production server), then just write two or more .yml
files and when building one of them or run them just use -f
argument. Like this:
docker-compose -f your_file_name.yml build
Share services from one container to another
Let us say you have a database in one container and a server in another container, how can you use that database from that server? Rather than doing the communication manually, I would recommend using docker compose. For example:
version: "2"
services:
web:
build: .
container_name: dz01
depends_on:
- db
volumes:
- ./src:/src
expose:
- "8000"
db:
image: postgres:alpine
container_name: pz01
port:
- "5432:5432"
In here, database service is defined as db
. From web container, you can simply access the database using:
psql -h db -p 5432
Even wget db:5432
will work, because the word db
will be resolved automatically through docker compose.
Docker compose shell and logs
Access docker compose shell by:
docker exec -ti container_name /bin/sh
Access docker compose log by:
docker-compose logs service_name
Build arguments or ARG
Build arguments or ARG
is value which is available during build. It is useful for many cases:
. Set value of environment variable during build.
. Use same Dockerfile in multiple projects. For example, you have a django Docker Image, and you can use it in similar projects. Just you need to know project root and where the requirements
file is. Example code:
ARG PROJECT_ROOT
ARG REQUIREMENTS_DIR
ENV SRC_DIR PROJECT_ROOT # Setting the environment variable from Build Argument
ADD SRC_DIR /app
WORKDIR /app
RUN pip install -r "${REQUIREMENTS_DIR}" # Installing Requirements from ARGS
CMD ["python", "manage.py", "runserver"]
Basic usages of ARG
Pass build arguments when building the image like this:
docker build --build-arg PROJECT_ROOT=./src REQUIREMENTS_DIR=./requirements/local.txt
Or if you use docker-compose.yml
then update file like this:
version: "3"
services:
django:
build:
context: ./app
dockerfile: Dockerfile
args:
PROJECT_ROOT: ./src
REQUIREMENTS_DIR: ./requirements/local.pip
Envionment variable or ENV
Using ENV
will create environment variables inside Docker container. You can also send them from outside when building the Dockerfile(through Build Arguments) or running the image.
Basic usages of ENV
If you are running the Image using docker
command in terminal or command line, then use argument -e
.
docker run -e "SRC_DIR=./src" django
Or you can declare them in docker-compose.yml
file:
version: "3"
services:
django:
environment:
- "SRC_DIR=./src"
Set default value for environment variables
You can simply do that by:
# With default value
ENV ABC ./src
# Without Default value
ENV XYZ
And you can override the value of ABC
here by passing the environment from outside of container, ie docker run -e ABC=./abc ...
.
Loading environment variables from file
You can store your environment variables in a file and load them in docker-compose.yml
via env_file
:
django:
env_file:
- web-variables.env
Which is similar to what you can use docker run --env-file=FILE ...
for load the environment file when running a docker image.
Using .env
in docker compose
You can put environment variables inside .env
file and it will be picked up automatically from docker compose. This pretty cool feature as there are some interesting usages within the docker compose file itself.
$ cat .env
PORT=8088
$ cat docker-compose.yml
version: '3'
services:
django:
build:
context: .
dockerfile: ./compose/django/Dockerfile
image: django
ports:
- "${PORT}:8000"
So when you run docker-compose up
then the variable ${PORT}
will be replaced by 8088.
Use host machine environment variables
It will work almost same as above example. Just define the value of PORT
in your host machine, then it will automatically be picked up when you run docker-compose up
$ export PORT=8088
$ cat docker-compose.yml
version: '3'
services:
django:
build:
context: .
dockerfile: ./compose/django/Dockerfile
image: django
ports:
- "${PORT}:8000"
ARG
vs ENV
As explained above, ARG
is only build time variables. Means it will be available when you are building the Image from a Dockerfile. On the other hand, ENV
can be accessed when you are running the Image. But you can still use the environment variable when building the Image. Then you have to use either ARG
to update the ENV
value or use a default value.
In conclusion
In this post, I tried to explain usages of docker compose, build arguments and environment variables in as detail as possible. But its better to use them in your own project to understand these better. Also checkout the reference links given below which has more detailed explanation.
Relevent posts
- Tips on Writing Dockerfile, Reduce Size and Build Time of an Image
- Tips on Using Volume, Entrypoint and .dockerignore file
References
- https://vsupalov.com/docker-arg-env-variable-guide/
- Official Documentation on Environment Variable: https://docs.docker.com/compose/environment-variables/
- Official Documentation Docker Compose: https://docs.docker.com/compose/
Last updated: Dec 29, 2024