Docker Swarm: Migrating off of hand-edited config files

Config Files

Often, on-prem applications will rely on one or more configuration files that end-users will edit in order to configure the application. For example, your app might expect a file at /etc/myapp/app.properties that contains details for configuring and tuning an application:

mysql_url=mysql://some-user:password@some-host/some-database
num_queue_workers=2

This guide will walk through using Replicated to migrate off of hand-edited configuration files in favor of a more user-friendly web UI, without modifying application code.

We use .properties for this example, but the same applies to .env files as well as other common formats like JSON, YAML, or TOML configuration files.

Step 1: Replicated config section

The first step is defining the Replicated Config Screen UI that end-users will use to configure their instance. For the above properties file, this might look like:

config:
  - name: basic
    title: App Settings
    items:
      - title: MySQL Connection String
        name: mysql_url
        type: password
        required: true
      - name:  num_queue_workers
        title: Queue Worker Count
        help_text: Use this field to tune the number of worker processes that will be used.
        type: text
        default: 2


Note that since the MySQL URL might contain a password, we've marked it as sensitive via the `type: password` designation. This will ensure it is not displayed in the UI, and that it will be encrypted at rest in Replicated's internal database.

Docker Swarm: Injecting the Secret

Replicated’s docker swarm integration supports injecting specific secrets into the application stack. In your # kind: replicated document, you can add the following secret

swarm:
  secrets:
    - name: app.properties
      value: |
        mysql_url={{repl ConfigOption "mysql_url"}}
        num_queue_workers={{repl ConfigOption "num_queue_workers"}}

Configuring services

In your # kind: scheduler-swarm document, you’ll need to declare that the secret will be injected into the stack with

secrets:
  app.properties:
    external: true

And then you can inject the secret into your application container. Assuming it will check for a file at CONFIG_FILE_PATH, your service might look like this.

# kind: scheduler-swarm
version: "3.7"
services:
  api:
    image: quay.io/mycompany/my-api:1.0.1
    secrets:
      - app.properties
    environment:
      - CONFIG_FILE_PATH=/run/secrets/app.properties
  # ... more services


secrets:
  app.properties:
    external: true