Developer Tools AWS

Dokku PaaS on AWS User Guide

| Product: Dokku PaaS on AWS

Overview

This image ships Dokku on Ubuntu 24.04 LTS, ready to take a git push and build, deploy and route your application the moment the machine boots. Dokku is installed from the project's official apt repository, pinned to a known release, with Docker Engine and nginx preinstalled as the build and routing layer.

Dokku is an open source, self hosted Platform as a Service. It brings the Heroku workflow to a single server you own: you push your application with git and Dokku builds it, using Cloud Native or Heroku buildpacks, a Dockerfile or a prebuilt image, runs it as a container, and publishes it behind an nginx reverse proxy on its own hostname. A single command line manages the whole lifecycle: apps, environment variables, databases and services through plugins, scaling, domains, TLS and logs.

What this appliance does and does not do

Read this section before you deploy. It is the difference between an appliance that does what you think it does and one that quietly does not.

What Dokku is good at. Dokku gives one server the ergonomics of a managed platform. Push code and it builds and deploys it, maps a hostname, and keeps it running, with a clean CLI for config, scaling, logs, databases and TLS. It is ideal for side projects, internal tools, review and staging environments, and small production workloads where you want push to deploy simplicity without a managed platform bill.

What Dokku is not. Dokku is a single node PaaS. This image does not include, and Dokku itself is not:

  • a multi node cluster or an orchestrator: it runs apps on this one server, it does not schedule across a fleet,
  • a web control panel: Dokku is managed entirely from the command line and over SSH,
  • a managed database service: it provisions databases as local containers through plugins, which you operate yourself,
  • a hosted platform with an account and a billing plan: everything runs on infrastructure you own and administer.

What makes this image different

It is honest about having no credential. Dokku's access model is SSH public keys added to the dokku user for git push deploys. There is no password, no web login and no default account. This image ships with no deploy key baked in at all, so nothing usable is embedded in it: you add your own key on first use, and only your key can deploy. The Docker daemon listens only on its local unix socket, never over unauthenticated TCP, so it cannot be driven off box.

Docker and nginx are preinstalled and proven. The container runtime and the reverse proxy are installed, enabled and health checked during the build, and the whole app lifecycle is proven end to end before the image is sealed by actually deploying a container and serving it over HTTP. What you boot is a working PaaS, not a set of packages you still have to wire together.

Docker storage is on its own disk. Docker's entire storage root at /var/lib/docker is a dedicated, independently resizable EBS data volume, so every built image, container and buildpack cache lives on its own disk rather than the OS root. You can grow it without touching the operating system disk.

Routing is configured for you on first boot. On the first boot of every instance, a first boot service resolves the instance's public address and sets Dokku's global application domain to <public-ip>.nip.io, so your first deployed app gets a working hostname with no DNS to configure. You can point your own domain at it whenever you like.

The base stays patched. The Ubuntu base is fully updated at build time and keeps receiving security updates through the normal unattended-upgrades path for the life of the release.

1. Launch the instance from the AWS Marketplace

Sign in to the AWS Management Console, open EC2, and choose Launch instance. Under Application and OS Images select AWS Marketplace AMIs, search for Dokku, and select the cloudimg listing. The defaults in this guide assume:

  • Instance type: m5.large runs the appliance and image based deploys comfortably. If you build large applications from source with buildpacks, size up so the build step has RAM headroom.
  • Inbound ports: SSH (22) for deploying and managing, and HTTP (80) plus HTTPS (443) for your applications' traffic. Restrict port 22 to your own management network, and open 80/443 as wide as your apps need.
  • Authentication: your own EC2 key pair for the ubuntu administrator.

Connecting to your instance

Connect over SSH as the login user for your operating system variant:

OS variant SSH login user
Ubuntu 24.04 ubuntu

2. Connect and read the connection info

Replace <public-ip> with your instance's public IP address:

ssh ubuntu@<public-ip>

Every instance writes its own connection details on first boot. Read them:

sudo cat /root/dokku-info.txt

This shows the global application domain set for this instance, the git remote pattern for pushing apps, and the exact commands to add your SSH key. Nothing in this file is a secret: the appliance ships with no credential, so this is connection information, not a password.

3. Confirm Dokku, Docker and nginx are healthy

dokku version
docker info --format 'Docker {{.ServerVersion}}, {{.Containers}} containers, storage {{.Driver}}'
systemctl is-active docker.service nginx.service
sudo test -f /var/lib/cloudimg/dokku-firstboot.done && echo "firstboot sentinel present"
findmnt /var/lib/docker -o TARGET,SOURCE,FSTYPE,SIZE

You should see the pinned Dokku version, a healthy Docker engine, both docker and nginx reported active, the first boot sentinel present, and /var/lib/docker mounted on its own dedicated volume. That is the whole platform confirmed up on one screen.

Dokku, Docker and nginx healthy with the first boot complete and Docker storage on its own volume

4. Add your SSH key so you can deploy

Deploys are authorised by SSH public key. From your workstation, add your public key to Dokku so your git push is accepted. The image ships with no key, so this is the first thing you do:

# On your workstation: send your public key to the server and register it with Dokku.
cat ~/.ssh/id_ed25519.pub | ssh ubuntu@<public-ip> "sudo dokku ssh-keys:add admin"

The key mechanism itself is easy to verify on the machine. This generates a throwaway key, registers it, lists the registered keys, then removes it again, so you can see exactly how ssh-keys:add, ssh-keys:list and ssh-keys:remove behave:

ssh-keygen -q -t ed25519 -N '' -f /tmp/dokku_demo_key <<<y >/dev/null
sudo dokku ssh-keys:add demokey /tmp/dokku_demo_key.pub
sudo dokku ssh-keys:list
sudo dokku ssh-keys:remove demokey
rm -f /tmp/dokku_demo_key /tmp/dokku_demo_key.pub
echo "key add / list / remove all worked"

Each registered key is what lets a matching git push dokku main authenticate as the dokku user and trigger a deploy. A push from a key you have not registered is refused, so no one can deploy without a key you added.

Adding, listing and removing a Dokku deploy SSH key

5. Deploy and serve your first app

The fastest way to see the platform working is to deploy a prebuilt image. This creates an app, deploys a tiny web image with git:from-image, and confirms it is served through nginx on its own hostname:

sudo dokku apps:destroy demo --force 2>/dev/null || true
sudo dokku apps:create demo
sudo dokku git:from-image demo nginxdemos/hello:plain-text
APPURL="$(sudo dokku url demo)"; echo "app URL: ${APPURL}"
HOST="$(echo "${APPURL}" | sed 's#https\?://##')"
for i in $(seq 1 12); do
  CODE="$(curl -s -o /dev/null -w '%{http_code}' -H "Host: ${HOST}" http://127.0.0.1/)"
  [ "${CODE}" = "200" ] && break; sleep 3
done
echo "served HTTP ${CODE} at ${APPURL}"

Dokku pulls the image, starts the container and writes the nginx vhost for demo.<your-domain>. The app answers with HTTP 200 at the URL shown. Because the global domain is a nip.io address derived from your public IP, that hostname already resolves from anywhere once you open port 80.

A first app deployed on Dokku and served through nginx with HTTP 200

6. The git push workflow

The real Dokku workflow is git push. Once your key is registered (section 4), from your application's own git repository on your workstation you add the Dokku remote and push a branch. Dokku detects the language, builds the app with buildpacks or your Dockerfile, and deploys it:

# On your workstation, inside your app's git repository:
git remote add dokku dokku@<public-ip>:myapp
git push dokku main
# Dokku builds and deploys it, then serves it at http://myapp.<your-domain>

You create the app once before the first push (dokku apps:create myapp, on the server or over ssh dokku@<public-ip> apps:create myapp). Every subsequent git push is a new release.

7. Manage apps: config, scaling, logs and plugins

Everything about a running app is managed from the CLI. These are read only reports against the demo app you deployed above:

sudo dokku apps:list
sudo dokku ps:report demo | sed -n '1,8p'
sudo dokku config:show demo 2>/dev/null || echo "(no config vars set yet)"
sudo dokku logs demo --num 10 2>/dev/null | tail -n 10
sudo dokku plugin:list | sed -n '1,10p'

Set configuration and secrets with dokku config:set demo KEY=value, scale process types with dokku ps:scale demo web=2, add a hostname with dokku domains:add demo app.example.com, and attach a database by installing the relevant plugin (for example dokku-postgres) and linking it to the app. The bundled plugins listed above are the core set; official service plugins add databases, caches and more.

Managing a Dokku app: process report, config and plugin list

8. Add your own domain and TLS

To serve an app on your own domain, point a DNS record at the instance's public IP and add the domain to the app, then let Dokku's Let's Encrypt plugin provision a certificate:

# Point app.example.com at this instance, then:
dokku domains:add myapp app.example.com
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku letsencrypt:set myapp email you@example.com
dokku letsencrypt:enable myapp

Dokku obtains and renews the certificate and reconfigures nginx to serve https://app.example.com. Keep port 443 open in your security group.

9. Add a database with a plugin

Dokku's official plugins add managed datastores your app can link to. For example, to add PostgreSQL:

# On the instance:
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git
sudo dokku postgres:create mydb
sudo dokku postgres:link mydb myapp   # injects DATABASE_URL and restarts the app

Redis, MySQL, MongoDB and more are available as the same style of plugin. Their container data lives on the dedicated /var/lib/docker volume alongside your app images.

10. First boot and troubleshooting

First boot is handled by dokku-firstboot.service, which sets this instance's global application domain and writes /root/dokku-info.txt. To inspect it:

systemctl status dokku-firstboot.service --no-pager | sed -n '1,6p'
dokku domains:report --global

If first boot did not complete (for example the machine lost power mid first boot), re-run it:

# Re-run first boot if it did not complete.
sudo rm -f /var/lib/cloudimg/dokku-firstboot.done
sudo systemctl restart dokku-firstboot.service

To change the global domain yourself at any time, run dokku domains:set-global your-domain.com. Existing apps keep their own explicit domains.

11. Licensing

Dokku is licensed under the MIT License, a permissive licence, and is installed unmodified from the project's official apt repository; the MIT licence text is baked into the image at /opt/dokku/LICENSE. Docker Engine (Apache-2.0) and nginx are installed from their respective official repositories. The underlying Ubuntu operating system is installed from Ubuntu's public apt archive and stays patchable through the normal unattended-upgrades path for the life of the release.

Support

Every cloudimg deployment is backed by 24/7 support. If you have any questions about this image, contact us at support@cloudimg.co.uk.