Introduction
Dokku is basically a self-hosted Heroku. It allows you to deploy your apps with a simple git push and it'll handle all the building and deploying automatically.
After having trouble finding an up-to-date and exhaustive how-to guide, I decided to write the steps down, It'll help me later and hopefully you as well ? Here are the steps I went through !
Setup your server
Create a DigitalOcean Dokku droplet or any other basic Ubuntu/Debian Server on which you installed Dokku
(facultative) Point a domain or Sub-domain to your Dokku installation
Visit your server's IP in your browser to finish the Dokku setup, make sure the SSH key is the correct one. Enter your Top Level Domain in the hostname field. I chose to use the virtualhost naming for my Dokku apps, I think it makes more sense for web apps!
Install the MySQL plugin for Dokku on your server
dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql
- (optional) Install the Let's Encrypt plugin if you want free SSL certificates
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
Project Setup
- Add PHP extension requirements to
composer.json
. This tells Dokku to activate those extensions on your server. Here are the ones I needed as example !
"require": {
"ext-bcmath": "*",
"ext-ctype": "*",
"ext-curl": "*",
"ext-exif": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-pdo": "*",
"ext-openssl": "*",
"ext-tokenizer": "*",
"ext-xml": "*",
"ext-zip": "*"
}
After making the changes in
composer.json
you'll need to update it usingcomposer update
. You might encounter problems with the PHP extensions not being installable on your local env, in that case usecomposer update --ignore-platform-reqs
to avoid installing them.Add a build script to package.json, it will be run automatically on deploy by Dokku
"scripts": {
"production": "mix --production",
"build": "npm run production"
},
Make sure your
config/database.php
has this line in the 'mysql' config :
'url' => env('DATABASE_URL'),
Create a Procfile (a file named Procfile at the root of the project). The
release
part contains the command that'll be run right after a build. Theweb
part specifies the web server to run, here we simply run the default PHP server from Heroku and point it to thepublic
folder
release: php artisan migrate --force
web: vendor/bin/heroku-php-apache2 public/
- Specify the buildpacks you'll need in a .buildpacks file at the root of the project. You can see these as "build steps" before putting your application online.
heroku-buildpack-php
install your composer packages (amongst other things) andheroku-buildpack-nodejs
install your npm dependencies and runs your build script.
https://github.com/heroku/heroku-buildpack-php
https://github.com/heroku/heroku-buildpack-nodejs
Dokku Setup
Create the app on the Dokku server with this command
dokku apps:create {name_of_your_app}
Add the git remote on your local dev environment with :
git remote add {remote_name} dokku@{server_url}:{app_name}
remote_name
can be whatever. I use "staging" and "production" for example.app_name
is the name you gave your Dokku app at the previous step.Set up all your environment variables on the server using the
dokku config:set {your_app_name} VAR=VALUE VAR2=VALUE2 ...
command. Don't forget to mention an APP_KEY, APP_ENV, APP_URL, etc !Create a MySQL database and link it to your app (your-db-name can be anything)
dokku mysql:create {your-db-name}
dokku mysql:link {your-db-name} {your_app_name}
- Get the MySQL connection URL (mysql://user@example...) and set it as a variable for your app
dokku mysql:info {your-db-name} --dsn
dokku config:set {your_app_name} DATABASE_URL={connection_string_from_previous_command}
Deployment
- Push your app to your Dokku server using :
git push {remote_name}
(optional) Add a Let's encrypt certificate to your app !
- Setup your contact email for Let's encrypt and generate your certificate
dokku config:set --no-restart {your_app_name} DOKKU_LETSENCRYPT_EMAIL={your_email_address}
dokku letsencrypt:enable {your_app_name}
All done 💃
Enjoy your app !
Top comments (2)
Looks it was conflicting with the other ENVs of the database... now it's working.