Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e220da491 | ||
|
|
e0c49ec724 | ||
|
|
938a16de53 | ||
|
|
80d13c0005 | ||
|
|
d1f358c6fb | ||
|
|
f5f7b8dd7e | ||
|
|
795da11d24 | ||
|
|
c63be44989 | ||
|
|
17271b6132 | ||
|
|
82b700d635 | ||
|
|
da465a61dd | ||
|
|
875da5211f | ||
|
|
fc8e8484c6 | ||
|
|
7ebdcaa2e5 | ||
|
|
8e5c8c0832 | ||
|
|
4abccf0119 | ||
|
|
dd9ef4866c | ||
|
|
8502881633 | ||
|
|
43e9e6ddb6 | ||
|
|
471a5fa087 | ||
|
|
f95ad79fc4 | ||
|
|
896ce50c93 | ||
|
|
cbbc63d0f8 | ||
|
|
1f73b58340 | ||
|
|
881a700e99 | ||
|
|
9d81dda524 | ||
|
|
566cc15081 | ||
|
|
f1827a86a4 | ||
|
|
fc1762156d | ||
|
|
343ee24c46 | ||
|
|
441d212ef2 | ||
|
|
bc072e1db3 | ||
|
|
ab7f9f1161 | ||
|
|
e95d1e8602 | ||
|
|
948d7902f2 | ||
|
|
8535900f9d | ||
|
|
152b060901 | ||
|
|
464ef4d879 | ||
|
|
156e987300 | ||
|
|
8abb9ec408 | ||
|
|
97734cc242 | ||
|
|
93a01fb763 | ||
|
|
2a51301a5d | ||
|
|
1d6d5755d4 | ||
|
|
6fed503024 | ||
|
|
95914d1c13 | ||
|
|
92c18fa664 | ||
|
|
7bd5df0e25 | ||
|
|
9b5abeac4d | ||
|
|
de09260c33 | ||
|
|
7cf28ee01f | ||
|
|
e04b90c416 | ||
|
|
5e1b5b2900 | ||
|
|
2464bc0458 |
2
AUTHORS
2
AUTHORS
@@ -4,6 +4,7 @@
|
||||
Alexander <iam.asm89@gmail.com>
|
||||
Alexander Beletsky <alexander.beletsky@gmail.com>
|
||||
Alexis Gavoty <kload@kload.fr>
|
||||
Christian Joudrey <cmallette@gmail.com>
|
||||
Felipe Coury <felipe.coury@gmail.com>
|
||||
Jeff Lindsay <progrium@gmail.com>
|
||||
Jose Diaz-Gonzalez <dokku@josediazgonzalez.com>
|
||||
@@ -11,6 +12,7 @@ Leo Unbekandt <leo@unbekandt.eu>
|
||||
Ludovic Perrine <jazzzz@gmail.com>
|
||||
Luigi Maselli <grigio.org@gmail.com>
|
||||
Martin Weiss <kornnflake@gmail.com>
|
||||
Michael Hobbs <github@psudo.net>
|
||||
Paul Lietar <paul@lietar.net>
|
||||
Rajiv Makhijani <rajiv@blue-tech.org>
|
||||
rhy-jot <rhy-jot@myeml.net>
|
||||
|
||||
27
HISTORY.md
27
HISTORY.md
@@ -1,5 +1,32 @@
|
||||
# History
|
||||
|
||||
## 0.3.13
|
||||
|
||||
- #815: @abossard Added wordpress installation helper to plugin index
|
||||
- #858: @josegonzalez Disable server tokens in nginx. Closes #857
|
||||
- #859: @josegonzalez Pass command being executed when retrieving DOCKER_ARGS via pluginhook.
|
||||
- #861: @josegonzalez Default DOKKU_ROOT to ~dokku if unspecified. Closes #587
|
||||
- #863: @josegonzalez Add missing properties to the php composer.json
|
||||
- #864: @michaelhobbs bind docker container to internal port if using vhosts
|
||||
- #867: @michaelhobbs silent grep stderr. closes #862
|
||||
- #868: @michaelhobbs use circleci for automated testing
|
||||
- #872: @michaelhobbs fix/enable multi buildpack test
|
||||
- #873: @michaelhobbs support pre deployment usage of domains plugin. fixes interface binding issue
|
||||
- #874: @josegonzalez Add advanced installation docs that were removed in #706. Closes #869
|
||||
- #876: @vincentfretin give CACHE_PATH env variable for forward compatibility with herokuish
|
||||
- #877: @michaelhobbs add MH to AUTHORS
|
||||
- #880: @michaelhobbs disable VHOST deployment if global VHOST file is missing and an app domain has not been added
|
||||
- #881: @jomo troubleshooting typo: 64 != 46
|
||||
- #884: @michaelhobbs IP and PORT are likely to get clobbered. rename them
|
||||
- #885: @michaelhobbs test deploy node app without procfile
|
||||
|
||||
## 0.3.12
|
||||
|
||||
- #846: @michaelhobbs add certificate CN to app VHOST if it's not already
|
||||
- #847: @leonardodino Update bootstrap.sh: new docs url
|
||||
- #849: @cjoudrey Add docs for CHECKS
|
||||
- #850: @michaelhobbs test scala deployment
|
||||
|
||||
## 0.3.11
|
||||
|
||||
- #821: @michaelhobbs use wercker for automated testing
|
||||
|
||||
3
Makefile
3
Makefile
@@ -4,7 +4,6 @@ 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 ?= https://github.com/progrium/buildstep.git
|
||||
PREBUILT_STACK_URL ?= https://github.com/progrium/buildstep/releases/download/2014-12-16/2014-12-16_42bd9f4aab.tar.gz
|
||||
DOKKU_ROOT ?= /home/dokku
|
||||
PLUGINS_PATH ?= /var/lib/dokku/plugins
|
||||
|
||||
# If the first argument is "vagrant-dokku"...
|
||||
@@ -40,7 +39,7 @@ addman:
|
||||
mandb
|
||||
|
||||
version:
|
||||
git describe --tags > ${DOKKU_ROOT}/VERSION 2> /dev/null || echo '~${DOKKU_VERSION} ($(shell date -uIminutes))' > ${DOKKU_ROOT}/VERSION
|
||||
git describe --tags > ~dokku/VERSION 2> /dev/null || echo '~${DOKKU_VERSION} ($(shell date -uIminutes))' > ~dokku/VERSION
|
||||
|
||||
plugin-dependencies: pluginhook
|
||||
dokku plugins-install-dependencies
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Dokku [](https://app.wercker.com/project/bykey/029900380b7e5f31bbf4392725067769)
|
||||
# Dokku [](https://circleci.com/gh/progrium/dokku/tree/master)
|
||||
|
||||
Docker powered mini-Heroku. The smallest PaaS implementation you've ever seen. Sponsored by our friends at [Deis](http://deis.io/).
|
||||
|
||||
@@ -10,7 +10,7 @@ Docker powered mini-Heroku. The smallest PaaS implementation you've ever seen. S
|
||||
|
||||
To install the latest stable version of dokku, you can run the following bootstrapper command:
|
||||
|
||||
$ wget -qO- https://raw.github.com/progrium/dokku/v0.3.11/bootstrap.sh | sudo DOKKU_TAG=v0.3.11 bash
|
||||
$ wget -qO- https://raw.github.com/progrium/dokku/v0.3.13/bootstrap.sh | sudo DOKKU_TAG=v0.3.13 bash
|
||||
|
||||
### Upgrading
|
||||
|
||||
|
||||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
@@ -3,7 +3,7 @@
|
||||
|
||||
BOX_NAME = ENV["BOX_NAME"] || "trusty"
|
||||
BOX_URI = ENV["BOX_URI"] || "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
|
||||
BOX_MEMORY = ENV["BOX_MEMORY"] || "512"
|
||||
BOX_MEMORY = ENV["BOX_MEMORY"] || "1024"
|
||||
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
|
||||
|
||||
@@ -9,7 +9,7 @@ export DOKKU_REPO=${DOKKU_REPO:-"https://github.com/progrium/dokku.git"}
|
||||
|
||||
if ! command -v apt-get &>/dev/null
|
||||
then
|
||||
echo "This installation script requires apt-get. For manual installation instructions, consult https://github.com/progrium/dokku ."
|
||||
echo "This installation script requires apt-get. For manual installation instructions, consult http://progrium.viewdocs.io/dokku/advanced-installation ."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -33,4 +33,4 @@ make install
|
||||
|
||||
echo
|
||||
echo "Almost done! For next steps on configuration:"
|
||||
echo " https://github.com/progrium/dokku#configuring"
|
||||
echo " http://progrium.viewdocs.io/dokku/installation#user-content-configuring"
|
||||
|
||||
28
circle.yml
Normal file
28
circle.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
machine:
|
||||
services:
|
||||
- docker
|
||||
dependencies:
|
||||
cache_directories:
|
||||
- "~/docker"
|
||||
override:
|
||||
# need to add the dokku user to the docker group
|
||||
- sudo -E CI=true make -e sshcommand
|
||||
- sudo usermod -G docker dokku
|
||||
- sudo -E CI=true DOCKER_VERSION=1.4.1 make -e install: { timeout: 300 }
|
||||
- make -e ci-dependencies
|
||||
#### circle does some weird *expletive* with regards to root and gh auth (needed for gitsubmodules test)
|
||||
- sudo rsync -a ~ubuntu/.ssh/ ~root/.ssh/
|
||||
- sudo chown -R root:root ~root/.ssh/
|
||||
- sudo sed -e 's:/home/ubuntu:/root:g' ~root/.ssh/config
|
||||
####
|
||||
- sudo -E make -e setup-deploy-tests
|
||||
test:
|
||||
override:
|
||||
- sudo -E make -e lint
|
||||
- sudo -E make -e unit-tests
|
||||
### deploy tests (against buildstep release) ####
|
||||
- sudo -E make -e deploy-tests: { timeout: 1800 }
|
||||
### deploy tests (against buildstep master) ####
|
||||
- sudo docker rmi -f progrium/buildstep
|
||||
- sudo -E BUILD_STACK=true make -e stack
|
||||
- sudo -E make -e deploy-tests: { timeout: 1800 }
|
||||
@@ -21,7 +21,7 @@ if ARGV[0] == "onboot"
|
||||
exit
|
||||
end
|
||||
|
||||
version = "v0.3.11"
|
||||
version = "v0.3.13"
|
||||
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
|
||||
|
||||
37
docs/advanced-installation.md
Normal file
37
docs/advanced-installation.md
Normal file
@@ -0,0 +1,37 @@
|
||||
#Advanced installation
|
||||
|
||||
## Development
|
||||
|
||||
If you plan on developing dokku, the easiest way to install from your own repository is cloning the repository and calling the install script. Example:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/yourusername/dokku.git
|
||||
cd dokku
|
||||
sudo make install
|
||||
```
|
||||
|
||||
The `Makefile` allows source URLs to be overridden to include customizations from your own repositories. The `DOCKER_URL`, `PLUGINHOOK_URL`, `SSHCOMMAND_URL` and `STACK_URL` environment variables may be set to override the defaults (see the `Makefile` for how these apply). Example:
|
||||
|
||||
```shell
|
||||
sudo SSHCOMMAND_URL=https://raw.github.com/yourusername/sshcommand/master/gitreceive make install
|
||||
```
|
||||
|
||||
## Bootstrap a server from your own repository
|
||||
|
||||
The bootstrap script allows the dokku repository URL to be overridden to bootstrap a host from your own clone of dokku using the `DOKKU_REPO` environment variable. Example:
|
||||
|
||||
```shell
|
||||
wget https://raw.github.com/progrium/dokku/master/bootstrap.sh
|
||||
chmod +x bootstrap.sh
|
||||
sudo DOKKU_REPO=https://github.com/yourusername/dokku.git ./bootstrap.sh
|
||||
```
|
||||
|
||||
## Custom buildstep build
|
||||
|
||||
Dokku ships with a pre-built version of version of the [buildstep](https://github.com/progrium/buildstep) component by default. If you want to build your own version you can specify that with an env variable.
|
||||
|
||||
```shell
|
||||
git clone https://github.com/progrium/dokku.git
|
||||
cd dokku
|
||||
sudo BUILD_STACK=true make install
|
||||
```
|
||||
@@ -81,6 +81,26 @@ This is in particular useful, then you want to deploy to root domain, as
|
||||
remote: -----> Application deployed:
|
||||
remote: http://dokku.me
|
||||
|
||||
# Zero downtime deploy
|
||||
|
||||
Following a deploy Dokku's default behaviour is to switch new traffic over to the new container immediately.
|
||||
|
||||
This can be problematic for applications that take some time to boot up and can lead to `502 Bad Gateway` errors.
|
||||
|
||||
Dokku provides a way to run a set of checks against the new container, and only switch traffic over if all checks complete successfully.
|
||||
|
||||
To specify checks, add a `CHECKS` file to the root of your project directory. This is a text file with one line per check. Empty lines and lines starting with `#` are ignored.
|
||||
|
||||
A check is a relative URL and may be followed by expected content from the page, for example:
|
||||
|
||||
```
|
||||
/about Our Amazing Team
|
||||
```
|
||||
|
||||
Dokku will wait `DOKKU_CHECKS_WAIT` seconds (default: `5`) before running the checks to give server time to start. For shorter/longer wait, change the `DOKKU_CHECKS_WAIT` environment variable.
|
||||
|
||||
Dokku will wait `DOKKU_WAIT_TO_RETIRE` seconds (default: `60`) before stopping the old container such that no existing connections to it are dropped.
|
||||
|
||||
# Removing a deployed app
|
||||
|
||||
SSH onto the server, then execute:
|
||||
|
||||
@@ -11,7 +11,7 @@ Ubuntu 14.04 x64 x64. Ideally have a domain ready to point to your host. It's de
|
||||
To install the latest stable version of dokku, you can run the following bootstrapper command:
|
||||
|
||||
```shell
|
||||
wget -qO- https://raw.github.com/progrium/dokku/v0.3.11/bootstrap.sh | sudo DOKKU_TAG=v0.3.11 bash
|
||||
wget -qO- https://raw.github.com/progrium/dokku/v0.3.13/bootstrap.sh | sudo DOKKU_TAG=v0.3.13 bash
|
||||
```
|
||||
|
||||
## Configuring
|
||||
|
||||
@@ -136,3 +136,25 @@ dokku domains:clear myapp
|
||||
# remove a custom domain from app
|
||||
dokku domains:remove myapp example.com
|
||||
```
|
||||
|
||||
### Container network interface binding
|
||||
|
||||
> New as of 0.3.13
|
||||
|
||||
The deployed docker container running your app's web process will bind to either the internal docker network interface (i.e. `docker inspect --format '{{ .NetworkSettings.IPAddress }}' $CONTAINER_ID`) or an external interface (i.e. 0.0.0.0) depending on dokku's VHOST configuration. Dokku will attempt to bind to the internal docker network interface unless you specifically set NO_VHOST for the given app or your dokku installation is not setup to use VHOSTS (i.e. $DOKKU_ROOT/VHOST is missing or $DOKKU_ROOT/HOSTNAME is set to an IPv4 or IPv6 address)
|
||||
|
||||
```shell
|
||||
# container bound to docker interface
|
||||
root@dokku:~/dokku# docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
1b88d8aec3d1 dokku/node-js-app:latest "/bin/bash -c '/star About a minute ago Up About a minute goofy_albattani
|
||||
|
||||
root@dokku:~/dokku# docker inspect --format '{{ .NetworkSettings.IPAddress }}' goofy_albattani
|
||||
172.17.0.6
|
||||
|
||||
# container bound to all interfaces (previous default)
|
||||
root@dokku:/home/dokku# docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
d6499edb0edb dokku/node-js-app:latest "/bin/bash -c '/star About a minute ago Up About a minute 0.0.0.0:49153->5000/tcp nostalgic_tesla
|
||||
|
||||
```
|
||||
|
||||
@@ -228,6 +228,7 @@ Note: The following plugins have been supplied by our community and may not have
|
||||
|
||||
| Plugin | Author | Compatibility |
|
||||
| ------------------------------------------------------------------------------------------------- | --------------------- | --------------------- |
|
||||
| [Wordpress](https://github.com/dudagroup/dokku-wordpress-template) | [abossard][] | Dokku dev, mariadb, volume, domains |
|
||||
| [Node](https://github.com/pnegahdar/dokku-node) | [pnegahdar][] | |
|
||||
| [Node](https://github.com/ademuk/dokku-nodejs) | [ademuk][] | |
|
||||
| [Chef cookbooks](https://github.com/fgrehm/chef-dokku) | [fgrehm][] | |
|
||||
|
||||
@@ -22,7 +22,7 @@ http {
|
||||
```
|
||||
|
||||
Note that the `server_names_hash_bucket_size` setting defines the maximum domain name length.
|
||||
A value of 64 would allow domains with up to 46 characters. Set it to 128 if you need longer ones.
|
||||
A value of 64 would allow domains with up to 64 characters. Set it to 128 if you need longer ones.
|
||||
|
||||
Save the file and try stopping nginx and starting it again:
|
||||
|
||||
|
||||
24
dokku
24
dokku
@@ -4,7 +4,7 @@ shopt -s nullglob
|
||||
|
||||
export DOKKU_DISTRO=${DOKKU_DISTRO:="ubuntu"}
|
||||
export DOKKU_IMAGE=${DOKKU_IMAGE:="progrium/buildstep"}
|
||||
export DOKKU_ROOT=${DOKKU_ROOT:="/home/dokku"}
|
||||
export DOKKU_ROOT=${DOKKU_ROOT:=~dokku}
|
||||
|
||||
export PLUGIN_PATH=${PLUGIN_PATH:="/var/lib/dokku/plugins"}
|
||||
export DOKKU_NOT_IMPLEMENTED_EXIT=10
|
||||
@@ -54,7 +54,7 @@ case "$1" in
|
||||
docker commit $id $IMAGE > /dev/null
|
||||
[[ -d $CACHE_DIR ]] || mkdir $CACHE_DIR
|
||||
pluginhook pre-build $APP
|
||||
id=$(docker run -d -v $CACHE_DIR:/cache $IMAGE /build/builder)
|
||||
id=$(docker run -d -v $CACHE_DIR:/cache -e CACHE_PATH=/cache $IMAGE /build/builder)
|
||||
docker attach $id
|
||||
test "$(docker wait $id)" -eq 0
|
||||
docker commit $id $IMAGE > /dev/null
|
||||
@@ -81,9 +81,19 @@ case "$1" in
|
||||
fi
|
||||
|
||||
# start the app
|
||||
DOCKER_ARGS=$(: | pluginhook docker-args $APP)
|
||||
id=$(docker run -d -p 5000 -e PORT=5000 $DOCKER_ARGS $IMAGE /bin/bash -c "/start web")
|
||||
port=$(docker port $id 5000 | sed 's/[0-9.]*://')
|
||||
DOCKER_ARGS=$(: | pluginhook docker-args $APP deploy)
|
||||
BIND_EXTERNAL=$(pluginhook bind-external-ip $APP)
|
||||
|
||||
if [[ "$BIND_EXTERNAL" = "false" ]];then
|
||||
port=5000
|
||||
id=$(docker run -d -e PORT=$port $DOCKER_ARGS $IMAGE /bin/bash -c "/start web")
|
||||
ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $id)
|
||||
else
|
||||
id=$(docker run -d -p 5000 -e PORT=5000 $DOCKER_ARGS $IMAGE /bin/bash -c "/start web")
|
||||
port=$(docker port $id 5000 | sed 's/[0-9.]*://')
|
||||
ipaddr=127.0.0.1
|
||||
fi
|
||||
echo $ipaddr > "$DOKKU_ROOT/$APP/IP"
|
||||
|
||||
# if we can't post-deploy successfully, kill new container
|
||||
function kill_new {
|
||||
@@ -95,7 +105,7 @@ case "$1" in
|
||||
# run checks first, then post-deploy hooks, which switches Nginx traffic
|
||||
trap kill_new INT TERM EXIT
|
||||
echo "-----> Running pre-flight checks"
|
||||
pluginhook check-deploy $id $APP $port
|
||||
pluginhook check-deploy $id $APP $port ${ipaddr:-localhost}
|
||||
|
||||
# now using the new container
|
||||
echo $id > "$DOKKU_ROOT/$APP/CONTAINER"
|
||||
@@ -103,7 +113,7 @@ case "$1" in
|
||||
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$port" > "$DOKKU_ROOT/$APP/URL"
|
||||
|
||||
echo "-----> Running post-deploy"
|
||||
pluginhook post-deploy $APP $port
|
||||
pluginhook post-deploy $APP $port $ipaddr
|
||||
trap - INT TERM EXIT
|
||||
|
||||
# kill the old container
|
||||
|
||||
@@ -48,7 +48,7 @@ case "$1" in
|
||||
|
||||
shift 2
|
||||
|
||||
DOCKER_ARGS=$(: | pluginhook docker-args $APP)
|
||||
DOCKER_ARGS=$(: | pluginhook docker-args $APP run)
|
||||
docker run -i -t $DOCKER_ARGS $IMAGE /exec "$@"
|
||||
;;
|
||||
|
||||
|
||||
@@ -3,5 +3,5 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
APP="$1"; IMAGE="dokku/$APP"; CACHE_DIR="$DOKKU_ROOT/$APP/cache"
|
||||
if [[ -d $CACHE_DIR ]]; then
|
||||
docker run --rm -v "$CACHE_DIR:/cache" "$IMAGE" find /cache -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} \;
|
||||
docker run --rm -v "$CACHE_DIR:/cache" "$IMAGE" find /cache -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} \; || true
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
RE_IPV4="([0-9]{1,3}[\.]){3}[0-9]{1,3}"
|
||||
|
||||
RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7::
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|
||||
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|
||||
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
|
||||
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index)
|
||||
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
|
||||
|
||||
domains_restart_app() {
|
||||
APP="$1";
|
||||
|
||||
if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then
|
||||
echo "-----> Releasing $APP ..."
|
||||
dokku release $APP
|
||||
echo "-----> Release complete!"
|
||||
echo "-----> Deploying $APP ..."
|
||||
dokku deploy $APP
|
||||
echo "-----> Deploy complete!"
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
domains)
|
||||
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
|
||||
@@ -23,22 +51,24 @@ case "$1" in
|
||||
else
|
||||
VHOST=$(< "$DOKKU_ROOT/HOSTNAME")
|
||||
fi
|
||||
if [[ "$VHOST" =~ ([0-9]{1,3}[\.]){3}[0-9]{1,3} ]];then
|
||||
echo "ip found as hostname. disabling vhost support"
|
||||
if [[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]];then
|
||||
echo "unsupported vhost config found. disabling vhost support"
|
||||
[[ ! $(grep -q NO_VHOST "$DOKKU_ROOT/$APP/ENV") ]] && echo "export NO_VHOST='1'" >> "$DOKKU_ROOT/$APP/ENV"
|
||||
else
|
||||
echo "-----> Creating new $VHOST_PATH..."
|
||||
SUBDOMAIN=${APP/%\.${VHOST}/}
|
||||
hostname=$(: | pluginhook nginx-hostname $APP $SUBDOMAIN $VHOST)
|
||||
if [[ ! -n $hostname ]]; then
|
||||
if [[ "$APP" == *.* ]] && [[ "$SUBDOMAIN" == "$APP" ]]; then
|
||||
hostname="${APP/\//-}"
|
||||
else
|
||||
hostname="${APP/\//-}.$VHOST"
|
||||
if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
|
||||
echo "-----> Creating new $VHOST_PATH..."
|
||||
SUBDOMAIN=${APP/%\.${VHOST}/}
|
||||
hostname=$(: | pluginhook nginx-hostname $APP $SUBDOMAIN $VHOST)
|
||||
if [[ ! -n $hostname ]]; then
|
||||
if [[ "$APP" == *.* ]] && [[ "$SUBDOMAIN" == "$APP" ]]; then
|
||||
hostname="${APP/\//-}"
|
||||
else
|
||||
hostname="${APP/\//-}.$VHOST"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$hostname" > $VHOST_PATH
|
||||
echo "$hostname" > $VHOST_PATH
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
@@ -61,6 +91,8 @@ case "$1" in
|
||||
|
||||
dokku domains:setup $APP
|
||||
echo "$3" >> "$DOKKU_ROOT/$APP/VHOST"
|
||||
# we need to restart the app to make sure we're binding to the appropriate network interface
|
||||
domains_restart_app $APP
|
||||
pluginhook post-domains-update $APP
|
||||
echo "-----> Added $3 to $APP"
|
||||
|
||||
|
||||
34
plugins/nginx-vhosts/bind-external-ip
Executable file
34
plugins/nginx-vhosts/bind-external-ip
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
APP="$1"
|
||||
set +e; NO_VHOST=$(dokku config:get $APP NO_VHOST); set -e
|
||||
|
||||
RE_IPV4="([0-9]{1,3}[\.]){3}[0-9]{1,3}"
|
||||
|
||||
RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7::
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|
||||
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|
||||
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
|
||||
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index)
|
||||
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
|
||||
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && GLOBAL_VHOST=$(< "$DOKKU_ROOT/VHOST")
|
||||
|
||||
if [[ -n "$NO_VHOST" ]]; then
|
||||
echo true # bind to external ip. VHOST is disabled
|
||||
elif [[ "$GLOBAL_VHOST" =~ $RE_IPV4 ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV6 ]]; then
|
||||
echo true # bind to external ip. GLOBAL_VHOST is somehow an IPv4 or IPv6 address
|
||||
elif [[ -z "$GLOBAL_VHOST" ]] && [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
|
||||
echo true # bind to external ip. no GLOBAL_VHOST and no app vhost
|
||||
elif [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
|
||||
echo false # bind to docker ip. this app has a vhost defined
|
||||
else
|
||||
echo false
|
||||
fi
|
||||
@@ -15,15 +15,21 @@ restart_nginx () {
|
||||
|
||||
case "$1" in
|
||||
nginx:build-config)
|
||||
APP="$2"; PORT="$3"
|
||||
[[ -z "$PORT" ]] && PORT=$(< "$DOKKU_ROOT/$APP/PORT")
|
||||
APP="$2"; DOKKU_APP_LISTEN_PORT="$3"; DOKKU_APP_LISTEN_IP="${4}"
|
||||
VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
|
||||
WILDCARD_SSL="$DOKKU_ROOT/tls"
|
||||
SSL="$DOKKU_ROOT/$APP/tls"
|
||||
|
||||
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then
|
||||
DOKKU_APP_LISTEN_PORT=$(< "$DOKKU_ROOT/$APP/PORT")
|
||||
fi
|
||||
if [[ -z "$DOKKU_APP_LISTEN_IP" ]] && [[ -f "$DOKKU_ROOT/$APP/IP" ]]; then
|
||||
DOKKU_APP_LISTEN_IP=$(< "$DOKKU_ROOT/$APP/IP")
|
||||
fi
|
||||
|
||||
[[ -f "$DOKKU_ROOT/$APP/ENV" ]] && source $DOKKU_ROOT/$APP/ENV
|
||||
|
||||
if [[ ! -n "$NO_VHOST" ]]; then
|
||||
if [[ ! -n "$NO_VHOST" ]] && [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
|
||||
NONSSL_VHOSTS=$(cat $VHOST_PATH)
|
||||
if [[ -e "$SSL/server.crt" ]] && [[ -e "$SSL/server.key" ]]; then
|
||||
SSL_INUSE="$SSL"
|
||||
@@ -45,7 +51,9 @@ EOF
|
||||
|
||||
SSL_HOSTNAME=$(openssl x509 -in $SSL_INUSE/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-)
|
||||
SSL_HOSTNAME=$(echo "$SSL_HOSTNAME" | sed 's|\.|\\.|g' | sed 's/\*/\.\*/g')
|
||||
SSL_VHOSTS=$(egrep ^"$SSL_HOSTNAME"$ $VHOST_PATH)
|
||||
|
||||
[[ -z "$(egrep ^"$SSL_HOSTNAME"$ $VHOST_PATH)" ]] && echo "$SSL_HOSTNAME" | sed 's/\\./\./g' >> $VHOST_PATH
|
||||
SSL_VHOSTS=$(egrep ^"$SSL_HOSTNAME"$ $VHOST_PATH || exit 0)
|
||||
NONSSL_VHOSTS=$(egrep -v ^"$SSL_HOSTNAME"$ $VHOST_PATH || exit 0)
|
||||
|
||||
while read line; do
|
||||
@@ -65,25 +73,27 @@ EOF
|
||||
# Include SSL_VHOSTS so we can redirect http to https on that hostname as well
|
||||
NOSSL_SERVER_NAME=$(echo $NONSSL_VHOSTS $SSL_VHOSTS| tr '\n' ' ')
|
||||
|
||||
echo "-----> Creating $SCHEME nginx.conf"
|
||||
echo "upstream $APP { server 127.0.0.1:$PORT; }" > $DOKKU_ROOT/$APP/nginx.conf
|
||||
eval "cat <<< \"$(< $NGINX_CONF)\" >> $DOKKU_ROOT/$APP/nginx.conf"
|
||||
if [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then
|
||||
echo "-----> Creating $SCHEME nginx.conf"
|
||||
echo "upstream $APP { server $DOKKU_APP_LISTEN_IP:$DOKKU_APP_LISTEN_PORT; }" > $DOKKU_ROOT/$APP/nginx.conf
|
||||
eval "cat <<< \"$(< $NGINX_CONF)\" >> $DOKKU_ROOT/$APP/nginx.conf"
|
||||
|
||||
echo "-----> Running nginx-pre-reload"
|
||||
pluginhook nginx-pre-reload $APP $PORT
|
||||
echo "-----> Running nginx-pre-reload"
|
||||
pluginhook nginx-pre-reload $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP
|
||||
|
||||
echo " Reloading nginx"
|
||||
restart_nginx
|
||||
echo " Reloading nginx"
|
||||
restart_nginx
|
||||
fi
|
||||
else
|
||||
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
|
||||
echo "-----> NO_VHOST set, deleting $APP/VHOST"
|
||||
echo "-----> VHOST support disabled, deleting $APP/VHOST"
|
||||
rm "$DOKKU_ROOT/$APP/VHOST"
|
||||
fi
|
||||
if [[ -f "$DOKKU_ROOT/$APP/nginx.conf" ]]; then
|
||||
echo "-----> NO_VHOST set, deleting nginx.conf"
|
||||
echo "-----> VHOST support disabled, deleting nginx.conf"
|
||||
rm "$DOKKU_ROOT/$APP/nginx.conf"
|
||||
|
||||
echo "-----> NO_VHOST set, reloading nginx after nginx.conf deletion"
|
||||
echo "-----> VHOST support disabled, reloading nginx after nginx.conf deletion"
|
||||
restart_nginx
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -3,7 +3,8 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
case "$DOKKU_DISTRO" in
|
||||
ubuntu)
|
||||
apt-get install -qq -y software-properties-common python-software-properties
|
||||
[[ -z "$CIRCLECI" ]] && apt-get install -qq -y software-properties-common python-software-properties
|
||||
[[ -n "$CIRCLECI" ]] && aptitude install -q -y software-properties-common python-software-properties
|
||||
add-apt-repository -y ppa:nginx/stable
|
||||
apt-get update
|
||||
apt-get install -qq -y nginx dnsutils
|
||||
|
||||
@@ -44,6 +44,7 @@ events {
|
||||
}
|
||||
|
||||
http {
|
||||
server_tokens off;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
APP="$1"; PORT="$2"
|
||||
APP="$1"; PORT="$2"; IP="$3"
|
||||
|
||||
set +e; NO_VHOST=$(dokku config:get $APP NO_VHOST); set -e
|
||||
|
||||
@@ -11,4 +11,4 @@ elif [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
|
||||
dokku domains:setup $APP
|
||||
fi
|
||||
|
||||
dokku nginx:build-config $APP $PORT
|
||||
dokku nginx:build-config $APP $PORT $IP
|
||||
|
||||
26
tests.mk
26
tests.mk
@@ -17,7 +17,7 @@ ifdef ENABLE_DOKKU_TRACE
|
||||
echo "export DOKKU_TRACE=1" >> /home/dokku/dokkurc
|
||||
endif
|
||||
@echo "Setting dokku.me in /etc/hosts"
|
||||
sudo /bin/bash -c "[[ `ping -c1 dokku.me > /dev/null 2>&1; echo $$?` -eq 0 ]] || echo \"127.0.0.1 dokku.me *.dokku.me\" >> /etc/hosts"
|
||||
sudo /bin/bash -c "[[ `ping -c1 dokku.me > /dev/null 2>&1; echo $$?` -eq 0 ]] || echo \"127.0.0.1 dokku.me *.dokku.me www.test.app.dokku.me\" >> /etc/hosts"
|
||||
|
||||
@echo "-----> Generating keypair..."
|
||||
mkdir -p /root/.ssh
|
||||
@@ -39,7 +39,7 @@ endif
|
||||
@echo "-----> Intitial SSH connection to populate known_hosts..."
|
||||
ssh -o StrictHostKeyChecking=no dokku@dokku.me help > /dev/null
|
||||
|
||||
ifeq ($(shell grep dokku.me /home/dokku/VHOST),)
|
||||
ifeq ($(shell grep dokku.me /home/dokku/VHOST 2>/dev/null),)
|
||||
@echo "-----> Setting default VHOST to dokku.me..."
|
||||
echo "dokku.me" > /home/dokku/VHOST
|
||||
endif
|
||||
@@ -54,8 +54,9 @@ lint:
|
||||
# SC2034: VAR appears unused - https://github.com/koalaman/shellcheck/wiki/SC2034
|
||||
# SC2086: Double quote to prevent globbing and word splitting - https://github.com/koalaman/shellcheck/wiki/SC2086
|
||||
# SC2143: Instead of [ -n $(foo | grep bar) ], use foo | grep -q bar - https://github.com/koalaman/shellcheck/wiki/SC2143
|
||||
# SC2001: See if you can use ${variable//search/replace} instead. - https://github.com/koalaman/shellcheck/wiki/SC2001
|
||||
@echo linting...
|
||||
@$(QUIET) find . -not -path '*/\.*' | xargs file | egrep "shell|bash" | awk '{ print $$1 }' | sed 's/://g' | xargs shellcheck -e SC2034,SC2086,SC2143
|
||||
@$(QUIET) find . -not -path '*/\.*' | xargs file | egrep "shell|bash" | awk '{ print $$1 }' | sed 's/://g' | xargs shellcheck -e SC2034,SC2086,SC2143,SC2001
|
||||
|
||||
unit-tests:
|
||||
@echo running unit tests...
|
||||
@@ -74,7 +75,7 @@ deploy-test-go:
|
||||
cd tests && ./test_deploy ./apps/go dokku.me
|
||||
|
||||
deploy-test-java:
|
||||
@echo deploying app...
|
||||
@echo deploying java app...
|
||||
cd tests && ./test_deploy ./apps/java dokku.me
|
||||
|
||||
deploy-test-multi:
|
||||
@@ -82,9 +83,13 @@ deploy-test-multi:
|
||||
cd tests && ./test_deploy ./apps/multi dokku.me
|
||||
|
||||
deploy-test-nodejs-express:
|
||||
@echo deploying app...
|
||||
@echo deploying nodejs-express app...
|
||||
cd tests && ./test_deploy ./apps/nodejs-express dokku.me
|
||||
|
||||
deploy-test-nodejs-express-noprocfile:
|
||||
@echo deploying nodejs-express app with no Procfile...
|
||||
cd tests && ./test_deploy ./apps/nodejs-express-noprocfile dokku.me
|
||||
|
||||
deploy-test-php:
|
||||
@echo deploying php app...
|
||||
cd tests && ./test_deploy ./apps/php dokku.me
|
||||
@@ -93,6 +98,10 @@ deploy-test-python-flask:
|
||||
@echo deploying python-flask app...
|
||||
cd tests && ./test_deploy ./apps/python-flask dokku.me
|
||||
|
||||
deploy-test-scala:
|
||||
@echo deploying scala app...
|
||||
cd tests && ./test_deploy ./apps/scala dokku.me
|
||||
|
||||
deploy-test-static:
|
||||
@echo deploying static app...
|
||||
cd tests && ./test_deploy ./apps/static dokku.me
|
||||
@@ -104,13 +113,12 @@ deploy-tests:
|
||||
@$(QUIET) $(MAKE) deploy-test-gitsubmodules
|
||||
@$(QUIET) $(MAKE) deploy-test-go
|
||||
@$(QUIET) $(MAKE) deploy-test-java
|
||||
# broken with new buildstep.
|
||||
# ref: https://github.com/progrium/dokku/issues/832
|
||||
# ref: https://github.com/heroku/heroku-buildpack-ruby/pull/319
|
||||
# @$(QUIET) $(MAKE) deploy-test-multi
|
||||
@$(QUIET) $(MAKE) deploy-test-multi
|
||||
@$(QUIET) $(MAKE) deploy-test-nodejs-express
|
||||
@$(QUIET) $(MAKE) deploy-test-nodejs-express-noprocfile
|
||||
@$(QUIET) $(MAKE) deploy-test-php
|
||||
@$(QUIET) $(MAKE) deploy-test-python-flask
|
||||
@$(QUIET) $(MAKE) deploy-test-scala
|
||||
@$(QUIET) $(MAKE) deploy-test-static
|
||||
|
||||
test: setup-deploy-tests lint unit-tests deploy-tests
|
||||
|
||||
@@ -2,5 +2,5 @@ source "https://rubygems.org"
|
||||
|
||||
ruby '1.9.3'
|
||||
|
||||
gem 'compass'
|
||||
gem 'compass', ">= 1.0.1"
|
||||
gem 'sass-globbing'
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
chunky_png (1.3.0)
|
||||
compass (0.12.3)
|
||||
chunky_png (1.3.3)
|
||||
compass (1.0.1)
|
||||
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)
|
||||
compass-core (~> 1.0.1)
|
||||
compass-import-once (~> 1.0.5)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
sass (>= 3.3.13, < 3.5)
|
||||
compass-core (1.0.1)
|
||||
multi_json (~> 1.0)
|
||||
sass (>= 3.3.0, < 3.5)
|
||||
compass-import-once (1.0.5)
|
||||
sass (>= 3.2, < 3.5)
|
||||
ffi (1.9.6)
|
||||
multi_json (1.10.1)
|
||||
rb-fsevent (0.9.4)
|
||||
rb-inotify (0.9.5)
|
||||
ffi (>= 0.5.0)
|
||||
sass (3.4.9)
|
||||
sass-globbing (1.1.1)
|
||||
sass (>= 3.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
compass
|
||||
compass (>= 1.0.1)
|
||||
sass-globbing
|
||||
|
||||
1
tests/apps/nodejs-express-noprocfile/CHECKS
Normal file
1
tests/apps/nodejs-express-noprocfile/CHECKS
Normal file
@@ -0,0 +1 @@
|
||||
/ nodejs/express
|
||||
2
tests/apps/nodejs-express-noprocfile/check_deploy
Executable file
2
tests/apps/nodejs-express-noprocfile/check_deploy
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
set -e; output="$(curl -s -S "$1")"; echo "$output"; test "$output" == "nodejs/express"
|
||||
14
tests/apps/nodejs-express-noprocfile/package.json
Normal file
14
tests/apps/nodejs-express-noprocfile/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "node-example",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"express": "2.5.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": "0.8.x",
|
||||
"npm": "1.1.x"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node web.js"
|
||||
}
|
||||
}
|
||||
12
tests/apps/nodejs-express-noprocfile/web.js
Normal file
12
tests/apps/nodejs-express-noprocfile/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('nodejs/express');
|
||||
});
|
||||
|
||||
var port = process.env.PORT || 5000;
|
||||
app.listen(port, function() {
|
||||
console.log("Listening on " + port);
|
||||
});
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"name": "test-php-app",
|
||||
"description": "a test php app for dokku",
|
||||
"require": {
|
||||
"monolog/monolog": "~1.7",
|
||||
"silex/silex": "~1.1"
|
||||
|
||||
21
tests/apps/scala/LICENSE
Normal file
21
tests/apps/scala/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Joe Kutner
|
||||
|
||||
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.
|
||||
1
tests/apps/scala/Procfile
Normal file
1
tests/apps/scala/Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: target/universal/stage/bin/scala-getting-started
|
||||
33
tests/apps/scala/README.md
Normal file
33
tests/apps/scala/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# scala-getting-started
|
||||
|
||||
A barebones Scala app, which can easily be deployed to Heroku.
|
||||
|
||||
This application support the [Getting Started with Scala on Heroku](https://devcenter.heroku.com/articles/getting-started-with-scala) article - check it out.
|
||||
|
||||
## Running Locally
|
||||
|
||||
Make sure you have Scala and sbt installed. Also, install the [Heroku Toolbelt](https://toolbelt.heroku.com/).
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/heroku/scala-getting-started.git
|
||||
$ cd scala-getting-started
|
||||
$ sbt compile stage
|
||||
$ foreman start web
|
||||
```
|
||||
|
||||
Your app should now be running on [localhost:5000](http://localhost:5000/).
|
||||
|
||||
## Deploying to Heroku
|
||||
|
||||
```sh
|
||||
$ heroku create
|
||||
$ git push heroku master
|
||||
$ heroku open
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
For more information about using Scala on Heroku, see these Dev Center articles:
|
||||
|
||||
- [Scala on Heroku](https://devcenter.heroku.com/categories/scala)
|
||||
|
||||
14
tests/apps/scala/build.sbt
Normal file
14
tests/apps/scala/build.sbt
Normal file
@@ -0,0 +1,14 @@
|
||||
import NativePackagerKeys._
|
||||
|
||||
packageArchetype.java_application
|
||||
|
||||
name := """scala-getting-started"""
|
||||
|
||||
version := "1.0"
|
||||
|
||||
scalaVersion := "2.10.4"
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.twitter" % "finagle-http_2.10" % "6.18.0",
|
||||
"postgresql" % "postgresql" % "9.0-801.jdbc4"
|
||||
)
|
||||
2
tests/apps/scala/check_deploy
Executable file
2
tests/apps/scala/check_deploy
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e; output="$(curl -s -S $1)"; echo $output; test "$output" == "Hello from Scala!"
|
||||
4
tests/apps/scala/project/build.properties
Normal file
4
tests/apps/scala/project/build.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
#Activator-generated Properties
|
||||
#Wed Aug 13 09:36:12 CDT 2014
|
||||
template.uuid=a855816c-0367-44ba-9adb-6a903f6ad599
|
||||
sbt.version=0.13.5
|
||||
1
tests/apps/scala/project/plugins.sbt
Normal file
1
tests/apps/scala/project/plugins.sbt
Normal file
@@ -0,0 +1 @@
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.4")
|
||||
65
tests/apps/scala/src/main/scala/com/example/Server.scala
Normal file
65
tests/apps/scala/src/main/scala/com/example/Server.scala
Normal file
@@ -0,0 +1,65 @@
|
||||
package com.example
|
||||
|
||||
import com.twitter.finagle.{Http, Service}
|
||||
import com.twitter.util.{Await, Future}
|
||||
import com.twitter.finagle.http.Response
|
||||
import java.net.InetSocketAddress
|
||||
import org.jboss.netty.handler.codec.http._
|
||||
import util.Properties
|
||||
import java.net.URI
|
||||
import java.sql.Connection
|
||||
import java.sql.DriverManager
|
||||
|
||||
object Server {
|
||||
def main(args: Array[String]) {
|
||||
val port = Properties.envOrElse("PORT", "8080").toInt
|
||||
println("Starting on port: "+port)
|
||||
|
||||
val server = Http.serve(":" + port, new Hello)
|
||||
Await.ready(server)
|
||||
}
|
||||
}
|
||||
|
||||
class Hello extends Service[HttpRequest, HttpResponse] {
|
||||
def apply(request: HttpRequest): Future[HttpResponse] = {
|
||||
if (request.getUri.endsWith("/db")) {
|
||||
showDatabase(request);
|
||||
} else {
|
||||
showHome(request);
|
||||
}
|
||||
}
|
||||
|
||||
def showHome(request: HttpRequest): Future[HttpResponse] = {
|
||||
val response = Response()
|
||||
response.setStatusCode(200)
|
||||
response.setContentString("Hello from Scala!")
|
||||
Future(response)
|
||||
}
|
||||
|
||||
def showDatabase(request: HttpRequest): Future[HttpResponse] = {
|
||||
val connection = getConnection
|
||||
val stmt = connection.createStatement
|
||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ticks (tick timestamp)")
|
||||
stmt.executeUpdate("INSERT INTO ticks VALUES (now())")
|
||||
|
||||
val rs = stmt.executeQuery("SELECT tick FROM ticks")
|
||||
|
||||
var out = ""
|
||||
while (rs.next) {
|
||||
out += "Read from DB: " + rs.getTimestamp("tick") + "\n"
|
||||
}
|
||||
|
||||
val response = Response()
|
||||
response.setStatusCode(200)
|
||||
response.setContentString(out)
|
||||
Future(response)
|
||||
}
|
||||
|
||||
def getConnection(): Connection = {
|
||||
val dbUri = new URI(System.getenv("DATABASE_URL"))
|
||||
val username = dbUri.getUserInfo.split(":")(0)
|
||||
val password = dbUri.getUserInfo.split(":")(1)
|
||||
val dbUrl = "jdbc:postgresql://" + dbUri.getHost + dbUri.getPath
|
||||
DriverManager.getConnection(dbUrl, username, password)
|
||||
}
|
||||
}
|
||||
1
tests/apps/scala/system.properties
Normal file
1
tests/apps/scala/system.properties
Normal file
@@ -0,0 +1 @@
|
||||
java.runtime.version=1.7
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
set -xeo pipefail
|
||||
|
||||
SELF=$(which $0); APP="$1"; TARGET="$2"; FORWARDED_PORT="$3"
|
||||
REMOTE="dokku@$TARGET"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
deploy_app
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
|
||||
48
tests/unit/nginx-vhosts.bats
Normal file
48
tests/unit/nginx-vhosts.bats
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -f "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
|
||||
[[ -f "$DOKKU_ROOT/HOSTNAME" ]] && cp -f "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/HOSTNAME.bak"
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST"
|
||||
[[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME"
|
||||
}
|
||||
|
||||
@test "nginx (no server tokens)" {
|
||||
deploy_app
|
||||
run /bin/bash -c "curl -s -D - $(dokku url $TEST_APP) -o /dev/null | egrep '^Server' | egrep '[0-9]+'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "nginx:build-config (with SSL CN mismatch)" {
|
||||
setup_test_tls
|
||||
deploy_app
|
||||
run /bin/bash -c "dokku domains $TEST_APP | grep node-js-app.dokku.me"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_output "node-js-app.dokku.me"
|
||||
}
|
||||
|
||||
@test "nginx:build-config (no global VHOST and domains:add)" {
|
||||
destroy_app
|
||||
rm "$DOKKU_ROOT/VHOST"
|
||||
create_app
|
||||
run dokku domains:add $TEST_APP www.test.app.dokku.me
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
deploy_app
|
||||
sleep 5 # wait for nginx to reload
|
||||
run bash -c "response=\"$(curl -s -S www.test.app.dokku.me)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
}
|
||||
110
tests/unit/ports.bats
Normal file
110
tests/unit/ports.bats
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -f "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
|
||||
[[ -f "$DOKKU_ROOT/HOSTNAME" ]] && cp -f "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/HOSTNAME.bak"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST"
|
||||
[[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME"
|
||||
}
|
||||
|
||||
@test "port exposure (with global VHOST)" {
|
||||
echo "dokku.me" > "$DOKKU_ROOT/VHOST"
|
||||
deploy_app
|
||||
CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }')
|
||||
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "port exposure (without global VHOST and real HOSTNAME)" {
|
||||
rm "$DOKKU_ROOT/VHOST"
|
||||
echo "dokku.me" > "$DOKKU_ROOT/HOSTNAME"
|
||||
deploy_app
|
||||
CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }')
|
||||
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "port exposure (with NO_VHOST set)" {
|
||||
deploy_app
|
||||
dokku config:set $TEST_APP NO_VHOST=1
|
||||
CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }')
|
||||
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "port exposure (without global VHOST and IPv4 address as HOSTNAME)" {
|
||||
rm "$DOKKU_ROOT/VHOST"
|
||||
echo "127.0.0.1" > "$DOKKU_ROOT/HOSTNAME"
|
||||
deploy_app
|
||||
CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }')
|
||||
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "port exposure (without global VHOST and IPv6 address as HOSTNAME)" {
|
||||
rm "$DOKKU_ROOT/VHOST"
|
||||
echo "fda5:c7db:a520:bb6d::aabb:ccdd:eeff" > "$DOKKU_ROOT/HOSTNAME"
|
||||
deploy_app
|
||||
CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }')
|
||||
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "port exposure (pre-deploy domains:add)" {
|
||||
create_app
|
||||
run dokku domains:add $TEST_APP www.test.app.dokku.me
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
|
||||
deploy_app
|
||||
sleep 5 # wait for nginx to reload
|
||||
|
||||
CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }')
|
||||
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_failure
|
||||
|
||||
run bash -c "response=\"$(curl -s -S www.test.app.dokku.me)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "port exposure (no global VHOST and domains:add post deploy)" {
|
||||
rm "$DOKKU_ROOT/VHOST"
|
||||
deploy_app
|
||||
|
||||
run dokku domains:add $TEST_APP www.test.app.dokku.me
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
|
||||
CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }')
|
||||
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_failure
|
||||
|
||||
run bash -c "response=\"$(curl -s -S www.test.app.dokku.me)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
}
|
||||
BIN
tests/unit/server_ssl.tar
Normal file
BIN
tests/unit/server_ssl.tar
Normal file
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# constants
|
||||
DOKKU_ROOT=${DOKKU_ROOT:=~dokku}
|
||||
TEST_APP=my-cool-guy-test-app
|
||||
|
||||
# test functions
|
||||
@@ -89,7 +90,7 @@ destroy_app() {
|
||||
|
||||
deploy_app() {
|
||||
TMP=$(mktemp -d -t "$TARGET.XXXXX")
|
||||
rmdir $TMP && cp -r ./tests/apps/config $TMP
|
||||
rmdir $TMP && cp -r ./tests/apps/nodejs-express $TMP
|
||||
cd $TMP
|
||||
git init
|
||||
git config user.email "robot@example.com"
|
||||
@@ -101,3 +102,10 @@ deploy_app() {
|
||||
git commit -m 'initial commit'
|
||||
git push target master || destroy_app
|
||||
}
|
||||
|
||||
setup_test_tls() {
|
||||
TLS="/home/dokku/$TEST_APP/tls"
|
||||
mkdir -p $TLS
|
||||
tar xf $BATS_TEST_DIRNAME/server_ssl.tar -C $TLS
|
||||
sudo chown -R dokku:dokku $TLS
|
||||
}
|
||||
|
||||
39
wercker.yml
39
wercker.yml
@@ -1,39 +0,0 @@
|
||||
box: wercker-labs/docker
|
||||
no-response-timeout: 20
|
||||
build:
|
||||
steps:
|
||||
- script:
|
||||
name: install os requirements
|
||||
code: |-
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y make software-properties-common git wget man-db
|
||||
- script:
|
||||
name: ci dependencies
|
||||
code: make -e ci-dependencies
|
||||
- script:
|
||||
name: install dokku
|
||||
code: sudo -E CI=true DOCKER_VERSION=1.4.0 make -e install
|
||||
- script:
|
||||
name: setup deploy tests
|
||||
code: sudo -E make -e setup-deploy-tests
|
||||
- script:
|
||||
name: lint
|
||||
code: sudo -E make -e lint
|
||||
- script:
|
||||
name: unit tests
|
||||
code: sudo -E make -e unit-tests
|
||||
- script:
|
||||
name: deploy tests (against buildstep release)
|
||||
code: sudo -E make -e deploy-tests
|
||||
- script:
|
||||
name: deploy tests (against buildstep master)
|
||||
code: |-
|
||||
sudo docker rmi -f progrium/buildstep
|
||||
sudo -E BUILD_STACK=true make -e stack
|
||||
sudo -E make -e deploy-tests
|
||||
after-steps:
|
||||
- wouter/irc-notify:
|
||||
server: irc.freenode.net
|
||||
port: 6667
|
||||
nickname: dokku-wercker
|
||||
channel: dokku
|
||||
Reference in New Issue
Block a user