For many applications, a database of some sort is required. A big question when packaging an on-prem app is whether to embed this database alongside the rest of your application, or to require an end customer to provide the connection details for a DB instance that they manage.
Tradeoffs
The key tradeoff is ease-of-setup for the customer vs. ease-of-maintainability for the application vendor, and often the answer is to allow both configurations. You can include an embedded database for trials and proof-of-concept installations, and then when your customer wants to set up a hardened production installation, they can supply connection details.
Docker Swarm Postgres Example
Configuration
First, we need some configuration items to allow the end customer to configure which mode they want to run in
config:
- name: db_settings_type
title: Database Type
description: Would you like to run an internal database or provide your own?
items:
- name: db_type
type: select_one
default: embedded
items:
- name: embedded
title: Embedded
- name: external
title: External
- name: external_db_config
title: External DB Settings
description: DB connection settings
when: db_type=external
items:
- name: database_connection_string
type: text
default: postgres://user:password@postgres.mycompany.com/some-database
Docker Swarm
On the swarm side, we need to reference those config options to control what runs in the cluster. We’ll toggle the number of postgres replicas that run, as well as the connection details for our example API server.
---
# kind: scheduler-swarm
version: '3.4'
services:
postgres:
image: postgres:10.4
deploy:
replicas: {{repl if ConfigOptionEquals "db_type" "embedded"}}1{{repl else}}0{{repl end}}
environment:
PG_PASSWORD: fake
PG_USER: fake
PG_DATABASE: my_app
api:
image: registry.replicated.com/my-app/api:1.0.1
environment:
POSTGRES_CONNSTRING: {{repl if ConfigOptionEquals "db_type" "external"}}{{repl ConfigOption "database_connection_string"}}{{repl else}}postgresql://postgres:postgres@postgres/my-app{{repl end}}
Note that this example omits (for brevity) how to securely create a persistent password/username for your postgres instance. A good guide for this can be found in Populating Config Values with Commands.
End to End
A full end-to-end example can be found in the optional-database branch of the replicated-starter-swarm repo.