0

Running Canary on Linux

Starting in version 26.8, the following Canary services have the ability to run in a Linux environment:

  • OPC Collector
  • MQTT Collector
  • Store & Forward
  • Administrator
  • Identity

Services are distributed as container images the user configures with environment variables using their preferred container runtime. This article demonstrates the Docker runtime.

Container Images

All images are published to the Canary registry at containers.canarylabs.com. Five service images are available:

Image Service Description
canary-administrator Administrator Central management interface for the services below.
canary-identity Identity Authentication and authorization for all other services.
canary-store-and-forward Store and Forward Buffers and forwards collected data to its destination.
canary-mqtt-collector MQTT Collector Collects data from MQTT sources and sends it to Store & Forward.
canary-opc-collector OPC Collector Collects data from OPC UA sources and sends it to Store & Forward.

Version Tags

Image tags follow Canary's standard release versioning. Each release publishes a tag for the full version and for each shorter prefix, plus latest. For release 26.7.0, the tags would be:

Tag Resolves to Used when you want...
26.8.0 Exactly 26.8.0 A fully pinned, reproducible deployment.
26.8 The latest 26.8.x patch Automatic patch updates within a minor release.
26 The latest 26.x release Automatic minor and patch updates within a major release.
latest The most recent release The newest version, regardless of major.

For production environments, use specific tags, such as 26.8.0 or 26.8, so deployments are predictable. Reserve latest for evaluation and testing.

Pulling Images

If the Linux environment does not have internet access, the image must be pulled onto a machine that does have internet using the following steps:

  1. Pull an image by combining the registry, image name, and a version tag:
    docker pull containers.canarylabs.com/canary-identity:26.8
  2. Export the image to a .tar file:
    docker save -o canary-identity.tar containers.canarylabs.com/canary-identity:26.8
  3. Copy the .tar file to the offline machine.
  4. On the offline machine, load the image from the .tar file:
    docker load -i canary-identity.tar

Docker-Compose.yml File

Make a directory in which to create a docker-compose.yml file.

mkdir canary-docker
cd canary-docker
vim docker-compose.yml

The following .yml file is an example that runs all five services on a single Compose network. Because the services share a network, each one reaches the others by its service name (i.e., the Collectors point at canary-store-and-forward), so no endpoint hostnames need to be hard-coded. It uses the SelfSignedCertificate encryption to keep the first run simple. Copy/paste into a text editor and edit as needed. Not every service is required - it depends on the use case. At a minimum, the stack will require the Administrator, a Collector, and Store & Forward. The Identity service may already exist on a separate server.

# Shared configuration applied to every service.
x-canary-common: &canary-common
  CANARY_ENDPOINT_ENCRYPTION_KIND: SelfSignedCertificate
  CANARY_IDENTITY_CLIENT_ENDPOINT_API: canary-identity-hostname
  CANARY_IDENTITY_CLIENT_ENDPOINT_OIDC: canary-identity-hostname

# Shared volumes mounted into every service.
x-canary-volumes: &canary-volumes
  - canary-config:/etc/opt/Canary
  - canary-data:/var/opt/Canary

services:
  canary-administrator:
    image: containers.canarylabs.com/canary-administrator:26.8
    restart: unless-stopped
    environment:
      <<: *canary-common
      CANARY_ADMIN_SERVICE_ENDPOINT_IDENTITY: canary-identity
      CANARY_ADMIN_SERVICE_ENDPOINT_STORE_AND_FORWARD: canary-store-and-forward
      CANARY_ADMIN_SERVICE_ENDPOINT_MQTT_COLLECTOR: canary-mqtt-collector
      CANARY_ADMIN_SERVICE_ENDPOINT_OPC_COLLECTOR: canary-opc-collector
    volumes: *canary-volumes
    ports:
      - "55273:55273"      # gRPC API — Admin Client connection

  canary-identity:
    image: containers.canarylabs.com/canary-identity:26.8
    restart: unless-stopped
    environment:
      <<: *canary-common
    volumes: *canary-volumes
    ports:
      - "55353:55353"      # REST API — Admin Client authentication
      # - "55351:55351"    # gRPC API — only for Canary software outside this stack

  canary-store-and-forward:
    image: containers.canarylabs.com/canary-store-and-forward:26.8
    restart: unless-stopped
    environment:
      <<: *canary-common
    volumes: *canary-volumes
    # ports:
    #   - "55293:55293"    # REST API — Write Web API
    #   - "55291:55291"    # gRPC API — inbound data from remote Store and Forward services

  canary-mqtt-collector:
    image: containers.canarylabs.com/canary-mqtt-collector:26.8
    restart: unless-stopped
    environment:
      <<: *canary-common
      CANARY_MQTT_COLLECTOR_SAF_ENDPOINT: canary-store-and-forward
    volumes: *canary-volumes
    depends_on:
      - canary-store-and-forward

  canary-opc-collector:
    image: containers.canarylabs.com/canary-opc-collector:26.8
    restart: unless-stopped
    environment:
      <<: *canary-common
      CANARY_OPC_COLLECTOR_SAF_ENDPOINT: canary-store-and-forward
    volumes: *canary-volumes
    depends_on:
      - canary-store-and-forward

volumes:
  canary-config:
  canary-data:

Shared Common Variables

The common variables are identical for every service. Define them once and reuse them. Two approaches work well and can be combined.

  • YAML anchor (within a Compose file) - define the shared values once as an extension field and merge them into each service's environment block with <<. This is the approach used in the example above.
  • .env file (external values) - Keep environment-specific values - especially secrets such as a certificate password - in a .env file next to your docker-compose.yml. Compose loads it automatically and references the values with ${VARIABLE}. This keeps secrets out of the Compose file itself.

Endpoint Encryption

  • controls TLS for the service's own endpoints
Variable Description
CANARY_ENDPOINT_ENCRYPTION_KIND Encryption type: 
SelfSignedCertificate or PfxFile
CANARY_ENDPOINT_ENCRYPTION_CERTIFICATE_FILE_PATH Path to the .pfx file. Required when the kind is PfxFile.
CANARY_ENDPOINT_ENCRYPTION_CERTIFICATE_PASSWORD Password for the .pfx file. Required when the kind is PfxFile and the .pfx file is password protected.
  • Encryption kinds:
    • SelfSignedCertificate - the service generates its own self-signed certificate - the simplest option and a good starting point for evaluation or internal networks.
    • PfxFile - load a certificate from a .pfx file using the file path and password variables above. See Using your own certificate.

Using Your Own Certificate

To serve endpoints with your own certificate instead of a self-signed one, switch the encryption kind to PfxFile, mount the .pfx into the container, and point the service at it. Keep the password in a .env file rather than in the Compose file.

.env:

CANARY_CERT_PASSWORD=your-pfx-password

Updated shared block with a volume mount:

x-canary-common: &canary-common
  CANARY_ENDPOINT_ENCRYPTION_KIND: PfxFile
  CANARY_ENDPOINT_ENCRYPTION_CERTIFICATE_FILE_PATH: /certs/canary.pfx
  CANARY_ENDPOINT_ENCRYPTION_CERTIFICATE_PASSWORD: ${CANARY_CERT_PASSWORD}
  CANARY_IDENTITY_CLIENT_ENDPOINT_API: canary-identity
  CANARY_IDENTITY_CLIENT_ENDPOINT_OIDC: canary-identity

services:
  canary-identity:
    image: containers.canarylabs.com/canary-identity:26.8
    restart: unless-stopped
    environment:
      <<: *canary-common
    volumes:
      - canary-config:/etc/opt/Canary   # shared volumes, listed explicitly so the certificate can be added
      - canary-data:/var/opt/Canary
      - ./canary.pfx:/certs/canary.pfx:ro

Identity Connection

  • tells each service where to reach the Identity service. Specify a port only if you are not using the default; otherwise, the hostname alone is enough (for example, identity.example.com).
Variable Description
CANARY_IDENTITY_CLIENT_ENDPOINT_API gRPC API endpoint of the Identity service.
CANARY_IDENTITY_CLIENT_ENDPOINT_OIDC REST (OIDC) endpoint of the Identity service.

Volumes

  • Each container uses two mount points:
Path Contents
/etc/opt/Canary Configuration files
/var/opt/Canary Runtime data

For most installations, mount the same volumes into every container so they share one configuration and data store. Importantly, this will allow the Admin Client to display a combined message log for all services. The example above does this with two named volumes (canary-config and canary-data).

Services

Each service contains its own image, restart option, environment variables, volumes, and ports.

Administrator variables

Variable Description
CANARY_ADMIN_SERVICE_ENDPOINT_IDENTITY Endpoint of the Identity service.
CANARY_ADMIN_SERVICE_ENDPOINT_STORE_AND_FORWARD Endpoint of the Store and Forward service.
CANARY_ADMIN_SERVICE_ENDPOINT_MQTT_COLLECTOR Endpoint of the MQTT Collector service.
CANARY_ADMIN_SERVICE_ENDPOINT_OPC_COLLECTOR Endpoint of the OPC Collector service.

MQTT Collector variables

Variable Description
CANARY_MQTT_COLLECTOR_SAF_ENDPOINT Endpoint of the Store and Forward service.

OPC Collector variables

Variable Description
CANARY_OPC_COLLECTOR_SAF_ENDPOINT Endpoint of the Store and Forward service.

The Identity and Store & Forward services require only the common variables.

Ports

Each service listens on the ports below. On a shared Docker network, services reach one another internally without publishing anything to the host; you only need to publish a port when something outside the network has to reach it - most commonly the Admin Client.

Service Port API Used by Publish to Host?
Administrator 55273 gRPC Admin Client connection Yes - the Admin Client connects here.
Identity 55353 REST Client authentication (the Admin Client) Yes - the Admin Client authenticates here.
Identity 55351 gRPC Request authorization by Canary services Internal only; publish only if Canary software outside this stack authorizes against it.
Store & Forward 55293 REST Write Web API Only if external systems write data through the Web API.
Store & Forward 55291 gRPC Inbound data from remote Store and Forward services Only if remote Store and Forward services proxy data to this instance.

The MQTT and OPC collectors make only outbound connections (to Identity and Store & Forward), so they do not need any published ports.

Running the Stack

Once the docker-compose.yml file is configured and saved, the container ecosystem can be built. From the directory containing the .yml file, run the following command:
 

docker compose up -d  # Start all services in the background

Other Commands

docker compose logs -f  # View logs for all services

docker compose ps  # Check status of services

docker compose down  # Stop and remove the containers

Connecting with the Admin Client

Once built, the user can connect to the system using the Admin client installed on a Windows machine to configure the Collectors and/or Identity service. The client connects to the Administrator service on port 55273. If the Identity service is installed as a container, 55353 must also be open for the Admin client to authenticate.

Reply

null