Skip to content

Docker Compose File Requirements

Version Specification

The last compatible (V1) version of the Docker Compose Specification is 3.8. Although the most up to date (V2) version is the new Compose Specification Reference. However, for compatibility reasons it is preferred to stay with V1 versions 3.7 or higher.

When using V1 versions, it is important to run docker-compose in compatibility mode. These versions have specifications for running Docker Swarm environments. Because we are running in standalone mode, the compatibility flag must be enabled.

$ docker-compose --compatibility -f file1 -f file2 -f fileN up

About Logging Options Configurations

Currently, Docker Runtime is configured to redirect logs to the system journal where they are scraped by a Fluent-Bit instance. This includes the server logs and all container logs. Any configuration of the log driver within compose files should be avoided. As this logging driver works with TCP sockets, any configuration used for Files Logging Drivers (like local or json-file), such as max-size, max-file, or compress must not be used as those options are incompatible with TCP Socket Logging drivers. Explicit configuration of a container to use other logging sinks (such as null) that override the Docker Runtime configuration should be done with caution.

Naming

The container name in the .yml must be the exact string of the application name registered with the configuration manager with “_0” as a suffix.

The HCC2 does not yet support creating multiple instances.

Run the Container in Read Only

To reduce the number of write operations in the containers partition, run all containers in read-only mode. It is important to observe which folders the application tries to write to, and put those folders on a TMPFS mount (volatile data). See Persistent Data for information on how to store non-volatile data.

Container Restart Policy

If the container is part of the core services and this container should remain live most of the time, set up a policy to restart the container on failure. Docker will try to restart the container if the application fails.

Dependencies among Containers

If the container depends on another container, it should query that container to see if it is available and wait for the required services to be running. Explicit depends_on instructions are forbidden in the HCC2 for a number of reasons.

  • They make it nearly impossible for docker-compose to independently start or stop containers, complicating device management.
  • They significantly impact startup/shutdown time.
  • Using depends_on causes a false sense of security and poor habits. There is still the initialization period where the dependency container has been started by Docker but is not yet available. A communication endpoint might not be ready, so it is best to design an application in a resilient way to allow for other services not being available.

DO NOT link services using the depends_on instruction

services:
  unity:
    depends_on:
      - configmgr
...

Network Port Mapping

This section describes what to do if a port from the container is exposed to the host. This information is useful for containers that interact with the web servers or web applications. If the container does not have to expose any port to the host, then the practice is discouraged.

Firewall

The HCC2 has a firewall. To be accessible from the outside, it must both expose any ports that need to be visible from the outside AND ensure the ports are added to the firewall.

Container Resource Management

The container should set explicit limits on its CPU and memory resource usage. If the service must have resources reserved for operations, then use deploy/resources reservations. For more details, refer to Resource Limits.

---
services:
  unity:
    deploy:
      resources:
        limits:
          cpu: "1.0"          # use up to 1 CPU core
          memory: "268435456" # use up to 256MB of RAM
...

Environment Variables

Use environment variables if the containerized application needs configurable arguments or parameters at launch. These variables allow you to change the values of parameters through the YAML file without rebuilding the container. Refer to Rules and Best Practices | Setup via Environment Variables and Parameters

Network and Volume Naming

For Docker networks and volumes that will be interacting with the container, it is important to use a unique name in the Compose file and avoid use of generic names such as network1 or volume1. Generic names for networks and volumes can cause a problem at the merging stage of the docker-compose command, when it loads all the compose files needed to perform a service. Any network or volume will be created automatically when docker-compose runs. If the docker-compose shuts down a described service, the persistent volumes will not be deleted. Sensia recommends adding a prefix to each volume name to reflect the name of the container it belongs to. In the case of shared volumes, ensure the volume name is unique and known to the containers accessing it.

Warning

All containers on the internal HCC2 bus communicate over the EdgeNet network. Any app interacting with this network must include it on its networks list.

Tip

The service that executes all the compose files scans for defined networks and initializes them to ensure they are started EXACTLY ONCE before any containers start. This means containers must indicate external: true for all custom networks. See the example below.

References

Full Compose File Example

---
version: "3.7"

services:
  unity:
    image: qratehcc2sdk.azurecr.io/unity_top:#BUILD_NUMBER#
    container_name: unity_0
    read_only: true
    restart: on-failure
    networks:
      - edgenet
    ports:
      - '8443:8443/tcp'
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: "268435456"
    volumes:
      - configmgr_unity_vol:/shared/update
    tmpfs:
      - /home/node:uid=1000,gid=1000
      - /opt/unity_top/server/logs:uid=1000,gid=1000
      - /opt/unity_top/node_modules/.cache:uid=1000,gid=1000
      - /tmp
    environment:
      - CFG_MGR_IP=tcp://configmgr:5000

networks:
  edgenet:
    external: true

volumes:
  configmgr_unity_vol:
    name: configmgr_unity_vol
...