Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63f45e37ff | ||
|
|
1f4c1b5871 | ||
|
|
9432a380d0 | ||
|
|
2474844856 | ||
|
|
1d7422efb9 | ||
|
|
e2135a2c5f | ||
|
|
1d16541362 | ||
|
|
22c25dc40a | ||
|
|
dfac47cbe2 | ||
|
|
bd5b2b210c | ||
|
|
e33f5c94a5 | ||
|
|
80d6188032 | ||
|
|
6d82792508 | ||
|
|
e2a5e92cf7 | ||
|
|
9e49bc12ed | ||
|
|
4907c3c684 | ||
|
|
69c13f1bd3 | ||
|
|
3fcc49ff00 | ||
|
|
0c49481282 | ||
|
|
900fe6fe8c | ||
|
|
2368f2d65d | ||
|
|
f6b7b62b15 | ||
|
|
a9af04db81 | ||
|
|
c5665e1e83 | ||
|
|
09610c1e4e | ||
|
|
dd4c390168 | ||
|
|
b1267ebf56 | ||
|
|
7fc7a46ed3 | ||
|
|
0e46eba05b | ||
|
|
c2ae9fabe0 | ||
|
|
ee7d3295c9 | ||
|
|
082ba1dc96 | ||
|
|
ceeff6d09f | ||
|
|
25f4a81b71 | ||
|
|
37f977a68d | ||
|
|
75286cdfa1 | ||
|
|
217d00a1bc | ||
|
|
12c907b148 | ||
|
|
8c237153d2 | ||
|
|
4ec4354b0a | ||
|
|
59dfe6b529 | ||
|
|
f4d3d80075 | ||
|
|
af8e103bb3 | ||
|
|
0272e87433 | ||
|
|
c5b7a63c8d | ||
|
|
88433433dc | ||
|
|
8fca2204ed | ||
|
|
acb226cb86 | ||
|
|
d208e53649 | ||
|
|
57906fa562 | ||
|
|
3a3b56c7ab | ||
|
|
a892a920a8 | ||
|
|
f0c41e3a81 | ||
|
|
7b28307306 | ||
|
|
7f0591fa1e | ||
|
|
419efc2cf1 | ||
|
|
d9ed1e07eb | ||
|
|
3ee694d3ea | ||
|
|
7eae3b063c | ||
|
|
c16afaa338 | ||
|
|
921bdc48a6 | ||
|
|
b602cd3127 | ||
|
|
d72b79a18d | ||
|
|
723cf1d43d | ||
|
|
693800d709 | ||
|
|
28de3ecaa3 | ||
|
|
bd21149e8d | ||
|
|
c2aaa94523 | ||
|
|
1050f350c0 | ||
|
|
ec9e61d2bc | ||
|
|
74dfb605d7 | ||
|
|
b206c2b4f5 | ||
|
|
8210323ece | ||
|
|
fff066b120 | ||
|
|
48b4e330a3 | ||
|
|
baefdabdfc | ||
|
|
acf2dfa73a | ||
|
|
9876561fa9 | ||
|
|
2f97afb3f0 | ||
|
|
776c7c38af | ||
|
|
f64e27f32e | ||
|
|
6718094237 | ||
|
|
c77cbf1d3a | ||
|
|
1e76aba0af | ||
|
|
5c58a5e8e7 | ||
|
|
a4451e82ac | ||
|
|
4e737e739f | ||
|
|
aaa4f0fade | ||
|
|
56de22a3c8 | ||
|
|
1705307081 | ||
|
|
dd356d02ee | ||
|
|
c317dca558 | ||
|
|
9eff936676 | ||
|
|
882e7ac5fe | ||
|
|
95c9656fc8 | ||
|
|
432aec67d5 | ||
|
|
2ed527bedc | ||
|
|
698e5e5d0e | ||
|
|
10a8c75224 | ||
|
|
8a9182c859 | ||
|
|
e42c028d18 | ||
|
|
7ed57b285c | ||
|
|
99e0a43f81 | ||
|
|
e126da0db2 | ||
|
|
455be29249 | ||
|
|
3f487b2291 | ||
|
|
9ec7501940 | ||
|
|
a9e0a7b57e | ||
|
|
f4018db310 | ||
|
|
cb781f9ce1 | ||
|
|
ad9fe82bc7 | ||
|
|
dfcc46b1d2 | ||
|
|
4bc45256ff | ||
|
|
725a2e02da | ||
|
|
252b1ed8b6 | ||
|
|
9953030478 | ||
|
|
e8037da726 | ||
|
|
e85ab7bab4 | ||
|
|
d11f732595 | ||
|
|
f9db09fb21 | ||
|
|
557d555858 |
1
AUTHORS
1
AUTHORS
@@ -8,6 +8,7 @@ Felipe Coury <felipe.coury@gmail.com>
|
||||
Jeff Lindsay <progrium@gmail.com>
|
||||
Jose Diaz-Gonzalez <dokku@josediazgonzalez.com>
|
||||
Leo Unbekandt <leo@unbekandt.eu>
|
||||
Ludovic Perrine <jazzzz@gmail.com>
|
||||
Luigi Maselli <grigio.org@gmail.com>
|
||||
Martin Weiss <kornnflake@gmail.com>
|
||||
Paul Lietar <paul@lietar.net>
|
||||
|
||||
13
HISTORY.md
13
HISTORY.md
@@ -1,11 +1,20 @@
|
||||
# History
|
||||
|
||||
## 0.2.0 (in progress)
|
||||
## 0.3.0 (in progress)
|
||||
|
||||
* Cache dir is preserved across builds
|
||||
* Added git submodules support
|
||||
|
||||
## 0.2.0 (2013-11-24)
|
||||
|
||||
* Added DOKKU_TRACE variable for verbose trace information
|
||||
* Added an installer (for pre-built images)
|
||||
* Application config (environment variable management)
|
||||
* Backup/import plugin
|
||||
* Basic hooks/plugin system
|
||||
* Cache dir is preserved across builds
|
||||
* Command to delete an application
|
||||
* Exposed commands over SSH using sshcommand
|
||||
* Git handling is moved to a plugin
|
||||
* Integration test coverage
|
||||
* Pulled nginx vhosts out into plugin
|
||||
* Run command
|
||||
|
||||
4
LICENSE
4
LICENSE
@@ -1,7 +1,7 @@
|
||||
Copyright (C) 2013 Jeff Lindsay
|
||||
Copyright (C) 2014 Jeff Lindsay
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
31
Makefile
31
Makefile
@@ -1,20 +1,31 @@
|
||||
DOKKU_VERSION = master
|
||||
|
||||
SSHCOMMAND_URL ?= https://raw.github.com/progrium/sshcommand/master/sshcommand
|
||||
PLUGINHOOK_URL ?= https://s3.amazonaws.com/progrium-pluginhook/pluginhook_0.1.0_amd64.deb
|
||||
STACK_URL ?= github.com/progrium/buildstep
|
||||
PREBUILT_STACK_URL ?= https://s3.amazonaws.com/progrium-dokku/progrium_buildstep_79cf6805cf.tgz
|
||||
STACK_URL ?= https://github.com/progrium/buildstep.git
|
||||
PREBUILT_STACK_URL ?= https://github.com/progrium/buildstep/releases/download/2014-03-08/2014-03-08_429d4a9deb.tar.gz
|
||||
DOKKU_ROOT ?= /home/dokku
|
||||
|
||||
.PHONY: all install copyfiles plugins dependencies sshcommand pluginhook docker aufs stack count
|
||||
.PHONY: all install copyfiles version plugins dependencies sshcommand pluginhook docker aufs stack count
|
||||
|
||||
all:
|
||||
# Type "make install" to install.
|
||||
|
||||
install: dependencies stack copyfiles plugins
|
||||
install: dependencies stack copyfiles plugins version
|
||||
|
||||
copyfiles:
|
||||
copyfiles: addman
|
||||
cp dokku /usr/local/bin/dokku
|
||||
mkdir -p /var/lib/dokku/plugins
|
||||
cp -r plugins/* /var/lib/dokku/plugins
|
||||
|
||||
addman:
|
||||
mkdir -p /usr/local/share/man/man1
|
||||
cp dokku.1 /usr/local/share/man/man1/dokku.1
|
||||
mandb
|
||||
|
||||
version:
|
||||
git describe --tags > ${DOKKU_ROOT}/VERSION 2> /dev/null || echo '~${DOKKU_VERSION} ($(shell date -uIminutes))' > ${DOKKU_ROOT}/VERSION
|
||||
|
||||
plugins: pluginhook docker
|
||||
dokku plugins-install
|
||||
|
||||
@@ -35,7 +46,11 @@ docker: aufs
|
||||
curl https://get.docker.io/gpg | apt-key add -
|
||||
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
|
||||
apt-get update
|
||||
apt-get install -y lxc-docker
|
||||
ifdef DOCKER_VERSION
|
||||
apt-get install -y lxc-docker-${DOCKER_VERSION}
|
||||
else
|
||||
apt-get install -y lxc-docker
|
||||
endif
|
||||
sleep 2 # give docker a moment i guess
|
||||
|
||||
aufs:
|
||||
@@ -43,9 +58,9 @@ aufs:
|
||||
|
||||
stack:
|
||||
ifdef BUILD_STACK
|
||||
@docker images | grep progrium/buildstep || docker build -t progrium/buildstep ${STACK_URL}
|
||||
@docker images | grep progrium/buildstep || (git clone ${STACK_URL} /tmp/buildstep && docker build -t progrium/buildstep /tmp/buildstep && rm -rf /tmp/buildstep)
|
||||
else
|
||||
@docker images | grep progrium/buildstep || curl ${PREBUILT_STACK_URL} | gunzip -cd | docker import - progrium/buildstep
|
||||
@docker images | grep progrium/buildstep || curl -L ${PREBUILT_STACK_URL} | gunzip -cd | docker import - progrium/buildstep
|
||||
endif
|
||||
|
||||
count:
|
||||
|
||||
58
README.md
58
README.md
@@ -6,22 +6,30 @@ Docker powered mini-Heroku. The smallest PaaS implementation you've ever seen.
|
||||
|
||||
## Requirements
|
||||
|
||||
Assumes Ubuntu 13 x64 right now. Ideally have a domain ready to point to your host. It's designed for and is probably
|
||||
Assumes Ubuntu 13 or 12.04 x64 right now. Ideally have a domain ready to point to your host. It's designed for and is probably
|
||||
best to use a fresh VM. The bootstrapper will install everything it needs.
|
||||
|
||||
**Note: There are known issues with docker and Ubuntu 13.10 ([1](https://github.com/dotcloud/docker/issues/1300), [2](https://github.com/dotcloud/docker/issues/1906)) - use of 13.04 is recommended until these issues are resolved.**
|
||||
**Note: There are known issues with docker and Ubuntu 13.10 ([1](https://github.com/dotcloud/docker/issues/1300), [2](https://github.com/dotcloud/docker/issues/1906)) - use of 12.04 is recommended until these issues are resolved.**
|
||||
|
||||
## Installing
|
||||
|
||||
### Stable
|
||||
|
||||
$ wget -qO- https://raw.github.com/progrium/dokku/v0.2.2/bootstrap.sh | sudo DOKKU_TAG=v0.2.2 bash
|
||||
|
||||
**Note**: Users on 12.04 will need to run `apt-get install -y python-software-properties` before bootstrapping stable.
|
||||
|
||||
### Development
|
||||
|
||||
$ wget -qO- https://raw.github.com/progrium/dokku/master/bootstrap.sh | sudo bash
|
||||
|
||||
This may take around 5 minutes. Certainly better than the several hours it takes to bootstrap Cloud Foundry.
|
||||
|
||||
You may also wish to take a look at the [advanced installation](http://progrium.viewdocs.io/dokku/advanced-installation) document for aditional installation options.
|
||||
You may also wish to take a look at the [advanced installation](http://progrium.viewdocs.io/dokku/advanced-installation) document for additional installation options.
|
||||
|
||||
## Configuring
|
||||
|
||||
Set up a domain and a wildcard domain pointing to that host. Make sure `/home/dokku/VHOST` is set to this domain. By default it's set to whatever the hostname the host has. This file only created if the hostname can be resolved by dig (`dig +short $HOSTNAME`). Otherwise you have to create the file manually and set it to your prefered domain. If this file still not present when you push your app, dokku will publish the app with a port number (i.e. `http://example.com:49154` - note the missing subdomain).
|
||||
Set up a domain and a wildcard domain pointing to that host. Make sure `/home/dokku/VHOST` is set to this domain. By default it's set to whatever hostname the host has. This file is only created if the hostname can be resolved by dig (`dig +short $(hostname -f)`). Otherwise you have to create the file manually and set it to your preferred domain. If this file still is not present when you push your app, dokku will publish the app with a port number (i.e. `http://example.com:49154` - note the missing subdomain).
|
||||
|
||||
You'll have to add a public key associated with a username by doing something like this from your local machine:
|
||||
|
||||
@@ -52,9 +60,20 @@ Now you can deploy apps on your Dokku. Let's deploy the [Heroku Node.js sample a
|
||||
|
||||
You're done!
|
||||
|
||||
Dokku only supports deploying from its master branch, so if you'd like to deploy a different local branch use: ```git push progrium <local branch>:master```
|
||||
|
||||
Right now Buildstep supports buildpacks for Node.js, Ruby, Python, [and more](https://github.com/progrium/buildstep#supported-buildpacks). It's not hard to add more, [go add more](https://github.com/progrium/buildstep#adding-buildpacks)!
|
||||
Please check the documentation for your particular build pack as you may need to include configuration files (such as a Procfile) in your project root.
|
||||
|
||||
## Remote commands
|
||||
|
||||
Dokku commands can be run over ssh. Anywhere you would run `dokku <command>`, just run `ssh -t dokku@progriumapp.com <command>`
|
||||
The `-t` is used to request a pty. It is highly recommended to do so.
|
||||
To avoid the need to type the `-t` option each time, simply create/modify a section in the `.ssh/config` on the client side, as follows :
|
||||
|
||||
Host progriumapp.com
|
||||
RequestTTY yes
|
||||
|
||||
## Run a command in the app environment
|
||||
|
||||
It's possible to run commands in the environment of the deployed application:
|
||||
@@ -87,9 +106,34 @@ config:set <app> KEY1=VALUE1 [KEY2=VALUE2 ...] - set one or more config vars
|
||||
config:unset <app> KEY1 [KEY2 ...] - unset one or more config vars
|
||||
```
|
||||
|
||||
## SSL support
|
||||
## TLS/SPDY support
|
||||
|
||||
Dokku provides easy SSL support from the box. To enable SSL connection to your application, copy `.crt` and `.key` file into `/home/dokku/:app/ssl` folder (notice, file names should be `server.crt` and `server.key`, respectively). Redeployment of application will be needed to apply SSL configuration. Once it redeployed, application will be accessible by `https://` (redirection from `http://` is applied as well).
|
||||
Dokku provides easy TLS/SPDY support out of the box. This can be done app-by-app or for all subdomains at once. Note that whenever TLS support is enabled SPDY is also enabled.
|
||||
|
||||
### Per App
|
||||
|
||||
To enable TLS connection to to one of your applications, copy or symlink the `.crt`/`.pem` and `.key` files into the application's `/home/dokku/:app/tls` folder (create this folder if it doesn't exist) as `server.crt` and `server.key` respectively.
|
||||
|
||||
Redeployment of the application will be needed to apply TLS configuration. Once it is redeployed, the application will be accessible by `https://` (redirection from `http://` is applied as well).
|
||||
|
||||
### All Subdomains
|
||||
|
||||
To enable TLS connections for all your applications at once you will need a wildcard TLS certificate.
|
||||
|
||||
To enable TLS across all apps, copy or symlink the `.crt`/`.pem` and `.key` files into the `/home/dokku/tls` folder (create this folder if it doesn't exist) as `server.crt` and `server.key` respectively. Then, enable the certificates by editing `/etc/nginx/conf.d/dokku.conf` and uncommenting these two lines (remove the #):
|
||||
|
||||
ssl_certificate /home/dokku/tls/server.crt;
|
||||
ssl_certificate_key /home/dokku/tls/server.key;
|
||||
|
||||
The nginx configuration will need to be reloaded in order for the updated TLS configuration to be applied. This can be done either via the init system or by re-deploying the application. Once TLS is enabled, the application will be accessible by `https://` (redirection from `http://` is applied as well).
|
||||
|
||||
**Note**: TLS will not be enabled unless the application's VHOST matches the certificate's name. (i.e. if you have a cert for *.example.com TLS won't be enabled for something.example.org or example.net)
|
||||
|
||||
### HSTS Header
|
||||
|
||||
The [HSTS header](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) is an HTTP header that can inform browsers that all requests to a given site should be made via HTTPS. dokku does not, by default, enable this header. It is thus left up to you, the user, to enable it for your site.
|
||||
|
||||
Beware that if you enable the header and a subsequent deploy of your application results in an HTTP deploy (for whatever reason), the way the header works means that a browser will not attempt to request the HTTP version of your site if the HTTPS version fails.
|
||||
|
||||
## Upgrading
|
||||
|
||||
@@ -117,7 +161,7 @@ eventually replace the Docker image for buildstep.
|
||||
|
||||
## Support
|
||||
|
||||
You can use [Github Issues](https://github.com/progrium/dokku/issues), check [Troubleshooting](https://github.com/progrium/dokku/wiki/Troubleshooting) on the wiki, or join us on Freenode in #dokku
|
||||
You can use [Github Issues](https://github.com/progrium/dokku/issues), check [Troubleshooting](https://github.com/progrium/dokku/wiki/Troubleshooting) on the wiki, or join us on [freenode in #dokku](https://webchat.freenode.net/?channels=%23dokku)
|
||||
|
||||
## Components
|
||||
|
||||
|
||||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
@@ -3,6 +3,7 @@
|
||||
|
||||
BOX_NAME = ENV["BOX_NAME"] || "raring"
|
||||
BOX_URI = ENV["BOX_URI"] || "https://cloud-images.ubuntu.com/vagrant/raring/current/raring-server-cloudimg-amd64-vagrant-disk1.box"
|
||||
BOX_MEMORY = ENV["BOX_MEMORY"] || "512"
|
||||
DOKKU_DOMAIN = ENV["DOKKU_DOMAIN"] || "dokku.me"
|
||||
DOKKU_IP = ENV["DOKKU_IP"] || "10.0.0.2"
|
||||
PREBUILT_STACK_URL = File.exist?("#{File.dirname(__FILE__)}/stack.tgz") ? 'file:///root/dokku/stack.tgz' : nil
|
||||
@@ -25,6 +26,7 @@ Vagrant::configure("2") do |config|
|
||||
# Ubuntu's Raring 64-bit cloud image is set to a 32-bit Ubuntu OS type by
|
||||
# default in Virtualbox and thus will not boot. Manually override that.
|
||||
vb.customize ["modifyvm", :id, "--ostype", "Ubuntu_64"]
|
||||
vb.customize ["modifyvm", :id, "--memory", BOX_MEMORY]
|
||||
end
|
||||
|
||||
config.vm.provision :shell, :inline => "apt-get -y install git && cd /root/dokku && #{make_cmd}"
|
||||
|
||||
16
bootstrap.sh
16
bootstrap.sh
@@ -5,15 +5,25 @@ export DOKKU_REPO=${DOKKU_REPO:-"https://github.com/progrium/dokku.git"}
|
||||
|
||||
if ! which apt-get &>/dev/null
|
||||
then
|
||||
echo "This installation script requires apt-get. For manual installation instructions, consult https://github.com/progrium/dokku ."
|
||||
exit 1
|
||||
echo "This installation script requires apt-get. For manual installation instructions, consult https://github.com/progrium/dokku ."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
apt-get install -y git make curl software-properties-common
|
||||
|
||||
[[ `lsb_release -sr` == "12.04" ]] && apt-get install -y python-software-properties
|
||||
|
||||
cd ~ && test -d dokku || git clone $DOKKU_REPO
|
||||
cd dokku && test $DOKKU_BRANCH && git checkout origin/$DOKKU_BRANCH || true
|
||||
cd dokku
|
||||
git fetch origin
|
||||
|
||||
if [[ -n $DOKKU_BRANCH ]]; then
|
||||
git checkout origin/$DOKKU_BRANCH
|
||||
elif [[ -n $DOKKU_TAG ]]; then
|
||||
git checkout $DOKKU_TAG
|
||||
fi
|
||||
|
||||
make install
|
||||
|
||||
echo
|
||||
|
||||
@@ -16,11 +16,12 @@ if ARGV[0] == "onboot"
|
||||
f.puts " }"
|
||||
f.puts "}"
|
||||
end
|
||||
`rm /etc/nginx/sites-enabled/*`
|
||||
puts "Installed Upstart service and default Nginx virtualhost for installer to run on boot."
|
||||
exit
|
||||
end
|
||||
|
||||
version = "v0.2.0"
|
||||
version = "v0.2.1"
|
||||
dokku_root = ENV["DOKKU_ROOT"] || "/home/dokku"
|
||||
admin_key = `cat /root/.ssh/authorized_keys`.split("\n").first
|
||||
hostname = `bash -c '[[ $(dig +short $HOSTNAME) ]] && echo $HOSTNAME || curl icanhazip.com'`.strip
|
||||
@@ -103,7 +104,7 @@ __END__
|
||||
});
|
||||
}
|
||||
function update() {
|
||||
if ($("#vhost").is(":checked") && !isNaN($("#hostname").val()[0])) {
|
||||
if ($("#vhost").is(":checked") && $("#hostname").val().match(/^(\d{1,3}\.){3}\d{1,3}$/)) {
|
||||
alert("In order to use virtualhost naming, the hostname must not be an IP but a valid domain name.")
|
||||
$("#vhost").prop('checked', false);
|
||||
}
|
||||
@@ -118,4 +119,4 @@ __END__
|
||||
update();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
48
dokku
48
dokku
@@ -7,58 +7,65 @@ export PLUGIN_PATH=${PLUGIN_PATH:="/var/lib/dokku/plugins"}
|
||||
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
if [[ $(id -un) != "dokku" && $1 != "plugins-install" ]]; then
|
||||
sudo -u dokku -H $0 "$@"
|
||||
exit
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
receive)
|
||||
APP="$2"; IMAGE="app/$APP"
|
||||
echo "-----> Building $APP ..."
|
||||
cat | dokku build $APP $IMAGE
|
||||
echo "-----> Releasing $APP ..."
|
||||
dokku release $APP $IMAGE
|
||||
echo "-----> Deploying $APP ..."
|
||||
dokku deploy $APP $IMAGE
|
||||
APP="$2"; IMAGE="dokku/$APP"
|
||||
echo "-----> Cleaning up ..."
|
||||
dokku cleanup
|
||||
echo "-----> Building $APP ..."
|
||||
cat | dokku build $APP
|
||||
echo "-----> Releasing $APP ..."
|
||||
dokku release $APP
|
||||
echo "-----> Deploying $APP ..."
|
||||
dokku deploy $APP
|
||||
echo "=====> Application deployed:"
|
||||
echo " $(dokku url $APP)"
|
||||
echo
|
||||
;;
|
||||
|
||||
build)
|
||||
APP="$2"; IMAGE="$3"; CACHE_DIR="$HOME/$APP/cache"
|
||||
APP="$2"; IMAGE="dokku/$APP"; CACHE_DIR="$DOKKU_ROOT/$APP/cache"
|
||||
id=$(cat | docker run -i -a stdin progrium/buildstep /bin/bash -c "mkdir -p /app && tar -xC /app")
|
||||
test $(docker wait $id) -eq 0
|
||||
docker commit $id $IMAGE > /dev/null
|
||||
[[ -d $CACHE_DIR ]] || mkdir $CACHE_DIR
|
||||
pluginhook pre-build $APP $IMAGE
|
||||
pluginhook pre-build $APP
|
||||
id=$(docker run -d -v $CACHE_DIR:/cache $IMAGE /build/builder)
|
||||
docker attach $id
|
||||
test $(docker wait $id) -eq 0
|
||||
docker commit $id $IMAGE > /dev/null
|
||||
pluginhook post-build $APP
|
||||
;;
|
||||
|
||||
release)
|
||||
APP="$2"; IMAGE="$3"
|
||||
pluginhook pre-release $APP $IMAGE
|
||||
APP="$2"; IMAGE="dokku/$APP"
|
||||
pluginhook pre-release $APP
|
||||
if [[ -f "$DOKKU_ROOT/$APP/ENV" ]]; then
|
||||
id=$(cat "$DOKKU_ROOT/$APP/ENV" | docker run -i -a stdin $IMAGE /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/app-env.sh")
|
||||
test $(docker wait $id) -eq 0
|
||||
docker commit $id $IMAGE > /dev/null
|
||||
fi
|
||||
pluginhook post-release $APP $IMAGE
|
||||
pluginhook post-release $APP
|
||||
;;
|
||||
|
||||
deploy)
|
||||
APP="$2"; IMAGE="$3"
|
||||
pluginhook pre-deploy $APP $IMAGE
|
||||
APP="$2"; IMAGE="dokku/$APP"
|
||||
pluginhook pre-deploy $APP
|
||||
|
||||
# kill the app when running
|
||||
if [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then
|
||||
if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then
|
||||
oldid=$(< "$DOKKU_ROOT/$APP/CONTAINER")
|
||||
docker kill $oldid > /dev/null
|
||||
docker inspect $oldid &> /dev/null && docker kill $oldid > /dev/null
|
||||
fi
|
||||
|
||||
# start the app
|
||||
id=$(docker run -d -p 5000 -e PORT=5000 $IMAGE /bin/bash -c "/start web")
|
||||
DOCKER_ARGS=$(: | pluginhook docker-args $APP)
|
||||
id=$(docker run -d -p 5000 -e PORT=5000 $DOCKER_ARGS $IMAGE /bin/bash -c "/start web")
|
||||
echo $id > "$DOKKU_ROOT/$APP/CONTAINER"
|
||||
port=$(docker port $id 5000 | sed 's/0.0.0.0://')
|
||||
echo $port > "$DOKKU_ROOT/$APP/PORT"
|
||||
@@ -86,8 +93,7 @@ case "$1" in
|
||||
deploy:all)
|
||||
for app in $(ls -d $DOKKU_ROOT/*/); do
|
||||
APP=$(basename $app);
|
||||
IMAGE="app/$APP"
|
||||
dokku deploy $APP $IMAGE
|
||||
dokku deploy $APP
|
||||
done
|
||||
;;
|
||||
|
||||
@@ -100,7 +106,9 @@ EOF
|
||||
;;
|
||||
|
||||
*)
|
||||
pluginhook commands "$@"
|
||||
for script in $(ls -d /var/lib/dokku/plugins/*/commands); do
|
||||
$script "$@"
|
||||
done
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
58
dokku.1
Normal file
58
dokku.1
Normal file
@@ -0,0 +1,58 @@
|
||||
.TH DOKKU 1 2014-03-08
|
||||
.\"Make sure to change that date when you commit a change!
|
||||
.\"
|
||||
.SH NAME
|
||||
dokku \- configure and get information from your dokku installation
|
||||
.\"
|
||||
.SH SYNOPSIS
|
||||
.B dokku
|
||||
.I <command>
|
||||
.\"
|
||||
.SH DESCRIPTION
|
||||
.B dokku
|
||||
is a catch-all command to configure your apps,
|
||||
work with plugins and inspect the current state of your server.
|
||||
.\"
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI backup:import " file"
|
||||
Import dokku config files.
|
||||
.TP
|
||||
.BI backup:export " file"
|
||||
Export dokku config files.
|
||||
.TP
|
||||
.BI config " <app>"
|
||||
Display the config vars for an app.
|
||||
.TP
|
||||
.BI config:get " <app> KEY"
|
||||
Display a specific config var for an app.
|
||||
.TP
|
||||
.BI config:set " <app> KEY1=VAL1" \fR\ (KEY2=VAL2\ \.\.\.)
|
||||
Set one or more config vars for an app.
|
||||
.TP
|
||||
.BI config:unset " <app> KEY1" \fR\ (KEY2\ \.\.\.)
|
||||
Remove one or more config vars from an app.
|
||||
.TP
|
||||
.BI delete " <app>"
|
||||
Delete an application.
|
||||
.TP
|
||||
.B help
|
||||
Print the list of commands.
|
||||
.TP
|
||||
.B logs \ \fI<app> \fR[\fI-t\fR]
|
||||
Show the last logs for an application (-t follows)
|
||||
.TP
|
||||
.B plugins-install
|
||||
Install active plugins.
|
||||
.TP
|
||||
.B plugins
|
||||
Print active plugins.
|
||||
.TP
|
||||
.BI run " <app> command"
|
||||
Run a command in the environment of an app.
|
||||
.TP
|
||||
.BI url " <app>"
|
||||
Show the url for an app.
|
||||
.TP
|
||||
.B version
|
||||
Print dokku's version.
|
||||
18
plugins/00_dokku-standard/backup-check
Executable file
18
plugins/00_dokku-standard/backup-check
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
VERSION="$1"
|
||||
IMPORT_DIR="$2"
|
||||
TARGET_DIR="$3"
|
||||
APPS="$(< $4 )"
|
||||
|
||||
ret=0
|
||||
|
||||
for app in $APPS; do
|
||||
if [[ -d $TARGET_DIR/$app ]]; then
|
||||
ret=1
|
||||
echo "Trying to import application $app which already exists." 2>&1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $ret
|
||||
|
||||
@@ -6,8 +6,8 @@ TARGET_DIR="$3"
|
||||
|
||||
[[ -f $IMPORT_DIR/.sshcommand ]] && mv $IMPORT_DIR/.sshcommand $TARGET_DIR/.sshcommand
|
||||
if [[ -f $IMPORT_DIR/.ssh/authorized_keys ]]; then
|
||||
mkdir $TARGET_DIR/.ssh
|
||||
mv $IMPORT_DIR/.ssh/authorized_keys $TARGET_DIR/.ssh/authorized_keys
|
||||
mkdir -p $TARGET_DIR/.ssh
|
||||
cat $IMPORT_DIR/.ssh/authorized_keys $TARGET_DIR/.ssh/authorized_keys | uniq > $TARGET_DIR/.ssh/authorized_keys
|
||||
chmod 0700 $TARGET_DIR/.ssh
|
||||
chmod 0600 $TARGET_DIR/.ssh/*
|
||||
fi
|
||||
|
||||
@@ -6,18 +6,21 @@ case "$1" in
|
||||
echo "Please specify an app to delete"
|
||||
exit 1
|
||||
fi
|
||||
APP="$2"; IMAGE="app/$APP";
|
||||
APP="$2"; IMAGE="dokku/$APP";
|
||||
if [[ ! -d "$DOKKU_ROOT/$APP" ]]; then
|
||||
echo "App does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pluginhook pre-delete $APP
|
||||
ID=$(< "$DOKKU_ROOT/$APP/CONTAINER")
|
||||
if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then
|
||||
ID=$(< "$DOKKU_ROOT/$APP/CONTAINER")
|
||||
|
||||
docker stop $ID > /dev/null || true
|
||||
docker rm $ID > /dev/null || true
|
||||
fi
|
||||
|
||||
docker stop $ID > /dev/null
|
||||
docker images | grep $IMAGE | awk '{print $3}' | xargs docker rmi &> /dev/null &
|
||||
docker rm $ID > /dev/null
|
||||
|
||||
pluginhook post-delete $APP
|
||||
;;
|
||||
@@ -32,11 +35,16 @@ case "$1" in
|
||||
echo "App $APP does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONTAINER=$(<$DOKKU_ROOT/$APP/CONTAINER)
|
||||
docker logs $CONTAINER | tail -n 100
|
||||
if [[ $3 == "-t" ]]; then
|
||||
docker attach $CONTAINER
|
||||
|
||||
if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then
|
||||
CONTAINER=$(<$DOKKU_ROOT/$APP/CONTAINER)
|
||||
if [[ $3 == "-t" ]]; then
|
||||
docker logs --follow $CONTAINER
|
||||
else
|
||||
docker logs $CONTAINER | tail -n 100
|
||||
fi
|
||||
else
|
||||
echo "Application's container not found"
|
||||
fi
|
||||
;;
|
||||
|
||||
@@ -45,13 +53,15 @@ case "$1" in
|
||||
echo "Please specify an app to run the command on"
|
||||
exit 1
|
||||
fi
|
||||
APP="$2"; IMAGE="app/$APP"
|
||||
APP="$2"; IMAGE="dokku/$APP"
|
||||
if [[ ! -d "$DOKKU_ROOT/$APP" ]]; then
|
||||
echo "App $APP does not exist"
|
||||
exit 1
|
||||
fi
|
||||
shift 2
|
||||
docker run -i -t -a stdout -a stderr $IMAGE /exec "$@"
|
||||
|
||||
DOCKER_ARGS=$(: | pluginhook docker-args $APP)
|
||||
docker run -i -t $DOCKER_ARGS $IMAGE /exec "$@"
|
||||
;;
|
||||
|
||||
url)
|
||||
@@ -66,14 +76,22 @@ case "$1" in
|
||||
fi
|
||||
;;
|
||||
|
||||
version)
|
||||
cat "$DOKKU_ROOT/VERSION" || {
|
||||
echo "Unable to determine dokku's version" 2>&1
|
||||
exit 1
|
||||
}
|
||||
;;
|
||||
|
||||
help)
|
||||
cat && cat<<EOF
|
||||
delete <app> Delete an application
|
||||
logs <app> [-t] Show the last logs for an application (-t follows)
|
||||
run <app> <cmd> Run a command in the environment of an application
|
||||
url <app> Show the URL for an application
|
||||
version Print dokku's version
|
||||
EOF
|
||||
;;
|
||||
|
||||
esac
|
||||
cat
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
sed -i 's/docker -d$/docker -d -r=true/' /etc/init/docker.conf
|
||||
|
||||
if [[ ! -f "$DOKKU_ROOT/HOSTNAME" ]]; then
|
||||
echo $(hostname -f) > $DOKKU_ROOT/HOSTNAME
|
||||
fi
|
||||
|
||||
10
plugins/00_dokku-standard/pre-delete
Executable file
10
plugins/00_dokku-standard/pre-delete
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
APP="$1"
|
||||
IMAGE=dokku/"$1"
|
||||
CACHE_DIR="$DOKKU_ROOT/$APP/cache"
|
||||
|
||||
docker run -v $CACHE_DIR:/cache $IMAGE find /cache -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} \;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ set -e; case "$1" in
|
||||
BACKUP_TMP_DIR=$(mktemp -d)
|
||||
BACKUP_TMP_FILE="$BACKUP_TMP_DIR/backup.tar"
|
||||
|
||||
pluginhook backup-export 1 $BACKUP_DIR | tar -cf $BACKUP_TMP_FILE --files-from -
|
||||
: | pluginhook backup-export 1 $BACKUP_DIR | tar -cf $BACKUP_TMP_FILE --files-from -
|
||||
|
||||
pushd $BACKUP_DIR > /dev/null
|
||||
ls -d */ | grep -oE '[^/]+' > "$BACKUP_TMP_DIR/.dokku_backup_apps"
|
||||
@@ -33,6 +33,13 @@ set -e; case "$1" in
|
||||
;;
|
||||
|
||||
backup:import)
|
||||
if [[ $2 == "-f" ]]; then
|
||||
force=true
|
||||
shift
|
||||
else
|
||||
force=false
|
||||
fi
|
||||
|
||||
INPUT_FILE="$2"
|
||||
[[ -z $INPUT_FILE ]] && INPUT_FILE="-"
|
||||
|
||||
@@ -56,8 +63,17 @@ set -e; case "$1" in
|
||||
BACKUP_ROOT="$BACKUP_TMP_DIR""$DOKKU_ROOT"
|
||||
TARGET_DIR="$DOKKU_ROOT"
|
||||
|
||||
if ! pluginhook backup-check $VERSION "$BACKUP_ROOT" "$TARGET_DIR" "$BACKUP_TMP_DIR/.dokku_backup_apps"; then
|
||||
if $force; then
|
||||
echo "-f used. Ignoring warnings."
|
||||
else
|
||||
echo "Archive did not pass sanity checks. Use -f to import anyway" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# create all the app directories
|
||||
while read app; do mkdir "$TARGET_DIR/$app"; echo "Imported $app"; done < $BACKUP_TMP_DIR/.dokku_backup_apps > /dev/null
|
||||
while read app; do mkdir "$TARGET_DIR/$app"; echo "Imported $app"; done < $BACKUP_TMP_DIR/.dokku_backup_apps
|
||||
|
||||
# have the plugins import their stuff
|
||||
pluginhook backup-import $VERSION "$BACKUP_ROOT" $TARGET_DIR "$BACKUP_TMP_DIR/.dokku_backup_apps"
|
||||
@@ -75,4 +91,4 @@ EOF
|
||||
;;
|
||||
|
||||
esac
|
||||
cat
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
shopt -s nullglob
|
||||
VERSION="$1"
|
||||
BASE_DIR="$2"
|
||||
|
||||
cat; find $BASE_DIR -regex ".*/ENV"
|
||||
cat; for i in $BASE_DIR/*/ENV; do echo $i; done
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
shopt -s nullglob
|
||||
VERSION="$1"
|
||||
IMPORT_DIR="$2"
|
||||
TARGET_DIR="$3"
|
||||
|
||||
cd $IMPORT_DIR
|
||||
for file in `find . -regex ".*/ENV"`; do
|
||||
for file in */ENV; do
|
||||
cp $file "$TARGET_DIR/$file"
|
||||
done
|
||||
|
||||
@@ -49,13 +49,13 @@ config_styled_hash () {
|
||||
}
|
||||
|
||||
config_restart_app() {
|
||||
APP="$1"; IMAGE="app/$APP"
|
||||
APP="$1";
|
||||
|
||||
echo "-----> Releasing $APP ..."
|
||||
dokku release $APP $IMAGE
|
||||
dokku release $APP
|
||||
echo "-----> Release complete!"
|
||||
echo "-----> Deploying $APP ..."
|
||||
dokku deploy $APP $IMAGE
|
||||
dokku deploy $APP
|
||||
echo "-----> Deploy complete!"
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ case "$1" in
|
||||
fi
|
||||
done
|
||||
|
||||
echo "=== $APP Config Vars"
|
||||
echo "=== $APP config vars ==="
|
||||
config_styled_hash "$VARS"
|
||||
;;
|
||||
|
||||
@@ -108,7 +108,6 @@ case "$1" in
|
||||
APP="$2"; APP_DIR="$DOKKU_ROOT/$APP"
|
||||
ENV_ADD=""
|
||||
ENV_TEMP=`cat "${ENV_FILE}"`
|
||||
ID=$(< "$APP_DIR/CONTAINER")
|
||||
RESTART=false
|
||||
VARS="${*:3}"
|
||||
|
||||
@@ -151,7 +150,6 @@ case "$1" in
|
||||
|
||||
APP="$2"; APP_DIR="$DOKKU_ROOT/$APP"
|
||||
ENV_TEMP=`cat "${ENV_FILE}"`
|
||||
ID=$(< "$APP_DIR/CONTAINER")
|
||||
VARS="${*:3}"
|
||||
|
||||
for var in $VARS; do
|
||||
@@ -173,4 +171,4 @@ EOF
|
||||
;;
|
||||
|
||||
esac
|
||||
cat
|
||||
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
git_archive_all() {
|
||||
APP=$1; REV=$2
|
||||
TMP_WORK_DIR=$(mktemp -d)
|
||||
chmod 755 $TMP_WORK_DIR
|
||||
unset GIT_DIR GIT_WORK_TREE
|
||||
git clone $DOKKU_ROOT/$APP $TMP_WORK_DIR > /dev/null
|
||||
pushd $TMP_WORK_DIR > /dev/null
|
||||
git config advice.detachedHead false
|
||||
git checkout $REV > /dev/null
|
||||
git submodule update --init --recursive > /dev/null
|
||||
find -name .git -prune -exec rm -rf {} \; > /dev/null
|
||||
tar c .
|
||||
popd > /dev/null
|
||||
rm -rf $TMP_WORK_DIR > /dev/null
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
git-hook)
|
||||
APP=$2
|
||||
@@ -10,7 +26,10 @@ case "$1" in
|
||||
# Only run this script for the master branch. You can remove this
|
||||
# if block if you wish to run it for others as well.
|
||||
if [[ $refname = "refs/heads/master" ]] ; then
|
||||
git archive $newrev | dokku receive $APP | sed -u "s/^/"$'\e[1G'"/"
|
||||
git_archive_all $APP $newrev | dokku receive $APP | sed -u "s/^/"$'\e[1G'"/"
|
||||
else
|
||||
echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to master."
|
||||
echo $'\e[1G\e[K'"-----> for example, try 'git push <dokku> ${refname/refs\/heads\/}:master'"
|
||||
fi
|
||||
|
||||
done
|
||||
@@ -20,7 +39,7 @@ case "$1" in
|
||||
APP="$(echo $2 | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g')"
|
||||
APP_PATH=$DOKKU_ROOT/$APP
|
||||
|
||||
if [[ $1 == "git-receive-pack" && ! -d $APP_PATH ]]; then
|
||||
if [[ $1 == "git-receive-pack" && ! -d "$APP_PATH/refs" ]]; then
|
||||
git init --bare $APP_PATH > /dev/null
|
||||
PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive"
|
||||
cat > $PRERECEIVE_HOOK <<EOF
|
||||
@@ -35,6 +54,8 @@ EOF
|
||||
git-shell -c "$args"
|
||||
;;
|
||||
|
||||
help)
|
||||
cat
|
||||
;;
|
||||
esac
|
||||
cat
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
shopt -s nullglob
|
||||
VERSION="$1"
|
||||
BASE_DIR="$2"
|
||||
|
||||
cat; find $BASE_DIR -regex ".*ssl/server\(.crt\|.key\)";
|
||||
cat; for i in $BASE_DIR/*/ssl/server.*; do echo $i; done
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
shopt -s nullglob
|
||||
VERSION="$1"
|
||||
IMPORT_DIR="$2"
|
||||
TARGET_DIR="$3"
|
||||
|
||||
cd $IMPORT_DIR
|
||||
|
||||
for file in `find . -regex ".*ssl/server\(.crt\|.key\)"`; do
|
||||
for file in */ssl/server.*; do
|
||||
mkdir -p $(dirname $TARGET_DIR$file)
|
||||
cp $file $TARGET_DIR$file
|
||||
done
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
cat
|
||||
|
||||
case "$1" in
|
||||
help)
|
||||
cat
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -14,8 +14,19 @@ if ! grep -q dokku-nginx-reload "/etc/sudoers"; then
|
||||
rm /tmp/sudoers.new
|
||||
fi
|
||||
|
||||
echo "include $DOKKU_ROOT/*/nginx.conf;" > /etc/nginx/conf.d/dokku.conf
|
||||
cat<<EOF > /etc/nginx/conf.d/dokku.conf
|
||||
include $DOKKU_ROOT/*/nginx.conf;
|
||||
|
||||
ssl_session_cache shared:SSL:20m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!CAMELLIA;
|
||||
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
#ssl_certificate $DOKKU_ROOT/tls/server.crt;
|
||||
#ssl_certificate_key $DOKKU_ROOT/tls/server.key;
|
||||
EOF
|
||||
sed -i 's/# server_names_hash_bucket_size/server_names_hash_bucket_size/' /etc/nginx/nginx.conf
|
||||
|
||||
if [[ ! -f "$DOKKU_ROOT/VHOST" ]]; then
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
APP="$1"; PORT="$2"
|
||||
WILDCARD_SSL="$DOKKU_ROOT/ssl"
|
||||
SSL="$DOKKU_ROOT/$APP/ssl"
|
||||
WILDCARD_SSL="$DOKKU_ROOT/tls"
|
||||
SSL="$DOKKU_ROOT/$APP/tls"
|
||||
|
||||
if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
|
||||
VHOST=$(< "$DOKKU_ROOT/VHOST")
|
||||
@@ -13,10 +13,16 @@ if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
|
||||
hostname="${APP/\//-}.$VHOST"
|
||||
fi
|
||||
|
||||
if [[ -f "$SSL/server.crt" ]] && [[ -f "$SSL/server.key" ]]; then
|
||||
if [[ -e "$SSL/server.crt" ]] && [[ -e "$SSL/server.key" ]]; then
|
||||
SSL_INUSE="$SSL"
|
||||
elif [[ -f "$WILDCARD_SSL/server.crt" ]] && [[ -f "$WILDCARD_SSL/server.key" ]] && [[ $hostname = `openssl x509 -in $WILDCARD_SSL/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-` ]]; then
|
||||
SSL_DIRECTIVES=$(cat <<EOF
|
||||
ssl_certificate $SSL_INUSE/server.crt;
|
||||
ssl_certificate_key $SSL_INUSE/server.key;
|
||||
EOF
|
||||
)
|
||||
elif [[ -e "$WILDCARD_SSL/server.crt" ]] && [[ -e "$WILDCARD_SSL/server.key" ]] && [[ $hostname = `openssl x509 -in $WILDCARD_SSL/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-` ]]; then
|
||||
SSL_INUSE="$WILDCARD_SSL"
|
||||
SSL_DIRECTIVES=""
|
||||
fi
|
||||
|
||||
# ssl based nginx.conf
|
||||
@@ -24,21 +30,20 @@ if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
|
||||
cat<<EOF > $DOKKU_ROOT/$APP/nginx.conf
|
||||
upstream $APP { server 127.0.0.1:$PORT; }
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
server_name $hostname;
|
||||
return 301 https://\$host\$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
listen [::]:443 ssl spdy;
|
||||
listen 443 ssl spdy;
|
||||
server_name $hostname;
|
||||
$SSL_DIRECTIVES
|
||||
|
||||
ssl on;
|
||||
ssl_certificate $SSL_INUSE/server.crt;
|
||||
ssl_certificate_key $SSL_INUSE/server.key;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!CAMELLIA;
|
||||
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
ssl_prefer_server_ciphers on;
|
||||
keepalive_timeout 70;
|
||||
add_header Alternate-Protocol 443:npn-spdy/2;
|
||||
|
||||
location / {
|
||||
proxy_pass http://$APP;
|
||||
@@ -60,6 +65,7 @@ else
|
||||
cat<<EOF > $DOKKU_ROOT/$APP/nginx.conf
|
||||
upstream $APP { server 127.0.0.1:$PORT; }
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
server_name $hostname;
|
||||
location / {
|
||||
|
||||
1
tests/apps/config/Procfile
Normal file
1
tests/apps/config/Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: node web.js
|
||||
3
tests/apps/config/check_deploy
Executable file
3
tests/apps/config/check_deploy
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
set -e; output="$(curl -s $1)"; echo $output; test "$output" == "config-test"
|
||||
|
||||
11
tests/apps/config/package.json
Normal file
11
tests/apps/config/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "node-example",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"express": "2.5.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": "0.8.x",
|
||||
"npm": "1.1.x"
|
||||
}
|
||||
}
|
||||
8
tests/apps/config/post-deploy
Executable file
8
tests/apps/config/post-deploy
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -ex;
|
||||
|
||||
REMOTE=$1
|
||||
REPO=$2
|
||||
|
||||
ssh $REMOTE config:set $REPO CONFTEST=config-test
|
||||
|
||||
12
tests/apps/config/web.js
Normal file
12
tests/apps/config/web.js
Normal file
@@ -0,0 +1,12 @@
|
||||
var express = require('express');
|
||||
|
||||
var app = express.createServer(express.logger());
|
||||
|
||||
app.get('/', function(request, response) {
|
||||
response.send(process.env.CONFTEST);
|
||||
});
|
||||
|
||||
var port = process.env.PORT || 5000;
|
||||
app.listen(port, function() {
|
||||
console.log("Listening on " + port);
|
||||
});
|
||||
1
tests/apps/gitsubmodules/Procfile
Normal file
1
tests/apps/gitsubmodules/Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: node node-js-sample/web.js
|
||||
2
tests/apps/gitsubmodules/check_deploy
Executable file
2
tests/apps/gitsubmodules/check_deploy
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
set -e; output="$(curl -s $1)"; echo $output; test "$output" == "Hello World!"
|
||||
11
tests/apps/gitsubmodules/package.json
Normal file
11
tests/apps/gitsubmodules/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "node-example",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"express": "~3.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "0.10.x",
|
||||
"npm": "1.3.x"
|
||||
}
|
||||
}
|
||||
2
tests/apps/gitsubmodules/pre-commit
Executable file
2
tests/apps/gitsubmodules/pre-commit
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
git submodule add https://github.com/heroku/node-js-sample.git node-js-sample
|
||||
1
tests/apps/java/Procfile
Normal file
1
tests/apps/java/Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: java -cp target/classes:target/dependency/* HelloWorld
|
||||
2
tests/apps/java/check_deploy
Executable file
2
tests/apps/java/check_deploy
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e; output="$(curl -s $1)"; echo $output; test "$output" == "Hello from Java!"
|
||||
37
tests/apps/java/pom.xml
Normal file
37
tests/apps/java/pom.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.example</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<artifactId>helloworld</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>7.6.0.v20120127</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>package</phase>
|
||||
<goals><goal>copy-dependencies</goal></goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
22
tests/apps/java/src/main/java/HelloWorld.java
Normal file
22
tests/apps/java/src/main/java/HelloWorld.java
Normal file
@@ -0,0 +1,22 @@
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.*;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.*;
|
||||
|
||||
public class HelloWorld extends HttpServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("Hello from Java!\n");
|
||||
}
|
||||
public static void main(String[] args) throws Exception{
|
||||
Server server = new Server(Integer.valueOf(System.getenv("PORT")));
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
context.addServlet(new ServletHolder(new HelloWorld()),"/*");
|
||||
server.start();
|
||||
server.join();
|
||||
}
|
||||
}
|
||||
3
tests/apps/multi/.bowerrc
Normal file
3
tests/apps/multi/.bowerrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"directory": "static/components"
|
||||
}
|
||||
3
tests/apps/multi/.buildpacks
Normal file
3
tests/apps/multi/.buildpacks
Normal file
@@ -0,0 +1,3 @@
|
||||
https://github.com/heroku/heroku-buildpack-ruby
|
||||
https://github.com/heroku/heroku-buildpack-nodejs
|
||||
https://github.com/heroku/heroku-buildpack-python
|
||||
6
tests/apps/multi/.gitignore
vendored
Normal file
6
tests/apps/multi/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
static/components
|
||||
static/.tmp
|
||||
.sass-cache
|
||||
.bundle
|
||||
.DS_Store
|
||||
1
tests/apps/multi/.npmrc
Normal file
1
tests/apps/multi/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
unsafe-perm = true
|
||||
6
tests/apps/multi/Gemfile
Normal file
6
tests/apps/multi/Gemfile
Normal file
@@ -0,0 +1,6 @@
|
||||
source "https://rubygems.org"
|
||||
|
||||
ruby '1.9.3'
|
||||
|
||||
gem 'compass'
|
||||
gem 'sass-globbing'
|
||||
19
tests/apps/multi/Gemfile.lock
Normal file
19
tests/apps/multi/Gemfile.lock
Normal file
@@ -0,0 +1,19 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
chunky_png (1.3.0)
|
||||
compass (0.12.3)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (= 3.2.14)
|
||||
fssm (0.2.10)
|
||||
sass (3.2.14)
|
||||
sass-globbing (1.1.0)
|
||||
sass (>= 3.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
compass
|
||||
sass-globbing
|
||||
43
tests/apps/multi/Gruntfile.js
Normal file
43
tests/apps/multi/Gruntfile.js
Normal file
@@ -0,0 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function (grunt) {
|
||||
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.initConfig({
|
||||
|
||||
compass: {
|
||||
options: {
|
||||
sassDir: 'static/styles',
|
||||
cssDir: 'static/.tmp/styles',
|
||||
generatedImagesDir: 'static/.tmp/images/generated',
|
||||
imagesDir: 'static/images',
|
||||
javascriptsDir: 'static/scripts',
|
||||
fontsDir: 'static/styles/fonts',
|
||||
importPath: 'static/components',
|
||||
httpImagesPath: '/images',
|
||||
httpGeneratedImagesPath: '/images/generated',
|
||||
httpFontsPath: '/styles/fonts',
|
||||
relativeAssets: false,
|
||||
assetCacheBuster: false,
|
||||
bundleExec: true,
|
||||
raw: 'Sass::Script::Number.precision = 10\n'
|
||||
},
|
||||
dist: {
|
||||
options: {
|
||||
// generatedImagesDir: '<%= yeoman.dist %>/static/images/generated'
|
||||
}
|
||||
},
|
||||
server: {
|
||||
options: {
|
||||
debugInfo: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('heroku', [
|
||||
'compass:server'
|
||||
]);
|
||||
|
||||
};
|
||||
1
tests/apps/multi/Procfile
Normal file
1
tests/apps/multi/Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: python app.py
|
||||
3
tests/apps/multi/README.md
Normal file
3
tests/apps/multi/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
This is a sample application to test heroku buildpack multi for integrating with buildstep: https://github.com/progrium/buildstep/pull/75
|
||||
|
||||
I am choosing to use the python, nodejs, and ruby buildpacks to create a very simple flask app that performs a bower install and a simple grunt task using compass.
|
||||
15
tests/apps/multi/app.py
Normal file
15
tests/apps/multi/app.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import os
|
||||
from flask import Flask, render_template
|
||||
from werkzeug.wsgi import SharedDataMiddleware
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/')
|
||||
def hello_world():
|
||||
return render_template('index.html')
|
||||
|
||||
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/': os.path.join(os.path.dirname(__file__), 'static') })
|
||||
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/': os.path.join(os.path.dirname(__file__), 'static/.tmp') })
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', debug=True)
|
||||
20
tests/apps/multi/bower.json
Normal file
20
tests/apps/multi/bower.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "test-buildpack-multi",
|
||||
"version": "0.0.0",
|
||||
"authors": [
|
||||
"Al Johri <al.johri@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"directory": "static/components",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"statc/components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"bootstrap-sass": "twbs/bootstrap-sass#~3.1.1"
|
||||
}
|
||||
}
|
||||
2
tests/apps/multi/check_deploy
Executable file
2
tests/apps/multi/check_deploy
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
set -e; curl -s $1 | grep -q "Heroku Multi Buildpack on Dokku"
|
||||
17
tests/apps/multi/package.json
Normal file
17
tests/apps/multi/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "test-buildpack-multi",
|
||||
"version": "0.0.0",
|
||||
"description": "Test application for heroku multi buildpack.",
|
||||
"author": "Al Johri",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bower": "~1.2.8",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-cli": "~0.1.13",
|
||||
"load-grunt-tasks": "~0.2.0",
|
||||
"grunt-contrib-compass": "~0.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "./node_modules/bower/bin/bower --allow-root install && ./node_modules/grunt-cli/bin/grunt heroku"
|
||||
}
|
||||
}
|
||||
1
tests/apps/multi/requirements.txt
Normal file
1
tests/apps/multi/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
Flask==0.10.1
|
||||
6
tests/apps/multi/static/styles/main.scss
Normal file
6
tests/apps/multi/static/styles/main.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
// override scss variables within bootsrap by delaring them
|
||||
// before importing bootstrap
|
||||
|
||||
$brand-primary: #428bca !default;
|
||||
|
||||
@import "bootstrap-sass/vendor/assets/stylesheets/bootstrap";
|
||||
34
tests/apps/multi/templates/index.html
Normal file
34
tests/apps/multi/templates/index.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sample Webpage</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link rel="stylesheet" type="text/css" href="/styles/main.css">
|
||||
<script type="text/javascript" src="/components/bootstap-sass/vendor/assets/javascripts/bootstrap/bootstrap.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row clearfix">
|
||||
<div class="col-md-12 column">
|
||||
<div class="jumbotron">
|
||||
<h1>
|
||||
Hello, world!
|
||||
</h1>
|
||||
<p>
|
||||
This is a sample website using the Heroku Multi Buildpack on Dokku. It uses the python, ruby, and node buildpacks. The node buildpack is for using bower and grunt. The ruby buildpack is for running compass. And last but not last, the python buildpack is to run the flask application.
|
||||
</p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-large" href="#">Learn more</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1 +1 @@
|
||||
web: bin/node web.js
|
||||
web: node web.js
|
||||
|
||||
0
tests/apps/static/.nginx
Normal file
0
tests/apps/static/.nginx
Normal file
2
tests/apps/static/check_deploy
Executable file
2
tests/apps/static/check_deploy
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
set -e; output="$(curl -s $1)"; echo $output; test "$output" == "<html><h3>Static Page</h3></html>"
|
||||
1
tests/apps/static/www/index.html
Normal file
1
tests/apps/static/www/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<html><h3>Static Page</h3></html>
|
||||
@@ -5,6 +5,7 @@ export PATH=/usr/local/sbin:/usr/sbin:/sbin:/bin:/usr/bin:/usr/local/bin
|
||||
unset GIT_DIR
|
||||
|
||||
if [[ $2 == *dokku* ]]; then
|
||||
date -uIseconds
|
||||
rm -rf /tmp/build
|
||||
mkdir /tmp/build
|
||||
cd /tmp/build
|
||||
@@ -33,4 +34,4 @@ if [[ $2 == *dokku* ]]; then
|
||||
done
|
||||
else
|
||||
echo "-----> Repository invalid."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -10,6 +10,7 @@ if [[ ! $(cat ~/.ssh/config 2>/dev/null | grep dokku.me) ]]; then
|
||||
touch ~/.ssh/config
|
||||
echo "Host dokku.me" >> ~/.ssh/config
|
||||
echo " Port $VAGRANT_SSH_PORT" >> ~/.ssh/config
|
||||
echo " RequestTTY yes" >> ~/.ssh/config
|
||||
fi
|
||||
echo "-----> Ensuring Vagrant is running..."
|
||||
cd "$(dirname $SELF)/.." && vagrant up | indent
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
set -exo pipefail
|
||||
SELF=`which $0`; APP="$1"; TARGET="$2"; FORWARDED_PORT="$3"
|
||||
REMOTE="dokku@$TARGET"
|
||||
REPO="test-$(basename $APP)-$RANDOM"
|
||||
|
||||
TMP=$(mktemp -d -t "$TARGET.XXXXX")
|
||||
trap "rm -rf $TMP" EXIT
|
||||
rmdir $TMP && cp -r $(dirname $SELF)/$APP $TMP
|
||||
@@ -8,14 +11,21 @@ cd $TMP
|
||||
git init
|
||||
git config user.email "robot@example.com"
|
||||
git config user.name "Test Robot"
|
||||
git remote add target $REMOTE:$REPO
|
||||
|
||||
[[ -f gitignore ]] && mv gitignore .gitignore
|
||||
git add .
|
||||
|
||||
[[ -x pre-commit ]] && ./pre-commit $REMOTE $REPO
|
||||
git commit -m 'initial commit'
|
||||
REPO="test-$(basename $APP)-$RANDOM"
|
||||
git remote add target dokku@$TARGET:$REPO
|
||||
git push target master
|
||||
URL=$(ssh dokku@$TARGET url $REPO)$FORWARDED_PORT
|
||||
[[ -x post-deploy ]] && ./post-deploy $REMOTE $REPO
|
||||
|
||||
URL=$(ssh $REMOTE url $REPO)$FORWARDED_PORT
|
||||
sleep 2
|
||||
./check_deploy $URL && echo "-----> Deploy success!" || {
|
||||
sleep 4
|
||||
./check_deploy $URL && echo "-----> Deploy success!"
|
||||
}
|
||||
|
||||
ssh $REMOTE delete $REPO
|
||||
|
||||
Reference in New Issue
Block a user