DEV Community

dband drm
dband drm

Posted on

Deploy to PostgreSQL with drm-cli + Liquibase: A Step-by-Step Guide

If you're running PostgreSQL with Liquibase or Flyway and you've ever been asked "what exactly was deployed to staging last Tuesday?" — and couldn't answer quickly — this post is for you.

drm-cli is a free, open-source database release manager that layers on top of Liquibase and Flyway. It doesn't replace your migration toolchain. It adds the layer those tools were never designed to provide: release history tracking, encrypted credentials, automated retries, and pre/post deployment scripts.

This walkthrough covers a complete PostgreSQL deployment with Liquibase. The setup for Flyway is identical — just swap the solution type in the config.


Prerequisites

Before you start:

  • Python 3.7+ installed on the host running drm-cli
  • git to clone the repo
  • Liquibase 4.25.0+ installed and on your PATH — download here
  • PostgreSQL JDBC driver (postgresql-*.jar) — download here
  • A PostgreSQL database you can connect to

Step 1 — Install drm-cli

Clone the repository and run the installer:

git clone https://github.com/dband-drm/drm-cli.git
cd drm-cli
python3 ./install.py
Enter fullscreen mode Exit fullscreen mode

The installer is interactive — it will prompt you for:

  • Installation path — where drm-cli will be installed (defaults to your home directory)
  • Encryption key — to encrypt sensitive data like connection strings at rest (optional but recommended)
  • Storage typejson (file-based, no extra dependencies) or sqlite

For a non-interactive install:

python3 ./install.py -d json -p none
Enter fullscreen mode Exit fullscreen mode

(-d json selects JSON storage, -p none means no encryption — use only for local test environments)

Once complete:

INFO - DRM installation finished successfully!!!
Enter fullscreen mode Exit fullscreen mode

Step 2 — Prepare Your Liquibase Changelogs

drm-cli works with your existing Liquibase changelogs. No changes to your migration scripts are needed:

my-changelogs/
├── db.changelog-root.xml
├── changes/
│   ├── 001-create-users-table.xml
│   ├── 002-add-email-index.xml
│   └── 003-create-orders-table.xml
Enter fullscreen mode Exit fullscreen mode

Note the path to this directory — you'll need it in the next step.


Step 3 — Configure Your Release

drm-cli stores all release configuration in a central database. Depending on the storage type you chose at install, this is either drm_db.json or drm_db.sqlite inside the db/ folder in your drm-cli installation directory.

JSON style

Open <install-path>/db/drm_db.json in any editor. Find the releases array and add your release with a solution and connection:

{
  "id": 10,
  "name": "postgresql-release-v1",
  "solutions": [
    {
      "name": "app-db-liquibase",
      "solution_type_id": 2,
      "path": "/path/to/my-changelogs",
      "connections": [
        {
          "name": "postgres-staging",
          "connection_type_id": 3,
          "connection_string": "url=jdbc:postgresql://127.0.0.1:5432/appdb;username=deploy_user;password=your-password;"
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Key fields:

  • solution_type_id: 2 — Liquibase (use 3 for Flyway)
  • path — the directory containing your Liquibase changelogs
  • connection_type_id: 3 — PostgreSQL
  • connection_string — the JDBC connection string Liquibase uses

SQLite style

Insert via SQL:

-- Add the release
INSERT INTO releases (id, name) VALUES (10, 'postgresql-release-v1');

-- Add the Liquibase solution
INSERT INTO solutions (id, name, release_id, ordinal, solution_type_id, path)
VALUES (100, 'app-db-liquibase', 10, 1, 2, '/path/to/my-changelogs');

-- Add the PostgreSQL connection
INSERT INTO connections (id, name, solution_id, connection_type_id, connection_string)
VALUES (1000, 'postgres-staging', 100, 3,
        'url=jdbc:postgresql://127.0.0.1:5432/appdb;username=deploy_user;password=your-password;');
Enter fullscreen mode Exit fullscreen mode

Step 4 — Run Your First Deployment

Navigate to your drm-cli installation directory and run:

python3 ./drm_deploy.py -c postgres-staging -r 10 --deploy
Enter fullscreen mode Exit fullscreen mode

Parameters:

  • -c postgres-staging — the connection name you defined in the config
  • -r 10 — the release ID
  • --deploy — execute the deployment (use --dryrun to generate scripts without running them)

You'll see output as drm-cli invokes Liquibase, captures the result, and records it:

INFO - DRM Deploy started
INFO - Running solution: app-db-liquibase
INFO - Executing Liquibase migrate...
INFO - Liquibase: Successfully applied 3 changesets
INFO - Deployment recorded successfully
INFO - DRM Deploy finished successfully!!!
Enter fullscreen mode Exit fullscreen mode

Step 5 — View Deployment History

After a deployment runs, drm-cli records the full event — timestamp, connection, release ID, and outcome.

JSON style

Browse to <install-path>/deployments/. Each deployment creates a log file named:

Deploy_{GUID}_C{connection-name}_R{release-id}.json
Enter fullscreen mode Exit fullscreen mode

Open it to see the full deployment record: every step, its start/end time, status, and any error messages.

SQLite style

Query the deployments table:

SELECT d.*, ds.name AS status
FROM deployments AS d
INNER JOIN deployment_statuses AS ds ON ds.id = d.deployment_status_id
ORDER BY d.start_time DESC
LIMIT 10;
Enter fullscreen mode Exit fullscreen mode

Step 6 — What Happens When a Migration Fails

If a deployment step fails — network hiccup, lock timeout, transient error — drm-cli retries automatically. Retry behavior is configured in drm_deploy.config inside your drm-cli installation:

"retry_attempts": 3,
"retry_delay_seconds": 10
Enter fullscreen mode Exit fullscreen mode

A failed step will retry up to 3 times with a 10-second delay. If all retries are exhausted, the deployment is marked failed and the full error is recorded in the deployment log.

Even when a deployment fails, the record is there. You know exactly what ran, what didn't, and when.


Step 7 — Encrypting Your PostgreSQL Credentials

If you installed drm-cli with an encryption key, use drm_crypto.py to encrypt your connection string:

python3 ./drm_crypto.py
Enter fullscreen mode Exit fullscreen mode

The utility prompts you for your encryption key and the value to encrypt, then returns the encrypted string. Replace the plaintext value in your connection config with the result:

"connection_string": "url=jdbc:postgresql://127.0.0.1:5432/appdb;username=deploy_user;password=ENCRYPTED_VALUE_HERE;"
Enter fullscreen mode Exit fullscreen mode

drm-cli decrypts credentials at deploy time — they never appear in logs or trace output.


Using Flyway Instead of Liquibase

Swap solution_type_id: 2 for solution_type_id: 3 and set path to your Flyway migrations directory:

{
  "name": "app-db-flyway",
  "solution_type_id": 3,
  "path": "/path/to/flyway/migrations",
  "connections": [
    {
      "name": "postgres-staging",
      "connection_type_id": 3,
      "connection_string": "url=jdbc:postgresql://127.0.0.1:5432/appdb;username=deploy_user;password=your-password;"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The deployment command is identical:

python3 ./drm_deploy.py -c postgres-staging -r 10 --deploy
Enter fullscreen mode Exit fullscreen mode

What's Next

  • Week 5 — Oracle deployments with drm-cli + Flyway or Liquibase
  • Week 6 — Pre/post deployment scripts: the pattern for automating steps that run before and after every deployment
  • Week 7 — Multi-database releases: SQL Server, PostgreSQL, and Oracle in a single coordinated release

The full source and documentation is at github.com/dband-drm/drm-cli. Open issues there if you hit anything unexpected.


drm-cli is free and open-source. No license tiers, no paid features.

Top comments (0)