Skip to main content
Arct Cloud provides the unmanaged Linux VPS for this deployment. Appwrite is not preinstalled or managed by Arct Cloud. You are responsible for application configuration, data, functions, email delivery, security, backups, scaling, and updates.

Choose a Plan

Appwrite’s official installation requirements specify at least 2 CPU cores, 4 GB RAM, 2 GB swap, Docker Compose v2, and a current Docker Engine. Appwrite does not publish a universal disk minimum. It runs many containers and stores database records, uploads, function code, site builds, certificates, and logs. Monitor memory and disk usage, then increase resources or use an external storage backend as the workload grows. These are practical starting points, not performance guarantees.

Before You Begin

Prepare the following:
  • A fresh Ubuntu 24.04 server
  • A dedicated hostname such as appwrite.example.com
  • An A record pointing the hostname to the VPS’s public IPv4 address
  • An email address for TLS certificate notifications
  • Encrypted off-server storage for configuration, database, and volume backups
  • An authenticated SMTP provider if users need verification or password recovery email
This guide uses Appwrite’s current stable 1.9.6 release and the installer’s default MongoDB backend. Check the Appwrite releases before installation and replace the version only after reviewing its release notes.

Install Appwrite

1

Deploy and Connect

2

Prepare DNS and the Firewall

Confirm the hostname resolves to this server:
Allow SSH before enabling UFW, then expose only the public web ports:
Port 20080 is used only by Appwrite’s installation wizard. The command below binds it to server loopback, so do not open it in UFW or an upstream firewall.
3

Install Docker Engine and Compose

Install Docker from Docker’s official Ubuntu repository:
4

Verify Memory and Add Swap

Check that the server has at least 4 GB RAM and 2 GB swap:
On a fresh server with no swap, create the 2 GB swap file required by Appwrite:
Run the swap creation commands only when swapon --show is empty and /swapfile does not already exist.
5

Start the Installer Privately

Create the parent directory, then run Appwrite’s official installer with two deliberate safeguards: an exact image tag and a loopback-only wizard port.
Leave this SSH session open while the installer waits for the web wizard.
The installer controls Docker through /var/run/docker.sock, which is equivalent to root access on the host. Use only Appwrite’s official image with a reviewed release tag.
6

Complete the Private Setup Wizard

From a second terminal on your local computer, open an SSH tunnel:
Open http://127.0.0.1:20080 and complete the wizard:
  1. Enter appwrite.example.com as the hostname.
  2. Keep MongoDB selected unless you have planned a MariaDB deployment and backup strategy.
  3. Configure automatic HTTPS and its notification email.
  4. Generate the application encryption key and save it outside the VPS.
  5. Create the root console account with a unique password.
  6. Review the settings, then start the installation.
The setup wizard remains private for the entire first-account flow. Stop the tunnel with Ctrl+C only after the installer finishes and the root account exists.
7

Rotate Default Service Secrets

Appwrite’s database security guidance requires changing the database credentials before production. The 1.9.6 wizard sets the application encryption key, but its generated configuration retains known defaults for _APP_DB_PASS, _APP_DB_ROOT_PASS, and _APP_EXECUTOR_SECRET. Rotate all three immediately after setup and before creating projects or accepting production data.The following MongoDB-specific maintenance flow creates a root-only recovery set, transfers new values without printing them or placing them in host-side command arguments, changes the database credentials, atomically updates .env, and recreates every service with matching values:
This sequence is only for the MongoDB deployment in this guide. If it stops after changing MongoDB, do not restart the full stack or delete /root/appwrite-rotation.* or /opt/appwrite/.env.rotate.*. Keep the root-only recovery files, determine which credential changes completed, then finish installing the candidate .env or restore on a fresh instance.
Copy .env and the pre-rotation recovery set to encrypted off-server storage. Never regenerate _APP_OPENSSL_KEY_V1 on an existing instance: Appwrite uses it to protect passwords, OAuth secrets, API keys, and other sensitive values.
8

Verify the Deployment

Confirm the containers are healthy, then make the first HTTPS request. Appwrite can initially present a self-signed certificate; the first request triggers certificate issuance. Use --insecure only for that initial probe, wait for the certificate to be issued in the logs, and require the final check to pass normal TLS validation:
Sign in with the root account created in the private wizard, create a test project, and verify that its API endpoint uses https://appwrite.example.com/v1.

Production Security and Operations

Only ports 22, 80, and 443 should normally be public. Port 20080 is temporary and loopback-only. Database, Redis, worker, executor, and Docker API ports must remain private. Before storing production data:
  • Keep _APP_OPENSSL_KEY_V1 unchanged and backed up separately from the database
  • Require the default-secret rotation and non-printing validation above to pass
  • Force HTTPS and confirm no application SDK uses the plain HTTP endpoint
  • Keep console registration restricted to the root user and invite additional developers
  • Use Appwrite’s console IP or email allowlists when the dashboard needs tighter access
  • Keep Appwrite’s abuse protection and rate limits enabled
  • Configure authenticated SMTP and test verification and password-reset delivery
  • Use least-privilege API keys and review function permissions and runtime limits
  • Monitor CPU, RAM, swap, disk, container health, and log growth
Docker-published ports can bypass ordinary UFW forwarding rules. The wizard port is safe here because it is explicitly bound to 127.0.0.1; review every future Compose ports change before applying it.

Back Up and Restore

Self-hosted Appwrite does not provide automatic backups. A complete recovery set includes the database, Appwrite storage volumes, .env, docker-compose.yml, the encryption key, and the exact image versions. For the MongoDB deployment used in this guide, the following maintenance-window example records the configuration, stops Appwrite, creates an official logical database dump, and archives every non-database Compose-managed volume:
Copy the entire timestamped directory to encrypted storage outside the VPS and test it on a separate server. If you select MariaDB in the installer, use Appwrite’s documented mysqldump procedure instead of the MongoDB command. Restore only into a fresh installation running the matching Appwrite and database versions. For this MongoDB path, restore mongodb.archive into the fresh database, then restore the non-database storage archives with the saved configuration and encryption key. Do not also restore a raw MongoDB data volume: logical database restore and raw database-volume restore are alternative recovery methods. Never restore over a live database or delete the current volumes until the replacement instance has passed login, API, upload, function, and project checks.

Update and Migrate Safely

Appwrite updates can change both its Compose project and data schema. Before every update:
  1. Create and verify a complete off-server backup.
  2. Read every intervening release note.
  3. Record the current image tags and keep the existing VPS available.
  4. Test the same upgrade path on a replacement instance.
Run the official upgrade tool from the parent directory, replacing the example variable with an exact release tag:
Leave that command running while it waits for the private upgrade wizard. From a second terminal on your local computer, recreate the SSH tunnel:
Open http://127.0.0.1:20080, review the detected deployment and exact target release, then complete the upgrade wizard. Close the tunnel only after the upgrade command finishes. Patch releases do not always require a data migration. Run the migration command only when the release notes require it:
When crossing minor versions, Appwrite requires upgrading through each minor version’s latest patch. Do not start an older Appwrite image against data that a newer migration has changed. If an update fails, restore the complete pre-update recovery set on a fresh matching-version server instead of attempting an in-place downgrade.

Troubleshooting

Keep the installer terminal running, confirm sudo ss -lntp | grep ':20080' shows a loopback listener, and reconnect the SSH tunnel. Do not change the mapping to 0.0.0.0:20080 as a shortcut.
Confirm the A record points to this VPS, remove an incorrect AAAA record, and verify ports 80 and 443 are reachable. Review the Traefik and Appwrite logs for ACME or hostname errors.
Run free -h, swapon --show, df -h, and sudo docker stats. Appwrite’s many workers and build images can exceed the minimum profile; add memory or storage before increasing worker concurrency.
Configure an authenticated SMTP provider, normally on submission port 587, then test delivery and inspect the worker logs. Do not rely on unauthenticated local mail delivery.
Stop retrying against production data. Inspect the first migration error and the exact release notes, then recover on a separate server from the pre-update database, volumes, configuration, and encryption key.

Official Resources

Appwrite Installation

Official requirements, Docker installer, setup wizard, and manual Compose files.

Production Checklist

Security, scaling, email, monitoring, backups, and update guidance.

Appwrite on GitHub

Source code, releases, security policy, and issue tracker.
Appwrite is developed by Appwrite. Arct Cloud is an independent infrastructure provider and is not affiliated with, sponsored by, or endorsed by Appwrite.