Installing Central on DigitalOcean

If you'd like to set up an ODK server that's accessible from anywhere via the Internet, DigitalOcean provides a one-click configuration that's nicely geared with nearly all the tools you'll need to set up your new server. The only thing it doesn't do is register a domain name, which you will have to do in order to obtain a security certificate for your server.


If you have not already created a DigitalOcean account, use our referral link.

DigitalOcean will give you $200 of credit to spend during the first 60 days so that you can try things out. Once you have spent $25 with them, we’ll get $25 to put towards our hosting costs.

In general, this installation process will involve five phases:

  1. Getting a server and loading it with the appropriate base system.

  2. Getting a web address (domain name) and pointing it at your new server.

  3. Getting the Central software and installing it on your server.

  4. Preparing Central for startup and running it for the first time.

  5. Creating your first Central Administrator account and logging into it.

There are also some optional other steps you can take, which you can find at the bottom of this page.

Getting a Server

In this phase, you will create a new server on DigitalOcean, choose a pricing tier, configure it with the correct base operating system, and start it up.

If you haven't already, create an account on DigitalOcean. Then, from the DigitalOcean control panel, use the Create button at the top to create a new Droplet. This is their name for a server you can access and manage.


At the very top, under Choose an image, switch to the Marketplace tab and select the Docker option. The version does not matter.


As you continue down this page, there are a few options that may be important to you:

  • There is a section for standard droplets and another for more expensive optimized droplets. In general, you should not need optimized droplets.

  • The size option affects a few things, but the most important is the amount of memory available to your server. Memory does not affect storage space, it sets the amount of "thinking room" the server gets while it's working on things. If you don't expect many forms to be submitted at once and you don't expect many large media attachments, you can start with 1 GB. Higher-load servers and servers which handle many image or video attachments may need 2 GB or more. It is pretty easy to upgrade to a larger size later.


    If you choose a 1 GB server we strongly recommend you add swap.

  • The datacenter region selects where physically your server will be located. If you have security concerns, this is your chance to decide which country hosts your data. Otherwise, generally selecting the option with closest geographic proximity to your users is a good idea.

  • If you are technically savvy and understand what an SSH key is, there is a field here that you will want to fill in. If not, don't worry about it.

Once you click on Create, you'll be taken back to the Droplet management page. It may think for a moment, and then your new server should appear. Next to it will be an IP address, which should look something like This is where your server is publicly located on the Internet. Don't worry, nobody can do anything with it until you let them.

Congratulations! With those steps, you have now created a new server which you can access over the Internet, and started it up. Next, we will get a web domain name address (like to point at it.

Getting a Web Address (Domain Name)


To self-host Central, you must have a domain name (e.g., mapped to your server. For security reasons, Central will not work with just an IP address (e.g.,

Now is the time to set up a domain name. We will do so, and then configure it so that it sends users to the server you created in the previous step.

You'll need to do this for two reasons: a memorable name (like will be easier to remember and access than a pile of numbers, and you cannot get a security certificate without one. It is not currently possible to host Central within a subdirectory on another domain (so, is not possible, but is allowed, as is

If you already know how to do these sorts of things, feel free to ignore the following instructions and proceed on your own. You can rejoin us at the next section.

For the rest of us, there are some options here:

  • You can pay one of the many popular commercial domain registrars for a full domain name, like Search for "domain registrar" to find one of these. These often cost as little as $3/year.

  • You can use a free DNS service: we recommend FreeDNS, which has run for a long time and has a good reputation. With it, you can get a free name, albeit with a fixed second half (like If you choose this route, we recommend using one of the less popular names, as the heavily occupied names can run into trouble later on (in particular, getting a security certificate from Let's Encrypt).

Whichever option you choose, once you get a domain name you'll want to look at DigitalOcean's guide on setting up domain names for your Droplet. In general, you'll point your domain name in DigitalOcean's direction at your registrar, then in DigitalOcean itself you'll want to create an A record that points to the IP address we found above.

New domain names take a little bit to get working. Meanwhile, we can get working on installing the server software.

Installing Central

In this phase of installation, we will log into your new server, get the Central software, load some settings into it, and install it.

First, you'll need to be able to log into the server itself. If you are an advanced user who filled in an SSH key above, you're good to go. Otherwise, click your email for a message from DigitalOcean with your server password.

Once you have that password in hand, you'll be able to use the Launch Console button to log into your server: when it asks for login, type root and press Enter. Then type the password you were emailed and press Enter again.


Once you are in your server, you'll want to change your password so that people snooping your email do not gain access. You should be automatically asked for a new password the first time you log in. If you are not, type passwd and press Enter, then follow the instructions to choose a new password. From now on, you will use that password to log in.

Changing Server Settings

  1. Make sure you are running Docker Engine v23.x and Docker Compose v2.16.x or greater.

$ docker --version && docker compose version

If you are using old versions, follow the instructions to install Docker Engine (not Desktop) for Ubuntu, the operating system we recommend and support. The instructions will help you setup the Docker apt repository and install the latest version of Docker Engine and Docker Compose.

  1. Modify the system firewall for web form features in Central to work correctly (using Enketo).

$ ufw disable

You should see the message Firewall stopped and disabled on system startup. If so, you have configured the firewall correctly.

For advanced administrators

While it sounds dangerous, disabling your system firewall does not put your server at greater risk. In fact, most Linux operating systems come with the system firewall disabled.

If you don't want to disable the firewall entirely, you can instead configure Docker, iptables, and ufw yourself. This can be difficult to do correctly, so we don't recommend most people try. Another option is to use an upstream network firewall.

The goal here is to ensure that it is possible to access the host through its external IP from within each Docker container. In particular, if you can successfully curl your Central website over HTTPS on its public domain name, all Enketo features should work correctly.

Getting and Setting Up Central

  1. Download the software. In the server window, type:

    $ git clone

    and press Enter. It should think for some time and download many things.

  2. Go into the new central folder:

    $ cd central
  3. Get the latest client and server:

    $ git submodule update -i
  4. Update settings. First, copy the settings template file so you can edit it:

    $ cp .env.template .env
  5. Launch the nano text editing application and specify required settings:

    $ nano .env
    • Change the DOMAIN line so that after the = is the domain name you registered above. As an example: Do not include http:// or https:// in the domain.

    • Change the SYSADMIN_EMAIL line so that after the = is your own email address. The Let's Encrypt service will use this address only to notify you if something is wrong with your security certificate.

    • Leave the rest of the settings alone. If you have a custom security or network environment you are trying to integrate Central into, see the advanced configuration sections for more information on these options.

    • Hold Ctrl and press x to quit the text editor. Press y to indicate that you want to save the file, and then press Enter to confirm the file name. Do not change the file name.

  6. Let the system know that you want the latest version of the database:

    $ touch ./files/allow-postgres14-upgrade

    This is mostly useful for upgrades but is also currently necessary for fresh installs.

  7. Bundle everything together into a server. This will take a long time and generate quite a lot of text output. Don't worry if it seems to pause without saying anything for a while.

    $ docker compose build

    When it finishes, you should see some "Successfully built" type text and get your input prompt back.

Congratulations! You have installed your copy of Central. Next, we need to teach the server how to start it up, and do so.

Starting up Central

  1. Start the server software. The first time you start it, it will take a while to set itself up.

    $ docker compose up -d
  2. See whether ODK has finished loading.

    $ docker compose ps

    Under the Status column, for the central-nginx-1 row, you will want to see text that reads Up or Up (healthy). If you see Up (health: starting), give it a few minutes. If you see some other text, something has gone wrong.

  3. Visit your domain name in a web browser. If it's not accessible yet, you should continue waiting. Once it is accessible, check that you get the Central website.

You're almost done! All you have to do is create an Administrator account so that you can log into Central.

Logging into Central

If visiting your server domain name address in your browser does not load the Central website, you may have to wait a few minutes or hours (possibly even a day) for the domain name itself to get working. These instructions are explained in further depth on the page detailing the Central Command Line Tools.

Once you do see it working, you'll want to set up your first Administrator account. To do this:

  1. Ensure that you are in the central folder on your server. If you have not closed your console session from earlier, you should be fine. If you have just logged back into it:

    $ cd central
  2. Create a new account. Make sure to substitute the email address that you want to use for this account.

    $ docker compose exec service odk-cmd --email user-create

    Press Enter, and you will be asked for a password for this new account.

  3. Make the new account an administrator.

    $ docker compose exec service odk-cmd --email user-promote

    If you ever lose track of your password, you can reset it with

    $ docker compose exec service odk-cmd --email user-set-password
  4. Log into the Central website. Go to your domain name and enter in your new credentials. Once you have one administrator account, you do not have to go through this process again for future accounts: you can log into the website with your new account, and directly create new users.


We strongly recommend using a custom mail server to ensure password reset emails are delivered reliably. Learn more at troubleshooting emails.

Setting Up Backups

The next step is setting up automated system backups. We strongly recommend you have backups because they provide a safety net if something goes wrong.

You can find instructions for setting up backups in DigitalOcean's backups guide.

Note that Central has its own backups system that you can configure in addition to full system backups. Central's built-in backups are particularly helpful if you wish to backup your data via API.

Setting Up Monitoring

The last thing you will want to do is to set up server monitoring. Alerts and monitoring are important because they can inform you of problems with your server before they affect your data collection project.

You can find instructions for setting up alerts in the DigitalOcean's monitoring guide.

We strongly recommend creating an alert for Disk Utilization. A threshold of 90% is usually reasonable. By far the most common operations issue we see is servers running out of disk space as large media attachments pile up. If your server runs entirely out of disk space, it can crash and become unresponsive. It is best to upgrade your storage plan before this happens.

If you are familiar with server operations, you may wish to set up some other alerts: CPU usage and Memory Utilization are the most interesting remaining metrics. However, these are not as important or easily understandable as the Disk Utilization alert, so you may skip this if you're not sure what to do here.

You're done! Congratulations. In the future, you may wish to consult the Upgrading Central guide, but for now you may begin using Central. The Using ODK Central sections can help you with your next steps if you aren't sure how to proceed.

Advanced Configuration Options

The following sections each detail a particular customization you can make to your server setup. Most installations should not need to perform these tasks, and some of them assume some advanced working knowledge on administering Linux web servers. If you aren't sure what something means, the best option is probably to skip the section completely.

Adding Swap


We recommend monitoring memory usage to see how much memory your server is using.

If you are having issues with Central running out of memory, we strongly recommend adding physical memory. If you cannot add physical memory, adding swap can be an effective workaround against temporary memory spikes.

  1. To add 2 GB swap, log into your server's console and run these commands.

    $ fallocate -l 2G /swap
    $ dd if=/dev/zero of=/swap bs=1k count=2048k
    $ chmod 600 /swap
    $ mkswap /swap
    $ swapon /swap
  2. Make sure swap is only used when the server is almost out of memory.

    $ sysctl -w vm.swappiness=10
  3. Edit /etc/sysctl.conf and add the following to the end of the file to ensure that change is permanently available.

    $ nano /etc/sysctl.conf
  4. Edit /etc/fstab and add the following to the end of the file to ensure that the swap file is permanently available.

    $ nano /etc/fstab
    /swap swap swap defaults 0 0
  5. Finally, increase memory allocation so Central can use the swap you've added.

Adding External Storage

Forms with many large media attachments can fill up your droplet's storage space. To move your Central install to external storage, follow these steps:

  1. Add a new volume to your droplet.

  2. Find the location of your new volume. It will look like /mnt/your-volume-name.

    $ df -h | grep /mnt/
  3. Create a docker folder at that location.

    $ sudo mkdir /mnt/your-volume-name/docker
  4. Move the Docker data directory to the new volume. Use /mnt/your-volume-name/docker as the data-root path.

Increasing Memory Allocation

During upgrades or exports, some versions of Central may use more memory than the 2 GB typically available to the Central service. If you run into this problem, increase the memory allocated to the Central service.

  1. Ensure you have more than 2 GB of physical memory in your server. If you have less, add more physical memory.


    If you can't add more physical memory, add swap. This will result in slower performance than adding physical memory but can be acceptable if it is only needed for occasional exports or upgrades.

  2. Edit .env to add a SERVICE_NODE_OPTIONS variable with a --max-old-space-size flag set to your desired maximum memory in MB.

    $ cd central
    $ nano .env


    Choose a memory size that leaves enough memory for your server's operating system and any other applications. 3072 MB is a good starting point for a machine with 4 GB of RAM.

  3. Build and restart the service container.

    $ docker compose build service && docker compose stop service && docker compose up -d service

If an upgrade was the cause of the memory error, you may revert these changes after the upgrade and build and restart the service container.

Using a Custom SSL Certificate

Central uses Let's Encrypt SSL certificates to secure all communication. To use custom certificates:

  1. Generate a fullchain.pem (-out) file which contains your certificate followed by any necessary intermediate certificate(s).

  2. Generate a privkey.pem (-keyout) file which contains the private key used to sign your certificate.

  3. Copy those files into files/local/customssl/.

    $ cp fullchain.pem central/files/local/customssl/
    $ cp privkey.pem central/files/local/customssl/
  4. In .env, set SSL_TYPE to customssl and set DOMAIN to the domain name you registered.

    $ cd central
    $ nano .env


    Do not include http:// or https:// in the domain.

  5. Build and restart the nginx container.

    $ docker compose build nginx && docker compose stop nginx && docker compose up -d nginx

Using a Custom Mail Server


We recommend using a dedicated email service such as Mailjet for your custom mail server. Follow the dedicated service's instructions for enabling DKIM and SPF to ensure your messages are delivered.

Central comes with a mail server to send password reset emails. To use a custom mail server:

  1. Edit .env with your mail server host, port, and authentication details.

    $ cd central
    $ nano .env


    EMAIL_FROM is the address the email should come from. It's sometimes known as the sender address.

    EMAIL_IGNORE_TLS should generally be set to false. EMAIL_SECURE should be set to true if you use port 465 and set to false for other ports.

    EMAIL_USER and EMAIL_PASSWORD are both required.

  2. Build and restart the service container.

    $ docker compose build service && docker compose stop service && docker compose up -d service

Using a Custom Database Server


Using PostgreSQL 14 isn't strictly required, but we only test with and support PostgreSQL 14.

Using a custom database server that is not on your local network, may result in poor performance.

Central comes with a PostgreSQL v14.x database server to store your data. To use a custom PostgreSQL database server:

  1. Connect to your database server.

    $ psql -h mydbhost -p 5432 -U mydbadmin
  2. Ensure your database server uses the UTF8 encoding.

  3. Create the database user and database.

    CREATE USER mydbuser WITH PASSWORD 'mydbpassword';
  4. Ensure CITEXT and pg_trgm extensions exist on mydbname.

  5. Edit .env with your database server host, database name, and authentication details.

    $ cd central
    $ nano .env
  6. Build and restart the service container.

    $ docker compose build service && docker compose stop service && docker compose up -d service

Configuring Upstream SSL


We have not extensively tested this configuration and it is subject to change. Use at your own risk.

You may wish to run Central behind a reverse proxy or load balancer. In order to do that, you must disable Central's native SSL support in favor for the upstream SSL provider.

  1. Edit .env file to change your SSL type and HTTP/S ports. HTTP_PORT and HTTPS_PORT are the ports exposed on your host and UPSTREAM_HTTPS_PORT is the user-facing upstream HTTPS port.

    $ cd central
    $ nano .env
  1. Edit docker-compose.yml to add UPSTREAM_HTTPS_PORT to the service and enketo configurations.

    $ nano docker-compose.yml
  2. Build and restart all containers.

    $ docker compose build && docker compose stop && docker compose up -d

Configuring DKIM


Do not follow these instructions if you are using a custom mail server.

DKIM is a protocol which is used to help verify mail server identities. Without it, your sent mail is likely to be flagged as spam.

  1. Ensure that your server's name in DigitalOcean matches your full domain name, and that the hostname does as well. If you had to make changes for this step, restart the server to ensure they take effect.

  2. Generate a public and private key (if one doesn't already exist).

    $ cd central
    $ ! test -s files/mail/rsa.private && openssl genrsa -out files/mail/rsa.private 1024
    $ openssl rsa -in files/mail/rsa.private -out files/mail/rsa.public -pubout -outform PEM
  3. Ensure any changes to the DKIM private key are kept private.

    $ git update-index --skip-worktree files/mail/rsa.private
  4. Copy the contents of the public key with the boundary dashes removed.

    $ cat files/mail/rsa.public | grep -v "^-"
  5. Create four new DNS records in these locations:

    1. dkim._domainkey.DOMAIN-NAME-HERE: create a TXT record with the following content. Be sure to remove any newlines or line breaks.

      k=rsa; p=PUBLIC-KEY-HERE
    2. _dmarc.DOMAIN-NAME-HERE: create a TXT record with the following content.

      v=DMARC1; p=none
    3. DOMAIN-NAME-HERE: create a TXT record with the following content. Get the server IP address from the DigitalOcean control panel.

      v=spf1 a mx ip4:SERVER-IP-ADDRESS-HERE -all
    4. DOMAIN-NAME-HERE: create a MX record with the following content.

  6. Build and restart the mail container.

    $ docker compose build mail && docker compose stop mail && docker compose up -d mail

Enabling Single Sign-on

By default, users log into Central using an email address and password. However, if Single Sign-on (SSO) is enabled, then Central will no longer manage users' passwords and will instead forward users to a separate login server. This can be a convenient option if all of your users already have accounts on a service like Google Workspace or Azure Active Directory. Under this setup, the login server is called the "identity provider." If SSO is enabled, the identity provider will manage users' passwords, not Central.

Using a separate identity provider can allow you to enforce stricter security requirements than Central does. For example, Central requires that new passwords are at least 10 characters, but it does not require other password characteristics, such as the presence of certain symbols. However, if SSO is enabled in Central, and if the identity provider is configured to require specific password characteristics, then users will need to fulfill those requirements in order to log into Central. As another example, on its own, Central does not support multi-factor authentication (MFA). However, if SSO is enabled, and if the identity provider is configured to require MFA, then users will need to complete multi-factor authentication before logging into Central.

Central is compatible with any identity provider that uses the OpenID Connect (OIDC) protocol and is configured to require user email addresses. When SSO is enabled in Central, Central does not manage passwords, but it still identifies users using their email address. Central assumes that the identity provider verifies email addresses, requiring users to prove ownership of the email address they specify. If that is not the case, then do not enable SSO in Central.


If you configure an identity provider that does not require email proof of ownership, it will be possible for users to impersonate each other. This could lead to users gaining access to Central resources that they are not intended to access.


Enabling SSO currently disables API access. This means you won't be able to use PowerBI, Excel, ruODK, pyODK or other such tools to directly access data on your server. You'll need to export CSVs instead.

To enable SSO in Central, you will first need to configure your identity provider. You will then need to configure Central to provide information from your identity provider, specifically the issuer URL, client ID, and client secret.

  1. Follow your identity provider's documentation on configuring a new OIDC application (for example: Google, Azure, onelogin, Auth0). When prompted to specify a redirect or callback URL, provide the following (replace my-domain with your actual domain):

  2. In .env, set OIDC_ENABLED to true. Set OIDC_ISSUER_URL to the issuer URL that you obtained from your identity provider, OIDC_CLIENT_ID to the client ID, and OIDC_CLIENT_SECRET to the client secret.

    $ cd central
    $ nano .env
  3. Build and restart all containers.

    $ docker compose build && docker compose stop && docker compose up -d

Two Accounts: Central and the Identity Provider

When you enable SSO, users will use their account on the identity provider to log into Central. However, users will still have a Central account that is separate from their account on the identity provider. A Central account is not automatically created for each account on the identity provider. Instead, a Central Administrator will need to create a Central account for each user of the identity provider who should be allowed to log into Central.

Central users will be able to change their display name shown in Central and to choose a different name from what is shown in the identity provider. However, because Central identifies users by their email address, most users will not be allowed to change their email address. Only a Central Administrator will be able to change the email address associated with a Central account. That will be necessary if a user's email address changes in the identity provider. In that case, an Administrator will need to manually change the user's email address in Central to match their new address in the identity provider.

If a Central Administrator changes their own email address to one that does not match the identity provider, they may lose access to Central. If they are the only Administrator, they will need to use the command line to create a new Central Administrator that they do have access to.

Logout is not centralized, which means that when a user logs out of Central, that will not log them out of the identity provider. Conversely, when a user logs out of the identity provider, that will not log them out of Central. If a user logs out of Central, then goes to log back in, they may find that login is nearly instantaneous if they are still logged into the identity provider. That is, they may find that they are not required to log into the identity provider again in order to log into Central.

Enabling SSO in an Existing Installation

It is possible to enable SSO for an existing Central installation, even if the installation has existing users. Because Central identifies users by their email address, the address associated with each Central account must match the address of the corresponding account on the identity provider. If the email address does not match, the user will not be able to log in.

Enabling SSO will not log out users who are already logged in. Users who are already logged into Central will not be required to log into the identity provider until they are logged out of Central.

Disabling SSO

It is possible to disable SSO by following the steps below. If there were users before SSO was enabled (if SSO was disabled, then enabled, then disabled again), users will be able to log into Central using their same password from before SSO was enabled. You can reset users' passwords after disabling SSO.

To disable SSO:


    $ cd central
    $ nano .env
  2. Build and restart all containers.

    $ docker compose build && docker compose stop && docker compose up -d

Customizing Enketo


Customizing Enketo may break Central in subtle and unexpected ways. Do not make changes if you do not understand the implications of those changes.

Enketo is the software that Central uses to render forms in a web browser. It is used for form previews, web browser submission, and submission editing. Common customizations include enabling geocoding, adding analytics, and setting a default theme.

  1. Read the Enketo configuration tutorial and default-config.json to understand what is possible.

  2. Edit the file files/enketo/config.json.template with your desired changes.

    $ cd central
    $ nano files/enketo/config.json.template
  3. Build and restart all containers.

    $ docker compose build && docker compose stop && docker compose up -d

Disabling or Customizing Sentry

By default, we enable Sentry error logging in Central's service container, which provides the Central team with an anonymized log of unexpected errors that occur while your server is running.

This information is only visible to the development team and should never contain any of your user or form data, but if you feel uncomfortable with this, you can disable Sentry:

  1. Edit the file files/service/config.json.template and remove the sentry lines, starting with "sentry": { through the next three lines until you remove the matching }.

    $ cd central
    $ nano files/service/config.json.template
    "env": {
      "domain": "https://${DOMAIN}:${HTTPS_PORT}",
      "sysadminAccount": "${SYSADMIN_EMAIL}"
    "external": {
  2. Edit the file files/nginx/odk.conf.template and replace the csp-report lines, starting with location /csp-report { through the next two lines until you remove the matching } with:

    $ nano files/service/config.json.template
    location /csp-report {
      return 200 'CSP report discarded.';
      add_header Content-Type text/plain;
  3. Build and restart all containers.

    $ docker compose build && docker compose stop && docker compose up -d

If you wish to use your own Sentry instance to receive your own errors, take these steps:

  1. Create an account on Sentry, and create a new nodejs project.

  2. The new project will generate a DSN in this format:

  3. In .env, set SENTRY_SUBDOMAIN, SENTRY_KEY and SENTRY_PROJECT to the values from step 2.

    $ cd central
    $ nano .env
  4. Build and restart all containers.

    $ docker compose build && docker compose stop && docker compose up -d

Did this page help you?

Selecting an option will open a 1-question survey

👍 Yes 👎 No