Straight to Maintenance
Initialize the droplet with dokku app pre-setup
Visit the droplet IP to configure Dokku (keys, domain, virtual domain)
dokku plugin:install https://github.com/dokku/dokku-postgres postgres
dokku plugin:install https://github.com/dokku/dokku-redis redis
- App is configured for dokku
- Dokku is configured to receive a deploy (dokku app, its ENV and services are set up)
- git push dokku succeeds
- migrate manually with
dokku run <app_name> bundle exec rake db:migrate db:seed RAILS_ENV=<env>
- Update VHOST file with needed domains
- Rebuild/redeploy
-
- See if app's console runs
- See if app can be accessed via needed DNS
dokku apps:create ruby-rails-sample
2. install postgres plugin
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git
dokku postgres:create ruby-rails-sample
dokku postgres:link ruby-rails-sample ruby-rails-sample
NB, when you get git errors, run the key add command, so that on the droplet /home/dokku/.ssh/authoreized_keys
file contains something like "command="FINGERPRINT=13:9f:e7:8f:58:2e:54:46:19:c8:ae:d8:39:ce:8d:11 NAME="augusts" `cat /home/dokku/.sshcom..."
# you can remove remote with
git remote rm dokku
# deploy a test app to a name
git remote add dokku [email protected]:ruby-rails-sample
git push dokku master
# deploy to subdomain
git remote add dokku [email protected]:sub.dokku.me
git push dokku master
# deploy to root domain
git remote add dokku [email protected]:dokku.me
git push dokku master
# In case you need to deploy from non-master branch do
git push dokku <other_branch>:master
You can learn a lot from the sample rails app for dokku
production.rb https://gist.github.com/Epigene/ea6a1bd070b657189fbe
staging.rb https://gist.github.com/Epigene/6a2b957285584de0f1c6
Do not use rails_12_factor gem.
Instad set these two ENV options
RAILS_SERVE_STATIC_FILES=true RAILS_LOG_TO_STDOUT=true
gem 'rails_12factor', group: :production
# in /Procfile
web: bundle exec puma -C config/puma.rb
# in /config/puma.rb
workers 2
threads 5, 5
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RAILS_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
This is a bit of a hack
# in /lib/taks/deploy.rb
# This runs migs during dokku deploy, see https://buildtoship.com/run-migrations-on-dokku-heroku-deployment/
Rake::Task['assets:clean'].enhance do
puts ">>>>> Running Migs from the enhanced task!"
Rake::Task['db:migrate'].invoke
end
dokku ps:scale <app> web=1 worker=1 clockwork=1
Output existing ENV settings
dokku config <app>
Define new settings
For Rails apps it is key to define at least SECRET_KEY_BASE
and BUILDPACK_URL
.
See this dokku discussion for buildback necessity
# use command `dokku config:set <app-name> <key>=<value> <another_key>=<value>`
# e.g.
dokku config:set node-js-app KEY=\"VAL\ WITH\ SPACES\" ANOTHER_KEY="2"
# Producton example
dokku config:set blog.swisslanguages BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-ruby RAILS_ENV=production RACK_ENV=production SECRET_KEY_BASE=d2c7882551be2d54e3eaf0b5e03235096ef8997dbd3490de39d8ee055ae5dea5f210bf3400d3cd97a8cb37431f867da8ca67ad608e3c120ab0dff826455f95fc
# Staging example
dokku config:set blog.swisslanguages RAILS_ENV=staging RACK_ENV=staging SECRET_KEY_BASE=d2c7882551be2d54n3eaf0b5e03235096ef8997dbd3490de39d8ee051ae5dea5f210bf3400d3cd97a8cb37431f867ga8ca67ad608e3c120ab0dff826455f95fc
1. Add the deploy key plugin
Navigate to /home/dokku/.deployment-keys/shared/.ssh
and cat the id_rsa.pub, add contens to creative-deployer's ssh-keys
2. Add the host key plugin
Adding github should do the trick
dokku hostkeys:shared:autoadd github.com
1. Install the official redis plugin
sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis
# Modify the behavior of creator by setting ENV variables beforehand
# export REDIS_CUSTOM_ENV="PORT=6392"
dokku redis:create staging.app.swisslanguages.com
dokku redis:link redis_service app_name
# in /Procfile
worker: bundle exec rake resque:work TERM_CHILD=1 RESQUE_TERM_TIMEOUT=10 QUEUE=*
# or multi-worker boot
worker: bundle exec rake resque:workers COUNT=5 QUEUE="*"
Consult the documentation for more.
dokku ps:scale creative_invoice_platform web=1 worker=1
# in a cron task, sometime at night
dokku ps:restartall && dokku cleanup
Consult the official guide
Consider this SO question
mkdir /home/dokku/shared/<app_name>/
sudo chmod 777 -R /home/dokku/shared
sudo chown dokku:dokku -R /home/dokku/shared
dokku docker-options:add myapp deploy "-v /home/dokku/shared/<app_name>/path/in/container:/path/in/container"
dokku docker-options:add myapp run "-v /home/dokku/shared/<app_name>/path/in/container:/path/in/container"
e.g.
dokku docker-options:add uz-veselibu.lv deploy "-v /home/dokku/shared/uz-veselibu.lv/media:/app/public/media"
dokku docker-options:add uz-veselibu.lv run "-v /home/dokku/shared/uz-veselibu.lv/media:/app/public/media"
Follow the documentation
dokku certs:generate <app> DOMAIN
TODO See http://dokku.viewdocs.io/dokku~v0.5.6/checks-examples/
Given your app will be reachable at www.example.com
domain and use /cable
path for websocket communication..
config.action_cable.url = "ws://ccb.creative.gs/cable"
config.action_cable.mount_path = "/cable"
#config.action_cable.disable_request_forgery_protection = true # this is very lax!
config.action_cable.allowed_request_origins = [/https?:\/\/(\w+\.)*example.com/]
# in /nginx.conf.sigil
# THIS FILE IS USED BY DOKKU TO GENERATE APP'S custom nginx.conf
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }}
server {{ . }};
{{ end }}
}
server {
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }};
access_log /var/log/nginx/{{ .APP }}-access.log;
error_log /var/log/nginx/{{ .APP }}-error.log;
location / {
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
location /cable {
#proxy_pass http://ccb.creative.gs/cable;
proxy_pass http://{{ .APP }}/cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 90000s;
proxy_redirect off;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
}
dokku run <app_name> bundle exec rake db:migrate db:seed RAILS_ENV=production
dokku run <app_name> rails c
dokku ps:restart <app>
# harder version
dokku ps:rebuild <app>
Container app not starting for some reason?
dokku logs <app>
$ docker ps
$ docker logs -f <CONTAINER_ID>
# get containers by running `sudo docker ps`
sudo docker run -it dokku/wp:latest /bin/bash
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 deployer"
docker ps --filter status=dead --filter status=exited -aq | xargs -r docker rm -v
docker images --no-trunc | grep '<none>' | awk '{ print $3 }' | xargs -r docker rmi
dokku config <app>
dokku cat <app>/VHOST
dokku redis:unlink <app> <app>
dokku postgres:unlink <app> <app>
dokku apps:destroy <app>
dokku apps:create <app>
dokku config:set <app> ...
nano <app>/VHOST
dokku redis:link <app> <app>
dokku postgres:link <app> <app>
# SSH onto the server, then execute:
dokku apps:destroy <app>
# ssh into server, $ fish, $ dok
# dokku postgres:list
dokku postgres:export <name> > /home/dokku/latest.dump
# scp the dump
# general
scp_dokku (scp [email protected]:/home/dokku/latest.dump ~/Desktop/)
# staging
scp [email protected]:/home/dokku/latest.dump
# restire the DB from dump, username directive may be unnecessary
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U <username> -d <database> ~/Desktop/latest.dump
## OLD
psql --username=postgres <databasename> < data_base_dump.sql
# 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 CLEAN DISC, PERMANENTLY removing exited containers
sudo docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs sudo docker rm
dumpit_lite
scp NORD:/home/deployer/apps/nordenhealth/s_latest.dump ~/Desktop/
# you may want to see if it works locally
# rake db:drop db:create db:migrate
# psql -U <username> <db> < <file>
# e.g.
# psql -U augusts nord < /Users/augusts/Desktop/s_latest.dump
# a single file
scp ~/Desktop/s_latest.dump STAGING:/home/dokku
# all files in a directory
scp ~/Desktop/files/* CPP:/home/deployer/apps/
# not the seeds must be skipped
dokku run <app> bundle exec rake db:drop db:create db:migrate RAILS_ENV=staging
# SQL-type dumps
dokku postgres:connect staging.v1.stockholmhealth < /home/dokku/s_latest.dump
# binary dumps
dokku postgres:import <app> < /home/dokku/s_latest.dump
Thank you. I appreciate this beast of a gist. Please let me know how I can treat you to a coffee!