Provisioning a Docker Compose workload
With Docker Compose workloads, users have the possibility to manage multiple services in the Nerve system and establish a link between them. Users can also use a Docker container in combination with a Compose file to use the full extent of Docker Compose. In contrast, a Docker workload in the Nerve system is designed to cover basic functionalities and configuration options of a Docker container through the UI of the Management System.
Before provisioning a Docker Compose workload, a Compose file needs to be written.
Docker Compose file
A Docker Compose file is required when provisioning the workload. It needs to be written in YAML format. For information on how to write a Docker Compose file, refer to the official Docker Compose documentation. However, keep the following things in mind:
- Nerve validates the Compose file to v3.7 of the compose schema. Follow this schema to write a valid Compose file.
- The image attribute is required to be included in the Compose file. It also needs to be consistent with the image specified through the UI.
The validation check for the Compose file schema happens as soon as the file is uploaded in the workload settings with the UI giving a message whether the check has passed.
Examples:
-
Public Docker Hub registry
nodered/node-red-docker
nginx
-
Private registry with authentication and a tag at the end
auth.docker.test.host.cloud/workload:v1.3
Note
For services that offer a web UI or visualization, define a port in the range of 8500 — 8600 in the Compose file to have a web UI link appear in the workload management section of the Local UI.
Restrictions and constraints
Certain options are not allowed due to security concerns. These options are validated in a second check during the deployment process of the workload. Take a look at the list of prohibited parameters:
- network_mode: "host"
or
- networks:
nerve-test:
name: nerve-test
driver: host
The host network cannot be used. Use the default bridge network or user-defined bridge networks. Predefined Nerve networks can also be used. Refer to Networks for Docker workloads for more information.
- ipam:...
It is not possible to use ipam
parameters for configuring networks in order to specify a custom driver or a subnet, for example.
- privileged: true
Privileged mode cannot be set for any service. This is to avoid the container having root capabilities on the host.
- volumes:
- type: bind
source: ./static
target: /opt/app/static
or
- /opt/data:/var/lib/mysql (where the first part is a host path)
Bind mounts to host locations are not allowed. The only exception is /etc/localtime
. This allows a service to use the host time zone setting.
Environment variables
There is a set of restrictions and constraints for defining environment variables, especially when working with Nerve DNA. The Nerve system handles certain aspects in a certain way due to security concerns, which makes two things not possible:
- Environment variables cannot be used for ports to avoid the possibility of workload ports being reserved more than once.
- Environment variables cannot be used for volumes, bind volumes specifically, because users are restricted from using bind volumes with Nerve.
However, to work around the above restriction in regards to environment variables being used for ports, certain things should be considered:
- It is recommended to define default values for environment variables in the Docker Compose file. Otherwise they cannot be set via the Management System but only through the Nerve DNA process in an ENV file.
- Specific syntax should be used to make sure that environment variables from ENV files are considered as well.
Consider these suggestions especially when one Docker Compose workload is to be used on different nodes with ENV files further configuring environment variables for specific nodes.
Take a look at the following excerpt of a Compose file as an illustration:
restart: unless-stopped
environment:
- NGINX_PORT=${NGINX_PORT:-81}
ports:
- "8888:80"
- "8889:81"
An environment variable NGINX_PORT
is defined as NGINX_PORT=${NGINX_PORT:-81}
, following this syntax rule:
${VARIABLE:-default}
evaluates to default ifVARIABLE
is unset or empty in the environment.
So in the file above this means that the value for NGINX_PORT
will be 81
, unless NGINX_PORT
is defined in an ENV file that has been added through the Nerve DNA process.
While there are corner cases and combinations of defining environment variables that work with Nerve as well, the way described above is the recommended best practice to avoid error cases and complications.
For more information on working with Nerve DNA, refer to Nerve DNA.
Provisioning a Docker Compose workload
The following instructions only cover the required settings for provisioning a Docker Compose workload. Optional settings will be left out. Extended options are addressed in the last section of this chapter. However, note that some settings are necessary to provision a functioning workload. Make sure to understand the workload and its purpose before provisioning a workload.
Other workload types that can be provisioned are:
The process for each workload is highlighted in its respective chapter.
- Log in to the Management System.
- Select Workloads in the navigation on the left.
-
Select the yellow Docker Compose symbol (Add new Compose workload) in the upper-right.
-
In the new window, enter a name for the Docker Compose workload.
-
Select the Storage preference.
- Select Management System Registry if you want to use the Docker Registry of the Management System. This storage type supports image and layer management, offering greater flexibility and efficiency.
For the workloads that are using Management System Registry, URLs are needed. You have to push the images to the Management System Registry do make it deployable (see also). - Select Legacy storage if you want to use the image from the registry.
In the legacy storage workload, data is bundled into one package, facilitating uniform management and delivery.
When writing Compose files within Legacy storage, note the differences between public Docker Hub registries and private registries. Private registries require the full URL to be specified, as well as a username and password if they require authentication. Public Docker Hub registries can be specified in their short form. Visit Docker Hub to find Docker images and their paths.
- Select Management System Registry if you want to use the Docker Registry of the Management System. This storage type supports image and layer management, offering greater flexibility and efficiency.
-
Select the plus icon
next to Create version to add a new version of the workload.
-
In the next window, enter the following information in the Basic tab:
Category Settings and descriptions VERSION SPECIFIC INFO Version name
Enter a name for the version of this workload.
Compose file
Select the upload iconto open the file browser and upload a Compose file for the Docker container here. The Compose file needs to written in YAML format according to the Docker Compose schema v3.7.
Note that the image paths need to be included in the Compose file for every container or service. Refer to Docker Compose file for more information.
Once a Compose file is added, its contents are displayed on the right. Note that the attributes of the Compose file in the screenshot are example attributes.
The following picture shows a version configuration for a Legacy Storage.
Note
Once a Compose file has been uploaded, the Registries and Services and Remote Connections tabs become active and can be used for configuration. Refer to Settings for Docker Compose workloads for information on the settings.
-
Select Save in the lower-left corner to save the workload version.
The workload has now been provisioned and is ready to be deployed in the Deploy menu.
Note
You can also save the Docker Compose workload version, even the workload doesn't already exist in the Management System Registry. Consider that this Docker Compose workload is not deployable.
ou can check the status of the workload in the Workloads menu.
If the workload is not deployable, a warning is shown.
Hover over the warning symbol to get more detailed information.
For more information on how to control the workload after deployment and use workload specific features, refer to Workload control.
Settings for Docker Compose workloads
In the instructions above, all optional settings have been left out. Below is an overview of all the options for each Storage preference, along with an explanation for each option.
Management System Registry
Select one of the tabs below, to get an overview of all the options for the Management System Registry.
Category | Settings and descriptions |
---|---|
Version Specific Info | Version name A name for the workload version. This could be a reminder for a certain configuration. Example: Unlimited as a name for a Node-RED version that has unlimited access to CPU resources.Compose file Select the upload icon ![]() Note that the image paths need to be included in the Compose file. Refer to Docker Compose file for more information. Selector If labels have been defined and assigned to nodes, add them as selectors to the workload. When deploying a workload, the list of nodes will be filtered automatically to the specified label. Select the Insert label field to see a list of available labels. Mark as released Tick this checkbox to mark this workload as released. Once marked as released, the workload cannot be edited anymore. |
The services configuration tab provides a list of services. Each service listed in the Docker Compose file occupies one row in the list. The information of each column shows the following:
Column | Descriptions |
---|---|
Service Name | This is the name of the service as defined in the Docker Compose file. |
Image Name | This is the image name in the format of name:tag . Refer to DNA hash and Docker registry, to to learn more about tagging and DNA hash. |
Configuration storage | A drop-down menu appears when one or more volumes are defined for a service in the Docker Compose file. Select a volume from the drop-down menu to designate the volume for storage of configuration files and enable the application of configuration files. The default selection is None. Refer to Applying configuration files to a workload for more information. |
Restart on conf. update | A checkbox appears when one ore more volumes are defined for a service in the Compose file. Tick this checkbox to trigger an automatic restart of the service when configuration files are applied. Note that this only applies if a volume has been selected for configuration storage. |
Category | Settings and descriptions |
---|---|
REMOTE CONNECTIONS | Select the Remote connections tab to configure a remote connection to the workload. Make sure to configure the workload first so that a remote connection can be established. Note that for Docker Compose workloads the service needs to be specified in addition. Refer to Remote connections for more information and instructions for all remote connection types. |
Legacy storage
Select one of the tabs below, to get an overview of all the options for the Legacy storage.
Category | Settings and descriptions |
---|---|
Version Specific Info | Version name A name for the workload version. This could be a reminder for a certain configuration. Example: Unlimited as a name for a Node-RED version that has unlimited access to CPU resources.Compose file Select the upload icon ![]() Note that the image paths need to be included in the Compose file. Refer to Docker Compose file for more information. Selector If labels have been defined and assigned to nodes, add them as selectors to the workload. When deploying a workload, the list of nodes will be filtered automatically to the specified label. Select the Insert label field to see a list of available labels. Mark as released Tick this checkbox to mark this workload as released. Once marked as released, the workload cannot be edited anymore. |
Category | Settings and descriptions |
---|---|
REGISTRIES | This column contains a list of registries defined in the Compose file. Every registry entry has two fields where a Username and a Password can be entered. If the registry is password protected, credentials need to be entered for the image download and therefore the provisioning of the workload to proceed. Note that passwords are not stored. |
SERVICES | Search bar Enter a search term to filter the list of services by name. List of services Each service listed in the Docker Compose file occupies one row in the list. The information of each column shows the following:
|
Category | Settings and descriptions |
---|---|
REMOTE CONNECTIONS | Select the Remote connections tab to configure a remote connection to the workload. Make sure to configure the workload first so that a remote connection can be established. Note that for Docker Compose workloads the service needs to be specified in addition. Refer to Remote connections for more information and instructions for all remote connection types. |
Example Docker Compose file
This section presents examples of Docker Compose files that can be used to provision a Docker Compose workload. One example is for the Management System Registry and the other for Legacy Storage. They are designed for trying out Docker Compose workloads. When trying out Docker Compose files, make sure that they are aligned with the Docker Compose file requirements.
Description of the examples:
These examples for Docker Compose files can be used to quickly provision Docker Compose workloads, featuring PostgreSQL and Grafana. Both examples demonstrate how to set up a PostgreSQL service, named db
, using the postgres
container image. This service exposes port 5432
, defines environment variables, and uses a named volume for data storage. Upon deployment, a default network is created, and the container joins it under the name db
.
The Grafana service in both examples shows how to map the container port to a host port and connect the container to an existing network. This highlights the use of pre-configured networks for Docker and Docker Compose workloads. The service also defines environment variables and uses named volumes for configuration.
The use of pre-configured Nerve networks for Docker Compose workloads is recommended. Refer to Node internal networking for more information on Nerve networks.
Select one of the tabs below to get an example of a Docker Compose file for the Management System Registry or for the Legacy Storage.
The example for Management System Registry includes additional features such as using a private Docker registry, incorporating extra services like timescaledb
, gateway
, and supervisor-be
, and utilizing multiple custom networks. It also demonstrates advanced configurations like ulimits
, cap_add
, and depends_on
.
Use your specific Management System registry image path. Note that <cloudname>.dev.nerve.cloud
is a placeholder.
version: "3.5"
volumes:
timescale_data: null
grafana_data: null
config_and_certs: null
credentials: null
services:
timescaledb:
container_name: "nerve-ds-node_timescaledb_1"
image: "<cloudname>.dev.nerve.cloud/registry/nerve-dp-comp-storage-timescale:integration"
restart: "unless-stopped"
volumes:
- "timescale_data:/var/lib/postgresql/data"
ports:
- "127.0.0.1:47307:5432"
environment:
- "NERVE_DS_NETWORK=${NERVE_DS_NETWORK:-isolated1}"
- "NERVE_DS_ENV=${NERVE_DS_ENV:-NODE}"
networks:
isolated1:
aliases:
- "nerve_timescaledb"
grafana:
container_name: "nerve-ds-node_grafana_1"
image: "<cloudname>.dev.nerve.cloud/registry/nerve-dp-comp-visualization-grafana:integration"
restart: "unless-stopped"
depends_on:
- "timescaledb"
user: "0"
volumes:
- "grafana_data:/var/lib/grafana"
environment:
- "GF_AUTH_ANONYMOUS_ENABLED=true"
- "GF_AUTH_ANONYMOUS_ORG_ROLE=Viewer"
- "GF_AUTH_PROXY_ENABLED=true"
- "GF_AUTH_PROXY_AUTO_SIGN_UP=false"
- "GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/webui/nerve-ds-node_grafana_1/"
- "GF_SERVER_SERVE_FROM_SUB_PATH=true"
- "NERVE_WEB_UI_CONFIG_PASS_LOCATION_SUB_PATH=true"
ports:
- "127.0.0.1:8502:9300"
networks:
nerve-ds:
aliases:
- "nerve_grafana"
isolated1:
aliases:
- "nerve_grafana"
gateway:
image: "<cloudname>.dev.nerve.cloud/registry/nerve-dp-comp-gateway:integration"
container_name: "nerve-ds-node_gateway_1"
user: "root"
restart: "on-failure"
depends_on:
- "timescaledb"
environment:
- "DB_TIMESCALE_LOCAL_DB_PORT=5432"
- "SMART_CONNECTION_CREATION_MECHANISM_DURATION_S=6000"
volumes:
- "config_and_certs:/app/user_config"
- "credentials:/app/credentials"
ulimits:
rtprio: 49
cap_add:
- "SYS_NICE"
ports:
- "127.0.0.1:8500:47308"
- "127.0.0.1:5555:5555"
networks:
nerve-ds:
aliases:
- "gateway"
isolated1:
aliases:
- "gateway"
mgmt:
aliases:
- "gateway"
supervisor-be:
container_name: "nerve-ds-node_supervisor-be_1"
image: "<cloudname>.dev.nerve.cloud/registry/nerve-dp-sv-backend:integration"
restart: "unless-stopped"
depends_on:
- "timescaledb"
- "grafana"
ports:
- "127.0.0.1:8501:5005"
volumes:
- "credentials:/app/credentials"
environment:
- "VISU_PORT=9300"
networks:
nerve-ds:
aliases:
- "backend"
isolated1:
aliases:
- "backend"
networks:
nerve-ds:
name: "nerve-ds"
driver: "bridge"
isolated1:
external: true
mgmt:
external: true
version: '3.5'
services:
db:
image: postgres:alpine
environment:
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
restart: always
volumes:
- db_data:/var/lib/postgresql/data
expose:
- 5432
grafana:
image: grafana/grafana:7.5.17
container_name: grafana
ports:
- 3002:3000
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=grafana
networks:
extern1:
aliases:
- nerve_grafana
volumes:
- grafana_ds:/etc/grafana/provisioning/datasources
volumes:
db_data:
grafana_ds:
networks:
extern1:
external: true
Refer to the official Docker Compose documentation for more information on writing Compose files.