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:
- Pull an image by combining the registry, image name, and a version tag:
docker pull containers.canarylabs.com/canary-identity:26.8 - Export the image to a
.tarfile:docker save -o canary-identity.tar containers.canarylabs.com/canary-identity:26.8 - Copy the
.tarfile to the offline machine. - On the offline machine, load the image from the
.tarfile: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
environmentblock with<<. This is the approach used in the example above. .envfile (external values) - Keep environment-specific values - especially secrets such as a certificate password - in a.envfile next to yourdocker-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.pfxfile 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.