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 $100 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 1GB. Higher-load servers and servers which handle many image or video attachments may need 2GB or more. It is pretty easy to upgrade to a larger size later.


    If you choose a 1GB 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)#

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
  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 that way.


If you find that users are not receiving emails, read about troubleshooting emails.

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

$ docker compose exec service odk-cmd --email user-set-password

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 2GB 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

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 2GB 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 2GB 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. 3072MB is a good starting point for a machine with 4GB of RAM.

  3. Build and restart the service container.

    $ docker compose build 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 your own certs:

  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 up -d nginx

Using a Custom Mail Server#

Central comes with an mail server to send password reset emails. To use your own mail server:

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

    $ cd central
    $ nano .env


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

    If no authentication is required, remove the EMAIL_USER and EMAIL_PASSWORD lines.

  2. Build and restart the service container.

    $ docker compose build 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 your own 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 up -d service

Configuring DKIM#


Users are not receiving emails? Read troubleshooting emails before configuring DKIM.

DKIM is a security trust protocol which is used to help verify mail server identities. Without it, your sent mail is likely to be flagged as spam. If you intend to use a custom mail server, these instructions will not be relevant to you. Otherwise:

  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. Ensure there are no directories where you'll be placing the DKIM files.

    $ cd central
    $ rm -rf files/dkim/rsa.private
  3. Generate a public and private key and enable the DKIM configuration

    $ cd files/dkim
    $ openssl genrsa -out rsa.private 1024
    $ openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
    $ cp config.disabled config
  4. With the contents of the public key (cat rsa.public), you'll want to create two new TXT DNS records:

    1. At the location dkim._domainkey.DOMAIN-NAME-HERE, create a new TXT record with the contents k=rsa; p=PUBLIC-KEY-HERE. You only want the text between the dashed boundaries, and you'll want to be sure to remove any line breaks, so that it's all only letters, numbers, +, and /.

    2. At your domain name location, create a new TXT record with the contents. Get the server IP address from the DigitalOcean control panel.

      v=spf1 a mx ip4:SERVER-IP-ADDRESS-HERE -all
  5. Build and restart the mail container.

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

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 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 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 up -d