├── .gitignore ├── shell-scripts-to-include ├── dokku-user-allow-port-forwarding.sh ├── docker-enter.sh ├── remove-phantom-docker-images-and-containers.sh ├── delete-dokku-apps.sh └── limit-dokku-apps.sh ├── .gitmodules ├── Vagrantfile.erb ├── docs └── extras.md ├── provision.sh.erb └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /shell-scripts-to-include/dokku-user-allow-port-forwarding.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script enables port-forwarding for all users using ssh keys with the dokku user 4 | # and thus allows non-root users to connect to the mariadb instances on the dokku host 5 | 6 | set -x 7 | sed -i s/,no-port-forwarding//g /home/dokku/.ssh/authorized_keys 8 | 9 | exit 0 -------------------------------------------------------------------------------- /shell-scripts-to-include/docker-enter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Uses nsenter to step into a running container 4 | 5 | # usage: 6 | # ./docker-attach.sh CONTAINER_ID 7 | 8 | # for docker 0.9+ 9 | export PID=`docker inspect $1 | grep '"Pid":' | sed 's/[^0-9]//g'` 10 | set -x 11 | nsenter --target $PID --mount --uts --ipc --net --pid 12 | 13 | # for docker <0.9 14 | # lxc-attach -n `sudo docker inspect $1 | grep '"ID"' | sed 's/[^0-9a-z]//g'` /bin/bash -------------------------------------------------------------------------------- /shell-scripts-to-include/remove-phantom-docker-images-and-containers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker ps | grep -v mariadb | grep -v progrium | grep -v ubuntu | grep -v CONTAINER | awk '{ print $1 }' | xargs docker rm -f 4 | docker ps -a | grep -v dokku | grep -v mariadb | grep -v progrium | grep -v ubuntu| grep -v CONTAINER | awk '{ print $1 }' | xargs docker rm -f 5 | docker images | awk '{ print $3 }' | xargs docker rmi 6 | docker images | grep '' | awk '{ print $3 }' | xargs docker rmi -f 7 | 8 | exit 0 -------------------------------------------------------------------------------- /shell-scripts-to-include/delete-dokku-apps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: ./delete-dokku-apps.sh appname1 appname2 4 | 5 | # debug 6 | set -x 7 | 8 | # fail on any error 9 | set -o errexit 10 | 11 | for APPNAME in $@ 12 | do 13 | 14 | # delete any databases 15 | set +o errexit 16 | dokku mariadb:delete $APPNAME 17 | set -o errexit 18 | 19 | # delete the dokku app 20 | set +o errexit 21 | dokku delete $APPNAME 22 | set -o errexit 23 | 24 | # remove remaining cache-files and similar 25 | if [ -d /home/dokku/$APPNAME ]; then 26 | rm -r /home/dokku/$APPNAME 27 | fi 28 | 29 | # move remains from mariadb to a trash folder for inspection before they are deleted 30 | set +o errexit 31 | mkdir /home/dokku/.mariadb-trash 32 | mv /home/dokku/.mariadb/*$APPNAME /home/dokku/.mariadb-trash/ 33 | set -o errexit 34 | 35 | done -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/dokku"] 2 | path = vendor/dokku 3 | url = https://github.com/neam/dokku.git 4 | branch = awaiting-prs 5 | [submodule "vendor/buildstep"] 6 | path = vendor/buildstep 7 | url = https://github.com/progrium/buildstep.git 8 | [submodule "vendor/dokku-plugins/docker-options"] 9 | path = vendor/dokku-plugins/docker-options 10 | url = https://github.com/dyson/dokku-docker-options.git 11 | [submodule "vendor/dokku-plugins/user-env-compile"] 12 | path = vendor/dokku-plugins/user-env-compile 13 | url = https://github.com/musicglue/dokku-user-env-compile.git 14 | [submodule "vendor/dokku-plugins/mariadb"] 15 | path = vendor/dokku-plugins/mariadb 16 | url = https://github.com/motin/dokku-md-plugin.git 17 | [submodule "vendor/dokku-plugins/custom-domains"] 18 | path = vendor/dokku-plugins/custom-domains 19 | url = https://github.com/neam/dokku-custom-domains.git 20 | [submodule "vendor/dokku-plugins/nginx-vhosts-custom-configuration"] 21 | path = vendor/dokku-plugins/nginx-vhosts-custom-configuration 22 | url = https://github.com/neam/dokku-nginx-vhosts-custom-configuration.git 23 | [submodule "vendor/dokku-plugins/deployment-keys"] 24 | path = vendor/dokku-plugins/deployment-keys 25 | url = https://github.com/cedricziel/dokku-deployment-keys.git 26 | [submodule "vendor/dokku-plugins/hostkeys"] 27 | path = vendor/dokku-plugins/hostkeys 28 | url = https://github.com/cedricziel/dokku-hostkeys-plugin.git 29 | -------------------------------------------------------------------------------- /shell-scripts-to-include/limit-dokku-apps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: ./limit-dokku-apps.sh 4 | 5 | # Kills all but the most recent containers that matches the against the list of folders in /home/dokku 6 | # Use to kill off older dokku apps so that resourced can be freed up 7 | # Useful in the case that your CI is automatically adding new commit-specific deployments 8 | 9 | # Note: Error handling is inadequate - when there are no dokku apps at all or none matching the regexes, cryptic error messages will be shown 10 | 11 | # Example: ./limit-dokku-apps.sh 3 'develop' 'foo' 12 | 13 | set -x 14 | 15 | # fail on any error 16 | set -o errexit 17 | 18 | # config 19 | 20 | LIMIT=$1 21 | GREPARGS=$2 22 | GREPARGS_EXCLUDE=$3 23 | 24 | if [ "$GREPARGS" == "" ]; then 25 | GREPARGS_EXCLUDE="dontincludeanythingzxcvasdfqwer" 26 | fi 27 | 28 | if [ "$GREPARGS_EXCLUDE" == "" ]; then 29 | GREPARGS_EXCLUDE="dontexcludeanythingzxcvasdfqwer" 30 | fi 31 | 32 | # logic 33 | 34 | cd /home/dokku 35 | APPS=`ls -dlt */ | grep "$GREPARGS" | grep -v "$GREPARGS_EXCLUDE" | wc | awk '{ print $1 }'` 36 | let KILL=APPS-LIMIT 37 | 38 | echo "$APPS dokku apps matching regex \"$GREPARGS\" exclude \"$GREPARGS_EXCLUDE\"" 39 | ls -dlt */ | grep "$GREPARGS" | grep -v "$GREPARGS_EXCLUDE" 40 | echo 41 | 42 | if [ "$KILL" -gt 0 ] ; then 43 | 44 | # remove all but the LIMIT newest apps 45 | ls -dt */ | grep "$GREPARGS" | grep -v "$GREPARGS_EXCLUDE" | awk '{ print $1 }' | tail -n "$KILL" | sed 's/\///' | xargs delete-dokku-apps.sh 46 | 47 | # remove phantom docker images and containers 48 | remove-phantom-docker-images-and-containers.sh 49 | 50 | fi 51 | 52 | exit 0 -------------------------------------------------------------------------------- /Vagrantfile.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | 9 | config.vm.box = "tknerr/managed-server-dummy" 10 | 11 | config.ssh.private_key_path = "~/.ssh/id_rsa" 12 | 13 | # this allows the vagrant box to use the private keys on the host computer 14 | config.ssh.forward_agent = true 15 | 16 | config.vm.provider :rackspace do |rs, override| 17 | rs.username = "<%= ENV['RACKSPACE_USERNAME'] %>" 18 | rs.api_key = "<%= ENV['RACKSPACE_API_KEY'] %>" 19 | rs.flavor = /<%= ENV['SIZE'] %>/ 20 | rs.image = /Trusty/ 21 | rs.rackspace_region = "<%= ENV['RACKSPACE_VM_REGION'] %>" 22 | rs.public_key_path = "~/.ssh/id_rsa.pub" 23 | rs.server_name = "<%= ENV['HOSTNAME'] %>" 24 | override.ssh.username = 'root' 25 | end 26 | 27 | config.vm.provider :digital_ocean do |provider| 28 | provider.token = "<%= ENV['DIGITAL_OCEAN_TOKEN'] %>" 29 | provider.image = "Dokku v0.2.3 on Ubuntu 14.04" 30 | provider.private_networking = true 31 | provider.backups_enabled = true 32 | provider.region = "<%= ENV['DIGITAL_OCEAN_REGION'] %>" 33 | provider.size = "<%= ENV['SIZE'] %>" 34 | end 35 | 36 | config.vm.provider :managed do |managed, override| 37 | managed.server = "<%= ENV['HOSTNAME'] %>" 38 | override.ssh.username = "root" 39 | end 40 | 41 | # sets the name of the droplet/server 42 | config.vm.define "<%= ENV['HOSTNAME'] %>" do |t| 43 | end 44 | 45 | # Set up provisioning 46 | config.vm.provision "shell", :path => "provision.sh" 47 | 48 | end 49 | -------------------------------------------------------------------------------- /docs/extras.md: -------------------------------------------------------------------------------- 1 | Extras 2 | ====== 3 | 4 | The ordinary readme instructions use the "Managed Server" provider which allows us to provision any existing server accessible using SSH (key-based authentication): 5 | 6 | ```bash 7 | export PROVIDER=managed 8 | ``` 9 | 10 | However, you may also start without any existing server and let vagrant create one for you: 11 | 12 | ## A new or existing Digital Ocean droplet 13 | 14 | You need to have the vagrant digital ocean plugin installed: 15 | 16 | ```bash 17 | vagrant plugin install vagrant-digitalocean 18 | ``` 19 | 20 | Set configuration specific to Digital Ocean: 21 | 22 | ```bash 23 | export DIGITAL_OCEAN_TOKEN="replaceme" 24 | export DIGITAL_OCEAN_REGION="ams2" 25 | export SIZE=8GB 26 | export PROVIDER=digital_ocean 27 | ``` 28 | 29 | Note: If the droplet already exists, `vagrant up` will link to the existing droplet and let you provision that. Note that it will not resize the droplet to the requested size - that was to be done manually. 30 | 31 | ## A new Rackspace Cloud Server 32 | 33 | You need to have the vagrant rackspace plugin installed: 34 | 35 | ```bash 36 | vagrant plugin install vagrant-rackspace 37 | ``` 38 | 39 | Set configuration specific to Rackspace: 40 | 41 | ```bash 42 | export RACKSPACE_USERNAME="replaceme" 43 | export RACKSPACE_API_KEY="replaceme" 44 | export RACKSPACE_VM_REGION="lon" 45 | export SIZE='2 GB Performance' 46 | export PROVIDER=rackspace 47 | ``` 48 | 49 | Note: There is currently no way to link to an existing rackspace server - `vagrant up` will create a new server on Rackspace. To connect to an existing server, use the "" instructions below. 50 | 51 | ## Elsewhere 52 | 53 | Consult the Vagrant documentation on how to deploy from scratch using other providers. Any provider that works with Vagrant should work with these configurations since we don't use any provider-specific features. 54 | 55 | -------------------------------------------------------------------------------- /provision.sh.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | # fail on any error 6 | set -o errexit 7 | 8 | cd /root 9 | 10 | # in order to prevent accidental overwrites of /root contents, we cd into our own directory where we perform the provisioning 11 | 12 | if [ ! -d provisioning ]; then 13 | mkdir provisioning 14 | fi 15 | cd provisioning 16 | 17 | # make the bash prompt show the fqdn of the current host in order to prevent confusion of where commands are run 18 | echo 'export PS1="${PS1/\\h/\\H}"' >> ~/.bashrc 19 | echo 'export PS1="${PS1/\\h/\\H}" # yes two times since there are two "\h" to replace' >> ~/.bashrc 20 | 21 | # install build-essential and htop 22 | 23 | apt-get update 24 | apt-get install -y -q build-essential htop curl 25 | 26 | # install shell-scripts in /usr/local/bin 27 | 28 | cp /vagrant/shell-scripts-to-include/*.sh /usr/local/bin/ 29 | 30 | # function definitions 31 | 32 | install_dokku() { 33 | if [ -d /root/dokku/ ]; then 34 | rm -r /root/dokku/ 35 | fi 36 | cp -r /vagrant/vendor/dokku /root/dokku 37 | cd /root/dokku/ 38 | DOCKER_VERSION=<%= ENV['DOCKER_VERSION'] %> make install 39 | service docker restart 40 | sleep 3 41 | } 42 | 43 | install_buildstep() { 44 | if [ -d /root/buildstep ]; then 45 | rm -r /root/buildstep 46 | fi 47 | cp -r /vagrant/vendor/buildstep /root/buildstep 48 | cd /root/buildstep 49 | sudo make build 50 | } 51 | 52 | # install dokku to a pinned down revision of master branch and docker that we have tested 53 | 54 | if [ ! -f "/root/dokku/REVISION" ]; then 55 | install_dokku 56 | fi 57 | 58 | installed_docker_version="$(dpkg-query -S "$(which docker)" | awk '{ print $1 }' | sed 's/lxc-docker-//g' | sed 's/://g')" 59 | installed_dokku_revision="$(cat /root/dokku/REVISION)" 60 | 61 | if [ "$installed_docker_version" != "<%= ENV['DOCKER_VERSION'] %>" ] || [ "$installed_dokku_revision" != "<%= ENV['DOKKU_REVISION'] %>" ]; then 62 | 63 | echo "Warning: Upgrading Dokku and Docker! This may lead to unexpected consequences regarding already running containers" 64 | install_dokku 65 | 66 | fi 67 | 68 | # install buildstep to a pinned down version of buildstep that we have tested 69 | 70 | if [ ! -f "/root/buildstep/REVISION" ]; then 71 | install_buildstep 72 | fi 73 | 74 | installed_buildstep_version="$(cat /root/buildstep/REVISION)" 75 | 76 | if [ "$installed_buildstep_version" != "<%= ENV['BUILDSTEP_REVISION'] %>" ]; then 77 | 78 | echo "Warning: Upgrading Buildstep! This will affect already deployed dokku apps as soon as they are rebuilt/updated" 79 | install_buildstep 80 | 81 | fi 82 | 83 | # skip GUI install - install by script 84 | echo "<%= ENV['HOSTNAME'] %>" > /home/dokku/HOSTNAME 85 | echo "<%= ENV['VHOST'] %>" > /home/dokku/VHOST 86 | if [ -f "/etc/nginx/conf.d/dokku-installer.conf" ]; then 87 | cat /root/.ssh/authorized_keys | head -n 1 | sshcommand acl-add dokku admin 88 | rm /etc/nginx/conf.d/dokku-installer.conf && /etc/init.d/nginx stop && /etc/init.d/nginx start 89 | rm /etc/init/dokku-installer.conf && stop dokku-installer 90 | fi 91 | 92 | # remove existing custom plugins 93 | 94 | cd /var/lib/dokku/plugins/ 95 | shopt -s extglob 96 | set +o errexit 97 | rm -rv !(dokku-plugins|nginx-vhosts|00_dokku-standard|backup|checks|config|git|WARNING) 98 | set -o errexit 99 | 100 | # install our custom dokku plugins 101 | 102 | cp -r /vagrant/vendor/dokku-plugins/* /var/lib/dokku/plugins/ 103 | dokku plugins-install 104 | 105 | # update nginx.conf to support longer than 46 character hostnames (default value 64 which equals 46 chars) 106 | 107 | sed -i 's/server_names_hash_bucket_size 64;/server_names_hash_bucket_size 128;/' /etc/nginx/nginx.conf 108 | cat /etc/nginx/nginx.conf | grep server 109 | /etc/init.d/nginx restart 110 | 111 | # add a dokkurc file to easily turn on and off debug mode (https://github.com/progrium/dokku/wiki/Troubleshooting) 112 | 113 | echo '#export DOKKU_TRACE=1' > /home/dokku/dokkurc 114 | 115 | # newrelic 116 | 117 | wget -O - http://download.newrelic.com/548C16BF.gpg | sudo apt-key add - 118 | sudo sh -c 'echo "deb http://apt.newrelic.com/debian/ newrelic non-free" > /etc/apt/sources.list.d/newrelic.list' 119 | sudo apt-get update 120 | apt-get install -y -q newrelic-sysmond 121 | nrsysmond-config --set license_key=<%= ENV['NEW_RELIC_LICENSE_KEY'] %> 122 | nrsysmond-config --set loglevel=warning 123 | nrsysmond-config --set loglevel=warning 124 | /etc/init.d/newrelic-sysmond start 125 | 126 | # add extra swap to make dokku more stable in oom situations (https://github.com/dotcloud/docker/issues/1555) 127 | 128 | if [ ! -f "/var/swap.1" ]; then 129 | sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=4096 130 | sudo /sbin/mkswap /var/swap.1 131 | sudo /sbin/swapon /var/swap.1 132 | echo '/var/swap.1 swap swap defaults 0 0' > /etc/fstab 133 | fi 134 | 135 | # papertrail for the dokku rsyslog and vhost proxy 136 | 137 | export PAPERTRAIL_PORT=<%= ENV['PAPERTRAIL_PORT'] %> 138 | apt-get install -y -q ruby1.9.1-dev build-essential 139 | gem install remote_syslog 140 | export HOSTNAME=`hostname` 141 | echo "\$LocalHostName $HOSTNAME" > /etc/rsyslog.d/00-fixed-hostname.conf 142 | echo "*.* @logs.papertrailapp.com:$PAPERTRAIL_PORT" > /etc/rsyslog.d/999-papertrail.conf 143 | service rsyslog restart 144 | killall remote_syslog || true 145 | remote_syslog -p $PAPERTRAIL_PORT --hostname $HOSTNAME -d logs.papertrailapp.com /var/log/nginx/access.log /var/log/nginx/error.log /var/log/newrelic/nrsysmond.log 146 | 147 | # nsenter 148 | 149 | if [ ! -f /usr/local/bin/nsenter ]; then 150 | cd /tmp 151 | curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz \ 152 | | tar -zxf- 153 | cd util-linux-2.24 154 | ./configure --without-ncurses 155 | make nsenter 156 | cp nsenter /usr/local/bin/ 157 | fi 158 | 159 | # install and start mailcatcher on the dokku instance 160 | 161 | docker pull nisenabe/mailcatcher 162 | set +o errexit 163 | docker ps -a | grep 'nisenabe/mailcatcher' | awk '{ print $1 }' | xargs docker rm -f 164 | set -o errexit 165 | docker run -d -p 1080:1080 -p 1025:1025 nisenabe/mailcatcher mailcatcher -f --verbose --ip 0.0.0.0 --smtp-port 1025 --http-port 1080 166 | 167 | # done 168 | 169 | echo 170 | echo "Provisioning complete!" 171 | echo 172 | echo "Now running a basic Nginx configuration test to see if there are any issues: (You need to manually correct any errors reported below)" 173 | echo 174 | nginx -t 175 | 176 | cd /root 177 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Dokku Host Provisioning - 1.0.0 2 | ----------------------------- 3 | 4 | Provide monitorable, debuggable and reliable production and/or staging environments using Dokku. 5 | 6 | Uses [Vagrant](http://www.vagrantup.com/) to provision Dokku hosts that runs a specific version of Dokku, Buildstep, Docker and various plug-ins. 7 | 8 | Allows easy provisioning of multiple Dokku Hosts (one for staging and another for production is a good idea for instance) by generating vagrant configurations separately for each host. 9 | 10 | Provisions: 11 | 12 | * Specific tested versions of Docker, Dokku, Buildstep and Dokku plugins 13 | * New Relic 14 | * Papertrail 15 | * Mailcatcher 16 | * nsenter 17 | * htop and mosh 18 | * Swap 19 | * A set of helper shell scripts (read below under "Shell Scripts") 20 | 21 | Requirements: 22 | 23 | A Ubuntu 14.04 LTS server that you have root access to via SSH. (May work with later versions or recent Debian 8+ as well, but we have only tested it with Ubuntu 14.04) 24 | 25 | ## Dokku Plugins 26 | 27 | * custom-domains 28 | * docker-options 29 | * mariadb 30 | * nginx-vhosts-custom-configuration 31 | * user-env-compile 32 | * deployment-keys & hostkeys 33 | 34 | ## Dokku version 35 | 36 | The version of Dokku provisioned is the latest master branch as of 2014-10-02 with the following additional patches that have yet to be merged into official dokku: 37 | 38 | * [Plugin nginx-vhosts includes files in folder nginx.conf.d](https://github.com/progrium/dokku/pull/579) 39 | * [Added create command](https://github.com/progrium/dokku/pull/599) 40 | 41 | This corresponds loosely to Dokku version 0.3.1 in functionality. 42 | 43 | ## Buildstep version 44 | 45 | The version of Buildstep provisioned is the latest master branch as of 2014-10-02 while as [the current (last checked 2015-01-02) master Dokku branch by default installs one from 2014-03-08](https://github.com/progrium/dokku/blob/f6b7b62b15250e1e396d2363ef49b8c1784888c3/Makefile#L6). 46 | 47 | The most notable difference is that your Dokku apps will be based on Ubuntu 14.04 LTS instead of Ubuntu 12.10 which is no longer supported and thus do not receive security updates. 48 | 49 | ## Docker version 50 | 51 | 1.2.0 is the current version of Docker provisioned. 52 | 53 | ## Working buildpacks 54 | 55 | These buildpacks are known to work with the provisioned Dokku host: 56 | 57 | * [https://github.com/ddollar/heroku-buildpack-apt#7993a88465873f318486a388187764294a6a615d](https://github.com/ddollar/heroku-buildpack-apt#7993a88465873f318486a388187764294a6a615d) 58 | * [https://github.com/heroku/heroku-buildpack-nodejs#d04d0f07fe4f4b4697532877b9730f0d583acd1d](https://github.com/heroku/heroku-buildpack-nodejs#d04d0f07fe4f4b4697532877b9730f0d583acd1d) 59 | * [https://github.com/neam/appsdeck-buildpack-php#83b9f6b451c29685cd0185340c2242998e986323](https://github.com/neam/appsdeck-buildpack-php#83b9f6b451c29685cd0185340c2242998e986323) 60 | * [https://github.com/ddollar/heroku-buildpack-multi.git](https://github.com/ddollar/heroku-buildpack-multi.git) 61 | 62 | Other buildpacks may rely on older versions of Buildstep / Ubuntu 12.10 and needs to be updated before working. 63 | 64 | Notably, the default PHP buildpack is currently broken. To use the working PHP buildpack listed above in your project repo: 65 | 66 | Add a `.buildpacks` file that instructs your app to use the Multi-buildpack (which supports version pinning) and in turn tells the Multi-buildpack to use the tested version of the above buildpack: 67 | 68 | ```bash 69 | echo 'https://github.com/neam/appsdeck-buildpack-php#83b9f6b451c29685cd0185340c2242998e986323' > .buildpacks 70 | git add .buildpacks 71 | git commit -m 'Updated PHP buildpack' 72 | ``` 73 | 74 | Note: You can use all of the above buildpacks at once, so that composer deps, node, npm and apt dependencies all are installed by using the following as the contents of your `.buildpacks` file: 75 | 76 | ``` 77 | https://github.com/ddollar/heroku-buildpack-apt#7993a88465873f318486a388187764294a6a615d 78 | https://github.com/heroku/heroku-buildpack-nodejs#d04d0f07fe4f4b4697532877b9730f0d583acd1d 79 | https://github.com/neam/appsdeck-buildpack-php#313f71652cd79f6a6a045710ea6ae210a74cc4d2 80 | ``` 81 | 82 | ## Usage 83 | 84 | The general workflow: 85 | 86 | 1. Set configuration via environment variables in the shell 87 | 2. Generate a configuration for a specific server 88 | 3. Provision the server 89 | 90 | Repeat steps 2 and 3 for every dokku host you wish to provision. 91 | 92 | Anytime you want to change the configuration, updated libraries or similar, you run the steps again. 93 | 94 | ### Provisioning a Dokku Host 95 | 96 | First, make sure you have key-based SSH authentication set-up against your target server. 97 | 98 | Some general configuration variables are necessary for the configurations before provisioning: 99 | 100 | ```bash 101 | export PROVIDER=managed 102 | export PAPERTRAIL_PORT="12345" 103 | export NEW_RELIC_LICENSE_KEY="replaceme" 104 | ``` 105 | 106 | Set configuration that depends on DNS (Note: Dokku needs wildcard subdomain registration to be able to map virtual hosts based on sub-domains): 107 | 108 | Example 1: 109 | 110 | ```bash 111 | export VHOST=foodev.com 112 | ``` 113 | 114 | Example 2: 115 | 116 | ```bash 117 | export VHOST=foo.com 118 | ``` 119 | 120 | To build vagrant configuration for a particular dokku host: 121 | 122 | ```bash 123 | export HOSTNAME=dokku.$VHOST 124 | mkdir -p build/$HOSTNAME 125 | git submodule init 126 | git submodule update --recursive 127 | cd build/$HOSTNAME 128 | ../../build-vagrant-config.sh 129 | ``` 130 | 131 | Then, if this is the first run: 132 | 133 | ```bash 134 | vagrant up --provider=$PROVIDER 135 | ``` 136 | 137 | Then, when a server is up and running, it needs to be provisioned (this command can also be run on existing deployments to update the deployment): 138 | 139 | ```bash 140 | vagrant provision 141 | ``` 142 | 143 | To enter the virtual machine: 144 | 145 | ```bash 146 | vagrant ssh 147 | ``` 148 | 149 | Now add deploy/push-access for yourself and set the default vhost in order to verify that your dokku host works as it should. 150 | 151 | ## Adding deploy/push-access to a developer 152 | 153 | From a machine that has root-access to the dokku-host: 154 | 155 | ```bash 156 | export DOKKU_HOST=$HOSTNAME 157 | export PUBLIC_KEY=~/.ssh/id_rsa.pub 158 | export DEVELOPER=john 159 | cat $PUBLIC_KEY | ssh root@$DOKKU_HOST "sudo sshcommand acl-add dokku $DEVELOPER" 160 | ``` 161 | 162 | This command is successful if only a ssh key fingerprint and no error messages show up. 163 | 164 | ## Setting the default vhost 165 | 166 | Currently when you visit a vhost on the dokku domain that does not exist, a seemingly random dokku app deployment is served to the user. To prevent confusion, push an app to your dokku host with a name like "00-default". As long as it lists first in `ls /home/dokku/*/nginx.conf | head`, it will be used as the default nginx vhost. 167 | 168 | Example: 169 | 170 | ```bash 171 | mkdir /tmp/00-default-app 172 | cd /tmp/00-default-app 173 | git flow init --defaults 174 | echo "This dokku-deployment does not exist" > index.php 175 | git add index.php 176 | git commit -m "Added index page" 177 | echo 'https://github.com/neam/appsdeck-buildpack-php#83b9f6b451c29685cd0185340c2242998e986323' > .buildpacks 178 | git add .buildpacks 179 | git commit -m 'Updated PHP buildpack' 180 | export APPNAME=00-default 181 | git push dokku@$HOSTNAME:$APPNAME develop:master 182 | ``` 183 | 184 | ## Supporting apps that have submodules that reference private repositories 185 | 186 | The dokku user on the Dokku host needs to be able to successfully authenticate by ssh key to your git host. 187 | 188 | If your repositories are hosted on GitHub, log in as root on the Dokku host and make sure the following works by following [official GitHub instructions](https://help.github.com/articles/generating-ssh-keys/): 189 | 190 | ```bash 191 | su dokku 192 | ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts 193 | ssh -T git@github.com 194 | ``` 195 | 196 | If your repositories are hosted on Bitbucket, log in as root on the Dokku host and make sure the following works: 197 | 198 | ```bash 199 | su dokku 200 | ssh-keyscan -t rsa bitbucket.org >> ~/.ssh/known_hosts 201 | ssh -T git@bitbucket.org 202 | ``` 203 | 204 | (Details why this is necessary can be found in [this comment](https://github.com/progrium/dokku/issues/644#issuecomment-57082992)) 205 | 206 | ## Troubleshooting 207 | 208 | ### The default Nginx welcome page is showing instead of my deployed apps 209 | 210 | You might need to remove the default Nginx page installed by the Nginx package / your distribution. For instance: 211 | 212 | ```bash 213 | rm /etc/nginx/sites-enabled/default 214 | ``` 215 | 216 | Then try pushing/deploying again. If it still doesn't work, there may be some nginx configuration issue. Login to your server and run `nginx -t` to see potential issues. 217 | 218 | ### My submodules are not working 219 | 220 | Did you follow the instructions "Supporting apps that have submodules that reference private repositories" above? If yes and there are still issues, see "Report a problem" below. 221 | 222 | ### Report a problem 223 | 224 | If you suspect a bug in this project, report it on https://github.com/neam/dokku-host-provisioning/issues. 225 | 226 | If you suspect a bug in general when using dokku, report the issue at https://github.com/progrium/dokku/issues, be sure to include relevant debugging information, for instance: 227 | 228 | ``` 229 | After installing and configuring a new Dokku host, I noticed that ___________ was not working properly. 230 | I tried troubleshooting it by _________, and _________, but I suspect that this is a bug with Dokku. 231 | I installed Dokku and relevant plugins by running the provisioning scripts found on https://github.com/neam/dokku-host-provisioning (v1.0.0) 232 | ``` 233 | 234 | ## Shell scripts 235 | 236 | The following shell scripts are available in /usr/local/bin on the dokku hosts, and may be useful: 237 | 238 | * `docker-enter.sh` - Uses nsenter to step into a running container (unlike `docker run` which will allow you to enter a new container only) 239 | * `limit-dokku-apps.sh` - Use to delete dokku apps en masse (to free up resources) 240 | * `delete-dokku-apps.sh` - Used by `limit-dokku-apps.sh` to actually delete one or many apps 241 | * `remove-phantom-docker-images-and-containers.sh` - The name says it all 242 | * `dokku-user-allow-port-forwarding.sh` - This script enables port-forwarding for all users using ssh keys with the dokku user and thus allows non-root users to connect to the mariadb instances on the dokku host 243 | --------------------------------------------------------------------------------