Appwrite's default setup is designed to help you start building with Appwrite quickly. To succeed with Appwrite in a production environment, you should follow a few basic concepts and best practices. This document assumes you have some basic understanding of Docker and Docker Compose command-line tools.


Appwrite does not generate a unique encryption key during a default setup. This key encrypts your files and sensitive data like webhook passwords or API keys to keep them secure. To take advantage of this feature, you must generate a unique key and set it as the value of the _APP_OPENSSL_KEY_V1 environment variable.

You must set _APP_OPENSSL_KEY_V1 immediately after installation of a production Appwrite instance. Changing the _APP_OPENSSL_KEY_V1 variable will cause the loss of existing passwords, OAuth secrets, and API keys.

Make sure to keep this key in a safe place and never make it publicly accessible.

Best practice

You should always prefer HTTPS over HTTP in production environments. This keeps your APIs secure and prevents any redirects from interfering with your requests. You can force the use of HTTPS with the _APP_OPTIONS_FORCE_HTTPS environment variable.

Console access

Appwrite provides three different methods to limit access to your Appwrite Console.

  1. Whitelist a group of developers by IP using the _APP_CONSOLE_WHITELIST_IPS environment variable.

  2. Whitelist a group of developers by email using the _APP_CONSOLE_WHITELIST_EMAILS environment variable.

  3. Only the root user can signup. All other developers must be added through invitations. This is configured using the _APP_CONSOLE_WHITELIST_ROOT environment variable.

By default, only the first user can sign up on the Appwrite instance's dashboard. All other users must be added to the dashboard through invitation.

Learn more about environment variables


Appwrite is built with scalability in mind. Appwrite can scale both horizontally and vertically.

Each Appwrite instance is composed of many containers, each with its unique job. Appwrite's functions and worker containers are stateless. To scale them, all you need is to replicate them and set up a load balancer to distribute their load.

If you decide to set up a load balancer to scale a container, make sure all communication are routed through the load balancer and not directly to the replicated containers. You can configure communicating between Appwrite containers using Docker environment variables.

Two Appwrite containers are stateful. The MariaDB and Redis containers are used for storing data, cache and pub/sub messaging, and usage stats, respectively. To scale these containers, set up a standard cluster (same as you would with any other app using these technologies) according to your needs and performance.

Rate limits

If you disabled rate limits during development, make sure you re-enable them when moving to production environments. Rate limiting can be enabled by setting the _APP_OPTIONS_ABUSE environment variable to enabled.

Rate limits are an important mechanism to protect your app. Without rate limits, malicious actors can spam your APIs to perform denial-of-service type attacks or brute-force user passwords.

Learn more about environment variables


Sending emails is hard. There are a lot of spam rules and configurations to master in order to set up a functional SMTP server. While it is okay to use a self-hosted SMTP server during development, you should use a third-party SMTP provider for production so your email doesn't get labeled as spam.

You can change Appwrite's SMTP settings and credentials to any 3rd party provider you like that supports SMTP integration using our Docker environment variables. Most SMTP providers offer a decent free tier to get started with.


Backups are highly recommended for any production environment. Currently, there is no built-in script we provide to do this automatically. You must do the following to back up your Appwrite server data, stats, and files.

  1. Create a script to back up and restore the databases holding your Appwrite schemas. Note that trying to back up the database containers using a docker volume backup can result in a corrupted copy of your data. We recommend using the databases' built-in tools for this.

  2. Create a script to back up Appwrite storage volume. There are many online resources explaining different ways to backup a docker volume. When running on multiple servers, it is very recommended to use an attachable storage point. Some cloud providers offer integrated backups to such attachable mount like GCP, AWS, DigitalOcean, and the list continues.

  3. Create a script to back up .env and docker-compose.yml, which holds secrets and server configuration information.

Docker volume backups

Do not back up any stateful container using a docker volume backup, such as databases or Redis containers. This can result in corruption and permanent data loss.


By default, your Appwrite installation comes with error reporting turned off. You can enable dev mode to get access to more verbose error logs and stack traces.

In production, it is highly recommended to turn error reporting off. To do so, make sure the Appwrite container environment variable _APP_ENV value from is set to production and not development.

To monitor errors in production, add a third party monitoring service by setting the _APP_LOGGING_PROVIDER and _APP_LOGGING_CONFIG.

In production, it is highly recommended to turn error reporting off. To do so, make sure the Appwrite container environment variable _APP_ENV is set to production and not development.

Learn more about environment variables


In addition to the security practices mentioned, it is highly recommended to do regular audits to identify and fix potential security vulnerabilities and performance issues. You can use third-party tools and services that specialize in these areas. These tools can automatically check for vulnerabilities and even offer real-time monitoring.

Applying changes

After editing your docker-compose.yml or .env files, you will need to recreate your Appwrite stack by running the following compose command in your terminal.

docker compose up -d

You can verify if the changes have been successfully applied by running this command:

docker compose exec appwrite vars