Local RDS for integration tests

Run local RDS for integration tests with fakecloud. 163 RDS operations, real PostgreSQL/MySQL/MariaDB engines via Docker, snapshots, read replicas. Free, AGPL-3.0.

Need local RDS for integration tests? Use fakecloud.

curl -fsSL https://raw.githubusercontent.com/faiscadev/fakecloud/main/install.sh | bash
fakecloud

Point your AWS SDK at http://localhost:4566. Docker required because fakecloud runs real PostgreSQL/MySQL/MariaDB engines.

Why fakecloud for RDS

Create a PostgreSQL instance

aws --endpoint-url http://localhost:4566 rds create-db-instance \
  --db-instance-identifier mydb \
  --engine postgres \
  --engine-version 16 \
  --db-instance-class db.t3.micro \
  --allocated-storage 20 \
  --master-username admin \
  --master-user-password password \
  --publicly-accessible

aws --endpoint-url http://localhost:4566 rds wait db-instance-available \
  --db-instance-identifier mydb

Get the endpoint:

aws --endpoint-url http://localhost:4566 rds describe-db-instances \
  --db-instance-identifier mydb \
  --query 'DBInstances[0].Endpoint'

Connect with psql (or any Postgres driver):

PGPASSWORD=password psql -h <endpoint> -p 5432 -U admin -d postgres

It's a real Postgres 16. \l, CREATE EXTENSION pg_trgm, CREATE TRIGGER, JSONB — all work.

MySQL / MariaDB

aws --endpoint-url http://localhost:4566 rds create-db-instance \
  --db-instance-identifier mydb \
  --engine mysql \
  --engine-version 8.0 \
  --db-instance-class db.t3.micro \
  --allocated-storage 20 \
  --master-username admin \
  --master-user-password password

--engine mariadb for MariaDB.

Snapshots

aws --endpoint-url http://localhost:4566 rds create-db-snapshot \
  --db-instance-identifier mydb \
  --db-snapshot-identifier before-migration

# ... do stuff that might break ...

aws --endpoint-url http://localhost:4566 rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier mydb-restored \
  --db-snapshot-identifier before-migration

Real snapshot — pg_dump / mysqldump of the running instance.

Read replicas

aws --endpoint-url http://localhost:4566 rds create-db-instance-read-replica \
  --db-instance-identifier mydb-replica \
  --source-db-instance-identifier mydb

Real streaming replication on the Postgres side; binlog replication on MySQL/MariaDB.

In tests

import { RDSClient, CreateDBInstanceCommand, waitUntilDBInstanceAvailable } from '@aws-sdk/client-rds';
import { Client } from 'pg';

const rds = new RDSClient({ endpoint: 'http://localhost:4566' });

beforeAll(async () => {
  await rds.send(new CreateDBInstanceCommand({
    DBInstanceIdentifier: 'test-db',
    Engine: 'postgres',
    EngineVersion: '16',
    DBInstanceClass: 'db.t3.micro',
    AllocatedStorage: 20,
    MasterUsername: 'admin',
    MasterUserPassword: 'password',
  }));
  await waitUntilDBInstanceAvailable(
    { client: rds, maxWaitTime: 60 },
    { DBInstanceIdentifier: 'test-db' }
  );
});

test('app writes to real postgres via RDS emulation', async () => {
  const pg = new Client({
    host: 'localhost', port: 5432,
    user: 'admin', password: 'password', database: 'postgres',
  });
  await pg.connect();
  await pg.query('CREATE TABLE t (id int)');
  await pg.query('INSERT INTO t VALUES (1)');
  const r = await pg.query('SELECT * FROM t');
  expect(r.rows).toEqual([{ id: 1 }]);
});

Your Postgres integration tests run against a real Postgres that RDS manages. No compromises.

How it differs from alternatives

ToolReal PostgresReal MySQLSnapshotsRead replicasPrice
fakecloudYes (Docker)Yes (Docker)YesYesFree
LocalStack ProYesYesYesYesPaid
LocalStack CommunityNoNoNoNo— (not available)
Plain docker run postgresYes (DB only)YesManualManualFree, but no RDS API
MotoStubbedStubbedStubbedStubbedFree

If you want the RDS API + real engines without paying LocalStack Pro, fakecloud is the option.