Configuring containers
Last updated on 2024-12-24 | Edit this page
Estimated time: 198 minutes
Well this is interesting! The documentation for the SPUC container tells us that we can set an environment variable to enable an API endpoint for exporting the unicorn sightings. It also mentions that we can pass a parameter to change the units of the brightness of the unicorns. But how can we do this?
Overview
Questions
- How can I set environment variables in a container?
- How can I pass parameters to a container?
- How can I override the default command and entrypoint of a container?
Objectives
- Learn how to configure environment variables and parameters in containers
- Learn how to override the default command and entrypoint of a container
Setting the environment
We know we have to modify the environment variable
EXPORT
and set it to True
. This should enable
an API endpoint for exporting the unicorn sightings.
This sounds like a useful feature, but how can we set an environment
variable in a container? Thankfully this is quite straightforward, we
can use the -e
flag to set an environment variable in a
container.
Lets modifying our run command again:
BASH
docker stop spuc_container
docker run -d --rm --name spuc_container -p 8321:8321 -v ./print.config:/spuc/config/print.config -v spuc-volume:/spuc/output -e EXPORT=true spuacv/spuc:latest
docker logs spuc_container
OUTPUT
[...]
Welcome to the Space Purple Unicorn Counter!
:::: Units set to Imperial Unicorn Hoove Candles [iuhc] ::::
:: Try recording a unicorn sighting with:
curl -X PUT localhost:8321/unicorn_spotted?location=moon\&brightness=100
:: No plugins detected
:::: Unicorn sightings export activated! ::::
:: Try downloading the unicorn sightings record with:
curl localhost:8321/export
And now we can see that the export endpoint is available! Lets try it out!
OUTPUT
count,time,location,brightness,units
1,2024-10-16 09:14:17.719447,moon,100,iuhc
2,2024-10-16 09:14:17.726706,earth,10,iuhc
3,2024-10-16 09:14:17.732191,mars,400,iuhc
4,2024-10-16 10:53:13.449393,jupyter,210,iuhc
5,2024-10-16 12:53:51.726902,venus,148,iuhc
This is great! No need to bind mount or exec to get the data out of the container, we can just use the API endpoint.
Defaulting to network style connections is very common in Docker containers and saves a lot of hassle.
Environment variables are a very common tool for configuring containers. They are used to set things like API keys, database connection strings, and other configuration options.
Passing parameters (overriding the command)
In some other cases, parameters are passed to the container to configure its behaviour. This is the case for the brightness units in the SPUC container.
It is actually probably the first change you’d want to do to this particular container. It is recording the brightness of the unicorns in Imperial Unicorn Hoove Candles (iuhc)! This is a very outdated unit and we must change it to the much more standard Intergalactic Unicorn Luminosity Units (iulu).
Fortunately the SPUC documentations tells us that we can pass a
parameter to the container to set these units right. If we look
carefully at the entrypoint and command of the container, we can see
that the default units are set to iuhc
there:
BASH
docker inspect spuacv/spuc:latest -f "Entrypoint: {{.Config.Entrypoint}}\nCommand: {{.Config.Cmd}}"
OUTPUT
Entrypoint: [python /spuc/spuc.py]
Command: [--units iuhc]
What we have to do, then, is to override the Command part of
the default command. This is actually a very common thing to do when
running containers. It is done by passing a parameter at the end of our
run
command, after the image name:
BASH
docker stop spuc_container
docker run -d --rm --name spuc_container -p 8321:8321 -v ./print.config:/spuc/config/print.config -v spuc-volume:/spuc/output -e EXPORT=true spuacv/spuc:latest --units iulu
if we now register some unicorn sightings, we should see the brightness in iulu units.
BASH
curl -X PUT localhost:8321/unicorn_spotted?location=pluto\&brightness=66
curl localhost:8321/export
OUTPUT
count,time,location,brightness,units
1,2024-10-16 09:14:17.719447,moon,100,iuhc
2,2024-10-16 09:14:17.726706,earth,10,iuhc
3,2024-10-16 09:14:17.732191,mars,400,iuhc
4,2024-10-16 10:53:13.449393,jupyter,210,iuhc
5,2024-10-16 12:53:51.726902,venus,148,iuhc
6,2024-10-16 13:14:17.719447,pluto,66,iulu
We can already feel the weight lifting off our shoulders already! But we cannot mix iuhcs with iulus, so lets remove the volume and re-register our sightings with the correct units
BASH
docker stop spuc_container
docker volume rm spuc-volume
docker run -d --rm --name spuc_container -p 8321:8321 -v ./print.config:/spuc/config/print.config -v spuc-volume:/spuc/output -e EXPORT=true spuacv/spuc:latest --units iulu
curl -X PUT localhost:8321/unicorn_spotted?location=moon\&brightness=177
curl -X PUT localhost:8321/unicorn_spotted?location=earth\&brightness=18
curl -X PUT localhost:8321/unicorn_spotted?location=mars\&brightness=709
curl -X PUT localhost:8321/unicorn_spotted?location=jupyter\&brightness=372
curl -X PUT localhost:8321/unicorn_spotted?location=venus\&brightness=262
curl -X PUT localhost:8321/unicorn_spotted?location=pluto\&brightness=66
curl localhost:8321/export
OUTPUT
count,time,location,brightness,units
1,2024-10-16 13:15:03.719371,moon,177,iulu
2,2024-10-16 13:15:03.719398,earth,18,iulu
3,2024-10-16 13:15:03.719410,mars,709,iulu
6,2024-10-16 13:15:03.719425,jupyter,372,iulu
5,2024-10-16 13:15:03.719437,venus,262,iulu
6,2024-10-16 13:15:03.719447,pluto,66,iulu
Finally, we have the correct units for the brightness of the unicorns!
Overriding the entrypoint
We can also override the entrypoint of a container using the
--entrypoint
flag. This is useful if you want to run a
different command in the container, or if you want to run the container
interactively.
SPUC has an entrypoint of python /spuc/spuc.py
making it
hard to interact with. We can override this using the
--entrypoint
flag.
Challenge
Which of these are valid entrypoint and command combinations for the SPUC container? What are the advantages and disadvantages of each?
Entrypoint | Command | |
---|---|---|
A | python /spuc/spuc.py --units iuhc |
|
B | python /spuc/spuc.py |
--units iuhc |
C | python |
/spuc/spuc.py --units iuhc |
D | python /spuc/spuc.py --units iuhc |
These are all valid combinations! The best choice depends on the use case.
This combination bakes the command and the parameters into the image. This is useful if the command is always the same and the specified parameters are unlikely to change (although more may be appended).
This combination allows the command’s arguments to be changed easily, while baking-in which Python script to run.
This combination allows the Python script to be changed easily, which is more likely to be bad than good!
This combination allows maximum flexibility, but it requires the user to write the whole command to modify even the parameters.
Thanks to the SPUC documentation, our service is now running with the best units, and we can export the unicorn sightings using the API endpoint!
What else could we do with this container? Lets look at the docs again!
Key Points
- Environment variables and overriding the command and entrypoint of containers are the main ways to configure the behaviour of a container. A well structured container will have sensible defaults, but will also allow for configuration to be changed easily.
- Environment variables can be configured using the flag
-e
- The command can be used to pass parameters to the container, like
so:
docker run <image> <parameters>
This actually overrides the default command of the container. - The entrypoint can also be overridden using the
--entrypoint
flag.