How To: Install CouchDB on Fly.io

Published: 
Last updated: 

Table of contents

Intro

As Fly.io let's you run Dockerfiles, it's usually not a problem to deploy almost anything on their Edge-Network. When I tried CouchDB a couple of days ago, the Docker part was as straightforward as it can be, just had to figure out how to configure my fly app correctly so I could access it. So here I wanna share what was needed to get it running.

For now I'm just talking about running a single-node instance.

Initializing the App

If you don't need a custom Dockerfile, fly lets you just deploy existing images from Docker Hub. As I understand it defaults to Docker Hub, but providing a FQDN (fully qualified domain name), you should be able to launch/deploy Docker images from anywhere.
So in this case, as I just wanted to try out CouchDB I just ran the following command, (with flyctl installed).

fly launch --image apache/couchdb

which, after answering a few questions:

  1. App Name (leave blank to use an auto-generated name) - left it blank
  2. Select region - (gru)
  3. Would you like to setup a Postgresql database now? - (No)
  4. Would you like to deploy now? - (No, as I need to tweak the config first)

created a fly.toml file for me.

# fly.toml file generated for autogenerated-appname-1234 on 2022-05-10T11:32:36-05:00

app = "autogenerated-appname-1234"

kill_signal = "SIGINT"
kill_timeout = 5
processes = []

[build]
  image = "apache/couchdb"

[env]

[experimental]
  allowed_public_ports = []
  auto_rollback = true

[[services]]
  http_checks = []
  internal_port = 8080
  processes = ["app"]
  protocol = "tcp"
  script_checks = []

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"

This is the standard config, which listens internally on port 8080, so the app within the container should listen on that port, which CouchDB doesn't, and Fly normally only makes your app available on ports 80 for http and 443 for TLS/https, which isn't sufficient in this case.

Luckily Fly is pretty flexible so we can adjust to our needs.

CouchDB expects port 5984, so I changed internal_port and also added an additional services.ports. It might be possible to remove ports 80 and 443 though I didn't came to actually test that, I think without further configuration the deployment would fail as fly uses those ports for healthchecks.

We also want to create a volume, so CouchDB can store its data and survive app re-deploys. The following will create a volume in São Paulo, Brazil (gru is the airport identifier) with a size of 1 GB.

Make sure that the volume's region matches your app's region!

fly volumes create couchdbdata --region gru --size 1

couchdbdata is the volume's name, you can change that to your hearts desire, it's not too relevant, we just need it to connect it with our app, via the fly.tomls mounts key.

Uh and also CouchDB complained, that it won't auto-generate an admin user anymore, so we have to define 2 environment variables, which is best done via Fly Secrets, especially for sensitive information like in this case:

flyctl secrets set COUCHDB_USER="ADMIN_USER_NAME" COUCHDB_PASSWORD="YOUR_STRONG_ADMIN_PASSWORD"

Final fly.toml configuration file

# fly.toml file generated for autogenerated-appname-1234 on 2022-05-10T11:32:36-05:00

app = "autogenerated-appname-1234"

kill_signal = "SIGINT"
kill_timeout = 5
processes = []

[build]
  image = "apache/couchdb"

[experimental]
  allowed_public_ports = []
  auto_rollback = true

[mounts]
  source="couchdbdata"
  destination="/opt/couchbase/var"

[[services]]
  http_checks = []
  internal_port = 5984
  processes = ["app"]
  protocol = "tcp"
  script_checks = []

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 5984

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"

Note the highlighted lines in the code block above (lines 9-10, 16-18, 22, 41-43) to see what has changed.

You can make the changes, or just copy the whole block into your fly.toml, ideally from line 5 to keep your app name.

That's it for now, thanks for reading. And feel free to get in touch via Twitter.

Resources

https://docs.couchdb.org/en/stable/install/docker.html
https://docs.couchdb.org/en/stable/setup/single-node.html
https://docs.couchdb.org/en/stable/setup/cluster.html

Can Rau
Can Rau

Doing web-development since around 2000, building my digital garden with a mix of back-to-the-roots-use-the-platform and modern edge-rendered-client-side-magic tech 📻🚀

Living and working in Cusco, Perú 🦙