Appwrite on AWS User Guide
Overview
Appwrite is an open source backend as a service platform — a self-hosted Firebase alternative that gives developers a complete backend out of the box: user authentication with many login methods, a hosted database with per-document permissions, file storage, serverless functions, messaging and realtime subscriptions, all behind a clean REST, GraphQL and Realtime API and a polished web Console. The cloudimg image installs Appwrite as the official self-host Docker Compose stack and runs it as a systemd service, so a complete backend is online within minutes of launch.
What is included:
- Appwrite (BSD-3-Clause) deployed from the official self-host Docker Compose stack, pinned so the image never silently upgrades at build time
- Docker Engine (Docker CE) + the Docker Compose plugin, installed from the official Docker package repository
- The Appwrite Compose stack: the
appwriteAPI container, the Console SPA, the realtime websocket service and the full set of worker containers (audits, webhooks, deletes, databases, builds, certificates, functions, mails, messaging, migrations, maintenance and scheduler, a headless browser and the OpenRuntimes executor), withappwrite-mongodbas the database andappwrite-redisfor the cache, queues and pub/sub - The bundled Traefik reverse proxy (
appwrite-traefik) publishing the Console and the API on port 80 (and 443) - All stateful data — the MongoDB database, the Redis data and every uploaded file and storage volume — on a dedicated data volume mounted at
/var/lib/appwrite(Docker's data-root is relocated there), independently resizable - A per instance Console root account (email + a generated password) created at first boot, with Console registration locked to that account
- Two systemd units:
appwrite.service(a oneshot wrapper arounddocker compose up -d) andappwrite-firstboot.service - 24/7 cloudimg support
Prerequisites
An Amazon Web Services account where you can launch EC2 instances, an EC2 key pair in the target Region, and a VPC + subnet. m5.xlarge (4 vCPU / 16 GiB RAM) is the recommended starting size — comfortable for the ~25-container Appwrite stack. Security group inbound rules: allow 22/tcp from your management CIDR for SSH and 80/tcp from the CIDR that needs the Appwrite Console and API (add 443/tcp if you enable HTTPS).
Step 1: 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 Appwrite by cloudimg. Select the cloudimg listing and choose Select, then Continue on the subscription summary. Pick m5.xlarge or larger, choose your EC2 key pair, and under Network settings select a security group that allows inbound ports 22 and 80 as described above. Select Launch instance. First boot initialisation rotates every secret and creates the Console root account; allow a few minutes after the instance is running.
You can launch from the AWS CLI instead:
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.xlarge \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=appwrite-01}]'
Step 2: Connect over SSH
Replace <instance-ip> with the public IP of your instance. The SSH login user depends on the operating system of the AMI variant you launched:
| AMI variant | SSH login user |
|---|---|
| Appwrite on Ubuntu 24.04 | ubuntu |
ssh -i <path-to-key>.pem ubuntu@<instance-ip>
Step 3: Confirm the services are active
sudo systemctl is-active docker.service appwrite.service
docker --version
docker compose version
You should see active printed twice, the Docker Engine version, and the Docker Compose v2 plugin version.

Step 4: Confirm the Appwrite containers are running
sudo docker ps --format "table {{.Names}}\t{{.Status}}"
You should see the core containers — appwrite, appwrite-traefik, appwrite-mongodb and appwrite-redis — along with the Appwrite worker containers, all in the Up / healthy state.

Step 5: Confirm the data volume is mounted
All stateful Appwrite data lives on a dedicated data volume mounted at /var/lib/appwrite.
findmnt /var/lib/appwrite
df -h /var/lib/appwrite
findmnt shows the device backing /var/lib/appwrite and df confirms the dedicated volume.

Step 6: Check the Appwrite health endpoint
The Appwrite health endpoint is served unauthenticated through the bundled reverse proxy on port 80 and returns the running version.
curl -s http://localhost/v1/health/version
A JSON document with the Appwrite version confirms the API is up.
Step 7: Read the per instance Console credentials
A unique Console root email and password are generated for your instance on its first boot and written to a root-only file. Console registration is locked to this root account — it is the only login until you invite more users from the Console.
sudo cat /root/appwrite-credentials.txt
This file lists appwrite.url (where to sign in), appwrite.admin.email, appwrite.admin.pass and the appwrite.endpoint you point the SDKs at. Store the password somewhere safe.

Step 8: Sign in to the Appwrite Console
Browse to http://<instance-ip>/ and sign in with the appwrite.admin.email and appwrite.admin.pass from Step 7. The Console and the API are served on port 80 by the bundled reverse proxy.

After signing in you land on the projects overview. Create your first Appwrite project to start building.

Step 9: Build your backend in the Console
Inside a project you can model your data in the database (collections with attributes, indexes and per-document permissions), manage users and teams in Auth, store and serve files in Storage, write serverless functions, and subscribe to realtime events.

The project settings and API keys view is where you retrieve the project id and create the API keys your applications use.

Step 10: Connect the Appwrite SDKs
Point the Appwrite client and server SDKs at http://<instance-ip>/v1, using the project id and an API key created in the Console. For example, with the Node.js server SDK:
const { Client } = require("node-appwrite");
const client = new Client()
.setEndpoint("http://<instance-ip>/v1")
.setProject("<your-project-id>")
.setKey("<your-api-key>");
The same endpoint serves the REST, GraphQL and Realtime APIs.
Step 11: Manage the stack
The whole stack is managed by the appwrite.service systemd unit, which wraps docker compose under /opt/appwrite.
sudo systemctl restart appwrite.service
sudo systemctl status appwrite.service --no-pager
To inspect logs for a specific container:
cd /opt/appwrite && sudo docker compose logs --tail 50 appwrite
Enabling HTTPS on your own domain
The image serves plain HTTP on port 80 out of the box. To serve the Console and the API over HTTPS on your own domain, point an A record at the instance public IP, then set _APP_DOMAIN, _APP_CONSOLE_HOSTNAMES and _APP_OPTIONS_FORCE_HTTPS=enabled in /opt/appwrite/.env and restart appwrite.service. Appwrite's bundled Traefik then requests and renews a Let's Encrypt certificate automatically. Add 443/tcp to your security group inbound rules.
First-boot security model
On the first boot of each instance, appwrite-firstboot.service runs once and:
- Rotates every per instance secret in the stack — the API encryption key (
_APP_OPENSSL_KEY_V1), the OpenRuntimes executor secret, and the MongoDB and Redis passwords - Resolves the instance public IP via the EC2 Instance Metadata Service (IMDSv2) and points the request-host allowlist (
_APP_DOMAIN/_APP_CONSOLE_HOSTNAMES) at it, so the Console and API are reachable by IP - Recreates the Compose stack on a fresh, empty database and creates a fresh Console root account with a generated password, locking Console registration to it
- Writes the credentials to
/root/appwrite-credentials.txt(root-only, mode 0600)
No shared or default secret and no preexisting login ship in the image.
Support
24/7 technical support is included. Contact cloudimg at support@cloudimg.co.uk for help with deployment, projects and API keys, authentication providers, the database and permissions model, storage, serverless functions, messaging, realtime, TLS and backups.
Appwrite is a trademark of Appwrite, Inc. MongoDB is a trademark of MongoDB, Inc. Redis is a trademark of Redis Ltd. All other product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.