Sequin
Overview
This guide covers deploying and configuring Sequin on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images.
Sequin is the open source change data capture platform for PostgreSQL. It attaches to a logical replication slot, reads your database's write-ahead log, and turns every insert, update and delete into a durable, ordered stream of change events. Sequin delivers the events to the destination of your choice. Instead of writing triggers, polling tables or building a bespoke outbox, you point Sequin at a database and a sink. Sequin handles replication, ordering, batching, retries, backfills and delivery observability.
The SecureAnyCloud image ships the free and open source, MIT-licensed Sequin server, run the officially supported way as the upstream container pinned by image digest. It runs alongside a bundled PostgreSQL 16 started with wal_level=logical and a bundled Redis 7. All three images are pinned by digest and captured into the VM, so your instance starts in seconds without pulling anything.
A CDC platform holds credentials for your production databases, so nothing ships with a known secret. Upstream Sequin's default admin@sequinstream.com login and open self-signup are both disabled. A unique console credential, admin password, Management API token, database password, Redis password and TLS certificate are generated for each VM on first boot, before anything is reachable.
Sequin is a trademark of its respective owner. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by Sequin Labs, Inc. It ships the free and open source, MIT-licensed, self-hosted software, unmodified.
What you get:
- Sequin v0.14.6 (the MIT-licensed Sequin change data capture server and web console), pinned by image digest
- A bundled PostgreSQL 16 started with
wal_level=logical, pinned by image digest, reachable only inside a private Docker network (never published to a host port) - A bundled Redis 7 queue and cache, pinned by image digest, password protected and reachable only inside the private Docker network
- Docker Engine with the Sequin application published to the loopback interface only, fronted by nginx with TLS on port
443 sequin.service,sequin-firstboot.service,sequin-postboot.serviceandnginx.serviceas systemd units, enabled and active on boot- A unique console credential, admin password, Management API token, PostgreSQL password, Redis password and self-signed TLS certificate generated per VM on first boot, never baked into the image
- Upstream Sequin's default user and open self-signup both disabled, so there is no known login to change
- A working demo change data capture pipeline out of the box, so you can see real captured changes within seconds of first boot
- A clean, empty database on first boot: no default login, no shipped secret, no prior data
- Ubuntu 24.04 LTS base with latest security patches applied at build time
- Azure Linux Agent for seamless cloud integration and SSH key injection
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
- A subscription to the Sequin listing on Azure Marketplace
Recommended virtual machine size: Standard_D2s_v3 (2 vCPU, 8 GB RAM). Sequin runs on the Erlang virtual machine, and this image co-locates the server, PostgreSQL and Redis on one host. 8 GB is the sensible production starting point.
Standard_B2s (2 vCPU, 4 GB) works for evaluation and light workloads. For higher throughput or large backfills, use Standard_D4s_v3 or larger.
Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 443/tcp for the console and Management API from the networks that use them.
Deploy from the Azure Portal
Sign in to the Azure portal, choose Create a resource, search the Marketplace for Sequin by SecureAnyCloud, and select Create.
On Basics, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTPS (443).
Choose Review + create, then Create.
Deploy from the Azure CLI
RG="sequin-prod"; LOCATION="eastus"; VM_NAME="sequin-01" IMAGE_URN="sac1647283583153:sequin-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name sequin-vnet --address-prefix 10.100.0.0/16 --subnet-name sequin-subnet --subnet-prefix 10.100.1.0/24 az network nsg create -g "$RG" --name sequin-nsg az network nsg rule create -g "$RG" --nsg-name sequin-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name sequin-nsg --name allow-https --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 443 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:sequin-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--size Standard_D2s_v3 --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name sequin-vnet --subnet sequin-subnet --nsg sequin-nsg --public-ip-sku StandardConnect to your VM
ssh azureuser@<vm-ip>Confirm the services are running
The stack runs as three containers (Sequin, PostgreSQL and Redis) under one sequin.service, fronted by nginx. Confirm that the services are active, list the containers, and check which ports are bound.
nginx listens on :80 (which redirects to HTTPS) and :443. The Sequin application is published to 127.0.0.1:7376 (loopback only), and PostgreSQL and Redis have no host port at all:
sudo systemctl is-active docker sequin nginx
sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml ps
sudo ss -tln | grep -E ':80 |:443 |:7376'All three services report active, and the three containers are running. nginx is bound on :80 and :443, and the Sequin application is bound only on 127.0.0.1:7376.
PostgreSQL (5432) and Redis (6379) never appear on a host port, because they are reachable only inside the private Docker network. This is deliberate: the only way in from the network is the authenticated nginx front door.
Read the per instance credentials
First boot generated a unique console credential, admin password, Management API token, database password and Redis password for this VM, before anything was reachable. It wrote them to a root-only file. Read the file:
sudo cat /root/sequin-credentials.txtThe file (mode 0600 root:root) holds CONSOLE_USER and CONSOLE_PASSWORD (the nginx credential that gates the web console), ADMIN_EMAIL and ADMIN_PASSWORD (Sequin's own login), the API_TOKEN you authenticate the Management API with, POSTGRES_PASSWORD, REDIS_PASSWORD, and SEQUIN_URL (the address to reach this VM on). None of these values ship in the image. Every value is unique to this VM, so no two instances share a credential and there is no default login to change.
Verify the security model
The health endpoint is public so that load balancers can probe it. The console requires the per-instance nginx credential, and the Management API requires the per-instance bearer token. Confirm all three behaviors:
SEQUIN_TOKEN=$(sudo grep '^API_TOKEN=' /root/sequin-credentials.txt | cut -d= -f2-)
SEQUIN_USER=$(sudo grep '^CONSOLE_USER=' /root/sequin-credentials.txt | cut -d= -f2-)
SEQUIN_PASS=$(sudo grep '^CONSOLE_PASSWORD=' /root/sequin-credentials.txt | cut -d= -f2-)
curl -sk -o /dev/null -w 'health (no auth): %{http_code}\n' https://localhost/health
curl -sk -o /dev/null -w 'console (no credential): %{http_code}\n' https://localhost/
curl -sk -o /dev/null -w 'console (per VM cred): %{http_code}\n' -u "$SEQUIN_USER:$SEQUIN_PASS" https://localhost/
curl -sk -o /dev/null -w 'API (no token): %{http_code}\n' https://localhost/api/sinks
curl -sk -o /dev/null -w 'API (per VM token): %{http_code}\n' -H "Authorization: Bearer $SEQUIN_TOKEN" https://localhost/api/sinksThe health check returns 200 with no authentication. The console returns 401 with no credential and 302 (a redirect to the Sequin login) once the per-instance credential is supplied, so reaching the login page at all requires a secret. The Management API returns 401 with no token and 200 with the per-instance token.
The Management API is not behind the nginx credential. HTTP Basic authentication and bearer tokens both use the Authorization header, so a client cannot present both at once. Sequin's own per-instance API token gates the API instead. Every path is authenticated by a per-instance secret except /health.
Open the web console
Browse to https://<vm-ip>/. Your browser warns about the self-signed certificate that first boot generated for this VM. Accept it, or replace the certificate with your own as described in Step 11.
You are prompted twice, by design. First, the nginx front door asks for CONSOLE_USER and CONSOLE_PASSWORD. Then Sequin's own login page asks for ADMIN_EMAIL and ADMIN_PASSWORD. Both pairs come from /root/sequin-credentials.txt.
After you sign in, the Sinks page opens. The image ships a working demo pipeline called demo-redis-stream, already Healthy and reading from the bundled demo-source database:
The Databases page shows the bundled PostgreSQL registered as a change data capture source, with its logical replication slot and publication:
Watch real changes being captured
The image ships a demo source database, sequin_demo, whose public.records table is published to the replication slot and streamed to the Redis stream sequin.records. Write a row and watch it arrive:
sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml exec -T sequin_postgres \
psql -U sequin -d sequin_demo -c "insert into public.records (name) values ('order-4711');" sleep 8
REDIS_PASS=$(sudo grep '^REDIS_PASSWORD=' /root/sequin-credentials.txt | cut -d= -f2-) sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml exec -T sequin_redis \
redis-cli --no-auth-warning -a "$REDIS_PASS" XREVRANGE sequin.records + - COUNT 1The Redis stream entry contains the full change event: the record (your new row), the action (insert), the changes (for updates, the previous values) and metadata identifying the sink, database and table. That is the point of Sequin: your row change became a durable, ordered message in a stream, with no trigger and no polling.
Now check that the pipeline filters rather than forwarding everything. public.ignored_records exists in the same database but is deliberately not in the publication, so writes to it never reach the sink:
REDIS_PASS=$(sudo grep '^REDIS_PASSWORD=' /root/sequin-credentials.txt | cut -d= -f2-)
BEFORE=$(sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml exec -T sequin_redis \
redis-cli --no-auth-warning -a "$REDIS_PASS" XLEN sequin.records | tr -d '[:space:]')
sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml exec -T sequin_postgres \
psql -U sequin -d sequin_demo -c "insert into public.ignored_records (name) values ('never-streamed');" sleep 10
AFTER=$(sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml exec -T sequin_redis \
redis-cli --no-auth-warning -a "$REDIS_PASS" XLEN sequin.records | tr -d '[:space:]')
echo "stream length before=$BEFORE after=$AFTER (unpublished writes are correctly not delivered)"The stream length is unchanged, because Sequin correctly did not deliver the write to the unpublished table.
The console shows the same result. Open the sink and its Messages tab to see the delivered change events, throughput and health:
Query the Management API
Everything in the console is also available over the Management API, authenticated with the per-instance bearer token. List the configured sinks and databases:
SEQUIN_TOKEN=$(sudo grep '^API_TOKEN=' /root/sequin-credentials.txt | cut -d= -f2-)
curl -sk -H "Authorization: Bearer $SEQUIN_TOKEN" https://localhost/api/sinks | head -c 400; echo
curl -sk -H "Authorization: Bearer $SEQUIN_TOKEN" https://localhost/api/postgres_databases | head -c 400; echoUse the same token from your own machine by replacing localhost with your VM address, for example https://<vm-ip>/api/sinks. Treat the token as a production secret: it grants full control of every pipeline on this instance.
Connect your own database
The demo pipeline makes the image useful immediately, but the real workflow is to point Sequin at your own PostgreSQL. Sequin requires the source database to have wal_level = logical, plus a replication slot and a publication.
On your own database, run the following as a superuser. This is a template, not something to run on this VM:
ALTER SYSTEM SET wal_level = logical; -- restart PostgreSQL for wal_level to take effect CREATE PUBLICATION sequin_pub FOR TABLE public.orders, public.customers; SELECT pg_create_logical_replication_slot('sequin_slot', 'pgoutput');In the console, choose Databases, then Connect Database. Supply the host, port, database, user and password along with the slot and publication names.
Once the database is connected, choose Sinks, then Create Sink. Pick a destination: Kafka, SQS, SNS, Kinesis, NATS, RabbitMQ, Redis Streams, GCP Pub/Sub, Azure Event Hubs, Elasticsearch, Typesense, Meilisearch, an HTTP webhook, or Sequin's own pull API. Then select the tables and actions to stream. You can also run an initial backfill so that the sink starts from the current contents of the table rather than only future changes.
You can also declare pipelines as configuration. Sequin reads a YAML document describing accounts, databases and sinks, which is how this image provisions its own demo pipeline:
databases: - name: "production" hostname: "db.internal" port: 5432 database: "app" username: "sequin" password: "..." slot: name: "sequin_slot" publication: name: "sequin_pub" sinks: - name: "orders-to-kafka" database: "production" source: include_tables: - "public.orders" actions: [insert, update, delete] destination: type: "kafka" hosts: "kafka.internal:9092" topic: "orders"Use your own certificate and domain (production)
The image generates a self-signed TLS certificate for the VM's own IP on first boot, so the console is encrypted from the first request with no configuration. For production, point a DNS name at the VM and install a real certificate.
Replace /etc/sequin/tls/sequin.crt and /etc/sequin/tls/sequin.key with your certificate and private key (keep the key 0600 root:root), then reload nginx.
Also set SERVER_HOST in /etc/sequin/sequin.env to your DNS name so that the console generates correct absolute links, and restart the stack.
You can rotate the console credential at any time with htpasswd -B /etc/sequin/console.htpasswd SecureAnyCloud. Change the Sequin admin password from the console under account settings.
Server components
The image contains these components:
Sequin: v0.14.6, upstream container pinned by digest, published to 127.0.0.1:7376.
PostgreSQL: version 16 (alpine), pinned by digest, wal_level=logical, private Docker network only.
Redis: version 7 (alpine), pinned by digest, password protected, private Docker network only.
Front door: nginx, TLS on 443, port 80 redirects, per-VM bcrypt credential on the console.
Config: /etc/sequin/compose.yaml, with per-VM secrets in /etc/sequin/sequin.env (0600).
Credentials: /root/sequin-credentials.txt (0600 root:root).
Data: Docker named volumes sequin_pgdata and sequin_redisdata.
Licence: MIT.
Managing the Sequin service
sudo systemctl status sequin --no-pager | head -20 sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml ps
sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml logs --tail 20 sequinUse sudo systemctl restart sequin to restart the whole stack (the unit runs docker compose up -d --wait), and sudo systemctl stop sequin to bring it down.
The named volumes persist across restarts, so your pipelines, connected databases and replication progress survive.
Security recommendations
- Restrict
443/tcpin the NSG to the networks that genuinely need the console and Management API, and22/tcpto your management network only - Replace the self-signed certificate with a certificate for a real DNS name (Step 11)
- Treat
/root/sequin-credentials.txtas a production secret. Copy the values into your secret manager and consider removing the file afterwards - Rotate the Management API token from the console if it is ever shared, and rotate the console credential with
htpasswd - Give Sequin a dedicated PostgreSQL role on each source database with
REPLICATIONand read access to the published tables only, never a superuser - Keep the VM patched. Unattended security upgrades are enabled on this image
Support and Licensing
Sequin is licensed under the MIT License. This image bundles the unmodified upstream software and is produced by SecureAnyCloud, which is not affiliated with or endorsed by Sequin Labs, Inc.
Deploy on Azure
Find Sequin on Ubuntu 24.04 LTS by SecureAnyCloud on the Azure Marketplace.
Need Help?
SecureAnyCloud provides 24/7 support for this image. Contact us at secureanycloud.com.
Deploy on Azure
Launch Sequin on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
This image runs Sequin, the open source change data capture platform for PostgreSQL. Sequin reads a database's write-ahead log through a logical replication slot and turns every insert, update and delete into an ordered stream of change events. It delivers the events to the destination of your choice.
Because Sequin reads the replication log rather than polling tables, it captures every change without adding query load to the source database and without requiring application code to publish events. Change events can be delivered to Kafka, Amazon SQS, Amazon SNS, Amazon Kinesis, NATS, RabbitMQ, Redis Streams, GCP Pub/Sub, Azure Event Hubs, Elasticsearch, Typesense, Meilisearch, HTTP webhooks, and a pull-based API.
The image runs three pinned upstream containers on a private container network:
The Sequin server is an Elixir application built on the Phoenix framework, and it serves the web console. A PostgreSQL instance holds both Sequin's own metadata and the bundled demonstration source database. A Redis instance provides Sequin's queue and also acts as the demonstration sink destination.
Neither datastore is published to a host port. The Sequin console binds to 127.0.0.1:7376 and is reached only through an nginx front door that terminates TLS on port 443.
Rather than handing you an empty console, this image ships a complete working pipeline. First boot creates a demonstration source database with a captured table, a publication and a pre-created logical replication slot. A sink streams every insert, update and delete from that table into a Redis stream. You can write a row and read the captured change event back within seconds, then follow the same pattern to point Sequin at your own database.
Every secret is generated on the first boot of each deployed instance, so two instances launched from the same Amazon Machine Image never share a credential. Upstream Sequin provisions a well-known default administrator and allows open self-registration. This image disables both.
Prerequisites
Before you deploy this image, make sure you have:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network and port 443 for the Sequin web console
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Sequin. Select the SecureAnyCloud listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet, and create or select a security group that opens port 22 from your management network and port 443 for the web console.
Leave the root volume at the default size or larger. The image also attaches a dedicated data volume, described in Step 8.
Select Launch instance. First boot takes a few minutes after the instance state becomes Running and the status checks pass. During that time the image generates its secrets, creates the demonstration source database and starts the change data capture pipeline.
Launch the Instance from the AWS CLI
This command launches an instance from the SecureAnyCloud Sequin Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22 and 443, as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=sequin}]'When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.
Connect to Your Instance
Connect over SSH using your key pair. On Ubuntu 24.04, the login user is ubuntu.
ssh -i /path/to/your-key.pem ubuntu@<public-ip>Confirm the Stack Is Running
Four services make up the appliance. Docker runs the three pinned containers, a first-boot service generates the per-instance secrets, the Sequin service brings the containers up, and nginx terminates TLS in front of the console.
systemctl is-active docker.service sequin.service nginx.serviceEach line should read active. The unauthenticated health endpoint confirms that the Sequin server is answering through the nginx front door. It is deliberately open so that a load balancer can probe it without a credential.
curl -sk -o /dev/null -w 'health endpoint: HTTP %{http_code}\n' -m 20 https://127.0.0.1/healthConfirm the listening ports. The console is published on 443 and port 80 redirects to it. The Sequin application port 7376 is bound to the loopback interface only, so it is not reachable from outside the instance.
ss -tln | grep -E ':(80|443|7376) ' | sortThe bundled PostgreSQL and Redis are on the private container network and are deliberately not published to any host port. You can confirm this by their absence from that list.
Retrieve Your Per Instance Credentials
First boot generates every credential on your instance and writes them to a root-only file. Read the file:
sudo cat /root/sequin-credentials.txtThe file contains the console URL, an HTTP Basic credential that gates the console at the nginx layer, the Sequin administrator login, a management API token, and the passwords for the bundled datastores. To confirm which keys are present without revealing any values:
sudo awk -F= '/^[A-Z_]+=/ {print $1}' /root/sequin-credentials.txt | sortThe console is protected by two independent credentials: the HTTP Basic credential enforced by nginx, and then Sequin's own login. Both are unique to your instance.
Sign In to the Web Console
Browse to https://<public-ip>/. The image generates a self-signed TLS certificate on first boot that carries your instance's own address. Your browser warns once about the certificate. Accept it to continue, or install your own certificate as described in Step 10.
Your browser first prompts for the HTTP Basic credential. Enter CONSOLE_USER and CONSOLE_PASSWORD from the credentials file. The Sequin sign-in page then appears. Sign in with ADMIN_EMAIL and ADMIN_PASSWORD from the same file.
After you sign in, the Sinks view opens. The bundled demonstration pipeline, demo-redis-stream, is already running and reporting healthy against the demo-source database.
Watch Real Change Events Being Captured
Select the demo-redis-stream sink to open its overview. Sequin runs six health checks covering the replication slot, the source connection and the sink destination, and reports how many messages it has processed, how many are pending and how many are failing.
The Messages tab lists the individual change events Sequin has captured and delivered, with the source table, the primary key of the changed row, the delivery count and the commit time.
The Databases view shows the connected PostgreSQL source, its health, and how many sink consumers are reading from it.
You can verify the whole path end to end from the shell. The image ships a verifier that writes a uniquely marked row into the demonstration source table and waits for that exact change to arrive at the sink. It repeats the exercise for an update, then writes to a table that is deliberately excluded from the publication to confirm that the write is not forwarded. The verifier uses the per-instance credentials without ever printing them.
sudo /usr/local/sbin/sequin-roundtrip.shThe negative control matters: it shows that the pipeline filters on the PostgreSQL publication rather than forwarding every write in the database.
You can also inspect the replication slot directly. A slot whose active column is t means that Sequin currently holds a walsender streaming changes from the source.
sudo docker compose --env-file /etc/sequin/sequin.env -f /etc/sequin/compose.yaml exec -T sequin_postgres psql -qtAX -U sequin -d sequin_demo -c "select slot_name, plugin, active from pg_replication_slots;"The Dedicated Data Volume
Docker's data root at /var/lib/docker is a separate EBS volume, mounted by filesystem identifier so that it survives reboots and reattachment reliably. Every container image layer, the PostgreSQL data directory and write-ahead log, the replication slot state and the Redis append-only file live on it.
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/lib/dockerBecause capture state is on its own disk, you can grow it independently of the root volume. Modify the EBS volume in the EC2 console, then extend the filesystem on the instance with resize2fs. The fstab entry uses the filesystem UUID, so no change is needed after resizing.
Connect Sequin to Your Own Database
The demonstration pipeline shows the shape of a working setup. The next step is to point Sequin at your own PostgreSQL database. Your source database must have wal_level set to logical, and Sequin needs a role with the REPLICATION attribute.
On your source database, create a publication covering the tables you want captured, and a logical replication slot for Sequin to read from:
CREATE PUBLICATION my_publication FOR TABLE public.orders, public.customers; SELECT pg_create_logical_replication_slot('my_slot', 'pgoutput');Setting REPLICA IDENTITY FULL on a captured table makes update and delete events carry the complete previous row, which downstream consumers usually want:
ALTER TABLE public.orders REPLICA IDENTITY FULL;In the console, choose Databases, then Connect Database. Supply the host, port, database name, and the credentials for your replication role, along with the slot and publication names you created.
Once the database reports healthy, choose Sinks, then Create Sink. Pick your destination type, select the tables and the actions (insert, update, delete) you want forwarded, and supply the destination's connection details.
If your source database is Amazon RDS or Aurora PostgreSQL, set the rds.logical_replication parameter to 1 in the parameter group and reboot the instance before creating the slot. Make sure that the instance's security group allows Sequin to reach the database port.
You can also configure Sequin declaratively in YAML and apply the configuration with its CLI. The image uses this approach to provision the demonstration pipeline. The upstream configuration reference documents the full schema.
Use Your Own TLS Certificate
The image generates a self-signed certificate on first boot so that the console is never served in plain text. For production, replace it with a certificate issued for a hostname you control.
Place the certificate and private key on the instance, point /etc/nginx/sites-available/sequin at them by editing the ssl_certificate and ssl_certificate_key directives, validate the configuration with sudo nginx -t, and reload nginx.
If you terminate TLS at an Application Load Balancer instead, forward to port 443 on the instance and restrict the security group to the load balancer.
The Management API
Sequin exposes a management API authenticated by the bearer token stored as API_TOKEN in your credentials file. It is exempt from the nginx HTTP Basic layer, because HTTP Basic and bearer authentication both use the Authorization header and cannot coexist on one path. Sequin authenticates the API itself and rejects an absent or incorrect token.
curl -k -H "Authorization: Bearer <your-api-token>" https://<public-ip>/api/sinksThe round-trip verifier in Step 7 already proves that this path works on your instance, including that a wrong token is rejected.
Backup and Maintenance
The state that matters is Sequin's own metadata database, which holds your database connections, sinks and pipeline definitions. It lives in a Docker named volume on the dedicated data disk.
The most straightforward backup is an EBS snapshot of that data volume, which you can schedule with Amazon Data Lifecycle Manager. For a logical backup, run pg_dump against the sequin database inside the PostgreSQL container.
A logical replication slot retains write-ahead log segments on the source database until the consumer reads them. If Sequin is stopped for a long period while its slot still exists, WAL accumulates on your source database. Monitor replication lag on your source, and drop slots you no longer need.
To review recent service activity:
sudo journalctl -u sequin.service --no-pager --since '30 min ago' | tail -n 20Apply operating system updates with apt. After a reboot the stack restarts automatically, because the containers are configured to restart and the systemd units are enabled.
Troubleshooting
The browser warns about the certificate. This is expected on first use, because the certificate is self-signed and generated for your instance's address on first boot. Accept it, or install your own certificate as in Step 10.
The console asks for a password twice. This is by design. The first prompt is the nginx HTTP Basic credential (CONSOLE_USER and CONSOLE_PASSWORD). The second is Sequin's own sign-in page (ADMIN_EMAIL and ADMIN_PASSWORD). Both are in the credentials file.
A sink shows as unhealthy. Open the sink and read its health checks, which identify the failing component. The most common causes are an unreachable destination, wrong destination credentials, or a replication slot that was dropped on the source.
Change events are not arriving. Confirm that the source table is included in the publication, and that the replication slot shows active as t in the query in Step 7. A slot that exists but is never active usually means that Sequin cannot authenticate to the source database, or that the source role lacks the REPLICATION attribute.
First boot appears to take a long time. The first boot runs database migrations against a brand new database and starts three containers. Allow a few minutes after the status checks pass before the console answers.
Support
SecureAnyCloud publishes this image and provides 24/7 technical support by email and chat, covering deployment, connecting Sequin to your own PostgreSQL database, configuring sinks and destinations, replication slot and publication management, TLS termination and upgrades.
Sequin is open source software licensed under the MIT License. SecureAnyCloud is not affiliated with or endorsed by Sequin Labs, Inc. The Sequin name is used nominatively to identify the software shipped in this image. All product and company names are trademarks or registered trademarks of their respective holders.
Deploy on AWS
Launch Sequin on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com