Time: Approximately 20 minutes
During this exercise we will learn how add parameters and use them for deployment.
docker-app
makes the already existing Compose
variable substitutions system easy to use.
Just replace any part of the compose file with a variable using this form: ${path.to.my-variable}
docker-app
will seek into the parameters.yml
file, which is a simple key/value YAML file, to find the default value.
Here is the corresponding parameters.yml
file:
path:
to:
my-variable: myvalue
other-variable: othervalue
NOTE: All the application parameters will be displayed using the inspect
command.
We will re-use the first compose file we wrote, with the hello
service.
- Go back to
/workshop
and create a single-filehello
application using the previousdocker-compose.yml
words $ cd /workshop
/workshop $ docker-app init hello --compose-file docker-compose.yml --description "Hello DockerCon application" --single-file
It produces a hello.dockerapp
file which should be like the following:
# This section contains your application metadata.
# Version of the application
version: 0.1.0
# Name of the application
name: hello
# A short description of the application
description: Hello DockerCon application
# Namespace to use when pushing to a registry. This is typically your Hub username.
#namespace: myhubusername
# List of application maintainers with name and email for each
#maintainers:
# - name: John Doe
# email: [email protected]
---
# This section contains the Compose file that describes your application services.
version: '3.7'
services:
hello:
image: hashicorp/http-echo:latest
command: ["-text", "Hello DockerCon", "-listen",":8080"]
ports:
- 8080:8080
---
# This section contains the default values for your application parameters.
{}
- Edit the
hello.dockerapp
file and replace the "Hello DockerCon" text with a variable${hello.text}
and add the variable as a parameter in theparameters
section - Use
validate
while you edit your application to check everything is ok inspect
your application, now the parameters section is displayed
$ docker-app inspect hello
hello 0.1.0
Hello DockerCon application
Service (1) Replicas Ports Image
----------- -------- ----- -----
hello 1 8080 hashicorp/http-echo:latest
Parameter (1) Value
------------- -----
hello.text Hello DockerCon
- Replace all the
8080
ports with a${hello.port}
variable, and add it too to theparameters
section validate
theninspect
the application, it displays thehello.port
parameter
NOTE: metadata are available as read-only variables under the app
prefix. You can use them in your compose file:
${app.name}
${app.version}
${app.description}
NOTE: the parameters
section MUST define all the variables with a default value. If any parameter is missing, an error will occur on validate
or inspect
commands.
- Comment one of the two parameters, then
inspect
orvalidate
the application. Don't forget to uncomment the parameter.
$ docker-app validate hello
Error: failed to load Compose file: invalid interpolation format for services.hello.command.[]: "required variable hello.text is missing a value". You may need to escape any $ with another $.
The render
command will produce a compose file, substituting all the variables with the default values.
render
the hello application
$ docker-app render hello
version: "3.7"
services:
hello:
command:
- -text
- Hello DockerCon
- -listen
- :8080
image: hashicorp/http-echo:latest
ports:
- mode: ingress
target: 8080
published: 8080
protocol: tcp
- Modify the
hello.text
parameter in theparameters
section and re-render - Replace the
${hello.text}
variable by${app.description}
and re-render, then revert it - Save your rendered compose file using the
--output
flag
$ docker-app render hello --output hello.yml
You can also override all the variables using the command line, or create another parameters file, with other values, targeting another environment.
- Override the port using the
--set
flag with therender
command
$ docker-app render hello --set hello.port=8181
version: "3.7"
services:
hello:
command:
- -text
- Hello DockerCon
- -listen
- :8181
image: hashicorp/http-echo:latest
ports:
- mode: ingress
target: 8181
published: 8181
protocol: tcp
- Edit a new
prod-parameters.yml
file and add different values in it forhello.text
andhello.port
variables render
the application using this new settings file and the flag--parameters-files
$ cat prod-parameters.yml
hello:
text: Hello Workshop
port: 80
$ docker-app render hello --parameters-files prod-parameters.yml
version: "3.7"
services:
hello:
command:
- -text
- Hello Workshop
- -listen
- :80
image: hashicorp/http-echo:latest
ports:
- mode: ingress
target: 80
published: 80
protocol: tcp
NOTE: Parameters can be overridden using a mix of files or command line parameters. The parameters files doesn't need to define all the variables, a subset is enough. The precedence is the following:
- command line parameters, last one has precedence on the others
- files
- default values in the parameters section.
- Play with
render
command and mix--set
and--parameters-files
$ docker-app render hello -s hello.text="Hello Moby" -f prod-parameters.yml
NOTE: these flags work the same way with inspect
, validate
or install
commands.
- Try the same mix of parameters with
inspect
$ docker-app inspect hello -f prod-parameters.yml
hello 0.1.0
Hello DockerCon application
Service (1) Replicas Ports Image
----------- -------- ----- -----
hello 1 80 hashicorp/http-echo:latest
Parameters (2) Value
-------------- -----
hello.port 80
hello.text Hello Workshop
The rendered compose file can be directly injected to docker-compose up
or docker stack deploy
commands to deploy your application.
- Deploy using
docker stack deploy
, the-
references the standard input
$ docker-app render hello | docker stack deploy my-hello-app -c -
Creating network my-hello-app_default
Creating service my-hello-app_hello
- Open a browser at the
8080
port, it displaysHello DockerCon
- Re-deploy changing the text
$ docker-app render hello -s hello.text="Hello Moby" | docker stack deploy my-hello-app -c -
- Refresh your browser and check the message
- Deploy another application using the production parameters, it should open it on port
80
$ docker-app render hello -f prod-parameters.yml | docker stack deploy my-prod-app -c -
- Remove the two stacks using
docker stack rm
NOTE: With the parameters, you can now easily scale your application with docker stack
.
Bonus Exercise: Add parameterized deploy.replicas
to the hello
service and use it to scale up and down with the render
command and --set hello.replicas=X
- With parameters you can use the same compose file and target multiple environments (dev/test/staging/prod/...)
- Render let's you check what will be the exact compose-file deployed
- You can pipe the result of a render to your current workflow (
docker-compose
,docker stack deploy
) and still use some of the benefits of docker-app
Here is a generic application package template:
version: 0.1.0
name: base
description: A generic application template which takes an image as a parameter
maintainers:
- name: garethr
email: [email protected]
---
version: '3.7'
services:
app:
image: ${image}
ports:
- ${port}:${port}
deploy:
replicas: ${replicas}
resources:
limits:
memory: ${memory}
---
image:
port: 8080
replicas: 1
memory: 128MB