Thin-edge configuration with environment variables

Hello Cumulocity Community,

Product/components used and version/fix level:

thin edge latest, cumulocity platform

Question related to a free trial, or to a production (customer) instance?

customer instance

Detailed explanation of the problem:

In former Versions of thin-edge we adjusted some parts of the docker file, so we could use .env- files to import custom settings e.g. device certificates from outside the docker container. This was especially necessary because the edge-device, where thin-edge runs has no possibility to access volumes from outside (security reasons). As template we used the opcua-solution example from the github-repo and made some modifications to it:

  • adding smart rest template
  • adding script to open-rc to handle the env
FROM rust:alpine as builder

ARG VERSION=0.7.2

...

# Add custom smart rest templates to thin edge
RUN tedge config set c8y.smartrest.templates customTemplate

# Adding external certificates by env files
RUN ln -sf /sbin/openrc-init /sbin/init
COPY entry_start.sh /app/

RUN sed -i 's/\r$//' /app/entry_start.sh  && \
        chmod 755 /app/entry_start.sh

RUN rc-update add certcopy default
RUN echo 'rc_env_allow="CERTPUBLIC CERTPRIVATE baseUrl"' >> /etc/rc.conf

ENTRYPOINT ["/sbin/init"]

Now the code changed significantly, so that simple modifications like just changing the version number does not work anymore. The tedge-c8y-mapper and the mosquitto client are now separate instances.

If we use the latest base image from tedge (github-repo) is it still possible to add these necessary modifications to it? Do you use another init system now instead of open-rc? Is it possible to adjust the data for the mosquitto and tedge-c8y-mapper as well with the same methods?

Thanks in advance for your answers.

I’ll have a more in-depth answer for you shortly, but I just wanted to check that your goal was to have all of the thin-edge.io components (including the mosquitto broker) running in a single container, right?

Yes, if possible we would want to run it in a single container, like it was before. That would make our modifications easier to adapt.

I think there are few misconceptions here that I just want to clear up first…

The tedge-c8y-mapper and the mosquitto client are now separate instances.

The tedge-mapper-c8y and mosquitto service was never the same “instance”. Maybe you mean there were hosted in separate containers? But anyway, thin-edge.io is flexible to allow you to use it in different setups, so both cases are supported, and you can install thin-edge.io and the service definitions for the init system of your choice.

I’ve had other users ask a similar question, so I figured it would be worthwhile to show a more holistic example of the recommended way to run thin-edge.io and all it’s components in a single container with the help of the very container friendly s6-overlay init system.

Check out the new github repository, tedge-container-bundle, which shows you how to run everything. I would highly recommend forking the repo, and making your customization to it. This will also allow you to sync your forked repo if any changes are made to the upstream (e.g. the source project).

Please following the README.md in the tedge-container-bundle project, but below is just to show rough steps:

  1. Clone the project

    git clone https://github.com/thin-edge/tedge-container-bundle.git
    cd tedge-container-bundle
    
  2. Create the .env file and add your (see the README in the project it even shows how to encode the device certificates)

    # Device certificate (public/private)
    CERTPRIVATE=<base64_encoded_private_key>
    CERTPUBLIC=<base64_encoded_public_cert>
    
    # Which c8y instance you want to connect to
    TEDGE_C8Y_URL=example.cumulocity.com
    
    # You can turn specific services on/off via environment variables
    SERVICE_TEDGE_MAPPER_C8Y=1
    
  3. Start the docker compose project

    docker compose up --build
    

The output of the docker compose should look something like this:

[+] Running 1/1
 ✔ Container tedge-container-bundle-tedge-1  Recreated                                                                               0.1s 
Attaching to tedge-1
tedge-1  | s6-rc: info: service s6rc-fdholder: starting
tedge-1  | s6-rc: info: service s6rc-oneshot-runner: starting
tedge-1  | s6-rc: info: service s6rc-oneshot-runner successfully started
tedge-1  | s6-rc: info: service fix-attrs: starting
tedge-1  | s6-rc: info: service s6rc-fdholder successfully started
tedge-1  | s6-rc: info: service tedge-mapper-collectd-log: starting
tedge-1  | s6-rc: info: service tedge-mapper-c8y-log: starting
tedge-1  | s6-rc: info: service tedge-mapper-az-log: starting
tedge-1  | s6-rc: info: service tedge-mapper-aws-log: starting
tedge-1  | s6-rc: info: service tedge-agent-log: starting
tedge-1  | s6-rc: info: service mosquitto-log: starting
tedge-1  | s6-rc: info: service c8y-firmware-plugin-log: starting
tedge-1  | s6-rc: info: service fix-attrs successfully started
tedge-1  | s6-rc: info: service legacy-cont-init: starting
tedge-1  | s6-rc: info: service tedge-mapper-collectd-log successfully started
tedge-1  | s6-rc: info: service tedge-mapper-c8y-log successfully started
tedge-1  | s6-rc: info: service tedge-mapper-az-log successfully started
tedge-1  | s6-rc: info: service tedge-mapper-aws-log successfully started
tedge-1  | s6-rc: info: service tedge-agent-log successfully started
tedge-1  | s6-rc: info: service mosquitto-log successfully started
tedge-1  | s6-rc: info: service c8y-firmware-plugin-log successfully started
tedge-1  | cont-init: info: running /etc/cont-init.d/configure.sh
tedge-1  | Current User: tedge
tedge-1  | Writing thin-edge.io private key from env 'CERTPRIVATE' (decoding from base64) to file
tedge-1  | Writing thin-edge.io private key from env 'CERTPUBLIC' (decoding from base64) to file
tedge-1  | Connecting c8y
tedge-1  | Removing Cumulocity bridge.
tedge-1  | 
tedge-1  | Bridge doesn't exist. Operation finished!
tedge-1  | Detected mosquitto version >= 2.0.0
tedge-1  | Checking if tedgectl is available.
tedge-1  | 
tedge-1  | Warning: 'tedgectl' service manager is not available on the system.
tedge-1  | 
tedge-1  | Checking if configuration for requested bridge already exists.
tedge-1  | 
tedge-1  | Validating the bridge certificates.
tedge-1  | 
tedge-1  | Creating the device in Cumulocity cloud.
tedge-1  | 
tedge-1  | Saving configuration for requested bridge.
tedge-1  | 
tedge-1  | 'tedge connect' configured the necessary tedge components, but you will have to start the required services on your own.
tedge-1  | Start/restart mosquitto and other thin edge components.
tedge-1  | thin-edge.io works seamlessly with 'systemd'.
tedge-1  | 
tedge-1  | cont-init: info: /etc/cont-init.d/configure.sh exited 0
tedge-1  | s6-rc: info: service legacy-cont-init successfully started
tedge-1  | s6-rc: info: service tedge-mapper-collectd: starting
tedge-1  | s6-rc: info: service tedge-mapper-c8y: starting
tedge-1  | s6-rc: info: service tedge-mapper-az: starting
tedge-1  | s6-rc: info: service tedge-mapper-aws: starting
tedge-1  | s6-rc: info: service tedge-agent: starting
tedge-1  | s6-rc: info: service mosquitto: starting
tedge-1  | s6-rc: info: service c8y-firmware-plugin: starting
tedge-1  | s6-rc: info: service tedge-mapper-collectd successfully started
tedge-1  | s6-rc: info: service tedge-mapper-c8y successfully started
tedge-1  | s6-rc: info: service tedge-mapper-az successfully started
tedge-1  | s6-rc: info: service tedge-mapper-aws successfully started
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.245296388Z  INFO Runtime: Started    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.245324055Z  INFO Runtime: Running Signal-Handler-0    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.245340597Z  INFO Runtime: Running HealthMonitorActor-1    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.24642185Z  INFO Runtime: Running MQTT-2    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246444017Z  INFO Runtime: Running C8YJwtRetriever-3    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.2464496Z  INFO Runtime: Running HTTP-4    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246459933Z  INFO Runtime: Running C8Y-REST-5    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246464308Z  INFO Runtime: Running C8yAuthProxy-6    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246467725Z  INFO Runtime: Running FsWatcher-7    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246471933Z  INFO Runtime: Running Timer-8    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246503433Z  INFO mqtt_channel::connection: MQTT connecting to broker: host=127.0.0.1:1883, session_name=Some("tedge-mapper-c8y")    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246624892Z  INFO C8Y-REST: start initialisation    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246676184Z  INFO mqtt_channel::connection: MQTT connecting to broker: host=127.0.0.1:1883, session_name=None    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246862809Z  INFO HTTP Server: Cumulocity proxy has HTTPS disabled (configured in `c8y.proxy.cert_path`/`c8y.proxy.key_path`) and certificate authentication disabled (configured in `c8y.proxy.ca_path`)
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.246866643Z  INFO c8y_auth_proxy::server: Launching on port 8001 with HTTP
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247164935Z ERROR mqtt_channel::connection: MQTT: failed to connect to broker at '127.0.0.1:1883': I/O: Connection refused (os error 111)    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247194727Z ERROR mqtt_channel::connection: MQTT: failed to connect to broker at '127.0.0.1:1883': I/O: Connection refused (os error 111)    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247447269Z  INFO tedge_api::entity_store: Loading the entity store from the log    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247470769Z  INFO tedge_api::entity_store: Finished loading the entity store from the log    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247501978Z  INFO Runtime: Running CumulocityMapper-9    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247512186Z  INFO Runtime: Running MQTT-10    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247515645Z  INFO Runtime: Running Uploader-11    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247520311Z  INFO Runtime: Running Downloader-12    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247523686Z  INFO Runtime: Running OldAgentAdapter-13    
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.247556395Z  INFO mqtt_channel::connection: MQTT connecting to broker: host=127.0.0.1:1883, session_name=Some("last_will_c8y_mapper")    
tedge-1  | s6-rc: info: service mosquitto successfully started
tedge-1  | tedge-mapper-c8y | 2024-06-07T13:15:19.24766952Z ERROR mqtt_channel::connection: MQTT: failed to connect to broker at '127.0.0.1:1883': I/O: Connection refused (os error 111)    
tedge-1  | s6-rc: info: service c8y-firmware-plugin successfully started
tedge-1  | s6-rc: info: service tedge-agent successfully started
tedge-1  | s6-rc: info: service legacy-services: starting
tedge-1  | mosquitto | 1717766119: Loading config file /etc/tedge/mosquitto-conf/c8y-bridge.conf
tedge-1  | mosquitto | 1717766119: Loading config file /etc/tedge/mosquitto-conf/tedge-mosquitto.conf
tedge-1  | mosquitto | 1717766119: Note: It is recommended to replace `message_size_limit` with `max_packet_size`.
tedge-1  | mosquitto | 1717766119: mosquitto version 2.0.18 starting
tedge-1  | mosquitto | 1717766119: Config loaded from /etc/mosquitto/mosquitto.conf.
tedge-1  | mosquitto | 1717766119: Opening ipv4 listen socket on port 1883.
3 Likes

That was exactly what I needed. Now I just have to make a few adjustments for the opcua-gateway. Thank you!