Setup environment could be tedious, but Dokku just makes it tremendously easy. Even more, you can have your own CD setup under 5 mins with everything. Let’s see how we can get up and running for this app: A Node back-end with a create-react-app powered front end, and we will use MongoDB.
I use Ubuntu 18 x64, it should be more or less the same if you use other Linux distribution. I assume you start everything from scratch, I mean, a fresh newly installed OS.
- Download the bash command to install:
- Find the latest version number here: https://github.com/dokku/dokku/releases
- Execute it:
sudo DOKKU_TAG=v0.14.5 bash bootstrap.sh
- Open the IP or domain name from the browser.
- You will see a UI to setup the public key, you can paste it in the textbox or it will derive from the
~/.ssh/authorized_keyson the host.
- Then setup your domain name, if you want to deploy to sub-domain, you need to select that
Use virtualhost naming for apps. You don’t need to put the protocol here. And if you only have a IP, just put it there (IP only, no protocol), it’s fine.
- Login to your host
- Create the app to deploy:
dokku apps:create your-app-name
- Setup MongoDB
sudo dokku plugin:install https://github.com/dokku/dokku-mongo.git mongo
- Set version number:
- Create the database:
dokku mongo:create your-db-name
For the permission problem: you can add the permission to that folder:
chmod a+w /var/lib/dokku/services
- Link App to Database:
dokku mongo:link your-db-name your-app-name
When deploying, you can either use
Heroku or setup your own
buildpack is super easy, you open the
package.json, setup the node version and npm version with the one you like:
And then you just need a
start script in
package.json in order to start your back-end node app.
Something special here is that we need to build the front-end code.
The is my folder structure:
You can see here that the front end code sits in
client folder which is a sub-folder of the back-end code (
public folder is the folder for holding static assets. After building the front end code, the result should be ported to this folder.
So I add this simple script to
"heroku-postbuild": "cd client && npm i && npm run build && cd .. && rm -rf ./public && mv ./client/build ./public",
Nothing fancy here, it goes to the
client folder, install npm, then build, and go back to replace
The interesting part is
Dokku sees this, it will run the command after building. Which means, it will happen in the end in the end.
The basic idea of deploying is to
git push the code to your server, then
Dokku will create the Docker image, and swap with the production container.
So, in you repo, you first need to setup a
git remote add repo-name dokku@IP-OR-DOMAIN:your-app-name,
The key part of this is to setup the private key on your local machine. So it can connect to the server and do the push.
Finally, let’s push via
git push repo-name master.
Your code will be there.
Your server app will expose some port, and in order to access it from the browser, we need to map it to port 80 on the server.
Login to the server, setup the port.
dokku proxy:ports-set your-app-name http:80:your-app-port
your-app-port with your port in use.
So, every time, when Nginx receives a request, it will redirect to
Since we are already on the server, let’s setup the Ubuntu UFW. A built in firewall.
# enable it
You can get the connection string with this command on the server:
dokku mongo:info your-db-name
Dsn field is what you need. :)
So, everything will be fine, until you realize one problem, which is, every time you
git push, it will deploy, but it will install the
npm every time. This is due to the constraint that
HeroKu will not cache your dependencies.
It maybe fine for most of time, but when you concern about the time or you are deploying to an environment where you can’t easily access some website. Then you might want to change to another way to build, which is,
Use your own Dockerfile.
Dokku sees there is a
Dockerfile in the root of your app, it will use it instead of
I have written another blog to cover that, to make it a lot faster.
Hope it helps.
Thanks for reading!
Follow me (albertgao) on twitter, if you want to hear more about my interesting ideas.