RDS
Protocol: Query (XML) for management API + PostgreSQL / MySQL wire protocol for data plane
Management Endpoint: POST http://localhost:4566/
Data Endpoint: localhost:<proxy-port> (TCP)
Floci manages real PostgreSQL, MySQL, and MariaDB Docker containers and proxies TCP connections to them, including IAM authentication support.
RDS Data API (rds-data) is documented separately because it uses REST JSON routes instead of the RDS Query protocol. See RDS Data API.
Supported Management Actions
| Action | Description |
|---|---|
CreateDBInstance |
Start a new database instance |
DescribeDBInstances |
List instances and their connection info |
DeleteDBInstance |
Stop and remove an instance |
ModifyDBInstance |
Update instance settings |
RebootDBInstance |
Restart a database instance |
DescribeOrderableDBInstanceOptions |
List deterministic instance class options |
CreateDBSubnetGroup |
Create a DB subnet group |
DescribeDBSubnetGroups |
List DB subnet groups |
ModifyDBSubnetGroup |
Update DB subnet group description and subnet list |
DeleteDBSubnetGroup |
Delete a DB subnet group |
CreateDBCluster |
Create an Aurora-compatible cluster |
DescribeDBClusters |
List clusters |
DeleteDBCluster |
Delete a cluster |
ModifyDBCluster |
Update cluster settings |
CreateDBParameterGroup |
Create a parameter group |
DescribeDBParameterGroups |
List parameter groups |
DeleteDBParameterGroup |
Delete a parameter group |
ModifyDBParameterGroup |
Update parameter group settings |
DescribeDBParameters |
List parameters in a group |
CreateDBClusterParameterGroup |
- |
DescribeDBClusterParameterGroups |
- |
DeleteDBClusterParameterGroup |
- |
ModifyDBClusterParameterGroup |
- |
DescribeDBClusterParameters |
- |
CreateOptionGroup |
Create an option group |
DescribeOptionGroups |
List option groups, including the implicit default: groups |
ModifyOptionGroup |
Add, update, or remove options in an option group |
DeleteOptionGroup |
Delete an option group |
DescribeDBSnapshots |
- |
DescribeDBProxies |
List DB proxies |
CreateDBProxy |
Create a DB proxy |
ModifyDBProxy |
Update mutable DB proxy authentication, logging, timeout, TLS, role, and security-group settings |
DeleteDBProxy |
Delete a DB proxy |
RegisterDBProxyTargets |
Register a cluster or instance as a proxy target |
DeregisterDBProxyTargets |
Remove a cluster or instance from a proxy target group |
DescribeDBProxyTargetGroups |
List a proxy's target groups |
ModifyDBProxyTargetGroup |
Update target-group connection-pool configuration |
DescribeDBProxyTargets |
List a proxy target group's registered targets |
DescribeDBClusterSnapshots |
- |
AddTagsToResource |
Add tags to a DB resource |
ListTagsForResource |
List tags for a DB resource |
RemoveTagsFromResource |
Remove tags from a DB resource |
Configuration
| Variable | Default | Description |
|---|---|---|
FLOCI_SERVICES_RDS_ENABLED |
true |
Enable or disable the service |
FLOCI_SERVICES_RDS_MOCK |
false |
true = metadata only (no Docker container or auth proxy) |
FLOCI_SERVICES_RDS_PROXY_BASE_PORT |
7001 |
First host port in the RDS proxy range |
FLOCI_SERVICES_RDS_PROXY_MAX_PORT |
7099 |
Last host port in the RDS proxy range |
FLOCI_SERVICES_RDS_ENDPOINT_HOST |
(auto-detected) | Hostname advertised in RDS endpoints; when set in Docker, Floci advertises each proxy's published host port |
FLOCI_SERVICES_RDS_DEFAULT_POSTGRES_IMAGE |
postgres:16-alpine |
Docker image for PostgreSQL instances |
FLOCI_SERVICES_RDS_DEFAULT_MYSQL_IMAGE |
mysql:8.0 |
Docker image for MySQL instances |
FLOCI_SERVICES_RDS_DEFAULT_MARIADB_IMAGE |
mariadb:11 |
Docker image for MariaDB instances |
Docker Compose
RDS requires the Docker socket and port range exposure. For private registry authentication and other Docker settings see Docker Configuration.
When Docker publishes RDS proxy ports dynamically, set FLOCI_SERVICES_RDS_ENDPOINT_HOST to the
hostname used by clients. Floci inspects its own container through the Docker socket and returns the
corresponding published port from DescribeDBInstances and DescribeDBClusters. Leave the setting
unset to retain the auto-detected endpoint host and configured proxy port.
services:
floci:
image: floci/floci:latest
ports:
- "4566:4566"
- "7001-7099:7001-7099" # RDS proxy ports
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
FLOCI_SERVICES_DOCKER_NETWORK: my-project_default
FLOCI_SERVICES_RDS_PROXY_BASE_PORT: "7001"
Mock mode (CI / tests)
Set FLOCI_SERVICES_RDS_MOCK=true when you only need the management API shape: clusters and
instances are registered as available immediately, with no Docker container or auth proxy behind
them. Each resource still gets a unique endpoint port, but nothing listens on it.
# docker-compose.yml — CI / test environment
services:
floci:
image: floci/floci:latest
environment:
FLOCI_SERVICES_RDS_MOCK: "true"
Switching modes over persisted state
With a persistent storage mode, changing FLOCI_SERVICES_RDS_MOCK between restarts is
best-effort, as with the other mock-capable services: resources created in real mode and
deleted under mock leave their containers and volumes behind, and resources created in mock
mode are restored with fresh, empty containers when loaded in real mode.
DB proxy endpoint routing
DB proxy control-plane resources and target registration are modeled, but Floci's current
single-host TCP relay cannot expose multiple same-engine DB proxies as distinct AWS-style bare
hostnames on the same engine-default port. The standard Docker Compose mapping also exposes
only the 7001-7099 instance/cluster proxy range, not 1433, 3306, or 5432. Use mock mode
for DB proxy provisioning workflows until a dedicated endpoint-routing design is implemented.
DB proxy control-plane settings
Proxy and target-group settings are persisted and round-trip through the RDS Query API and
CloudFormation. Pool sizing, borrow timeout, idle timeout, TLS, init-query, and session-pinning
settings are currently control-plane metadata; the TCP relay does not yet implement those data-plane
behaviors. DefaultAuthScheme=IAM_AUTH is supported for control-plane workflows, but a real-mode
proxy using that scheme cannot register a target until backend IAM authentication is implemented.
Requests to RegisterDBProxyTargets, DeregisterDBProxyTargets, and
DescribeDBProxyTargets use the default target group when TargetGroupName is omitted,
matching the RDS API contract.
DB proxies currently support IPV4 for both endpoint and target connections; IPV6 and DUAL
endpoint networking require additional listener and Docker-network support.
Examples
export AWS_ENDPOINT_URL=http://localhost:4566
# Create a PostgreSQL instance
aws rds create-db-instance \
--db-instance-identifier mypostgres \
--db-instance-class db.t3.micro \
--engine postgres \
--master-username admin \
--master-user-password secret123 \
--allocated-storage 20 \
--endpoint-url $AWS_ENDPOINT_URL
# Get connection details
aws rds describe-db-instances \
--db-instance-identifier mypostgres \
--query 'DBInstances[0].Endpoint' \
--endpoint-url $AWS_ENDPOINT_URL
# Connect with psql (use the port returned above)
psql -h localhost -p 7001 -U admin
# Create a MySQL instance
aws rds create-db-instance \
--db-instance-identifier mymysql \
--db-instance-class db.t3.micro \
--engine mysql \
--master-username root \
--master-user-password secret123 \
--allocated-storage 20 \
--endpoint-url $AWS_ENDPOINT_URL
# Connect with mysql client
mysql -h 127.0.0.1 -P 7002 -u root -psecret123
Supported Engines
| Engine | Default image |
|---|---|
postgres |
postgres:16-alpine |
mysql |
mysql:8.0 |
mariadb |
mariadb:11 |
Override the image per-instance with the --engine-version flag or globally via environment variables.
Option Groups
Option groups are metadata: Floci stores the options you add, returns them on the wire, and attaches a group to a DB instance, but it does not install the underlying engine feature in the container.
As on AWS, every engine has an implicit default:<engine>-<major version> group that
DescribeOptionGroups returns even when you have created none. Floci ships the defaults for the
engines it can run (postgres 13–18, mysql 8.0/8.4, mariadb 10.11/11.2/11.4), so an
instance created without --option-group-name reports the matching default. Default groups can't
be modified, deleted, or tagged.
CreateOptionGroup accepts any EngineName AWS accepts — including oracle-*, sqlserver-*,
and db2-* — so a Terraform aws_db_option_group for an engine Floci cannot start still applies.
Attaching one to a DB instance requires the group's engine and major engine version to match the
instance, as on AWS: a mysql 8.0 group can't be attached to a mysql 8.4 instance. A mismatch
fails with InvalidParameterCombination.
aws rds create-option-group \
--option-group-name my-og \
--engine-name mysql \
--major-engine-version 8.0 \
--option-group-description "MySQL options" \
--endpoint-url $AWS_ENDPOINT_URL
aws rds modify-option-group \
--option-group-name my-og \
--options OptionName=MEMCACHED,Port=11211 \
--apply-immediately \
--endpoint-url $AWS_ENDPOINT_URL
aws rds describe-option-groups \
--engine-name mysql \
--endpoint-url $AWS_ENDPOINT_URL
Deleting a group that is still attached to a DB instance fails with
InvalidOptionGroupStateFault, matching AWS.
Known gaps, all deliberate:
| Behavior | Status |
|---|---|
CopyOptionGroup, DescribeOptionGroupOptions |
Not implemented — separate actions, not part of option group CRUD |
OptionGroupQuotaExceededFault (AWS caps an account at 20 groups) |
Not enforced — capping a local emulator would only get in a test's way |
OptionSetting metadata (DataType, ApplyType, AllowedValues, DefaultValue, Description) |
Omitted — it would require the per-engine option catalog DescribeOptionGroupOptions serves |
MaxRecords / Marker pagination |
Every group is returned in one page, as with every other RDS list action |
Persistence
Each DB instance and cluster gets its own named Docker volume (floci-rds-{volumeId}) created
automatically. No configuration is required.
| Scenario | Volume behavior |
|---|---|
memory mode (default) |
Volume is removed automatically when the instance is deleted |
persistent / hybrid / wal |
Volume is retained after delete — data survives for manual recovery |
# CI — ephemeral, volumes cleaned up on each delete
FLOCI_STORAGE_MODE=memory
# Local dev — retain DB data across Floci restarts
FLOCI_STORAGE_MODE=hybrid
# Local dev — also remove volumes immediately on delete
FLOCI_STORAGE_MODE=hybrid
FLOCI_STORAGE_PRUNE_VOLUMES_ON_DELETE=true
To use a host bind mount instead of a named volume (advanced), set an absolute path:
Docker Desktop on macOS
Named volumes work correctly on Docker Desktop for macOS. Bind mounts to paths inside the Floci container are not supported — use named volumes (the default).
Authentication
The RDS auth proxy validates the master username and password at the proxy layer. All other database users are passed through directly to the backend engine — create them with standard SQL (CREATE USER) and connect as normal.
IAM database authentication is also supported. Set --enable-iam-database-authentication at instance creation time and use aws rds generate-db-auth-token to obtain a token.