DEV Community

dband drm
dband drm

Posted on

Deploy to Oracle with drm-cli + Flyway: No Enterprise License Required

Oracle deployments have a reputation. They're slow to set up, painful to automate, and the tooling ecosystem tends to assume you have deep pockets. If you've tried to build a reliable Oracle deployment pipeline, you've probably hit at least one of these walls:

  • Flyway's Oracle support is locked behind Flyway Teams
  • Liquibase's Oracle features are split across free and commercial tiers
  • Rolling your own with SQLPlus scripts works — until it doesn't, and there's no audit trail when something goes wrong
  • Connection strings with credentials scattered across environment files and CI/CD config

drm-cli doesn't replace Flyway. It layers on top of it — adding release tracking, encrypted credentials, retry logic, and pre/post deployment scripting. And it's free and open-source, which means Oracle-grade deployment management without an Oracle-grade price tag.

This tutorial walks through a complete Oracle deployment using drm-cli + Flyway.


Prerequisites

Before you start, you'll need:


Project Structure

drm-cli works with a straightforward directory structure. Here's what a minimal Oracle project looks like:

my-oracle-project/
├── drm.yml
├── migrations/
│   ├── V1__create_accounts_table.sql
│   ├── V2__add_account_status.sql
│   └── V3__create_transactions_table.sql
└── drivers/
    └── ojdbc11.jar
Enter fullscreen mode Exit fullscreen mode

Your migrations follow standard Flyway naming conventions — drm-cli doesn't change that. It just takes responsibility for the release lifecycle around them.


Step 1 — Configure drm.yml

drm.yml is the project configuration file drm-cli reads at runtime. Here's a working example for an Oracle deployment:

project: my-oracle-project
version: "1.0.0"

release:
  history_db: release_history.db    # SQLite file — stores your full release audit trail
  retry_attempts: 3
  retry_delay_seconds: 10

targets:
  - name: oracle-prod
    tool: flyway
    database_type: oracle
    migrations_path: ./migrations
    drivers_path: ./drivers
    connection:
      encrypted: false
      url: "jdbc:oracle:thin:@//localhost:1521/XEPDB1"
      user: "deploy_user"
      password: "your-password-here"
Enter fullscreen mode Exit fullscreen mode

A note on the connection block: encrypted: false here for clarity, but drm-cli supports encrypting credentials at rest using a key you manage. We'll cover that in a follow-up article — for now, plain credentials are fine for a local test environment.


Step 2 — Write Your Migrations

Standard Flyway SQL migrations. Nothing unusual here:

-- V1__create_accounts_table.sql
CREATE TABLE accounts (
    account_id   NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    account_name VARCHAR2(100) NOT NULL,
    created_at   TIMESTAMP DEFAULT SYSTIMESTAMP
);
Enter fullscreen mode Exit fullscreen mode
-- V2__add_account_status.sql
ALTER TABLE accounts
ADD status VARCHAR2(20) DEFAULT 'ACTIVE';
Enter fullscreen mode Exit fullscreen mode
-- V3__create_transactions_table.sql
CREATE TABLE transactions (
    transaction_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    account_id     NUMBER NOT NULL,
    amount         NUMBER(15,2) NOT NULL,
    posted_at      TIMESTAMP DEFAULT SYSTIMESTAMP,
    CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES accounts(account_id)
);
Enter fullscreen mode Exit fullscreen mode

Step 3 — Run Your First Deployment

With your config in place, deploy with:

drm deploy --target oracle-prod
Enter fullscreen mode Exit fullscreen mode

You'll see output like this:

[drm-cli] Starting deployment → oracle-prod
[drm-cli] Tool: flyway | Database: oracle
[drm-cli] Running Flyway migrate...
[drm-cli] Flyway: Successfully applied 3 migrations to schema "DEPLOY_USER"
[drm-cli] Recording release to history...
[drm-cli] Deployment complete — Release ID: 001 | Status: SUCCESS
Enter fullscreen mode Exit fullscreen mode

That last line is what makes drm-cli different from running Flyway directly. Every deployment is written to the local release history database — timestamp, target, release ID, outcome.


Step 4 — Check Release History

drm history --target oracle-prod
Enter fullscreen mode Exit fullscreen mode
Release History — oracle-prod
─────────────────────────────────────────────────────────────────
ID   Version   Status    Started              Completed
001  1.0.0     SUCCESS   2026-04-20 09:14:32  2026-04-20 09:14:38
─────────────────────────────────────────────────────────────────
1 release found.
Enter fullscreen mode Exit fullscreen mode

This audit trail lives in the local SQLite file (release_history.db). It's yours — no cloud service, no external dependency.


Step 5 — What Happens When a Migration Fails

This is where retry logic matters. Let's say your network connection to Oracle drops mid-deployment — a perfectly ordinary thing to happen in production.

Configure retry_attempts and retry_delay_seconds in drm.yml (already set above), and drm-cli will automatically retry the deployment up to 3 times before marking it as failed.

[drm-cli] Starting deployment → oracle-prod
[drm-cli] Tool: flyway | Database: oracle
[drm-cli] Running Flyway migrate...
[drm-cli] Connection error — retrying in 10 seconds (attempt 1/3)
[drm-cli] Connection error — retrying in 10 seconds (attempt 2/3)
[drm-cli] Flyway: Successfully applied 1 migration to schema "DEPLOY_USER"
[drm-cli] Recording release to history...
[drm-cli] Deployment complete — Release ID: 002 | Status: SUCCESS
Enter fullscreen mode Exit fullscreen mode

If all retries are exhausted, the failed attempt is still recorded in release history — so you know exactly what ran, what didn't, and when.


Encrypting Your Oracle Credentials

Storing plaintext database credentials is a habit worth breaking. drm-cli supports encrypting the connection block in drm.yml using a key you control.

Switch to encrypted mode:

connection:
  encrypted: true
  url: "gAAAAABk..."       # encrypted value
  user: "gAAAAABk..."      # encrypted value
  password: "gAAAAABk..."  # encrypted value
Enter fullscreen mode Exit fullscreen mode

Encrypt your values with:

drm encrypt --value "jdbc:oracle:thin:@//localhost:1521/XEPDB1"
Enter fullscreen mode Exit fullscreen mode

drm-cli prompts for your encryption key and returns the encrypted string. The key never touches drm.yml — you pass it at runtime or load it from an environment variable.

Full encryption setup is covered in the drm-cli docs.


Using Liquibase Instead of Flyway

If your team uses Liquibase rather than Flyway, swap tool: flyway for tool: liquibase in drm.yml and point migrations_path at your changelog directory. The rest of the workflow is identical.


yaml
targets:
  - name: oracle-prod
    tool: liquibase
    database_type: oracle
    changelog_file: ./changelogs/db.changelog-root.xml
    drivers_path: ./drivers
    connection:
      encrypted: false
      url: "jdbc:oracle:thin:
Enter fullscreen mode Exit fullscreen mode

Top comments (0)