- DigitalOcean NYC3 Dokku 0.2.3 on 14.04 with Docker 1.2.0) - create droplet with public key, get an IP address
- Set up DNS for jbinto.ca:
A
records forjbinto.ca
and*.jbinto.ca
- DNS won't propogate immediately, so edit
/etc/hosts
for now - Go to http://jbinto.ca, check "Use virtual hosts", verify public key and hostname, finish setup
e.g. with heroku/node-js-sample
git clone https://github.com/heroku/node-js-sample.git
cd node-js-sample
git remote add jbinto [email protected]:node-js-app
git push jbinto master
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 281 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
-----> Cleaning up ...
remote: Cloning into '/tmp/tmp.fIZZh0DyW4'...
-----> Building node-js-app ...
remote: done.
remote: HEAD is now at 26721ee... boo
Node.js app detected
-----> Requested node range: 0.10.x
-----> Resolved node version: 0.10.33
-----> Downloading and installing node
-----> Restoring node_modules directory from cache
-----> Pruning cached dependencies not specified in package.json
-----> Installing dependencies
-----> Caching node_modules directory for future builds
-----> Cleaning up node-gyp and npm artifacts
-----> No Procfile found; Adding npm start to new Procfile
-----> Building runtime environment
-----> Discovering process types
Procfile declares types -> web
-----> Releasing node-js-app ...
-----> Deploying node-js-app ...
=====> Application deployed:
http://node-js-app.jbinto.ca
To [email protected]:node-js-app
a795d9c..26721ee master -> master
% cat ~/bin/dokku
#!/bin/bash
COMMAND="ssh [email protected] $*"
echo $COMMAND
eval $COMMAND
dokku help
dokku logs node-js-app -t
docker ps -a --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c2ecb8302bdec72cf36ec565e52205f4bd3eec451fc0361da51c83e2d1a303a dokku/node-js-app:latest "/bin/bash -c '/start web'" 25 minutes ago Up 25 minutes 0.0.0.0:49155->5000/tcp hopeful_newton
b046c2ee7ec4e5a27b346a3c55303d3c776c2416dc0d7a6ad4b3d266a234bc05 3488dc2ae9ab "/bin/bash -c 'mkdir -p /app/.profile.d && cat > /app/.profile.d/app-env.sh'" 25 minutes ago Exited (0) 25 minutes ago thirsty_curie
7bbbb1dfbc3ea537374589d7cc06c857c432b2b2d7d2554a70959ed1733e4eec ba7db93795dc "/build/builder" 25 minutes ago Exited (0) 25 minutes ago insane_shockley
eb1ef0666a77da85274a3e31b69adf0476ae9dba0d91d8b66a535ebff891217d progrium/buildstep:latest "/bin/bash -c 'mkdir -p /app && tar -xC /app'" 26 minutes ago Exited (0) 25 minutes ago angry_bell
fb6fa8ceb90cb12956944971cdd7b2b369f5e75a8e0abb110dd7081c066fedce 8e94fb9002bd "/bin/bash -c '/start web'" 51 minutes ago Exited (-1) 25 minutes ago furious_bartik
ssh [email protected]
cd /var/lib/dokku/plugins/
git clone https://github.com/Kloadut/dokku-pg-plugin postgresql
dokku plugins-install
exit
% dokku postgresql:create foo
-----> PostgreSQL container created: postgresql/foo
Host: 172.17.42.1
Port: 49156
User: 'root'
Password: ....
Database: 'db'
Url: 'postgres://root:[email protected]:49156/db'
dokku postgresql:console foo
(No prompt, ^C
to quit)
I attempted to push, but just as described in this issue, it fails to find ruby-2.1.5 on S3 (but can go back and manually change the URL back to 2.1.2).
This is because DigitalOcean's docker image for buildstep is out of date.
Fix:
ssh [email protected]
docker pull progrium/buildstep
exit
Use Unicorn:
Add unicorn-rails
to the top level of the Gemfile
. Run bundle
.
Create a Procfile
:
web: bundle exec rails server -p $PORT
Create Postgres container:
dokku postgresql:create sample-rails-app
I thought I'd have to manually link them together, but it appears to have done it for me.
(Is it okay that my database name == my app name? Is that how the magic happens?)
% dokku postgresql:create sample-rails-app
ssh [email protected] postgresql:create sample-rails-app
-----> Creating /home/dokku/sample-rails-app/ENV
-----> Setting config vars and restarting sample-rails-app
DATABASE_URL: postgres://root:[email protected]:49158/db
-----> Releasing sample-rails-app ...
-----> Release complete!
-----> Deploying sample-rails-app ...
-----> Checking status of PostgreSQL
Found image postgresql/sample-rails-app database
Checking status... ok.
-----> Deploy complete!
-----> sample-rails-app linked to postgresql/sample-rails-app database
-----> PostgreSQL container created: postgresql/sample-rails-app
Host: 172.17.42.1
Port: 49158
User: 'root'
Password: 'XXX'
Database: 'db'
Url: 'postgres://root:[email protected]:49158/db'
Disable SSL (for now):
In config/environments/production.rb
, set config.force_ssl
to false
And run
git push dokku master
Run migrations:
dokku run sample-rails-app bundle exec rake db:migrate
Seems to hang at the end, press enter and it lets go. (??)
And it works!
http://sample-rails-app.jbinto.ca/
Power cycle your droplet.
The container link between your postgres instance and sample-rails-app
is lost. The app shows 502 Bad Gateway.
You can restore it manually, but... it's a little fuzzy what parts are ephemeral and what parts aren't, and it feels flaky/too magical. I'm also surprised how heavily it relies on Heroku buildpacks. It makes sense to be compatible, but there's a lot of complexity being brought in...
This appears to be fixed for the mariadb plugin.
Some discussion here: https://www.digitalocean.com/community/questions/newbie-can-t-get-apps-to-run-after-restart-using-rails-postgre-docker-and-dokku
Just as in March, I find dokku
impressive but opaque. There's a few reasons to be excited.
- dokku-alt is a fork which adds several interesting features (Postgres, SPDY, HSTS, SSL management from command line, etc..). Unfortunately it has a low bus-factor and not a lot of mindshare (judging by twitter searches, stackoverflow answers). It's also plugin-incompatible with dokku, and has diverged further and further from upstream to be an entirely different project.
- As of Nov 2014 Deis is sponsoring the official dokku project, so it will get some more love.
I think Ansible + Dokku could be a killer combo. There's lots of fiddly stuff you have to do to get dokku running optimally. Sometimes you have to reach into the box and run some command, delete some .pid file... and Ansible is good at handling that stuff.
- Looks like I'm not alone in thinking this: mylittleapp is a Ansible playbook to provision a Dokku server
For now I will go back to Ansible+Capistrano. It may not be as whizbangmagic as git push
deployment, but I feel it's more transparent and repeatable. I'm sure we can get there eventually but it's a little sharp for me right now.