- Configure Kirby for Dokku
- Install deployment-keys and host keys Dokku plugins
- Set up staging and production environments
- Clone project repository into apps persistent storage folders
- Mount desired folders including
.git
folder to apps - Add
GIT_DIR
andGIT_WORK_TREE
environment variables to containers - Deploy to Dokku
Using Kirby CLI.
# Install Kirby and AutoGit
kirby install --kit plainkit
mv kirby my-project && cd my-project
kirby plugin:install pedroborges/kirby-autogit
# Set up AutoGit in site/config/config.php
# Make sure "autogit.webhook.secret" is not set to false, create a random secret
# Bootstrap Kirby for Dokku
curl -s https://www.gitignore.io/api/node%2Csass%2Cmacos%2Clinux%2Ckirby2%2Cwindows > .gitignore
echo 'https://github.com/heroku/heroku-buildpack-php' > .buildpacks
echo 'web: vendor/bin/heroku-php-apache2 -i custom_php.ini' > Procfile
echo -e 'extension=mbstring.so \nmemory_limit=512M \ncgi.fix_pathinfo = 0;' >> custom_php.ini
echo '{"keywords":["php","kirby"]}' > app.json
echo '{}' > composer.json
Modify .htaccess
to:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.([0-9a-z]{32})\.(js|css)$ $1.$3 [L]
# block text files in the content folder from being accessed directly
RewriteRule ^content/(.*)\.(txt|md|mdown)$ index.php [L]
# block all files in the site folder from being accessed directly
RewriteRule ^site/(.*) index.php [L]
# block all files in the kirby folder from being accessed directly
RewriteRule ^kirby/(.*) index.php [L]
# make panel links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^panel/(.*) panel/index.php [L]
# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
</IfModule>
# Set up Git
git init
git remote add origin [email protected]:username/my-project.git
# Push to project repository
git add .
git commit -m 'initial'
git push origin master
SSH into the server as root.
dokku apps:create my-app-staging
dokku apps:create my-app-production
Dokku SSH Deployment Keys Plugin
Install the deployment-keys plugin and copy/add the resulting public key to your GitHub/GitLab repository deployment keys (enable write access). The plugin will inject the deployment key in every new app container.
dokku plugin:install https://github.com/cedricziel/dokku-deployment-keys.git deployment-keys
# Show app deployment key
dokku deploymentkeys:show app-name
Dokku HostKeys Plugin
Install the host keys plugin and add your VCS provider - such as GitLab - to your shared host keys. The plugin will inject the host keys to ~/.ssh/known_hosts
in new app containers.
dokku plugin:install https://github.com/cedricziel/dokku-hostkeys-plugin.git hostkeys-keys
# Add VCS provider to shared hostkeys
dokku hostkeys:shared:autoadd gitlab.com
mkdir -p /var/lib/dokku/data/storage/{my-app-staging,my-app-production}
# Make sure you can clone the repository with the generated deployment key as root user
export GIT_SSH_COMMAND="ssh -i ~dokku/.deployment-keys/shared/.ssh/id_rsa -F /dev/null"
git clone [email protected]:username/my-project.git /var/lib/dokku/data/storage/my-app-staging
git clone [email protected]:username/my-project.git /var/lib/dokku/data/storage/my-app-production
chown -R 32767:32767 /var/lib/dokku/data/storage/my-app-staging
chown -R 32767:32767 /var/lib/dokku/data/storage/my-app-production
Include .git
folder to enable AutoGit to commit from inside the container using the injected deployment/host keys.
dokku storage:mount my-app-staging /var/lib/dokku/data/storage/my-app-staging/.git:/app/.git
dokku storage:mount my-app-staging /var/lib/dokku/data/storage/my-app-staging/content:/app/content
dokku storage:mount my-app-staging /var/lib/dokku/data/storage/my-app-staging/site/accounts:/app/site/accounts
dokku storage:mount my-app-production /var/lib/dokku/data/storage/my-app-production/.git:/app/.git
dokku storage:mount my-app-production /var/lib/dokku/data/storage/my-app-production/content:/app/content
dokku storage:mount my-app-production /var/lib/dokku/data/storage/my-app-production/site/accounts:/app/site/accounts
Doesn't work with dokku config:set
unfortunately.
dokku docker-options:add my-app-staging deploy "-e GIT_DIR=/app/.git -e GIT_WORK_TREE=/app"
dokku docker-options:add my-app-production deploy "-e GIT_DIR=/app/.git -e GIT_WORK_TREE=/app"
Exit server.
Find file site/plugins/autogit/lib/autogit.php
In function hasRemote
, replace:
$this->execute("remote get-url '{$remoteName}'");
With
$this->execute("config --get remote.origin.url");
On initial app deploy add to site/config/config.php
:
c::set('panel.install', true);
Add staging/production remotes and deploy!
git remote add staging [email protected]:my-app-staging
git remote add production [email protected]:my-app-production
git add .
git commit -m 'initial deploy'
git push staging master
git push production master
# After this, you - should - not have to deploy to Dokku when changing files locally
# Make sure to "git pull" first when there have been content commits/changes
# Just push to origin and press 'Get latest changes' in the Kirby CMS panel
# Setup the correct branch when working with staging/production environments
# It is possible for AutoGit to get out of sync with the project repository
# In this case, backup your persistent folder somewhere and delete persistent storage folder
# Clone repository into app persistent storage folder again
# Set permissions again
# Rebuild the app using "dokku ps:rebuild app-name"
Versions on time of writing:
- Dokku: v0.9.4
- Kirby: v2.4.1
- AutoGit: v0.5.0
SSH into the server as root.
# Install Let's Encrypt plugin
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
# Add domain to apps
dokku domains:add my-app-staging staging.my.domain
dokku domains:add my-app-production my.domain www.my.domain
# Enable SSL (make sure both apps are deployed)
dokku config:set my-app-staging --no-restart [email protected]
dokku config:set my-app-production --no-restart [email protected]
dokku letsencrypt my-app-staging
dokku letsencrypt my-app-production
# Auto-renew certificates
dokku letsencrypt:cron-job --add