Base Dokku setup on different hosting providers, with Terraform and Ansible.
This project works on the assumption that you already have:
- a Cloudflare account and a domain with DNS managed from Cloudflare.
- a GCP account. A Cloud Storage bucket will be created automatically and used to store the Terraform state, at no cost.
The following tools must be installed on your local machine:
- pipenv
- gcloud
- terraform
- terragrunt
- dokku
- (optional) pre-commit
All commands will be executed in a virtual environment created with pipenv. This workflow has been tested on macOS v13, some tools like whoami, cat, curl are already provide by OS.
-
Copy sample.env to .env and update GCP_PROJECT_ID and CLOUDFLARE_API_TOKEN variables.
cp sample.env .env
-
Create and active the virtual environment.
pipenv install pipenv shell
-
(optional) Configure gcloud and log in, if you have not already done it.
gcloud config configurations create ${GCP_PROJECT_ID} gcloud config set project ${GCP_PROJECT_ID} gcloud auth login gcloud auth application-default login
-
(optional) Install pre-commit hooks, only for local development.
pre-commit install
-
Change path to configuration folder and install Ansible dependencies.
ansible-galaxy role install -r requirements.yml --force ansible-galaxy collection install -r requirements.yml --force
-
Update HCLOUD_TOKEN in .env file.
# Reactivate the virtual environment to load new environment variables exit pipenv shell
-
Change path to root folder and set Terraform variables in .env file.
Check infrastructure/modules/hetzner/README.md for examples and available variables.
# Use current OS user for SSH authentication echo -e "\nTF_VAR_ssh_user={\"user\":\"$(whoami)\",\"keys\":[\"$(cat ~/.ssh/id_rsa.pub)\"]}" >> .env # Allow SSH connections only from current public IP address echo -e "\nTF_VAR_ssh_allow_ipv4=[\"$(curl -s https://ifconfig.me)/32\"]" >> .env # Reactivate the virtual environment to load new environment variables exit pipenv shell
-
Change path to infrastructure/environments/hetzner/server folder and create the infrastructure.
terragrunt apply # Add DOKKU_HOST environment variable and reactivate pipenv shell to pick new environment variables echo -e "\nDOKKU_HOST=$(terragrunt output -json server_ip | jq -r)" >> ../../../../.env exit pipenv shell
-
Change path to configuration folder and install Dokku. The Ansible playbook will also apply the DevSec Hardening Framework Baselines for SSH and OS.
# Check if Ansible can connect to server ansible-inventory --inventory hcloud.yml --graph ansible all --inventory hcloud.yml --module-name ping --limit label_project_dokku # Execute Ansible playbook for Hetzner cloud ansible-playbook playbooks/hetzner.yml --inventory hcloud.yml --limit label_project_dokku
This test works on the assumption that you want to have an application accessible under a subdomain, for example my-app.example.tld
.
Replace my-app.example.tld
with the FQDN for your application.
-
Change path to root folder and update .env file.
# Add application subdomains and reactivate pipenv shell to pick new environment variables echo -e "\nTF_VAR_dokku_apps_domains=[\"my-app.example.tld\"]" >> .env exit pipenv shell
-
Change path to infrastructure/environments/hetzner/server folder and update Cloudflare DNS.
terragrunt apply
-
Temporarily set Cloudflare SSL/TLS encryption mode to Flexible for
example.tld
. -
Open my-app.example.tld in browser.
Follow Dokku docs to deploy an application. Use Cloudflare Origin CA certificate for SSL/TLS configuration.