Skip to content

Instantly share code, notes, and snippets.

@Epigene
Last active March 31, 2016 11:24
Show Gist options
  • Save Epigene/692b9fc4b6cd5ef03f4b to your computer and use it in GitHub Desktop.
Save Epigene/692b9fc4b6cd5ef03f4b to your computer and use it in GitHub Desktop.
Dokku Droplet Workflow

Deploy a Rails app to Dokku droplet

Set up a droplet

Much in common with http://www.snip2code.com/Snippet/159602/Using-Dokku-to-deploy-a-Rails-Applicatio

Initialize droplet via https://www.digitalocean.com/community/tutorials/how-to-use-the-dokku-one-click-digitalocean-image-to-run-a-ruby-on-rails-app

Grab the latest dokku while you are at it. See Official Dokku Upgrade Guide

Pre v 0.4.0 update guide

$ Config locales
$ Deny root access

Config postgres DB plugin

v0.4.x

sudo dokku plugin:install https://github.com/dokku/dokku-postgres
  # install latest Postgres
  # visit http://www.postgresql.org/download/linux/ubuntu/
  sudo sh -c "echo 'deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
  wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -
  apt-get update
  apt-get -y install postgresql-common postgresql postgresql-9.4 postgresql-contrib
  
  cd /var/lib/dokku/plugins
  git clone https://github.com/Kloadut/dokku-pg-plugin.git postgresql
  dokku plugins-install
  dokku help | grep postgres
  # To delete a db container run:
    dokku postgresql:delete <app>

DO NOT Install Nginx-alt, BROKEN!!!

                       ### ^^^ One time server setup ^^^ ###

Make Rails app Dokku-friendly

NB, bunlder blocks do not work, use several source lines instead.

  # Use modified staging.rb environment from https://gist.github.com/Epigene/b94bc89eb397730503b8
  # Edit gemfile, add lines (remove existing webserver gem), bundle
    group :production, :staging do
      gem 'rails_12factor'
      gem 'thin'
    end
  
  # Delete Procfile, otherwise dokku deploy fails
  # (TO-DO) Solve worker run in procfile

Set up git remote

# Add a dokku remote following `git remote add <remote_name> <role>@<ip_or_domain>:<codename>`, for example:
# subdomain
$ git remote add dokku [email protected]:node
# full domain
$ git remote add dokku [email protected]:swisslanguages.com

# deploy to dokku remote
git push dokku master
# Dokku only deploys master, so in case of other branch deploy do `git push <remote> <other_branch>:master`:
git push dokku staging:master

ENV config

  # use command `dokku config:set <app-name> <key>=<value>`
  dokku config:set <app-name> RAILS_ENV=staging
  dokku config:set <app-name> SECRET_KEY_BASE=as6dka987da...
  dokku config:set <app-name> RACK_ENV=staging

Setup Postgres DB for a rails app

  # create db the same name as app
    dokku postgresql:create <app_name>
    dokku postgresql:link <app-name> <db-name>
    dokku run <app_name> bundle exec rake db:migrate db:seed RAILS_ENV=staging
    dokku run <app_name> rails c
    
  # (Extended) Restore with no dumpfile argument opens psql session
    dokku postgresql:restore <app-name>
    # Enable extensions, like HSTORE, if neccessary
      CREATE EXTENSION hstore;

Set up upload path (for assets you want to keep across deploys)

Consider this SO question Consider upgrading to v0.3.18

dokku docker-options:add myapp deploy "-v /path/on/host:/path/in/container"
dokku docker-options:add myapp run "-v /path/on/host:/path/in/container"

e.g.
dokku docker-options:add uz-veselibu.lv deploy "-v /home/dokku/uz-veselibu/shared/media:/app/public/media"
dokku docker-options:add uz-veselibu.lv run "-v /home/dokku/uz-veselibu/shared/media:/app/public/media"

Maintenance commands

To redeploy without changes

  dokku ps:restart <app>
  
  # harder version
  dokku ps:rebuild <app>

To get shell inside a container

  # get containers by running `sudo docker ps`
  sudo docker run -it dokku/wp:latest /bin/bash

To add additional SSH keys, run on the computer that wants to add:

  cat ~/.ssh/id_rsa.pub | ssh root@<IP> "sudo sshcommand acl-add dokku <key name>"
  e.g.
  cat ~/.ssh/id_rsa.pub | ssh [email protected] "sudo sshcommand acl-add dokku <new_deployer_name>"

To remove a container

  # SSH onto the server, then execute:
  dokku delete myapp

DB dump manipulation

Dump production, restore locally

# dokku postgresql:list
dokku postgresql:dump dietbikini.com > /root/latest.dump
scp_dokku
cat ~/Desktop/latest.dump | psql redirecter

Dump locally, restore in production

  # Dump it in sql form
    pg_dump -h localhost --username creative swiss > ~/latest.dump
    scp_swiss (scp it to own comp)
    # scp it to dokku server
      scp ~/Desktop/latest.dump [email protected]:/home/deployer/latest.sql
    # restore
      dokku postgresql:restore <app> < latest.sql
    # if fails, drop the db, run restore, migrate
      dokku postgresql:delete <app>
      dokku postgresql:create <app>
      dokku postgresql:link <app-name> <db-name>
      dokku postgresql:restore <app-name> < latest.sql
      dokku run <app> bundle exec rake db:migrate db:seed RAILS_ENV=staging
      (opt) dokku run <app> bundle exec rake clear:all_redundant_data RAILS_ENV=staging
      
    # To restore locally from SQL
      psql -U <user> <database>
      database=# \i /path/to/yourbackup.sql
      
    # TO CLEAN DISC, PERMANENTLY removing exited containers
      sudo docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs sudo docker rm

Custom NGINX.conf (redirects, exclusions etc)

sudo cp /home/dokku/<app>/nginx.conf /home/dokku/<app>/nginx.conf.template
sudo nano /home/dokku/<app>/nginx.conf.template
  # remove the first line containing the upstream
  # escape all dollar signs ($http_header becomes \$http_header)
  # add custom parts
  # dokku ps:rebuild <app>
  # cat /home/dokku/<app>/nginx.conf and see if it matches template (actual conf will have the upstream added)
# NB! Several domains (even www.domain.com and domain.com are DIFFERENT domains) must be added on seperate lines in VHOST file

Debugging

Container app not starting for some reason?

$ docker ps
$ docker logs -f <CONTAINER_ID>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment