Deploying Discourse with Dokku

Scott Batary
batary
Published in
3 min readJul 11, 2017

I’ve recently been using DigitalOcean’s Droplet service, which allows you to deploy SSD cloud servers with the press of a button.

I needed a quick and easy Docker-based solution to manage the applications I deployed to the Droplet, which lead me to Dokku.

Dokku

Dokku is a small PaaS that boasts easy Git deploys from the command line to the cloud. Once you’ve gone through the initial setup, all you need to do when deploying new applications is add a remote to your repository and push your code up to it. Dokku will handle the rest.

git remote add dokku dokku@example.com:todo 
git push dokku master

Dokku handles the routing for you (assuming you’ve setup your DNS correctly), and the app becomes available at https://todo.example.com.

Discourse

I wanted to use Dokku to manage my deployment of Discourse on my Droplet, but the setup process for Discourse requires a bootstrapping process that goes beyond what Dokku is capable of handling. But I still wanted Dokku to handle the routing and Let’s Encrypt SSL certificate.

What I ended up doing was using Discourse’s bootstrapping process to create a standalone container image called local_discourse/app with the configuration I needed. Then I made repository that just has a Dockerfile that derives itself from that base image. Dokku builds the image based on the bootstrapped one and deploys it for me.

I’ll outline the commands used for the bootstrapping and deployment process below.

Bootstrapping Discourse

Discourse has a repository that contains the files needed to bootstrap an image. Start off by being SSH’d into your server and cloning the repository.

mkdir /var/discourse 
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse

Then we’ll copy the default standalone configuration and modify it.

cp samples/standalone.yml containers/app.yml 
nano containers/app.yml

You’ll want to go down to the env section and modify the developer emails, hostname, and SMTP variables to match your environment. Email has to be setup correctly in order for Discourse to work.

Once you’re done, save the file and bootstrap the image.

./launcher bootstrap app

If successful, you should see an image named local_discourse/app when you run the following command.

docker images

Next we’ll use the launcher to start the Discourse instance, but only so we can get the docker run command that is output in the console window.

./launcher start app

The docker run should be output to the console window. Copy the command and save it for later. We'll need to replicate the same arguments when we deploy our app with Dokku.

Now you can stop and destroy the instance with the launcher.

./launcher stop app 
./launcher destroy app

Configuring Dokku

Now you can setup and configure the app with Dokku.

dokku apps:create discourse 
dokku proxy:ports-add discourse http:80:80 https:443:80
dokku proxy:ports-remove discourse http:80:5000

Next we need to take the arguments passed into the docker run command and add them to Dokku. However, first you need to strip out the -p port:port arguments. For reference, it should look something like this.

dokku docker-options:add discourse run,deploy "-e LANG=en_US.UTF-8 -e RAILS_ENV=production -e UNICORN_WORKERS=3 -e UNICORN_SIDEKIQS=1 -e RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 -e RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000 -e RUBY_GC_HEAP_INIT_SLOTS=400000 -e RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5 -e DISCOURSE_DB_SOCKET=/var/run/postgresql -e DISCOURSE_DB_HOST= -e DISCOURSE_DB_PORT= -e DISCOURSE_HOSTNAME=xxx.xxx -e DISCOURSE_DEVELOPER_EMAILS=xxx@xxx.xxx -e DISCOURSE_SMTP_ADDRESS=xxx.xxx -e DISCOURSE_SMTP_PORT=587 -e DISCOURSE_SMTP_USER_NAME=xxx@xxx.xxx -e DISCOURSE_SMTP_PASSWORD=xxx -e DISCOURSE_SMTP_ENABLE_START_TLS=true -h xxxxxx -e DOCKER_HOST_IP=x.x.x.x -v /var/discourse/shared/standalone:/shared -v /var/discourse/shared/standalone/log/var-log:/var/log --mac-address xx:xx:xx:xx:xx:xx"

You can take it a step further and issue a Let’s Encrypt certificate for your new app.

dokku config:set --no-restart discourse DOKKU_LETSENCRYPT_EMAIL=scott@batary.io 
dokku letsencrypt discourse

Deploying Discourse

Now you can create your Git repository and add a Dockerfile.

FROM local_discourse/app ENTRYPOINT ["/sbin/boot"]

Then add your remote and push it up to your server.

git remote add dokku dokku@example.com:discourse 
git add . git commit -m "initial commit"
git push dokku master

And now Discourse should be available.

--

--