Background Link to heading
I recently setup dokku to host a handful of self-hosted and personal apps. Fast-forward a few months and I can’t remember how to deploy a new app with my setup 😂
For future-self, I’m going to document here how to deploy mealie, which at the time of writing suggests the following docker compose file. This can be adapted for anything that can be deployed with a single Dockefile.
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v2.4.1
container_name: mealie
restart: always
ports:
- "9925:9000"
deploy:
resources:
limits:
memory: 1000M
volumes:
- mealie-data:/app/data/
environment:
# Set Backend ENV Variables Here
ALLOW_SIGNUP: "false"
PUID: 1000
PGID: 1000
TZ: America/Anchorage
BASE_URL: https://mealie.yourdomain.com
volumes:
mealie-data:
Prep dokku Link to heading
Create a new new app in dokku:
dokku apps:create mealie
Now set some env vars:
dokku config:set mealie BASE_URL=https://mealie.yourdomain.com
dokku config:set mealie TZ=America/Anchorage
dokku config:set mealie ALLOW_SIGNUP=false
Next, match the compose file and set a 1gb memory limit:
dokku resource:limit --memory 1000 mealie
Now we’ll map some persistent storage, this requires a few commands:
dokku storage:ensure-directory mealie
Note the actual directory on the host in the output of this command, for me, it is /var/lib/dokku/data/storage/mealie
. Now mount that directory into the app:
dokku storage:mount mealie /var/lib/dokku/data/storage/mealie:/app/data
Since this is a bind mount on the host, there may be permission issues, depending on the container. The storage:ensure-directory
command has multiple options for setting the uid/gid if you run into issues. Certain containers also support uid/gid mapping (like this one with the PUID, PGUID env vars), so use those if needed.
Finally, double check the domain (it should be automatically, matching the app name).
dokku domains:report
If for some reason you have varying dokku app name and target sub-domains, you can manage it via the dokku domains:[add|remove]
sub-commands, just make sure dokku domains:report
looks right before proceeding.
Create Dockerfile for the app Link to heading
We’ll use a Dockerfile to trigger the dokku deploy. There are multiple approaches to deploy apps in dokku, but I find this one clean and easy to manage.
FROM ghcr.io/mealie-recipes/mealie:v2.4.1
EXPOSE 9000
Create a new directory, put that Dockefile in it, and init a new git repo:
mkdir dokku-mealie
cd dokku-mealie
# create Dockerfile referenced above
git init
git add .
git commit -m "Initial commit"
At this point, I normally push the repo to a git remote. Prefixing these repos with dokku-
makes is easy to identify and manage repos that hold dokku apps.
Now we’re ready to push to dokku:
git remote add dokku dokku:mealie
git push dokku master
Now just 🙏 it works.
Note: I setup a host entry in my ssh config (~/.ssh/config
) to simplify adding dokku origins:
Host dokku
HostName my-hostname-or-ip
User dokku
IdentityFile ~/.ssh/my-ssh-key
Expose the app Link to heading
At this point, the app is probably exposed on http port 9000. We don’t want that, instead let’s make sure it’s exposed over https.
I am using cloudflare’s dns proxy to handle my traffic and their built in certificate management. So that means I don’t need lets-encrypt to issue me cerifificates within dokku, but I do need to install the cloudflare certificate on a per-app basis (even though it is a wildcard cert, I can’t figure out how to install a global cert in dokku):
dokku certs:add mealie < cert-key.tar
Where cert-key.tar
is an archive consisting of two files, server.crt
and server.key
(via cloudflare).
Next let’s let dokku know it should server this over https:
dokku ports:add mealie https:443:9000
dokku ports:remove mealie http:9000:9000
At this point, everything should work :)