Apicurio Registry on AWS User Guide
Overview
This image runs Apicurio Registry, the open source runtime registry and datastore for API definitions and event schemas. Apicurio Registry stores and serves Avro, Protobuf, JSON Schema, OpenAPI, AsyncAPI, GraphQL and WSDL/XSD artifacts through a REST API, a Confluent compatible Schema Registry API and a web UI, so producers and consumers across your event streaming and API estate can share a single source of truth for their contracts.
The registry backend is the official Apicurio Registry 3.2.6 Quarkus application, run under a headless OpenJDK 21 runtime as a dedicated unprivileged apicurio system account under a systemd service that starts it on boot and restarts it on failure. Durable storage is a local PostgreSQL database whose data directory lives on a dedicated, independently resizable EBS data volume mounted at /var/lib/postgresql. The official pre built React web UI is served statically by nginx.
This image is secure by default. Apicurio Registry has no built in authentication in this configuration, so exposing it directly would let anyone read, write or delete your schemas. Instead, the registry backend binds to the loopback interface only, and nginx on port 80 is the sole public listener, fronting the whole surface behind an HTTP Basic Auth gate as the admin user. The password is generated on the first boot of every deployed instance, so two instances launched from the same AMI never share a password. It is written to /root/apicurio-credentials.txt with mode 0600 so that only the root user can read it. An unauthenticated /healthz endpoint is provided for load balancer probes, and a set of example schemas is registered on first boot so the UI is immediately populated.

Prerequisites
Before you deploy this image you need:
- 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 allowing inbound port 22 from your management network, port 80 for the web UI and API, and optionally port 443 if you add TLS
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Launching the instance
You can launch this product from the AWS Marketplace console or from the AWS CLI. In the Marketplace console, subscribe to the product, choose Launch through EC2, then select your instance type, VPC, subnet, key pair and security group. A general purpose m5.large instance is a sensible starting point; the registry runs comfortably on any instance with enough memory for the JVM and PostgreSQL, and you can scale up for larger artifact catalogues and higher request rates.
When you configure the security group, allow inbound TCP port 22 from your management network and TCP port 80 from the networks that will reach the web UI and API. The registry backend itself is never exposed directly; nginx on port 80 is the only public listener.
Connecting to your instance
Connect over SSH as the default login user for your operating system variant. The private key is the EC2 key pair you selected at launch.
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i /path/to/your-key.pem ubuntu@<public-ip>
Retrieving the web UI and API password
The HTTP Basic Auth password is unique to each instance and is stored in a root only file. Retrieve it over SSH:
sudo grep '^APICURIO_PASSWORD=' /root/apicurio-credentials.txt
The full credentials file also records the registry URL, the username (admin) and the PostgreSQL database credentials:
sudo cat /root/apicurio-credentials.txt
Verifying the service
The registry, PostgreSQL and nginx are all managed by systemd. Confirm they are active:
systemctl is-active apicurio nginx postgresql
The unauthenticated health endpoint returns ok and is what you point a load balancer or uptime probe at:
curl -fsS http://127.0.0.1/healthz
Using the web UI
Open http://<public-ip>/ in a browser. Your browser will prompt for credentials; sign in as admin with the password from the credentials file. The dashboard shows artifact and version counts, recent artifacts and quick actions. Use Explore to browse groups and artifacts, and Search to find artifacts across the registry.

Selecting an artifact shows its metadata, its versions, and its content. The example user-signup artifact registered on first boot is a JSON Schema you can inspect and download.

The content view renders the stored schema with syntax highlighting and a JSON/YAML toggle.

Using the core REST API
The Apicurio core REST API v3 is served on the same port 80 behind the same Basic Auth gate. List the artifacts in the default group:
PW=$(sudo grep '^APICURIO_PASSWORD=' /root/apicurio-credentials.txt | cut -d= -f2-)
curl -s -u "admin:$PW" http://127.0.0.1/apis/registry/v3/groups/default/artifacts | jq '.artifacts[].artifactId'
Register a new JSON Schema artifact and read its content back to confirm it persisted:
PW=$(sudo grep '^APICURIO_PASSWORD=' /root/apicurio-credentials.txt | cut -d= -f2-)
curl -s -u "admin:$PW" -X POST \
'http://127.0.0.1/apis/registry/v3/groups/default/artifacts?ifExists=FIND_OR_CREATE_VERSION' \
-H 'Content-Type: application/json' \
-d '{"artifactId":"product-updated","artifactType":"JSON","name":"Product Updated Event","firstVersion":{"version":"1.0.0","content":{"content":"{\"type\":\"object\",\"title\":\"ProductUpdated\",\"properties\":{\"sku\":{\"type\":\"string\"}}}","contentType":"application/json"}}}' \
-o /dev/null -w 'register HTTP %{http_code}\n'
curl -s -u "admin:$PW" \
'http://127.0.0.1/apis/registry/v3/groups/default/artifacts/product-updated/versions/branch=latest/content'
From your own workstation, target the instance's public address instead of loopback:
curl -s -u 'admin:<APICURIO_PASSWORD>' http://<public-ip>/apis/registry/v3/groups/default/artifacts
Using the Confluent compatible Schema Registry API
Apicurio Registry implements the API defined by the Confluent Schema Registry, so Kafka producers and consumers using the Confluent serializers work unchanged. Point them at http://<public-ip>/apis/ccompat/v7. List the registered subjects:
PW=$(sudo grep '^APICURIO_PASSWORD=' /root/apicurio-credentials.txt | cut -d= -f2-)
curl -s -u "admin:$PW" http://127.0.0.1/apis/ccompat/v7/subjects
Register an Avro schema under a subject and read it back by its assigned id:
PW=$(sudo grep '^APICURIO_PASSWORD=' /root/apicurio-credentials.txt | cut -d= -f2-)
curl -s -u "admin:$PW" -X POST \
'http://127.0.0.1/apis/ccompat/v7/subjects/orders-value/versions' \
-H 'Content-Type: application/vnd.schemaregistry.v1+json' \
-d '{"schemaType":"AVRO","schema":"{\"type\":\"record\",\"name\":\"Order\",\"fields\":[{\"name\":\"orderId\",\"type\":\"string\"}]}"}'
echo
curl -s -u "admin:$PW" http://127.0.0.1/apis/ccompat/v7/subjects/orders-value/versions
The PostgreSQL data volume
The registry's durable state lives in a local PostgreSQL database whose data directory is on a dedicated EBS volume mounted at /var/lib/postgresql, separate from the operating system disk. This lets you resize or snapshot the schema store independently. Confirm the mount and that the PostgreSQL data directory sits on it:
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/postgresql
sudo -u postgres psql -tAc 'SHOW data_directory'
To resize the store, grow the EBS volume in the AWS console, then extend the filesystem on the instance with resize2fs.
Backup and maintenance
Because all registry state is in PostgreSQL, a logical dump captures every group, artifact and version. Take a backup with pg_dump:
sudo -u postgres pg_dump apicurio | gzip > /var/tmp/apicurio-backup.sql.gz
Store the resulting file off the instance (for example in Amazon S3). You can also take EBS snapshots of the /var/lib/postgresql volume for point in time backups. The operating system is fully patched at build time and continues to receive unattended security updates.
Security notes
- The registry backend listens only on
127.0.0.1; nginx on port 80 is the only public listener and every UI and API path except/healthzrequires authentication. - The Basic Auth password and the PostgreSQL password are both generated per instance on first boot. No shared or default credential ships in the AMI.
- Restrict the security group so that only trusted networks reach port 80, and add TLS termination (port 443) in front of the registry for production use.
- The dedicated data volume can use AWS EBS encryption; enable it when launching the instance or use encrypted snapshots.
Support
This AMI is published by cloudimg with 24/7 technical support included. For deployment help, sizing guidance, PostgreSQL and backup questions, API and authentication configuration, or any issues including requesting refunds, contact support@cloudimg.co.uk.