nginx-vhosts rewrite

This commit is contained in:
Michael Hobbs
2016-02-14 18:43:40 -08:00
parent 4404e145c0
commit 9842d7498b
65 changed files with 1779 additions and 1123 deletions

View File

@@ -58,6 +58,7 @@ etc). Please include:
* The output of `free -m`
* The output of `docker version`.
* The output of `docker -D info`.
* The output of `sigil -v`.
* The output of `docker run --rm -ti gliderlabs/herokuish:latest herokuish version`
* The output of `dokku version`.
* The output of `dokku plugin`.

View File

@@ -7,6 +7,7 @@ Output of the following commands
- `free -m`:
- `docker version`:
- `docker -D info`:
- `sigil -v`:
- `docker run -ti gliderlabs/herokuish:latest herokuish version`:
- `dokku version`:
- `dokku plugin`:

View File

@@ -2,6 +2,7 @@ DOKKU_VERSION = master
SSHCOMMAND_URL ?= https://raw.githubusercontent.com/dokku/sshcommand/master/sshcommand
PLUGN_URL ?= https://github.com/dokku/plugn/releases/download/v0.2.1/plugn_0.2.1_linux_x86_64.tgz
SIGIL_URL ?= https://github.com/gliderlabs/sigil/releases/download/v0.3.3/sigil_0.3.3_Linux_x86_64.tgz
STACK_URL ?= https://github.com/gliderlabs/herokuish.git
PREBUILT_STACK_URL ?= gliderlabs/herokuish:latest
DOKKU_LIB_ROOT ?= /var/lib/dokku
@@ -77,7 +78,7 @@ plugin-dependencies: plugn
plugins: plugn docker
sudo -E dokku plugin:install --core
dependencies: apt-update sshcommand plugn docker help2man man-db
dependencies: apt-update sshcommand plugn docker help2man man-db sigil
$(MAKE) -e stack
apt-update:
@@ -98,6 +99,10 @@ plugn:
wget -qO /tmp/plugn_latest.tgz ${PLUGN_URL}
tar xzf /tmp/plugn_latest.tgz -C /usr/local/bin
sigil:
wget -qO /tmp/sigil_latest.tgz ${SIGIL_URL}
tar xzf /tmp/sigil_latest.tgz -C /usr/local/bin
docker: aufs
apt-get install -qq -y curl
egrep -i "^docker" /etc/group || groupadd docker

112
deb.mk
View File

@@ -20,34 +20,52 @@ SSHCOMMAND_VERSION ?= 0.1.0
SSHCOMMAND_ARCHITECTURE = amd64
SSHCOMMAND_PACKAGE_NAME = sshcommand_$(SSHCOMMAND_VERSION)_$(SSHCOMMAND_ARCHITECTURE).deb
GOROOT = /usr/lib/go
GOBIN = /usr/bin/go
GOPATH = /home/vagrant/gocode
SIGIL_DESCRIPTION = 'Standalone string interpolator and template processor'
SIGIL_REPO_NAME ?= gliderlabs/sigil
SIGIL_VERSION ?= 0.3.3
SIGIL_ARCHITECTURE = amd64
SIGIL_PACKAGE_NAME = sigil_$(SIGIL_VERSION)_$(SIGIL_ARCHITECTURE).deb
.PHONY: install-from-deb deb-all deb-herokuish deb-dokku deb-plugn deb-setup deb-sshcommand
GOROOT = /usr/local/go
GOBIN = /usr/local/go/bin/go
GOPATH = /home/vagrant/gocode
GOTARBALL = go1.5.3.linux-amd64.tar.gz
.PHONY: install-from-deb deb-all deb-herokuish deb-dokku deb-plugn deb-setup deb-sshcommand deb-sigil
install-from-deb:
echo "--> Initial apt-get update"
@echo "--> Initial apt-get update"
sudo apt-get update -qq > /dev/null
sudo apt-get install -qq -y apt-transport-https
echo "--> Installing docker"
@echo "--> Installing docker"
wget -nv -O - https://get.docker.com/ | sh
echo "--> Installing dokku"
@echo "--> Installing dokku"
wget -nv -O - https://packagecloud.io/gpg.key | apt-key add -
echo "deb https://packagecloud.io/dokku/dokku/ubuntu/ trusty main" | sudo tee /etc/apt/sources.list.d/dokku.list
@echo "deb https://packagecloud.io/dokku/dokku/ubuntu/ trusty main" | sudo tee /etc/apt/sources.list.d/dokku.list
sudo apt-get update -qq > /dev/null
sudo apt-get install dokku
sudo DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt-get install -yy dokku
deb-all: deb-herokuish deb-dokku deb-plugn deb-sshcommand
golang:
ifeq (,$(wildcard /tmp/$(GOTARBALL)))
@echo "-> Installing golang"
mkdir -p /tmp/build/usr/local/bin $(GOPATH)
sudo apt-get clean
sudo apt-get update -qq > /dev/null
sudo apt-get install -qq -y git mercurial > /dev/null 2>&1
sudo wget -nv -O /tmp/$(GOTARBALL) https://storage.googleapis.com/golang/$(GOTARBALL)
sudo tar -C /usr/local -xzf /tmp/$(GOTARBALL)
endif
deb-all: deb-herokuish deb-dokku deb-plugn deb-sshcommand deb-sigil
mv /tmp/*.deb .
echo "Done"
@echo "Done"
deb-setup:
echo "-> Updating deb repository and installing build requirements"
@echo "-> Updating deb repository and installing build requirements"
sudo apt-get update -qq > /dev/null
sudo apt-get install -qq -y gcc git ruby-dev ruby1.9.1 > /dev/null 2>&1
sudo DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt-get install -qq -y gcc git ruby-dev ruby1.9.1 > /dev/null 2>&1
command -v fpm > /dev/null || sudo gem install fpm --no-ri --no-rdoc
ssh -o StrictHostKeyChecking=no git@github.com || true
@@ -55,26 +73,26 @@ deb-herokuish: deb-setup
rm -rf /tmp/tmp /tmp/build $(HEROKUISH_PACKAGE_NAME)
mkdir -p /tmp/tmp /tmp/build
echo "-> Creating deb files"
echo "#!/usr/bin/env bash" >> /tmp/tmp/post-install
echo "sleep 5" >> /tmp/tmp/post-install
echo "count=\`sudo docker images | grep gliderlabs/herokuish | wc -l\`" >> /tmp/tmp/post-install
echo 'if [ "$$count" -ne 0 ]; then' >> /tmp/tmp/post-install
echo " echo 'Removing old herokuish image'" >> /tmp/tmp/post-install
echo " sudo docker rmi gliderlabs/herokuish" >> /tmp/tmp/post-install
echo "fi" >> /tmp/tmp/post-install
echo "echo 'Importing herokuish into docker (around 5 minutes)'" >> /tmp/tmp/post-install
echo "sudo docker build -t gliderlabs/herokuish /var/lib/herokuish 1> /dev/null" >> /tmp/tmp/post-install
@echo "-> Creating deb files"
@echo "#!/usr/bin/env bash" >> /tmp/tmp/post-install
@echo "sleep 5" >> /tmp/tmp/post-install
@echo "count=\`sudo docker images | grep gliderlabs/herokuish | wc -l\`" >> /tmp/tmp/post-install
@echo 'if [ "$$count" -ne 0 ]; then' >> /tmp/tmp/post-install
@echo " echo 'Removing old herokuish image'" >> /tmp/tmp/post-install
@echo " sudo docker rmi gliderlabs/herokuish" >> /tmp/tmp/post-install
@echo "fi" >> /tmp/tmp/post-install
@echo "echo 'Importing herokuish into docker (around 5 minutes)'" >> /tmp/tmp/post-install
@echo "sudo docker build -t gliderlabs/herokuish /var/lib/herokuish 1> /dev/null" >> /tmp/tmp/post-install
echo "-> Cloning repository"
@echo "-> Cloning repository"
git clone -q "https://github.com/$(HEROKUISH_REPO_NAME).git" /tmp/tmp/herokuish > /dev/null
rm -rf /tmp/tmp/herokuish/.git /tmp/tmp/herokuish/.gitignore
echo "-> Copying files into place"
@echo "-> Copying files into place"
mkdir -p "/tmp/build/var/lib"
cp -rf /tmp/tmp/herokuish /tmp/build/var/lib/herokuish
echo "-> Creating $(HEROKUISH_PACKAGE_NAME)"
@echo "-> Creating $(HEROKUISH_PACKAGE_NAME)"
sudo fpm -t deb -s dir -C /tmp/build -n herokuish -v $(HEROKUISH_VERSION) -a $(HEROKUISH_ARCHITECTURE) -p $(HEROKUISH_PACKAGE_NAME) --deb-pre-depends 'docker-engine-cs | docker-engine | lxc-docker (>= 1.6.1) | docker.io (>= 1.6.1) | tutum-agent' --deb-pre-depends sudo --after-install /tmp/tmp/post-install --url "https://github.com/$(HEROKUISH_REPO_NAME)" --description $(HEROKUISH_DESCRIPTION) --license 'MIT License' .
mv *.deb /tmp
@@ -105,41 +123,55 @@ deb-dokku: deb-setup
dpkg-deb --build /tmp/build "/vagrant/dokku_`cat /tmp/build/var/lib/dokku/STABLE_VERSION`_$(DOKKU_ARCHITECTURE).deb"
mv *.deb /tmp
deb-plugn: deb-setup
deb-plugn: deb-setup golang
rm -rf /tmp/tmp /tmp/build $(PLUGN_PACKAGE_NAME)
mkdir -p /tmp/tmp /tmp/build
mkdir -p /tmp/tmp /tmp/build /tmp/build/usr/local/bin
echo "-> Cloning repository"
@echo "-> Cloning repository"
git clone -q "https://github.com/$(PLUGN_REPO_NAME).git" /tmp/tmp/plugn > /dev/null
rm -rf /tmp/tmp/plugn/.git /tmp/tmp/plugn/.gitignore
echo "-> Copying files into place"
mkdir -p /tmp/build/usr/local/bin $(GOPATH)
sudo apt-get clean
sudo apt-get update -qq > /dev/null
sudo apt-get install -qq -y git golang mercurial > /dev/null 2>&1
@echo "-> Copying files into place"
export PATH=$(PATH):$(GOROOT)/bin:$(GOPATH)/bin && export GOROOT=$(GOROOT) && export GOPATH=$(GOPATH):/tmp/tmp/plugn && go get github.com/dokku/plugn
export PATH=$(PATH):$(GOROOT)/bin:$(GOPATH)/bin && export GOROOT=$(GOROOT) && export GOPATH=$(GOPATH):/tmp/tmp/plugn && cd /home/vagrant/gocode/src/github.com/dokku/plugn && make deps
export PATH=$(PATH):$(GOROOT)/bin:$(GOPATH)/bin && export GOROOT=$(GOROOT) && export GOPATH=$(GOPATH):/tmp/tmp/plugn && cd /home/vagrant/gocode/src/github.com/dokku/plugn && rm plugn && go build -o plugn
export PATH=$(PATH):$(GOROOT)/bin:$(GOPATH)/bin && export GOROOT=$(GOROOT) && export GOPATH=$(GOPATH):/tmp/tmp/plugn && cd /home/vagrant/gocode/src/github.com/dokku/plugn && rm -f plugn && go build -o plugn
mv /home/vagrant/gocode/src/github.com/dokku/plugn/plugn /tmp/build/usr/local/bin/plugn
echo "-> Creating $(PLUGN_PACKAGE_NAME)"
@echo "-> Creating $(PLUGN_PACKAGE_NAME)"
sudo fpm -t deb -s dir -C /tmp/build -n plugn -v $(PLUGN_VERSION) -a $(PLUGN_ARCHITECTURE) -p $(PLUGN_PACKAGE_NAME) --url "https://github.com/$(PLUGN_REPO_NAME)" --description $(PLUGN_DESCRIPTION) --license 'MIT License' .
mv *.deb /tmp
deb-sshcommand: deb-setup
rm -rf /tmp/tmp /tmp/build $(SSHCOMMAND_PACKAGE_NAME)
mkdir -p /tmp/tmp /tmp/build
mkdir -p /tmp/tmp /tmp/build /tmp/build/usr/local/bin
echo "-> Cloning repository"
@echo "-> Cloning repository"
git clone -q "https://github.com/$(SSHCOMMAND_REPO_NAME).git" /tmp/tmp/sshcommand > /dev/null
rm -rf /tmp/tmp/sshcommand/.git /tmp/tmp/sshcommand/.gitignore
echo "-> Copying files into place"
@echo "-> Copying files into place"
mkdir -p "/tmp/build/usr/local/bin"
cp /tmp/tmp/sshcommand/sshcommand /tmp/build/usr/local/bin/sshcommand
chmod +x /tmp/build/usr/local/bin/sshcommand
echo "-> Creating $(SSHCOMMAND_PACKAGE_NAME)"
@echo "-> Creating $(SSHCOMMAND_PACKAGE_NAME)"
sudo fpm -t deb -s dir -C /tmp/build -n sshcommand -v $(SSHCOMMAND_VERSION) -a $(SSHCOMMAND_ARCHITECTURE) -p $(SSHCOMMAND_PACKAGE_NAME) --url "https://github.com/$(SSHCOMMAND_REPO_NAME)" --description $(SSHCOMMAND_DESCRIPTION) --license 'MIT License' .
mv *.deb /tmp
deb-sigil: deb-setup golang
rm -rf /tmp/tmp /tmp/build $(SIGIL_PACKAGE_NAME)
mkdir -p /tmp/tmp /tmp/build /tmp/build/usr/local/bin
@echo "-> Cloning repository"
git clone -q "https://github.com/$(SIGIL_REPO_NAME).git" /tmp/tmp/sigil > /dev/null
rm -rf /tmp/tmp/sigil/.git /tmp/tmp/sigil/.gitignore
@echo "-> Copying files into place"
export PATH=$(PATH):$(GOROOT)/bin:$(GOPATH)/bin && export GOROOT=$(GOROOT) && export GOPATH=$(GOPATH):/tmp/tmp/sigil && go get github.com/gliderlabs/sigil
export PATH=$(PATH):$(GOROOT)/bin:$(GOPATH)/bin && export GOROOT=$(GOROOT) && export GOPATH=$(GOPATH):/tmp/tmp/sigil && cd /home/vagrant/gocode/src/github.com/gliderlabs/sigil && make deps
export PATH=$(PATH):$(GOROOT)/bin:$(GOPATH)/bin && export GOROOT=$(GOROOT) && export GOPATH=$(GOPATH):/tmp/tmp/sigil && cd /home/vagrant/gocode/src/github.com/gliderlabs/sigil && rm -f sigil && go build -o sigil
mv /home/vagrant/gocode/src/github.com/gliderlabs/sigil/sigil /tmp/build/usr/local/bin/sigil
@echo "-> Creating $(SIGIL_PACKAGE_NAME)"
sudo fpm -t deb -s dir -C /tmp/build -n sigil -v $(SIGIL_VERSION) -a $(SIGIL_ARCHITECTURE) -p $(SIGIL_PACKAGE_NAME) --url "https://github.com/$(SIGIL_REPO_NAME)" --description $(SIGIL_DESCRIPTION) --license 'MIT License' .
mv *.deb /tmp

View File

@@ -0,0 +1,20 @@
# 0.5.0 Migration Guide
## nginx-vhosts
- The nginx-vhosts template language is now [sigil](https://github.com/gliderlabs/sigil)
- No need to escape literal `$` characters (or other "bash-isms")
- Template variables are represented as {{ .VARIABLE_NAME }}
- A detailed list of template variables can be found [here](/dokku/nginx#available-template-variables)
- A custom nginx-vhosts template must be named `nginx.conf.sigil`
- The default path for this custom template is the root of your repo (i.e. `/app` in the container or `WORKDIR` if defined in a dockerfile app)
- Dokku no longer looks for this file in `/home/dokku/myapp` on the dokku server
- Check out an example template [here](/dokku/nginx/)
- Support for server-wide SSL certs have been dropped in favor of using the `certs` plugin
- `dokku certs:add myapp < certs.tar`
- All domains for an SSL-enabled app will be redirected to https by default
- This can be overridden with a custom template
- Replaced "magic" `NO_VHOST` variable with `domains:enable/disable`
- Simplified zero downtime control
- `checks:enable/disable`
## Dockerfile apps with multiple ports
- Dockerfiles with multiple `EXPOSE` clauses will get all **tcp** ports proxied by default (nginx does not support proxying udp)
- UDP can be exposed by disabling the nginx proxy with `dokku proxy:disable myapp`

View File

@@ -1,6 +1,10 @@
# Zero Downtime Deploys
> New as of 0.3.0
```
checks <app> Show zero-downtime status
checks:disable <app> Disable zero-downtime checks
checks:enable <app> Enable zero-downtime checks
```
Following a deploy, dokku will now wait `10` seconds before routing traffic to the new container. If the container is not running after this time, then the deploy is failed and your old container will continue serving traffic. You can modify this value using the following command:
@@ -38,14 +42,10 @@ Dokku will retry the checks `5` times until the checks are successful. If all 5
dokku config:set --global DOKKU_CHECKS_ATTEMPTS=2
```
You can also choose to skip checks completely either globally or on a per-application basis:
You can also choose to skip checks completely on a per-application basis:
```shell
# globally
dokku config:set --global DOKKU_SKIP_ALL_CHECKS=true
# for APP
dokku config:set APP DOKKU_SKIP_ALL_CHECKS=true
dokku checks:disable APP
```
## Checks Examples

View File

@@ -101,14 +101,40 @@ Beware that if you enable the header and a subsequent deploy of your application
## Running behind a load balancer
> New as of 0.3.17
Your application has access to the HTTP headers `X-Forwarded-Proto`, `X-Forwarded-For` and `X-Forwarded-Port`. These headers indicate the protocol of the original request (HTTP or HTTPS), the port number, and the IP address of the client making the request, respectively. The default configuration is for Nginx to set these headers.
If your server runs behind an HTTP/S load balancer, then Nginx will see all requests as coming from the load balancer. If your load balancer sets the `X-Forwarded-` headers, you can tell Nginx to pass these headers from load balancer to your application by setting the `DOKKU_SSL_TERMINATED` environment variable:
If your server runs behind an HTTP/S load balancer, then Nginx will see all requests as coming from the load balancer. If your load balancer sets the `X-Forwarded-` headers, you can tell Nginx to pass these headers from load balancer to your application by using the following [nginx custom template](/dokku/nginx/#customizing-the-nginx-configuration)
```shell
dokku config:set myapp DOKKU_SSL_TERMINATED=1
server {
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }};
access_log /var/log/nginx/{{ .APP }}-access.log;
error_log /var/log/nginx/{{ .APP }}-error.log;
# set a custom header for requests
add_header X-Served-By www-ec2-01;
location / {
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_set_header X-Forwarded-Port $http_x_forwarded_port;
proxy_set_header X-Request-Start $msec;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }}
server {{ . }};
{{ end }}
}
}
```
Only use this option if:

View File

@@ -3,70 +3,74 @@
Dokku uses nginx as its server for routing requests to specific applications. By default, access and error logs are written for each app to `/var/log/nginx/${APP}-access.log` and `/var/log/nginx/${APP}-error.log` respectively
```
nginx:access-logs <app> [-t] Show the nginx access logs for an application (-t follows)
nginx:build-config <app> (Re)builds nginx config for given app
nginx:disable <app> Disable nginx for an application (forces container binding to external interface)
nginx:enable <app> Enable nginx for an application
nginx:error-logs <app> [-t] Show the nginx error logs for an application (-t follows)
nginx:access-logs <app> [-t] Show the nginx access logs for an application (-t follows)
nginx:build-config <app> (Re)builds nginx config for given app
nginx:error-logs <app> [-t] Show the nginx error logs for an application (-t follows)
```
## Customizing the nginx configuration
> New as of 0.3.10.
Dokku uses a templating library by the name of [sigil](https://github.com/gliderlabs/sigil) to generate nginx configuration for each app. If you'd like to provide a custom template for your application, there are a couple options:
Dokku currently templates out an nginx configuration that is included in the `nginx-vhosts` plugin. If you'd like to provide a custom template for your application, there are a few options:
- Copy the existing pertinent (ssl or non-ssl) template found (by default) in `/var/lib/dokku/plugins/available/nginx-vhosts/templates`, place it either in `/home/dokku/APP` or check it into the root of your app repo, and name it one of the following:
- `nginx.conf.template` (since 0.3.10)
- `nginx.conf.ssl_terminated.template` (since 0.4.0)
- `nginx.ssl.conf.template` (since 0.4.2)
> If placed on the dokku server, the template file **must** be owned by user and group `dokku:dokku`.
For instance - assuming defaults - to customize the nginx template in use for the `myapp` application, create the file `nginx.conf.template` in your repo or on disk with the with the following contents:
- Copy the following example template to a file named `nginx.conf.sigil` and either:
- check it into the root of your app repo
- `ADD` it to your dockerfile `WORKDIR`
### Example Custom Template
```
server {
listen [::]:80;
listen 80;
server_name $NOSSL_SERVER_NAME;
access_log /var/log/nginx/${APP}-access.log;
error_log /var/log/nginx/${APP}-error.log;
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }};
access_log /var/log/nginx/{{ .APP }}-access.log;
error_log /var/log/nginx/{{ .APP }}-error.log;
# set a custom header for requests
add_header X-Served-By www-ec2-01;
location / {
proxy_pass http://$APP;
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Port \$server_port;
proxy_set_header X-Request-Start \$msec;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }}
server {{ . }};
{{ end }}
}
include $DOKKU_ROOT/$APP/nginx.conf.d/*.conf;
}
```
The above is a sample http configuration that adds an `X-Served-By` header to requests.
A few tips for custom nginx templates:
- Special characters - dollar signs, spaces inside of quotes, etc. - should be escaped with a single backslash or can cause deploy failures.
- Templated files will be validated via `nginx -t`.
- Application environment variables can be used within your nginx configuration.
After your changes a `dokku deploy myapp` will regenerate the `/home/dokku/myapp/nginx.conf` file which is then used.
### Available template variables
```
{{ .APP }} Application name
{{ .APP_SSL_PATH }} Path to SSL certificate and key
{{ .DOKKU_ROOT }} Global dokku root directory (ex: app dir would be `{{ .DOKKU_ROOT }}/{{ .APP }}`)
{{ .DOKKU_APP_LISTENERS }} List of IP:PORT pairs of app containers
{{ .NGINX_PORT }} Non-SSL nginx listener port (same as `DOKKU_NGINX_PORT` config var)
{{ .NGINX_SSL_PORT }} SSL nginx listener port (same as `DOKKU_NGINX_SSL_PORT` config var)
{{ .NOSSL_SERVER_NAME }} List of non-SSL VHOSTS
{{ .RAW_TCP_PORTS }} List of exposed tcp ports as defined by Dockerfile `EXPOSE` directive (**Dockerfile apps only**)
{{ .SSL_INUSE }} Boolean set when an app is SSL-enabled
{{ .SSL_SERVER_NAME }} List of SSL VHOSTS
```
### Customizing via configuration files included by the default templates
The default nginx.conf- templates will include everything from your apps `nginx.conf.d/` subdirectory in the main `server {}` block (see above):
The default nginx.conf template will include everything from your apps `nginx.conf.d/` subdirectory in the main `server {}` block (see above):
```
include $DOKKU_ROOT/$APP/nginx.conf.d/*.conf;
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
```
That means you can put additional configuration in separate files, for example to limit the uploaded body size to 50 megabytes, do
@@ -86,7 +90,7 @@ Applications typically have the following structure for their hostname:
scheme://subdomain.domain.tld
```
The `subdomain` is inferred from the pushed application name, while the `domain` is set during initial configuration in the `$DOKKU_ROOT/VHOST` file.
The `subdomain` is inferred from the pushed application name, while the `domain` is set during initial configuration in the `$DOKKU_ROOT/VHOST` file or via `dokku domains:set-global`.
You can optionally override this in a plugin by implementing the `nginx-hostname` plugin trigger. For example, you can reverse the subdomain with the following sample `nginx-hostname` plugin trigger:
@@ -104,30 +108,32 @@ If the `nginx-hostname` has no output, the normal hostname algorithm will be exe
You can also use the built-in `domains` plugin to handle:
### Disabling VHOSTS
If desired, it is possible to disable vhosts by setting the environment variable `NO_VHOST=1`:
```shell
dokku config:set myapp NO_VHOST=1
```
On subsequent deploys, the nginx virtualhost will be discarded. This is useful when deploying internal-facing services that should not be publicly routeable. As of 0.4.0, nginx will still be configured to proxy your app on some random high port. This allows internal services to maintain the same port between deployments. You may change this port by setting `DOKKU_NGINX_PORT` and/or `DOKKU_NGINX_SSL_PORT` (for services configured to use SSL.)
### Domains plugin
> New as of 0.3.10
```shell
domains:add <app> DOMAIN Add a custom domain to app
domains <app> List custom domains for app
domains:clear <app> Clear all custom domains for app
domains:remove <app> DOMAIN Remove a custom domain from app
domains:add <app> DOMAIN Add a domain to app
domains [<app>] List domains
domains:clear <app> Clear all domains for app
domains:disable <app> Disable VHOST support
domains:enable <app> Enable VHOST support
domains:remove <app> DOMAIN Remove a domain from app
domains:set-global <domain> Set global domain name
```
The domains plugin allows you to specify custom domains for applications. This plugin is aware of any ssl certificates that are imported via `nginx:import-ssl`. Be aware that setting `NO_VHOST` will override any custom domains.
### Disabling VHOSTS
Custom domains are also backed up via the built-in `backup` plugin
If desired, it is possible to disable vhosts with the domains plugin.
```shell
dokku domains:disable myapp
```
On subsequent deploys, the nginx virtualhost will be discarded. This is useful when deploying internal-facing services that should not be publicly routeable. As of 0.4.0, nginx will still be configured to proxy your app on some random high port. This allows internal services to maintain the same port between deployments. You may change this port by setting `DOKKU_NGINX_PORT` and/or `DOKKU_NGINX_SSL_PORT` (for services configured to use SSL.)
The domains plugin allows you to specify custom domains for applications. This plugin is aware of any ssl certificates that are imported via `certs:add`. Be aware that disabling domains (with `domains:disable`) will override any custom domains.
```shell
# where `myapp` is the name of your app
@@ -145,26 +151,6 @@ dokku domains:clear myapp
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
```
## Default site

28
docs/proxy.md Normal file
View File

@@ -0,0 +1,28 @@
# Proxy plugin
As of dokku 0.5.0, the proxy functionality has been decoupled from the nginx-vhosts plugin into the proxy plugin. In the future this will allow other proxy software (HAproxy for example) to be used instead of nginx.
```
proxy:disable <app> Disable proxy for app
proxy:enable <app> Enable proxy for app
proxy:set <app> <proxy_type> NOT IMPLEMENTED YET!!
```
## Container network interface binding
By default, the deployed docker container running your app's web process will bind to the internal docker network interface (i.e. `docker inspect --format '{{ .NetworkSettings.IPAddress }}' $CONTAINER_ID`). This behavior can be modified per app by disabling the proxy (i.e. `dokku proxy:disable <app>`). In this case, the container will bind to an external interface (i.e. 0.0.0.0) and your app container will be directly accessible by other hosts on your network.
```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 node-js-app.web.1
root@dokku:~/dokku# docker inspect --format '{{ .NetworkSettings.IPAddress }}' node-js-app.web.1
172.17.0.6
# container bound to all interfaces
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 node-js-app.web.1
```

40
dokku
View File

@@ -33,6 +33,8 @@ export DOKKU_CONTAINER_LABEL=dokku
export DOKKU_GLOBAL_RUN_ARGS="--label=$DOKKU_CONTAINER_LABEL"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
[[ -f $DOKKU_ROOT/dokkurc ]] && source $DOKKU_ROOT/dokkurc
[[ -d $DOKKU_ROOT/.dokkurc ]] && for f in $DOKKU_ROOT/.dokkurc/*; do source $f; done
@@ -104,15 +106,8 @@ case "$1" in
DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
oldids=$(get_app_container_ids $APP)
DOKKU_APP_SKIP_ALL_CHECKS=$(dokku config:get $APP DOKKU_SKIP_ALL_CHECKS || true)
DOKKU_APP_SKIP_DEFAULT_CHECKS=$(dokku config:get $APP DOKKU_SKIP_DEFAULT_CHECKS || true)
DOKKU_GLOBAL_SKIP_ALL_CHECKS=$(dokku config:get --global DOKKU_SKIP_ALL_CHECKS || true)
DOKKU_GLOBAL_SKIP_DEFAULT_CHECKS=$(dokku config:get --global DOKKU_SKIP_DEFAULT_CHECKS || true)
DOKKU_SKIP_ALL_CHECKS=${DOKKU_APP_SKIP_ALL_CHECKS:="$DOKKU_GLOBAL_SKIP_ALL_CHECKS"}
DOKKU_SKIP_DEFAULT_CHECKS=${DOKKU_APP_SKIP_DEFAULT_CHECKS:="$DOKKU_GLOBAL_SKIP_DEFAULT_CHECKS"}
DOKKU_DEFAULT_DOCKER_ARGS=$(: | plugn trigger docker-args-deploy $APP $IMAGE_TAG)
DOKKU_IS_APP_PROXY_ENABLED="$(is_app_proxy_enabled $APP)"
while read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^#.* ]] && continue
@@ -131,11 +126,11 @@ case "$1" in
DOCKER_ARGS="$DOKKU_DEFAULT_DOCKER_ARGS"
DOCKER_ARGS+=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' "
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
BIND_EXTERNAL=$(plugn trigger bind-external-ip $APP)
[[ -n "$DOKKU_HEROKUISH" ]] && START_CMD="/start $PROC_TYPE"
if [[ -z "$DOKKU_HEROKUISH" ]]; then
DOKKU_DOCKERFILE_PORTS=($(dokku config:get $APP DOKKU_DOCKERFILE_PORTS || true))
DOKKU_DOCKERFILE_PORT=$(dokku config:get $APP DOKKU_DOCKERFILE_PORT || true)
DOKKU_DOCKERFILE_START_CMD=$(dokku config:get $APP DOKKU_DOCKERFILE_START_CMD || true)
DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile $APP $PROC_TYPE)
@@ -143,18 +138,30 @@ case "$1" in
fi
if [[ "$PROC_TYPE" == "web" ]]; then
port=${DOKKU_DOCKERFILE_PORT:=5000}
if [[ "$BIND_EXTERNAL" = "true" ]]; then
id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -p $port -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
port=$(docker port $id $port | sed 's/[0-9.]*://')
ipaddr=127.0.0.1
if [[ -z "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then
port=5000
DOKKU_DOCKER_PORT_ARGS+="-p $port"
else
for p in ${DOKKU_DOCKERFILE_PORTS[*]};do
if [[ ! "$p" =~ .*udp.* ]]; then
# set port to first non-udp port
p=${p//\/tcp}
port=${port:="$p"}
fi
DOKKU_DOCKER_PORT_ARGS+=" -p $p "
done
fi
if [[ "$DOKKU_IS_APP_PROXY_ENABLED" = "true" ]]; then
id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
ipaddr=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $id)
# Docker < 1.9 compatibility
if [[ -z $ipaddr ]]; then
ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $id)
fi
else
id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
port=$(docker port $id $port | sed 's/[0-9.]*://')
ipaddr=127.0.0.1
fi
else
id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOCKER_ARGS $IMAGE $START_CMD)
@@ -168,8 +175,8 @@ case "$1" in
}
# run checks first, then post-deploy hooks, which switches Nginx traffic
if [[ "$DOKKU_SKIP_ALL_CHECKS" = "true" ]]; then
dokku_log_info1 "Skipping pre-flight checks"
if [[ "$(is_app_checks_enabled $APP)" == "false" ]]; then
dokku_log_info1 "zero downtime is disabled for app ($APP). skipping pre-flight checks"
else
trap kill_new INT TERM EXIT
dokku_log_info1 "Running pre-flight checks"
@@ -181,7 +188,6 @@ case "$1" in
[[ -n "$id" ]] && echo $id > "$DOKKU_CONTAINER_ID_FILE"
[[ -n "$ipaddr" ]] && echo $ipaddr > "$DOKKU_IP_FILE"
[[ -n "$port" ]] && echo $port > "$DOKKU_PORT_FILE"
[[ -n "$port" ]] && echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$port" > "$DOKKU_ROOT/$APP/URL"
# cleanup pre-migration files
rm -f $DOKKU_ROOT/$APP/CONTAINER $DOKKU_ROOT/$APP/IP $DOKKU_ROOT/$APP/PORT

View File

@@ -4,6 +4,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
case "$1" in
build)
@@ -35,8 +36,8 @@ case "$1" in
dockerfile)
# extract first port from Dockerfile
DOCKERFILE_PORT=$(get_dockerfile_exposed_port Dockerfile)
[[ -n "$DOCKERFILE_PORT" ]] && config_set --no-restart $APP DOKKU_DOCKERFILE_PORT=$DOCKERFILE_PORT
DOCKERFILE_PORTS=$(get_dockerfile_exposed_ports Dockerfile)
[[ -n "$DOCKERFILE_PORTS" ]] && config_set --no-restart $APP DOKKU_DOCKERFILE_PORTS="$DOCKERFILE_PORTS"
plugn trigger pre-build-dockerfile "$APP"
[[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache"
@@ -151,46 +152,7 @@ case "$1" in
url | urls)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; verify_app_name "$2"
eval "$(config_export app $APP)"
if [[ -s "$DOKKU_ROOT/$APP/URLS" ]]; then
case "$1" in
url)
grep "^http" "$DOKKU_ROOT/$APP/URLS" | head -1
;;
urls)
grep "^http" "$DOKKU_ROOT/$APP/URLS"
;;
esac
exit 0
fi
SCHEME="http"; SSL="$DOKKU_ROOT/$APP/tls"; WILDCARD_SSL="$DOKKU_ROOT/tls"
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]] || [[ -e "$WILDCARD_SSL/server.crt" && -e "$WILDCARD_SSL/server.key" ]]; then
SCHEME="https"
fi
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
shopt -s nullglob
for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE") (container)"
done
shopt -u nullglob
DOKKU_NGINX_PORT=$(config_get $APP DOKKU_NGINX_PORT || true)
DOKKU_NGINX_SSL_PORT=$(config_get $APP DOKKU_NGINX_SSL_PORT || true)
if [[ -n "$DOKKU_NGINX_PORT" ]]; then
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_PORT (nginx)"
fi
if [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
echo "https://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_SSL_PORT (nginx-ssl)"
fi
else
echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
fi
get_app_urls "$@"
;;
report)
@@ -201,6 +163,7 @@ case "$1" in
docker version
dokku_log_info1 "docker daemon info: "
docker -D info
dokku_log_info1 "sigil version: $(sigil -v)"
dokku_log_info1 "herokuish version: "
docker run --rm -ti gliderlabs/herokuish:latest herokuish version
dokku_log_info1 "dokku version: $(dokku version)"

View File

@@ -57,3 +57,5 @@ if [ ! -f "/home/dokku/HOSTNAME" ]; then
fi
EOF
chmod +x /etc/update-motd.d/99-dokku
chown dokku:dokku "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/VHOST"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core standard plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -7,13 +7,8 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
is_ssl_enabled() {
local APP=$1; verify_app_name $APP
APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
WILDCARD_SSL_PATH="$DOKKU_ROOT/tls"
if [[ -e "$APP_SSL_PATH/server.crt" ]] && [[ -e "$APP_SSL_PATH/server.key" ]]; then
echo app
return 0
elif [[ -e "$WILDCARD_SSL_PATH/server.crt" ]] && [[ -e "$WILDCARD_SSL_PATH/server.key" ]]; then
echo global
return 0
else
return 1
@@ -22,22 +17,14 @@ is_ssl_enabled() {
get_ssl_hostnames() {
local APP=$1; verify_app_name $APP
case "$(is_ssl_enabled $APP)" in
app)
SSL_PATH="$DOKKU_ROOT/$APP/tls"
;;
local SSL_PATH="$DOKKU_ROOT/$APP/tls"
global)
SSL_PATH="$DOKKU_ROOT/tls"
;;
esac
SSL_HOSTNAME=$(openssl x509 -in $SSL_PATH/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-)
SSL_HOSTNAME_ALT=$(openssl x509 -in $SSL_PATH/server.crt -noout -text | grep --after-context=1 '509v3 Subject Alternative Name:' | tail -n 1 | sed -e "s/[[:space:]]*DNS://g" | tr ',' '\n' || true)
local SSL_HOSTNAME=$(openssl x509 -in $SSL_PATH/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-)
local SSL_HOSTNAME_ALT=$(openssl x509 -in $SSL_PATH/server.crt -noout -text | grep --after-context=1 '509v3 Subject Alternative Name:' | tail -n 1 | sed -e "s/[[:space:]]*DNS://g" | tr ',' '\n' || true)
if [[ -n "$SSL_HOSTNAME_ALT" ]]; then
SSL_HOSTNAMES="${SSL_HOSTNAME}\n${SSL_HOSTNAME_ALT}"
local SSL_HOSTNAMES="${SSL_HOSTNAME}\n${SSL_HOSTNAME_ALT}"
else
SSL_HOSTNAMES=$SSL_HOSTNAME
local SSL_HOSTNAMES=$SSL_HOSTNAME
fi
echo -e $SSL_HOSTNAMES
return 0

View File

@@ -36,6 +36,7 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
APP="$1"; DOKKU_APP_CONTAINER_ID="$2"; DOKKU_APP_CONTAINER_TYPE="$3"; DOKKU_APP_LISTEN_PORT="$4"; DOKKU_APP_LISTEN_IP="$5"
@@ -55,6 +56,11 @@ fi
eval "$(config_export global)"
eval "$(config_export app $APP)"
if [[ "$(is_app_checks_enabled $APP)" == "false" ]];then
dokku_log_info2_quiet "Zero downtime checks for app ($APP) have been disabled. moving on..."
exit 0
fi
# Wait this many seconds (default 5) for server to start before running checks.
WAIT="${DOKKU_CHECKS_WAIT:-5}"
# Wait this many seconds (default 30) for each response.
@@ -80,11 +86,6 @@ cleanup() {
trap cleanup EXIT
if [[ ! -s "${TMPDIR}/CHECKS" ]] || [[ "$DOKKU_APP_CONTAINER_TYPE" != "web" ]]; then
if [[ "$DOKKU_SKIP_DEFAULT_CHECKS" = "true" ]]; then
dokku_log_verbose "Skipping default check..."
exit 0
fi
# We allow custom check for web instances only
if [[ "$DOKKU_APP_CONTAINER_TYPE" == "web" ]]; then
dokku_log_verbose "For more efficient zero downtime deployments, create a file CHECKS."

75
plugins/checks/commands Executable file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
[[ " checks checks:enable checks:disable help ps:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
checks_main() {
local desc="displays app zero-downtime status"
local ALL_APPS=$(dokku_apps)
if [[ -n "$1" ]]; then
local APP="$1"
fi
local APPS=${APP:="$ALL_APPS"}
dokku_col_log_info1_quiet "App Name" "Zero-Downtime Status"
for app in $APPS; do
verify_app_name "$app"
dokku_col_log_msg "$app" "$(is_app_checks_enabled $app)"
done
}
checks_enable() {
local desc="enable zero-downtime for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled $APP)" == "false" ]]; then
dokku_log_info1 "Enabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=1
else
dokku_log_info1 "zero downtime is already enabled for app ($APP)"
fi
}
checks_disable() {
local desc="disable zero-downtime for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled $APP)" == "true" ]]; then
dokku_log_info1 "Disabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=0
else
dokku_log_info1 "zero downtime is already disable for app ($APP)"
fi
}
case "$1" in
checks)
checks_main $2
;;
checks:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
checks_enable $2 --no-restart
;;
checks:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
checks_disable $2 --no-restart
;;
help | ps:help)
cat<<EOF
checks <app>, Show zero-downtime status
checks:enable <app>, Enable zero-downtime checks
checks:disable <app>, Disable zero-downtime checks
EOF
;;
*)
exit $DOKKU_NOT_IMPLEMENTED_EXIT
;;
esac

18
plugins/checks/functions Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
is_app_checks_enabled() {
local desc="return app zero-downtime checks status"
local APP="$1"; verify_app_name "$APP"
local DOKKU_CHECKS_ENABLED=$(config_get $APP DOKKU_CHECKS_ENABLED)
if [[ -z "$DOKKU_CHECKS_ENABLED" ]] || [[ "$DOKKU_CHECKS_ENABLED" == "1" ]];then
local status=true
else
local status=false
fi
echo $status
}

40
plugins/checks/install Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
migrate_checks_vars() {
local APPS="$(dokku_apps)"
local GLOBAL_SKIP_ALL_CHECKS=$(dokku config:get --global DOKKU_SKIP_ALL_CHECKS || true)
local GLOBAL_SKIP_DEFAULT_CHECKS=$(dokku config:get --global DOKKU_SKIP_DEFAULT_CHECKS || true)
local app
dokku_log_info1 "Migrating zero downtime env variables. The following variables have been deprecated"
dokku_log_info2 "DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS"
dokku_log_info2 "Please use dokku checks:[disable|enable] <app> to control zero downtime functionality"
for app in $APPS; do
local APP_SKIP_ALL_CHECKS=$(dokku config:get $app DOKKU_SKIP_ALL_CHECKS || true)
local APP_SKIP_DEFAULT_CHECKS=$(dokku config:get $app DOKKU_SKIP_DEFAULT_CHECKS || true)
if [[ "$APP_SKIP_ALL_CHECKS" == "true" ]] || [[ "$APP_SKIP_DEFAULT_CHECKS" == "true" ]] || \
[[ "$GLOBAL_SKIP_ALL_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_DEFAULT_CHECKS" == "true" ]]; then
dokku_log_info2 ""
dokku_log_info2 "zero downtime disabled for app ($app)"
config_set --no-restart $app DOKKU_CHECKS_ENABLED=0
fi
if [[ -n "$APP_SKIP_ALL_CHECKS" ]] || [[ -n "$APP_SKIP_DEFAULT_CHECKS" ]]; then
config_unset --no-restart $app DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS
fi
dokku_log_info2 "Migration complete"
dokku_log_info2 ""
done
if [[ -n "$GLOBAL_SKIP_ALL_CHECKS" ]] || [[ -n "$GLOBAL_SKIP_DEFAULT_CHECKS" ]]; then
dokku_log_info1 "Removing global zero downtime settings"
config_unset --global DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS
fi
}
migrate_checks_vars "$@"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core checks plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -258,11 +258,6 @@ get_app_container_ids() {
echo $DOKKU_CIDS
}
get_dockerfile_exposed_port() {
local DOCKERFILE_PORT=$(grep "^EXPOSE \+[[:digit:]]\+\(\/tcp\)\? *$" $1 | head -1 | sed 's/EXPOSE \+\([[:digit:]]\+\)\(\/tcp\)\?.*/\1/' || true)
echo "$DOCKERFILE_PORT"
}
get_app_running_container_ids() {
local APP=$1
verify_app_name $APP
@@ -441,3 +436,166 @@ get_ipv6_regex() {
# Fixes using a wildcard dns service such as xip.io which allows for *.<ip address>.xip.io
echo "${RE_IPV6}\$"
}
get_global_vhost() {
local GLOBAL_VHOST_FILE="$DOKKU_ROOT/VHOST"
[[ -f "$GLOBAL_VHOST_FILE" ]] && local GLOBAL_VHOST=$(< "$GLOBAL_VHOST_FILE")
echo $GLOBAL_VHOST
}
is_global_vhost_enabled() {
local desc="returns true if we have a valid global vhost set; otherwise returns false"
local GLOBAL_VHOST=$(get_global_vhost)
local GLOBAL_VHOST_ENABLED=true
local RE_IPV4="$(get_ipv4_regex)"
local RE_IPV6="$(get_ipv6_regex)"
if [[ -z "$GLOBAL_VHOST" ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV4 ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV6 ]]; then
local GLOBAL_VHOST_ENABLED=false
fi
echo $GLOBAL_VHOST_ENABLED
}
is_app_vhost_enabled() {
local desc="returns true or false if vhost support is enabled for a given application"
local APP=$1; verify_app_name $APP
local NO_VHOST=$(config_get $APP NO_VHOST)
local APP_VHOST_ENABLED=true
if [[ "$NO_VHOST" == "1" ]]; then
local APP_VHOST_ENABLED=false
fi
echo $APP_VHOST_ENABLED
}
disable_app_vhost() {
local desc="disable vhost support for given application"
local APP=$1; verify_app_name $APP
local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
local APP_URLS_FILE="$DOKKU_ROOT/$APP/URLS"
local DOKKU_NGINX_PORT=$(config_get $APP DOKKU_NGINX_PORT)
local DOKKU_NGINX_SSL_PORT=$(config_get $APP DOKKU_NGINX_SSL_PORT)
if [[ -f "$APP_VHOST_FILE" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/VHOST"
rm "$APP_VHOST_FILE"
fi
if [[ -f "$APP_URLS_FILE" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/URLS"
rm "$APP_URLS_FILE"
fi
if [[ "$DOKKU_NGINX_PORT" == "80" ]]; then
config_unset --no-restart $APP DOKKU_NGINX_PORT
fi
if [[ "$DOKKU_NGINX_SSL_PORT" == "443" ]]; then
config_unset --no-restart $APP DOKKU_NGINX_SSL_PORT
fi
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP NO_VHOST=1
}
enable_app_vhost() {
local desc="enable vhost support for given application"
local APP=$1; verify_app_name $APP
config_unset --no-restart $APP DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP NO_VHOST=0
}
get_dockerfile_exposed_ports() {
local DOCKERFILE_PORTS=$(egrep "^EXPOSE " $1 | awk '{ print $2 }' | xargs) || true
echo "$DOCKERFILE_PORTS"
}
get_app_raw_tcp_ports() {
local APP="$1"; verify_app_name "$APP"
local DOCKERFILE_PORTS="$(config_get $APP DOKKU_DOCKERFILE_PORTS)"
for p in $DOCKERFILE_PORTS; do
if [[ ! "$p" =~ .*udp.* ]]; then
p=${p//\/tcp}
raw_tcp_ports+="$p "
fi
done
raw_tcp_ports="$(echo $raw_tcp_ports| xargs)"
echo "$raw_tcp_ports"
}
get_container_ports() {
local APP="$1"; verify_app_name "$APP"
local APP_CIDS="$(get_app_container_ids $APP)"
local cid
for cid in $APP_CIDS; do
local container_ports="$(docker port $cid | awk '{ print $3 "->" $1}' | awk -F ":" '{ print $2 }')"
done
echo $container_ports
}
get_app_urls() {
local APP="$2"; verify_app_name "$APP"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports $APP)"
local URLS_FILE="$DOKKU_ROOT/$APP/URLS"
if [[ -s "$URLS_FILE" ]]; then
local app_urls="$(egrep -v "^#" $URLS_FILE)"
if [[ -n "$RAW_TCP_PORTS" ]]; then
for url in ${app_urls[*]}; do
for p in $RAW_TCP_PORTS; do
local port_urls+="$url:$p "
done
done
local port_urls="$(echo $port_urls| xargs)"
fi
local URLS=${port_urls:=$app_urls}
case "$1" in
url)
echo "$URLS" | tr ' ' '\n' | head -n1
;;
urls)
echo "$URLS" | tr ' ' '\n'
;;
esac
else
local SCHEME="http"; local SSL="$DOKKU_ROOT/$APP/tls"
local DOKKU_NGINX_PORT=$(config_get $APP DOKKU_NGINX_PORT || true)
local DOKKU_NGINX_SSL_PORT=$(config_get $APP DOKKU_NGINX_SSL_PORT || true)
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]]; then
local SCHEME="https"
fi
if [[ "$(is_app_proxy_enabled $APP)" == "false" ]]; then
if [[ -n "$RAW_TCP_PORTS" ]]; then
local APP_CONTAINER_PORTS="$(get_container_ports $APP)"
local app_port
for app_port in $APP_CONTAINER_PORTS; do
echo "$(< "$DOKKU_ROOT/HOSTNAME"):$app_port (container)"
done
else
shopt -s nullglob
for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do
echo "$SCHEME://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE") (container)"
done
shopt -u nullglob
fi
elif [[ -n "$DOKKU_NGINX_PORT" ]] || [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
if [[ -n "$DOKKU_NGINX_PORT" ]];then
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_PORT ($(get_app_proxy_type $APP))"
fi
if [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
echo "https://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_SSL_PORT ($(get_app_proxy_type $APP)-ssl)"
fi
elif [[ -n "$RAW_TCP_PORTS" ]]; then
for p in $RAW_TCP_PORTS; do
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$p"
done
else
echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
fi
fi
}

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core common plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -7,16 +7,17 @@ config_export() {
local APP="$2"
local ENV_FILE="$DOKKU_ROOT/$APP/ENV"
[[ $CONFIG_TYPE == "global" ]] && ENV_FILE="$DOKKU_ROOT/ENV"
[[ $CONFIG_TYPE == "global" ]] && local ENV_FILE="$DOKKU_ROOT/ENV"
[[ ! -f $ENV_FILE ]] && return 0
[[ ! -s $ENV_FILE ]] && return 0
VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
local VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
echo "$VARS" | awk '{print "export " $0}'
return 0
}
config_parse_args() {
unset APP ENV_FILE DOKKU_CONFIG_TYPE DOKKU_CONFIG_RESTART
case "$2" in
--global)
ENV_FILE="$DOKKU_ROOT/ENV"
@@ -57,21 +58,21 @@ config_styled_hash () {
local longest=""
while read -r word; do
KEY=$(echo $word | cut -d"=" -f1)
local KEY=$(echo $word | cut -d"=" -f1)
if [[ ${#KEY} -gt ${#longest} ]]; then
longest=$KEY
local longest=$KEY
fi
done <<< "$vars"
while read -r word; do
KEY=$(echo $word | cut -d"=" -f1)
VALUE=$(echo $word | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" -e "s/\$$//g")
local KEY=$(echo $word | cut -d"=" -f1)
local VALUE=$(echo $word | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" -e "s/\$$//g")
num_zeros=$((${#longest} - ${#KEY}))
zeros=" "
local num_zeros=$((${#longest} - ${#KEY}))
local zeros=" "
while [[ $num_zeros -gt 0 ]]; do
zeros="$zeros "
num_zeros=$((num_zeros - 1))
local zeros="$zeros "
local num_zeros=$((num_zeros - 1))
done
echo "$prefix$KEY:$zeros$VALUE"
done <<< "$vars"
@@ -101,13 +102,14 @@ is_config_export() {
config_all() {
[[ "$1" == "config" ]] || set -- "config" "$@"
config_parse_args "$@"
config_create "$ENV_FILE"
is_config_export "$@" && config_export "$DOKKU_CONFIG_TYPE" "$APP" && return 0
[[ "$APP" ]] && DOKKU_CONFIG_TYPE=$APP
[[ "$APP" ]] && local DOKKU_CONFIG_TYPE=$APP
[[ ! -s $ENV_FILE ]] && dokku_log_fail "no config vars for $DOKKU_CONFIG_TYPE"
VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
local VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
for var in "$@"; do
if [[ "$var" == "--shell" ]]; then
@@ -135,7 +137,7 @@ config_get() {
return 0
fi
KEY="$3"
local KEY="$3"
grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | grep "^export $KEY=" | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//"
}
@@ -153,9 +155,9 @@ config_set() {
fi
config_create "$ENV_FILE"
ENV_ADD=""
ENV_TEMP=$(cat "${ENV_FILE}")
RESTART_APP=false
local ENV_ADD=""
local ENV_TEMP=$(cat "${ENV_FILE}")
local RESTART_APP=false
shift 2
for var; do
@@ -168,20 +170,20 @@ config_set() {
done
for var; do
KEY=$(echo ${var} | cut -d"=" -f1)
VALUE=$(echo ${var} | cut -d"=" -f2-)
local KEY=$(echo ${var} | cut -d"=" -f1)
local VALUE=$(echo ${var} | cut -d"=" -f2-)
if [[ $KEY =~ [a-zA-Z_][a-zA-Z0-9_]* ]]; then
RESTART_APP=true
ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $KEY=/ d")
ENV_TEMP="${ENV_TEMP}
local RESTART_APP=true
local ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $KEY=/ d")
local ENV_TEMP="${ENV_TEMP}
export $KEY='$VALUE'"
ENV_ADD=$(echo -e "${ENV_ADD}" | sed "/^$KEY=/ d")
ENV_ADD="${ENV_ADD}$
local ENV_ADD=$(echo -e "${ENV_ADD}" | sed "/^$KEY=/ d")
local ENV_ADD="${ENV_ADD}$
${var}"
fi
done
ENV_ADD=$(echo "$ENV_ADD" | tail -n +2) #remove first empty line
local ENV_ADD=$(echo "$ENV_ADD" | tail -n +2) #remove first empty line
if [[ $RESTART_APP ]]; then
dokku_log_info1 "Setting config vars"
@@ -209,15 +211,14 @@ config_unset() {
fi
config_create "$ENV_FILE"
ENV_TEMP=$(cat "${ENV_FILE}")
VARS="${*:3}"
local ENV_TEMP=$(cat "${ENV_FILE}")
local VARS="${*:3}"
for var in $VARS; do
dokku_log_info1 "Unsetting $var"
ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $var=/ d")
local ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $var=/ d")
config_write "$ENV_TEMP"
[[ "$var" == "NO_VHOST" ]] && config_set --no-restart $APP NO_VHOST=0 && DOKKU_CONFIG_RESTART=true
done
plugn trigger post-config-update $APP "unset" "$@"

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
[[ " domains domains:setup domains:add domains:clear domains:remove help domains:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
[[ " domains domains:setup domains:add domains:clear domains:remove domains:disable domains:enable domains:set-global help domains:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
@@ -7,122 +7,68 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
case "$1" in
domains)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
dokku domains:setup $APP
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info2_quiet "$APP Domain Names"
get_app_domains "$APP"
else
dokku_log_fail "No domain names set for $APP"
fi
domains_main "$2"
;;
domains:setup)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"; VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
RE_IPV4="$(get_ipv4_regex)"; RE_IPV6="$(get_ipv6_regex)"
if [[ ! -f $VHOST_PATH ]]; then
if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
VHOST=$(< "$DOKKU_ROOT/VHOST")
else
VHOST=$(< "$DOKKU_ROOT/HOSTNAME")
fi
if [[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]]; then
dokku_log_info2 "unsupported vhost config found. disabling vhost support"
disable_app_vhost $APP --no-restart $APP
else
if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
dokku_log_info1 "Creating new $VHOST_PATH..."
SUBDOMAIN=${APP/%\.${VHOST}/}
hostname=$(: | plugn trigger nginx-hostname $APP $SUBDOMAIN $VHOST)
if [[ ! -n $hostname ]]; then
if [[ "$APP" == *.* ]] && [[ "$SUBDOMAIN" == "$APP" ]]; then
hostname="${APP/\//-}"
else
hostname="${APP/\//-}.$VHOST"
fi
fi
echo "$hostname" > $VHOST_PATH
fi
fi
fi
domains_setup "$2"
;;
domains:add)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $APP DOMAIN [DOMAIN ...]"
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
if [[ $(egrep -w "^{$3}$" "$DOKKU_ROOT/$APP/VHOST" > /dev/null 2>&1; echo $?) -eq 0 ]]; then
echo "$3 is already defined for $APP"
exit 1
fi
shift 2
dokku domains:setup $APP
for DOMAIN in "$@"; do
echo "$DOMAIN" >> "$DOKKU_ROOT/$APP/VHOST"
done
plugn trigger post-domains-update $APP "add" "$@"
for DOMAIN in "$@"; do
dokku_log_info1 "Added $DOMAIN to $APP"
done
shift 1
domains_add "$@"
;;
domains:clear)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
rm -f "$DOKKU_ROOT/$APP/VHOST"
dokku domains:setup $APP
plugn trigger post-domains-update $APP "clear"
dokku_log_info1 "Cleared domains in $APP"
domains_clear "$2"
;;
domains:remove)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $APP DOMAIN [DOMAIN ...]"
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
shift 2
dokku domains:setup $APP
for DOMAIN in "$@"; do
sed -i "/^$DOMAIN$/d" "$DOKKU_ROOT/$APP/VHOST"
done
plugn trigger post-domains-update $APP "remove" "$@"
for DOMAIN in "$@"; do
dokku_log_info1 "Removed $DOMAIN from $APP"
done
shift 1
domains_remove "$@"
;;
domains:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_disable "$2"
;;
domains:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_enable "$2"
;;
domains:set-global)
[[ -z $2 ]] && dokku_log_fail "Please specify a global domain name"
domains_set_global "$2"
;;
help | domains:help)
cat<<EOF
domains <app>, List custom domains for app
domains:add <app> DOMAIN, Add a custom domain to app
domains:clear <app>, Clear all custom domains for app
domains:remove <app> DOMAIN, Remove a custom domain from app
domains [<app>], List domains
domains:add <app> DOMAIN, Add a domain to app
domains:clear <app>, Clear all domains for app
domains:disable <app>, Disable VHOST support
domains:enable <app>, Enable VHOST support
domains:remove <app> DOMAIN, Remove a domain from app
domains:set-global <domain>, Set global domain name
EOF
;;

View File

@@ -3,9 +3,168 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
get_app_domains() {
local desc="return app domains"
verify_app_name $1
local APP=$1; local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
verify_app_name $APP
if [[ -f "$APP_VHOST_FILE" ]];then
cat "$APP_VHOST_FILE"
local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
local GLOBAL_HOSTNAME_PATH="$DOKKU_ROOT/HOSTNAME"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
if [[ -f "$APP_VHOST_FILE" ]]; then
cat "$APP_VHOST_FILE"
elif [[ -f "$GLOBAL_VHOST_PATH" ]]; then
cat "$GLOBAL_VHOST_PATH"
elif [[ -f "$GLOBAL_HOSTNAME_PATH" ]]; then
cat "$GLOBAL_HOSTNAME_PATH"
fi
fi
}
get_default_vhost() {
local desc="return default vhost"
verify_app_name "$1"
local APP="$1"; local RE_IPV4="$(get_ipv4_regex)"; local RE_IPV6="$(get_ipv6_regex)"
if [[ "$(is_global_vhost_enabled)" == "true" ]]; then
local VHOST=$(get_global_vhost)
if ! ([[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]]); then
local SUBDOMAIN=${APP/%\.${VHOST}/}
local hostname=$(: | plugn trigger nginx-hostname $APP $SUBDOMAIN $VHOST)
if [[ ! -n $hostname ]]; then
if [[ "$APP" == *.* ]] && [[ "$SUBDOMAIN" == "$APP" ]]; then
local hostname="${APP/\//-}"
else
local hostname="${APP/\//-}.$VHOST"
fi
fi
local DEFAULT_VHOST="$hostname"
fi
fi
echo "$DEFAULT_VHOST"
}
domains_setup() {
local desc="setup domains to default state"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"; local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
local RE_IPV4="$(get_ipv4_regex)"; local RE_IPV6="$(get_ipv6_regex)"
local DEFAULT_VHOST="$(get_default_vhost $APP)"
if [[ ! -f $APP_VHOST_PATH ]]; then
if [[ -n "$DEFAULT_VHOST" ]]; then
dokku_log_info1 "Creating new $APP_VHOST_PATH..."
echo "$DEFAULT_VHOST" > $APP_VHOST_PATH
else
dokku_log_info2 "no global VHOST set. disabling vhost support"
disable_app_vhost $APP --no-restart
fi
fi
}
domains_main() {
local desc="print app domains"
local APP="$1"
if [[ "$(is_global_vhost_enabled)" == "true" ]]; then
dokku_log_info2_quiet "Global Domain Name"
get_global_vhost
fi
if [[ -n "$APP" ]]; then
verify_app_name $APP
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info2_quiet "$APP Domain Names"
get_app_domains "$APP"
else
dokku_log_fail "No domain names set for $APP"
fi
fi
}
domains_add() {
local desc="add list of domains to app"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
if [[ $(egrep -w "^${2}$" "$APP_VHOST_PATH" > /dev/null 2>&1; echo $?) -eq 0 ]]; then
dokku_log_fail "$2 is already defined for $APP"
exit 1
fi
shift 1
for DOMAIN in "$@"; do
echo "$DOMAIN" >> "$APP_VHOST_PATH"
dokku_log_info1 "Added $DOMAIN to $APP"
done
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]];then
domains_enable "$APP" --no-restart
fi
plugn trigger post-domains-update $APP "add" "$@"
}
domains_clear() {
local desc="clear all app domains"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
rm -f "$APP_VHOST_PATH"
domains_setup "$APP"
plugn trigger post-domains-update $APP "clear"
dokku_log_info1 "Cleared domains in $APP"
}
domains_remove() {
local desc="remove list of app domains"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
local DEFAULT_VHOST="$(get_default_vhost $APP)"
shift 1
for DOMAIN in "$@"; do
sed -i "/^$DOMAIN$/d" "$DOKKU_ROOT/$APP/VHOST"
dokku_log_info1 "Removed $DOMAIN from $APP"
done
plugn trigger post-domains-update $APP "remove" "$@"
}
domains_disable() {
local desc="disable domains/VHOST support"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]];then
disable_app_vhost "$APP"
else
dokku_log_info1 "domains (VHOST) support is already disabled for app ($APP)"
fi
}
domains_enable() {
local desc="enable domains/VHOST support"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
local DEFAULT_VHOST="$(get_default_vhost $APP)"
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]];then
if [[ -n "$DEFAULT_VHOST" ]]; then
echo "$DEFAULT_VHOST" > "$APP_VHOST_PATH"
fi
[[ "$2" == "--no-restart" ]] && local ENABLE_APP_VHOST_ARGS=$2
enable_app_vhost "$APP" "$ENABLE_APP_VHOST_ARGS"
else
dokku_log_info1 "domains (VHOST) support is already enabled for app ($APP)"
fi
}
domains_set_global() {
local desc="set global domain name"
local NEW_GLOBAL_VHOST="$1"; local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
if [[ -n "$NEW_GLOBAL_VHOST" ]]; then
echo "$NEW_GLOBAL_VHOST" > $GLOBAL_VHOST_PATH
dokku_log_info1 "Set global domain to $NEW_GLOBAL_VHOST"
else
dokku_log_fail "New global domain name must not be blank"
fi
}

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core domains plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -1,13 +0,0 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
APP="$1"
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
echo true # bind to external ip. VHOST is disabled
elif [[ "$(is_global_vhost_enabled $APP)" == "false" ]] && [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
echo true # bind to external ip. no global vhost or global vhost is an ip
else
echo false
fi

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
[[ " nginx:build-config nginx:access-logs nginx:error-logs nginx:disable nginx:enable help nginx:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
[[ " nginx:build-config nginx:access-logs nginx:error-logs help nginx:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
@@ -7,58 +7,13 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
case "$1" in
nginx:build-config)
APP="$2"; DOKKU_APP_LISTEN_PORT="$3"; DOKKU_APP_LISTEN_IP="$4"
nginx_build_config $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
nginx_build_config $2
;;
nginx:access-logs|nginx:error-logs)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
APP="$2"
NGINX_LOGS_TYPE=${1#nginx:}
NGINX_LOGS_TYPE=${NGINX_LOGS_TYPE%-logs}
NGINX_LOGS_PATH="/var/log/nginx/$APP-$NGINX_LOGS_TYPE.log"
if [[ $3 == "-t" ]]; then
NGINX_LOGS_ARGS="-F"
else
NGINX_LOGS_ARGS="-n 20"
fi
tail "$NGINX_LOGS_ARGS" "$NGINX_LOGS_PATH"
;;
nginx:disable)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
APP="$2"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
config_set --no-restart $APP DOKKU_NO_NGINX=1
disable_app_vhost $APP
elif [[ "$(is_app_nginx_enabled $APP)" == "true" ]]; then
config_set --no-restart $APP DOKKU_NO_NGINX=1
nginx_build_config $APP
else
dokku_log_info1 "nginx is already disable for app ($APP)"
fi
;;
nginx:enable)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
APP="$2"
if [[ "$(is_app_nginx_enabled $APP)" == "false" ]]; then
config_unset --no-restart $APP DOKKU_NO_NGINX NO_VHOST
unset DOKKU_NO_NGINX NO_VHOST
nginx_build_config $APP
else
dokku_log_info1 "nginx is already enabled for app ($APP)"
fi
nginx_logs "$@"
;;
help | nginx:help)
@@ -66,8 +21,6 @@ case "$1" in
nginx:build-config <app>, (Re)builds nginx config for given app
nginx:access-logs <app> [-t], Show the nginx access logs for an application (-t follows)
nginx:error-logs <app> [-t], Show the nginx error logs for an application (-t follows)
nginx:disable <app>, Disable nginx for an application (forces container binding to external interface)
nginx:enable <app>, Enable nginx for an application
EOF
;;

View File

@@ -4,72 +4,13 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/certs/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
is_app_nginx_enabled() {
local APP="$1"
verify_app_name "$APP"
local DOKKU_NO_NGINX=$(config_get $APP DOKKU_NO_NGINX)
if [[ -z "$DOKKU_NO_NGINX" ]]; then
echo true
else
echo false
fi
}
is_global_vhost_enabled() {
local GLOBAL_VHOST_FILE="$DOKKU_ROOT/VHOST"
local GLOBAL_VHOST_ENABLED=true
[[ -f "$GLOBAL_VHOST_FILE" ]] && local GLOBAL_VHOST=$(< "$GLOBAL_VHOST_FILE")
# Ensure the ip address continues to the end of the line
# Fixes using a wildcard dns service such as xip.io which allows for *.<ip address>.xip.io
local RE_IPV4="$(get_ipv4_regex)"
local RE_IPV6="$(get_ipv6_regex)"
if [[ -z "$GLOBAL_VHOST" ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV4 ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV6 ]]; then
local GLOBAL_VHOST_ENABLED=false
fi
echo $GLOBAL_VHOST_ENABLED
}
is_app_vhost_enabled() {
local APP=$1; local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
verify_app_name $APP
local NO_VHOST=$(config_get $APP NO_VHOST)
local APP_VHOST_ENABLED=true
if [[ "$NO_VHOST" == "1" ]]; then
local APP_VHOST_ENABLED=false
elif [[ -f "$DOKKU_ROOT/$APP/nginx.conf" ]] && [[ ! -f "$APP_VHOST_FILE" ]] && [[ "$NO_VHOST" != "0" ]]; then
local APP_VHOST_ENABLED=false
fi
echo $APP_VHOST_ENABLED
}
disable_app_vhost() {
local APP=$1; local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
verify_app_name $APP
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/VHOST"
rm "$DOKKU_ROOT/$APP/VHOST"
fi
if [[ -f "$DOKKU_ROOT/$APP/URLS" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/URLS"
rm "$DOKKU_ROOT/$APP/URLS"
fi
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP NO_VHOST=1
}
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
validate_nginx() {
local desc="validate entire nginx config"
set +e
sudo /usr/sbin/nginx -t > /dev/null 2>&1
exit_code=$?
local exit_code=$?
set -e
if [[ "$exit_code" -ne "0" ]]; then
sudo /usr/sbin/nginx -t
@@ -78,6 +19,7 @@ validate_nginx() {
}
restart_nginx() {
local desc="restart nginx for given distros"
case "$DOKKU_DISTRO" in
debian)
sudo /usr/sbin/invoke-rc.d nginx reload > /dev/null
@@ -93,148 +35,166 @@ restart_nginx() {
esac
}
nginx_build_config() {
local APP="$1"; local DOKKU_APP_LISTEN_PORT="$2"; local DOKKU_APP_LISTEN_IP="$3"
verify_app_name "$APP"
VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
URLS_PATH="$DOKKU_ROOT/$APP/URLS"
WILDCARD_SSL_PATH="$DOKKU_ROOT/tls"
APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
APP_NGINX_TEMPLATE="$DOKKU_ROOT/$APP/nginx.conf.template"
APP_NGINX_SSL_TEMPLATE="$DOKKU_ROOT/$APP/nginx.ssl.conf.template"
nginx_logs() {
local desc="display app nginx logs"
local APP="$2"; verify_app_name "$APP"
local NGINX_LOGS_TYPE=${1#nginx:}
local NGINX_LOGS_TYPE=${NGINX_LOGS_TYPE%-logs}
local NGINX_LOGS_PATH="/var/log/nginx/$APP-$NGINX_LOGS_TYPE.log"
eval "$(config_export global)"
eval "$(config_export app $APP)"
if [[ $3 == "-t" ]]; then
NGINX_LOGS_ARGS="-F"
else
NGINX_LOGS_ARGS="-n 20"
fi
if [[ ! -n "$DOKKU_NO_NGINX" ]]; then
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -z "$DOKKU_APP_LISTEN_IP" ]]; then
shopt -s nullglob
for DOKKU_APP_IP_FILE in $DOKKU_ROOT/$APP/IP.web.*; do
DOKKU_APP_PORT_FILE="${DOKKU_APP_IP_FILE//IP/PORT}"
DOKKU_APP_LISTENER_IP=$(< $DOKKU_APP_IP_FILE)
DOKKU_APP_LISTENER_PORT=$(< $DOKKU_APP_PORT_FILE)
tail "$NGINX_LOGS_ARGS" "$NGINX_LOGS_PATH"
}
DOKKU_APP_LISTENERS+=" "
DOKKU_APP_LISTENERS+="$DOKKU_APP_LISTENER_IP:$DOKKU_APP_LISTENER_PORT"
DOKKU_APP_LISTENERS+=" "
done
shopt -u nullglob
fi
configure_nginx_ports() {
local desc="configure nginx listening ports"
local APP=$1; verify_app_name "$APP"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports $APP)"
local DOKKU_NGINX_PORT=$(config_get $APP DOKKU_NGINX_PORT)
local DOKKU_NGINX_SSL_PORT=$(config_get $APP DOKKU_NGINX_SSL_PORT)
local IS_APP_VHOST_ENABLED="$(is_app_vhost_enabled $APP)"
DOKKU_APP_CIDS=($(get_app_container_ids $APP))
for file in nginx.conf.template nginx.ssl.conf.template; do
docker cp "${DOKKU_APP_CIDS[0]}:/app/${file}" "$DOKKU_ROOT/$APP/" 2> /dev/null || true
done
[[ -f "$APP_NGINX_TEMPLATE" ]] && NGINX_TEMPLATE="$APP_NGINX_TEMPLATE" && NGINX_CUSTOM_TEMPLATE="true" && dokku_log_info1 'Overriding default nginx.conf with detected nginx.conf.template'
NGINX_CONF=$(mktemp -t "nginx.conf.XXXXXX")
SCHEME="http"
# if the app has is not vhost enabled then, let's make sure we're cleaned up
[[ "$(is_app_vhost_enabled $APP)" == "false" ]] && disable_app_vhost $APP --no-restart
if [[ -z "$DOKKU_NGINX_PORT" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
if [[ -z "$DOKKU_NGINX_PORT" ]]; then
if [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "no nginx port set. setting to random open high port"
local NGINX_PORT=$(get_available_port)
else
local NGINX_PORT=80
fi
config_set --no-restart $APP DOKKU_NGINX_PORT=${NGINX_PORT}
fi
if [[ -n "$NGINX_PORT" ]]; then
config_set --no-restart $APP DOKKU_NGINX_PORT="${NGINX_PORT}"
fi
fi
if (is_ssl_enabled $APP) && [[ -z "$DOKKU_NGINX_SSL_PORT" ]] && [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "no nginx ssl port set. setting to random open high port"
local NGINX_SSL_PORT=$(get_available_port)
else
NGINX_PORT=$DOKKU_NGINX_PORT
local NGINX_SSL_PORT=443
fi
config_set --no-restart $APP DOKKU_NGINX_SSL_PORT=${NGINX_SSL_PORT}
fi
}
NONSSL_VHOSTS=$(get_app_domains $APP)
if [[ -n "$(is_ssl_enabled $APP)" ]]; then
SSL_HOSTNAME=$(get_ssl_hostnames $APP)
SSL_INUSE=true
validate_ssl_domains() {
local desc="check configured domains against SSL cert contents and show warning if mismatched"
local APP=$1; verify_app_name "$APP"
local SSL_HOSTNAME=$(get_ssl_hostnames $APP)
local SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | xargs | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g' | sed 's/ /|/g')
local domain
[[ -n "$SSL_HOSTNAME" ]] && SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | xargs | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g' | sed 's/ /|/g')
if ! (egrep -q "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH &> /dev/null); then
dokku_log_info1 "No matching configured domains for $APP found in SSL certificate. Your app will show as insecure in a browser if accessed via SSL"
dokku_log_info1 "Please add appropriate domains via the dokku domains command"
[[ -n "$NONSSL_VHOSTS" ]] && dokku_log_info1 "Configured domains for app:"
for domain in $(echo $NONSSL_VHOSTS| xargs); do
dokku_log_info2 "$domain"
done
[[ -n "$SSL_HOSTNAME" ]] && dokku_log_info1 "Domains found in SSL certificate:"
for domain in $(echo $SSL_HOSTNAME | xargs); do
dokku_log_info2 "$domain"
done
fi
if ! (egrep -q "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH &> /dev/null); then
dokku_log_info1 "No matching configured domains for $APP found in SSL certificate. Your app will show as insecure in a browser if accessed via SSL"
dokku_log_info1 "Please add appropriate domains via the dokku domains command"
[[ -n "$NONSSL_VHOSTS" ]] && dokku_log_info1 "Configured domains for app:"
for domain in $(echo $NONSSL_VHOSTS| xargs); do
dokku_log_info2 "$domain"
done
[[ -n "$SSL_HOSTNAME" ]] && dokku_log_info1 "Domains found in SSL certificate:"
for domain in $(echo $SSL_HOSTNAME | xargs); do
dokku_log_info2 "$domain"
done
fi
}
if [[ "$(is_ssl_enabled $APP)" == "app" ]]; then
SSL_DIRECTIVES=$(cat <<EOF
ssl_certificate $APP_SSL_PATH/server.crt;
ssl_certificate_key $APP_SSL_PATH/server.key;
EOF
)
elif [[ "$(is_ssl_enabled $APP)" == "global" ]]; then
SSL_DIRECTIVES=""
fi
fi
get_custom_nginx_template() {
local APP="$1"; verify_app_name "$APP"
local DESTINATION="$2"
local IMAGE_TAG="$(get_running_image_tag $APP)"
local IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
local NGINX_TEMPLATE_NAME="nginx.conf.sigil"
if [[ -n "$SSL_INUSE" ]]; then
SCHEME="https"
copy_from_image "$IMAGE" "$NGINX_TEMPLATE_NAME" "$DESTINATION" 2>/dev/null || true
}
[[ -f "$APP_NGINX_SSL_TEMPLATE" ]] && NGINX_SSL_TEMPLATE="$APP_NGINX_SSL_TEMPLATE" && dokku_log_info1 'Overriding default nginx.ssl.conf with detected nginx.ssl.conf.template'
[[ -z "$NGINX_SSL_TEMPLATE" ]] && NGINX_SSL_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.ssl.conf.template"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
else
SSL_VHOSTS=$(< $DOKKU_ROOT/HOSTNAME)
fi
NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH 2> /dev/null || true)
nginx_build_config() {
local desc="build nginx config to proxy app containers using sigil"
local APP="$1"; verify_app_name "$APP"
local DOKKU_APP_LISTEN_PORT="$2"; local DOKKU_APP_LISTEN_IP="$3"
local VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"; local URLS_PATH="$DOKKU_ROOT/$APP/URLS"
local NGINX_TEMPLATE_NAME="nginx.conf.sigil"
local DEFAULT_NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/$NGINX_TEMPLATE_NAME"
local NGINX_TEMPLATE="$DEFAULT_NGINX_TEMPLATE"; local SCHEME=http
local NGINX_TEMPLATE_SOURCE="built-in"; local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports $APP)"
if [[ -z "$DOKKU_NGINX_SSL_PORT" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
dokku_log_info1 "no nginx ssl port set. setting to random open high port"
local NGINX_SSL_PORT=$(get_available_port)
local DOKKU_DISABLE_PROXY=$(config_get $APP DOKKU_DISABLE_PROXY)
local IS_APP_VHOST_ENABLED=$(is_app_vhost_enabled $APP)
if [[ -z "$DOKKU_DISABLE_PROXY" ]]; then
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -z "$DOKKU_APP_LISTEN_IP" ]]; then
shopt -s nullglob
local DOKKU_APP_IP_FILE
for DOKKU_APP_IP_FILE in $DOKKU_ROOT/$APP/IP.web.*; do
local DOKKU_APP_PORT_FILE="${DOKKU_APP_IP_FILE//IP/PORT}"
local DOKKU_APP_LISTENER_IP=$(< $DOKKU_APP_IP_FILE)
local DOKKU_APP_LISTENER_PORT=$(< $DOKKU_APP_PORT_FILE)
if [[ -z "$RAW_TCP_PORTS" ]]; then
local DOKKU_APP_LISTENERS+=" $DOKKU_APP_LISTENER_IP:$DOKKU_APP_LISTENER_PORT "
else
NGINX_SSL_PORT=443
local DOKKU_APP_LISTENERS+=" $DOKKU_APP_LISTENER_IP "
fi
config_set --no-restart $APP DOKKU_NGINX_SSL_PORT=${NGINX_SSL_PORT}
else
local NGINX_SSL_PORT=$DOKKU_NGINX_SSL_PORT
fi
while read -r line; do
[[ -z "$line" ]] && continue
dokku_log_info1 "Configuring SSL for $line...(using $NGINX_SSL_TEMPLATE)"
SSL_SERVER_NAME=$line
NOSSL_SERVER_NAME=$line
eval "cat <<< \"$(< $NGINX_SSL_TEMPLATE)\" >> $NGINX_CONF"
done <<< "$SSL_VHOSTS"
fi
if [[ -n "$DOKKU_SSL_TERMINATED" ]] && [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.conf.ssl_terminated.template"
elif [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.conf.template"
fi
if [[ -n "$NONSSL_VHOSTS" ]]; then
NOSSL_SERVER_NAME=$(echo $NONSSL_VHOSTS | tr '\n' ' ')
xargs -i echo "-----> Configuring {}...(using $NGINX_TEMPLATE)" <<< "$NONSSL_VHOSTS"
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
fi
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]] || ([[ -z "$NONSSL_VHOSTS" ]] && [[ -z "$SSL_VHOSTS" ]]); then
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
sed --in-place -n -e '/^.*server_name.*$/!p' $NGINX_CONF
fi
if [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then
echo "upstream $APP { server $DOKKU_APP_LISTEN_IP:$DOKKU_APP_LISTEN_PORT; }" >> $NGINX_CONF
elif [[ -n "$DOKKU_APP_LISTENERS" ]]; then
echo "upstream $APP { " >> $NGINX_CONF
for listener in $DOKKU_APP_LISTENERS; do
echo " server $listener;" >> $NGINX_CONF
local DOKKU_APP_LISTENERS=$(echo $DOKKU_APP_LISTENERS | xargs)
done
echo "}" >> $NGINX_CONF
shopt -u nullglob
elif [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then
local PASSED_LISTEN_IP_PORT=true
fi
local TMPDIR=$(mktemp -d /tmp/nginx_template.XXXXX)
local NGINX_CONF=$(mktemp -p ${TMPDIR} -t "nginx.conf.XXXXXX")
local CUSTOM_NGINX_TEMPLATE="$TMPDIR/$NGINX_TEMPLATE_NAME"
trap 'rm -rf "$NGINX_CONF $TMPDIR" > /dev/null' RETURN
get_custom_nginx_template "$APP" "$CUSTOM_NGINX_TEMPLATE"
if [[ -f "$CUSTOM_NGINX_TEMPLATE" ]]; then
dokku_log_info1 'Overriding default nginx.conf with detected nginx.conf.sigil'
local NGINX_TEMPLATE="$CUSTOM_NGINX_TEMPLATE"
local NGINX_TEMPLATE_SOURCE="app-supplied"
fi
# setup nginx listen ports
configure_nginx_ports "$APP"
local NGINX_PORT=$(config_get $APP DOKKU_NGINX_PORT)
local NGINX_SSL_PORT=$(config_get $APP DOKKU_NGINX_SSL_PORT)
local NONSSL_VHOSTS=$(get_app_domains "$APP")
local NOSSL_SERVER_NAME=$(echo $NONSSL_VHOSTS | xargs)
if is_ssl_enabled "$APP"; then
local SSL_INUSE=true; local SCHEME=https
validate_ssl_domains "$APP"
local SSL_HOSTNAME=$(get_ssl_hostnames $APP)
local SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | xargs | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g' | sed 's/ /|/g')
if [[ "$IS_APP_VHOST_ENABLED" == "true" ]]; then
local SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
else
local SSL_VHOSTS=$(< $DOKKU_ROOT/HOSTNAME)
fi
local SSL_SERVER_NAME=$(echo $SSL_VHOSTS | xargs)
fi
local SIGIL_PARAMS=(-f $NGINX_TEMPLATE APP="$APP" DOKKU_ROOT="$DOKKU_ROOT"
NOSSL_SERVER_NAME="$NOSSL_SERVER_NAME"
DOKKU_APP_LISTENERS="$DOKKU_APP_LISTENERS"
PASSED_LISTEN_IP_PORT="$PASSED_LISTEN_IP_PORT"
DOKKU_APP_LISTEN_PORT="$DOKKU_APP_LISTEN_PORT" DOKKU_APP_LISTEN_IP="$DOKKU_APP_LISTEN_IP"
APP_SSL_PATH="$APP_SSL_PATH" SSL_INUSE="$SSL_INUSE" SSL_SERVER_NAME="$SSL_SERVER_NAME"
NGINX_PORT="$NGINX_PORT" NGINX_SSL_PORT="$NGINX_SSL_PORT" RAW_TCP_PORTS="$RAW_TCP_PORTS")
# execute sigil template processing
xargs -i echo "-----> Configuring {}...(using $NGINX_TEMPLATE_SOURCE template)" <<< "$(echo ${SSL_VHOSTS} ${NONSSL_VHOSTS} | tr ' ' '\n' | sort -u)"
# echo "sigil ${SIGIL_PARAMS[@]}"
sigil "${SIGIL_PARAMS[@]}" > $NGINX_CONF
if is_deployed "$APP"; then
dokku_log_info1 "Creating $SCHEME nginx.conf"
mv $NGINX_CONF "$DOKKU_ROOT/$APP/nginx.conf"
@@ -251,13 +211,12 @@ EOF
validate_nginx && restart_nginx
fi
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
if ([[ -n "$NONSSL_VHOSTS" ]] || [[ -n "$SSL_VHOSTS" ]]) && [[ "$IS_APP_VHOST_ENABLED" == "true" ]]; then
echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" > $URLS_PATH
xargs -i echo "https://{}" <<< "${SSL_VHOSTS}" >> $URLS_PATH
xargs -i echo "http://{}" <<< "${NONSSL_VHOSTS}" >> $URLS_PATH
xargs -i echo "$SCHEME://{}" <<< "$(echo ${SSL_VHOSTS} ${NONSSL_VHOSTS} | tr ' ' '\n' | sort -u)" >> $URLS_PATH
fi
else
# note because this clause is long. if $DOKKU_NO_NGINX is set:
# note because this clause is long. if $DOKKU_DISABLE_PROXY is set:
dokku_log_info1 "nginx support is disabled for app ($APP)."
if [[ -f "$DOKKU_ROOT/$APP/nginx.conf" ]]; then
dokku_log_info1 "deleting nginx.conf"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core nginx-vhosts plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
case "$DOKKU_DISTRO" in
debian)

View File

@@ -1,15 +1,23 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
APP="$1"
if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
dokku_log_info1 "VHOST support disabled. Skipping domains setup"
elif [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku domains:setup $APP
nginx_post_deploy() {
local APP="$1"
if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
dokku_log_info1 "VHOST support disabled. Skipping domains setup"
elif [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
domains_setup $APP
fi
nginx_build_config $APP
fi
}
nginx_build_config $APP
if [[ "$(get_app_proxy_type $1)" == "nginx" ]]; then
nginx_post_deploy "$@"
fi

View File

@@ -2,7 +2,8 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
APP="$1"
nginx_build_config $APP
if [[ "$(get_app_proxy_type $1)" == "nginx" ]]; then
nginx_build_config $1
fi

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions"
nginx_disable() {
local desc="disable nginx proxy"
local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type $APP)" == "nginx" ]]; then
disable_app_vhost $APP --no-restart
ps_restart $APP
fi
}
nginx_disable "$@"

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions"
nginx_enable() {
local desc="enable nginx proxy"
local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type $APP)" == "nginx" ]]; then
enable_app_vhost $APP --no-restart
ps_restart $APP
fi
}
nginx_enable "$@"

View File

@@ -0,0 +1,20 @@
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;

View File

@@ -0,0 +1,2 @@
access_log /var/log/nginx/{{ .APP }}-access.log;
error_log /var/log/nginx/{{ .APP }}-error.log;

View File

@@ -0,0 +1,10 @@
{{ if .RAW_TCP_PORTS }}
{{ include "tcp.server.config" . }}
{{ else if .SSL_INUSE }}
{{ include "nossl.server.config" . }}
{{ include "ssl.server.config" . }}
{{ include "upstream.config" . }}
{{ else }}
{{ include "nossl.server.config" . }}
{{ include "upstream.config" . }}
{{ end }}

View File

@@ -1,19 +0,0 @@
# Nginx configuration when running behind a load balancer that terminates SSL
# connections (e.g. AWS ELB)
server {
listen [::]:$NGINX_PORT;
listen $NGINX_PORT;
server_name $NOSSL_SERVER_NAME;
location / {
proxy_pass http://$APP;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto;
proxy_set_header X-Forwarded-For \$http_x_forwarded_for;
proxy_set_header X-Forwarded-Port \$http_x_forwarded_port;
proxy_set_header X-Request-Start \$msec;
}
include $DOKKU_ROOT/$APP/nginx.conf.d/*.conf;
}

View File

@@ -1,28 +0,0 @@
server {
listen [::]:$NGINX_PORT;
listen $NGINX_PORT;
server_name $NOSSL_SERVER_NAME;
access_log /var/log/nginx/${APP}-access.log;
error_log /var/log/nginx/${APP}-error.log;
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://$APP;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Port \$server_port;
proxy_set_header X-Request-Start \$msec;
}
include $DOKKU_ROOT/$APP/nginx.conf.d/*.conf;
}

View File

@@ -1,40 +0,0 @@
server {
listen [::]:$NGINX_PORT;
listen $NGINX_PORT;
server_name $NOSSL_SERVER_NAME;
access_log /var/log/nginx/${APP}-access.log;
error_log /var/log/nginx/${APP}-error.log;
return 301 https://\$host:$NGINX_SSL_PORT\$request_uri;
}
server {
listen [::]:$NGINX_SSL_PORT ssl spdy;
listen $NGINX_SSL_PORT ssl spdy;
server_name $SSL_SERVER_NAME;
access_log /var/log/nginx/${APP}-access.log;
error_log /var/log/nginx/${APP}-error.log;
$SSL_DIRECTIVES
keepalive_timeout 70;
add_header Alternate-Protocol $NGINX_SSL_PORT:npn-spdy/2;
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://$APP;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Port \$server_port;
proxy_set_header X-Request-Start \$msec;
}
include $DOKKU_ROOT/$APP/nginx.conf.d/*.conf;
}

View File

@@ -0,0 +1,11 @@
server {
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
{{ if .NOSSL_SERVER_NAME }}server_name {{ .NOSSL_SERVER_NAME }}; {{ end }}
{{ include "log.config" . }}
{{ if .SSL_INUSE }}
return 301 https://$host:{{ .NGINX_SSL_PORT }}$request_uri;
{{ else }}
{{ include "location.config" . }}
{{ end }}
}

View File

@@ -0,0 +1,12 @@
server {
listen [::]:{{ .NGINX_SSL_PORT }} ssl spdy;
listen {{ .NGINX_SSL_PORT }} ssl spdy;
{{ if .SSL_SERVER_NAME }}server_name {{ .SSL_SERVER_NAME }}; {{ end }}
{{ include "log.config" . }}
ssl_certificate {{ .APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ .APP_SSL_PATH }}/server.key;
keepalive_timeout 70;
add_header Alternate-Protocol {{ .NGINX_SSL_PORT }}:npn-spdy/2;
{{ include "location.config" . }}
}

View File

@@ -0,0 +1,35 @@
{{ range .RAW_TCP_PORTS | split " " }}
{{ $port := . }}
server {
listen [::]:{{ $port }};
listen {{ $port }};
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log /var/log/nginx/{{ $.APP }}-access.log;
error_log /var/log/nginx/{{ $.APP }}-error.log;
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://{{ $.APP }}-{{ $port }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
}
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
{{ if $.DOKKU_APP_LISTENERS }}
upstream {{ $.APP }}-{{ $port }} {
{{ range $.DOKKU_APP_LISTENERS | split " " }} server {{ . }}:{{ $port }};{{ end }}
}
{{ end }}{{ end }}

View File

@@ -0,0 +1,9 @@
{{ if .DOKKU_APP_LISTENERS }}
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }} server {{ . }};
{{ end }}}
{{ else if .PASSED_LISTEN_IP_PORT }}
upstream {{ .APP }} {
server {{ .DOKKU_APP_LISTEN_IP }}:{{ .DOKKU_APP_LISTEN_PORT }};
}
{{ end }}

40
plugins/proxy/commands Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
[[ " proxy proxy:set proxy:enable proxy:disable help proxy:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
case "$1" in
proxy)
proxy_main $2
;;
proxy:set)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_set $2
;;
proxy:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_enable $2 --no-restart
;;
proxy:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_disable $2 --no-restart
;;
help | proxy:help)
cat<<EOF
proxy <app>, Show proxy for app
proxy:enable <app>, Enable proxy for app
proxy:disable <app>, Disable proxy for app
proxy:set <app> <proxy_type>, NOT IMPLEMENTED YET!!
EOF
;;
*)
exit $DOKKU_NOT_IMPLEMENTED_EXIT
;;
esac

74
plugins/proxy/functions Executable file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
is_app_proxy_enabled() {
local desc="return true if proxy is enabled; otherwise return false"
local APP="$1"; verify_app_name "$APP"
local APP_PROXY_ENABLED=true
local DOKKU_DISABLE_PROXY=$(config_get $APP DOKKU_DISABLE_PROXY)
if [[ -n "$DOKKU_DISABLE_PROXY" ]]; then
local APP_PROXY_ENABLED=false
fi
echo $APP_PROXY_ENABLED
}
get_app_proxy_type() {
local desc="return app proxy type"
local APP="$1"; verify_app_name "$APP"
local APP_PROXY_TYPE="nginx"
echo $APP_PROXY_TYPE
}
proxy_main() {
local desc="displays app proxy implementation"
local ALL_APPS=$(dokku_apps)
if [[ -n "$1" ]]; then
local APP="$1"
fi
local APPS=${APP:="$ALL_APPS"}
dokku_col_log_info1_quiet "App Name" "Proxy Type"
for app in $APPS; do
verify_app_name "$app"
dokku_col_log_msg "$app" "$(get_app_proxy_type $app)"
done
}
proxy_set() {
local desc="enable proxy for app"
local APP="$1"; verify_app_name "$APP"
dokku_log_info1 "proxy:set not implemented"
}
proxy_enable() {
local desc="enable proxy for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_proxy_enabled $APP)" == "false" ]]; then
dokku_log_info1 "Enabling proxy for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_unset $CONFIG_SET_ARGS $APP DOKKU_DISABLE_PROXY
plugn trigger proxy-enable "$APP"
else
dokku_log_info1 "proxy is already enabled for app ($APP)"
fi
}
proxy_disable() {
local desc="disable proxy for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_proxy_enabled $APP)" == "true" ]]; then
dokku_log_info1 "Disabling proxy for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP DOKKU_DISABLE_PROXY=1
plugn trigger proxy-disable "$APP"
else
dokku_log_info1 "proxy is already disable for app ($APP)"
fi
}

View File

@@ -0,0 +1,4 @@
[plugin]
description = "dokku core proxy plugin"
version = "0.5.0"
[plugin.config]

View File

@@ -7,72 +7,38 @@ source "$PLUGIN_AVAILABLE_PATH/ps/functions"
case "$1" in
ps)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; verify_app_name "$APP"; DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
for CID in $DOKKU_APP_RUNNING_CONTAINER_IDS; do
has_tty && DOKKU_RUN_OPTS="-i -t"
dokku_log_info1_quiet "running processes in container: $CID"
docker exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww"
done
ps_main $2
;;
ps:start)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP);
verify_app_name "$APP"
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if ! (is_app_running $APP); then
release_and_deploy "$APP" "$IMAGE_TAG"
else
echo "App $APP already running"
fi
ps_start $2
;;
ps:stop)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
verify_app_name "$APP"
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if [[ -n "$DOKKU_APP_RUNNING_CONTAINER_IDS" ]]; then
echo "Stopping $APP ..."
docker stop $DOKKU_APP_RUNNING_CONTAINER_IDS > /dev/null || true
plugn trigger post-stop $APP
else
echo "App $APP already stopped"
fi
ps_stop $2
;;
ps:rebuild)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; verify_app_name "$APP"
plugn trigger receive-app $APP
ps_rebuild $2
;;
ps:rebuildall)
for app in $(dokku_apps); do
is_deployed $app && dokku ps:rebuild $app
is_deployed $app && ps_rebuild $app
done
;;
ps:restart)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP)
verify_app_name "$APP"
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
release_and_deploy "$APP" "$IMAGE_TAG"
ps_restart $2
;;
ps:restartall)
for app in $(dokku_apps); do
dokku ps:restart $app
ps_restart $app
done
;;
@@ -81,34 +47,15 @@ case "$1" in
DOKKU_APP_RESTORE=$(dokku config:get $app DOKKU_APP_RESTORE || true)
if [[ $DOKKU_APP_RESTORE != 0 ]]; then
echo "Restoring app $app ..."
dokku ps:start $app
ps_start $app
fi
done
;;
ps:scale)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP)
verify_app_name "$APP"
DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
shift 2
[[ ! -e $DOKKU_SCALE_FILE ]] && generate_scale_file "$APP" "$IMAGE_TAG"
if [[ -z "$@" ]];then
dokku_log_info1_quiet "Scaling for $APP"
dokku_col_log_info1_quiet "proctype" "qty"
dokku_col_log_info1_quiet "--------" "---"
while read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue
PROC_NAME=${line%%=*}
PROC_COUNT=${line#*=}
dokku_col_log_info1 "$PROC_NAME" "$PROC_COUNT"
done < "$DOKKU_SCALE_FILE"
else
set_scale "$APP" "$@"
release_and_deploy "$APP" "$IMAGE_TAG"
fi
shift 1
ps_scale "$@"
;;
help | ps:help)

View File

@@ -79,3 +79,82 @@ set_scale() {
fi
done
}
ps_main() {
local APP="$1"; verify_app_name "$APP"
local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
for CID in $DOKKU_APP_RUNNING_CONTAINER_IDS; do
has_tty && DOKKU_RUN_OPTS="-i -t"
dokku_log_info1_quiet "running processes in container: $CID"
docker exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww"
done
}
ps_start() {
local APP="$1"; verify_app_name "$APP"
local IMAGE_TAG=$(get_running_image_tag $APP);
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if ! (is_app_running $APP); then
release_and_deploy "$APP" "$IMAGE_TAG"
else
echo "App $APP already running"
fi
}
ps_stop() {
local APP="$1"; verify_app_name "$APP"
local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if [[ -n "$DOKKU_APP_RUNNING_CONTAINER_IDS" ]]; then
echo "Stopping $APP ..."
docker stop $DOKKU_APP_RUNNING_CONTAINER_IDS > /dev/null || true
plugn trigger post-stop $APP
else
echo "App $APP already stopped"
fi
}
ps_rebuild() {
local APP="$1"; verify_app_name "$APP"
plugn trigger receive-app $APP
}
ps_restart() {
local APP="$1"; verify_app_name "$APP"
local IMAGE_TAG=$(get_running_image_tag $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
release_and_deploy "$APP" "$IMAGE_TAG"
}
ps_scale() {
local APP="$1"; verify_app_name "$APP"
local IMAGE_TAG=$(get_running_image_tag $APP)
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
shift 1
[[ ! -e $DOKKU_SCALE_FILE ]] && generate_scale_file "$APP" "$IMAGE_TAG"
if [[ -z "$@" ]];then
dokku_log_info1_quiet "Scaling for $APP"
dokku_col_log_info1_quiet "proctype" "qty"
dokku_col_log_info1_quiet "--------" "---"
while read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue
PROC_NAME=${line%%=*}
PROC_COUNT=${line#*=}
dokku_col_log_info1 "$PROC_NAME" "$PROC_COUNT"
done < "$DOKKU_SCALE_FILE"
else
set_scale "$APP" "$@"
release_and_deploy "$APP" "$IMAGE_TAG"
fi
}

View File

@@ -1,10 +1,4 @@
FROM ubuntu:trusty
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN true
RUN apt-get install -y software-properties-common && add-apt-repository ppa:chris-lea/node.js && apt-get update
RUN apt-get install -y build-essential curl postgresql-client-9.3 nodejs git
FROM node:4
COPY . /app
WORKDIR /app

View File

@@ -1,14 +1,9 @@
FROM ubuntu:trusty
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN true
FROM node:4
EXPOSE 3001/udp
EXPOSE 3000/tcp
EXPOSE 3003
RUN apt-get install -y software-properties-common && add-apt-repository ppa:chris-lea/node.js && apt-get update
RUN apt-get install -y build-essential curl postgresql-client-9.3 nodejs git
COPY . /app
WORKDIR /app
RUN npm install

View File

@@ -11,3 +11,7 @@ app.get('/', function(request, response) {
app.listen(app.get('port'), function() {
console.log("Node app is running at localhost:" + app.get('port'))
})
app.listen(3003, function() {
console.log("Node app is running at localhost:" + 3003)
})

View File

@@ -23,6 +23,7 @@ setup_circle() {
# sudo apt-get install -y -q "bash=$(apt-cache show bash | egrep "^Version: 4.3" | head -1 | awk -F: '{ print $2 }' | xargs)"
bash --version
docker version
lsb_release -a
# setup .dokkurc
sudo -E mkdir -p /home/dokku/.dokkurc
sudo -E chown dokku:ubuntu /home/dokku/.dokkurc

45
tests/unit/10_checks.bats Normal file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bats
load test_helper
#!/usr/bin/env bats
load test_helper
setup() {
create_app
}
teardown() {
destroy_app
}
@test "(checks) checks" {
run bash -c "dokku checks $TEST_APP | grep -q true"
echo "output: "$output
echo "status: "$status
assert_success
}
@test "(checks) checks:disable" {
dokku checks:disable $TEST_APP
assert_success
run bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_ENABLED"
echo "output: "$output
echo "status: "$status
assert_output "0"
}
@test "(checks) checks:enable" {
dokku checks:disable $TEST_APP
assert_success
dokku checks:enable $TEST_APP
assert_success
run bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_ENABLED"
echo "output: "$output
echo "status: "$status
assert_output "1"
}

View File

@@ -4,12 +4,12 @@ load test_helper
setup() {
create_app
DOCKERFILE="$BATS_TMPDIR/Dockerfile"
}
teardown() {
rm -rf /home/dokku/$TEST_APP/tls /home/dokku/tls
destroy_app
disable_tls_wildcard
dokku config:unset --global DOKKU_RM_CONTAINER
}
@@ -120,3 +120,29 @@ build_nginx_config() {
echo "status: "$status
assert_success
}
@test "(core) port exposure (dockerfile raw port)" {
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
cat<<EOF > $DOCKERFILE
EXPOSE 3001/udp
EXPOSE 3003
EXPOSE 3000/tcp
EOF
run get_dockerfile_exposed_ports $DOCKERFILE
echo "output: "$output
echo "status: "$status
assert_output "3001/udp 3003 3000/tcp"
}
@test "(core) port exposure (dockerfile tcp port)" {
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
cat<<EOF > $DOCKERFILE
EXPOSE 3001/udp
EXPOSE 3000/tcp
EXPOSE 3003
EOF
run get_dockerfile_exposed_ports $DOCKERFILE
echo "output: "$output
echo "status: "$status
assert_output "3001/udp 3000/tcp 3003"
}

View File

@@ -23,7 +23,7 @@ deploy_app_tar() {
@test "(tar) non-tarbomb deploy using tar:in" {
deploy_app_tar nodejs-express --transform 's,^,prefix/,'
run bash -c "response=\"$(curl -s -S my-cool-guy-test-app.dokku.me)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
run bash -c "response=\"$(curl -s -S ${TEST_APP}.dokku.me)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
echo "output: "$output
echo "status: "$status
assert_success
@@ -32,7 +32,7 @@ deploy_app_tar() {
@test "(tar) tarbomb deploy using tar:in" {
deploy_app_tar nodejs-express
run bash -c "response=\"$(curl -s -S my-cool-guy-test-app.dokku.me)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
run bash -c "response=\"$(curl -s -S ${TEST_APP}.dokku.me)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
echo "output: "$output
echo "status: "$status
assert_success

View File

@@ -70,6 +70,10 @@ teardown() {
}
@test "(client) domains" {
run bash -c "./contrib/dokku_client.sh domains:setup $TEST_APP"
echo "output: "$output
echo "status: "$status
assert_success
run bash -c "./contrib/dokku_client.sh domains $TEST_APP | grep -q ${TEST_APP}.dokku.me"
echo "output: "$output
echo "status: "$status

View File

@@ -1,91 +0,0 @@
#!/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"
DOCKERFILE="$BATS_TMPDIR/Dockerfile"
}
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"
}
check_urls() {
local PATTERN="$1"
run bash -c "dokku --quiet urls $TEST_APP | egrep \"${1}\""
echo "output: "$output
echo "status: "$status
assert_success
}
@test "(core) port exposure (with global VHOST)" {
echo "dokku.me" > "$DOKKU_ROOT/VHOST"
deploy_app
CONTAINER_ID=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep -q '[0-9]*'"
echo "output: "$output
echo "status: "$status
assert_failure
check_urls http://${TEST_APP}.dokku.me
}
@test "(core) port exposure (without global VHOST and real HOSTNAME)" {
rm "$DOKKU_ROOT/VHOST"
echo "${TEST_APP}.dokku.me" > "$DOKKU_ROOT/HOSTNAME"
deploy_app
CONTAINER_ID=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep -q '[0-9]*'"
echo "output: "$output
echo "status: "$status
assert_success
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
}
@test "(core) port exposure (with NO_VHOST set)" {
deploy_app
dokku config:set $TEST_APP NO_VHOST=1
CONTAINER_ID=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep -q '[0-9]*'"
echo "output: "$output
echo "status: "$status
assert_success
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
}
@test "(core) 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=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep -q '[0-9]*'"
echo "output: "$output
echo "status: "$status
assert_success
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
}
@test "(core) 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=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep -q '[0-9]*'"
echo "output: "$output
echo "status: "$status
assert_success
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
}

View File

@@ -3,14 +3,19 @@
load test_helper
setup() {
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
[[ -f "$DOKKU_ROOT/HOSTNAME" ]] && cp -fp "$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" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
[[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME" && chown dokku:dokku "$DOKKU_ROOT/HOSTNAME"
}
@test "(domains) domains" {
dokku domains:setup $TEST_APP
run bash -c "dokku domains $TEST_APP | grep ${TEST_APP}.dokku.me"
echo "output: "$output
echo "status: "$status
@@ -35,6 +40,18 @@ teardown() {
assert_success
}
@test "(domains) domains:add (duplicate)" {
run dokku domains:add $TEST_APP test.app.dokku.me
echo "output: "$output
echo "status: "$status
assert_success
run dokku domains:add $TEST_APP test.app.dokku.me
echo "output: "$output
echo "status: "$status
assert_failure
}
@test "(domains) domains:remove" {
run dokku domains:add $TEST_APP test.app.dokku.me
echo "output: "$output
@@ -67,3 +84,15 @@ teardown() {
echo "status: "$status
assert_success
}
@test "(domains) domains:set-global" {
run dokku domains:set-global global.dokku.me
echo "output: "$output
echo "status: "$status
assert_success
run bash -c "dokku domains | grep -q global.dokku.me"
echo "output: "$output
echo "status: "$status
assert_success
}

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env bats
load test_helper
source "$PLUGIN_CORE_AVAILABLE_PATH/config/functions"
setup() {
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
[[ -f "$DOKKU_ROOT/HOSTNAME" ]] && cp -fp "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/HOSTNAME.bak"
}
teardown() {
destroy_app
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
[[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME" && chown dokku:dokku "$DOKKU_ROOT/HOSTNAME"
}
@test "(nginx-vhosts) nginx:build-config (domains:disable/enable)" {
deploy_app
dokku domains:disable $TEST_APP
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
NGINX_PORT="$(config_get $TEST_APP DOKKU_NGINX_PORT)"
assert_http_success http://${HOSTNAME}:${NGINX_PORT}
dokku domains:enable $TEST_APP
check_urls http://${TEST_APP}.dokku.me
assert_http_success http://${TEST_APP}.dokku.me
}
@test "(nginx-vhosts) nginx:build-config (domains:add pre deploy)" {
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
check_urls http://www.test.app.dokku.me
assert_http_success http://www.test.app.dokku.me
}
@test "(nginx-vhosts) nginx:build-config (with global VHOST)" {
echo "dokku.me" > "$DOKKU_ROOT/VHOST"
deploy_app
check_urls http://${TEST_APP}.dokku.me
assert_http_success http://${TEST_APP}.dokku.me
}
@test "(nginx-vhosts) nginx:build-config (without global VHOST but real HOSTNAME)" {
rm "$DOKKU_ROOT/VHOST"
echo "${TEST_APP}.dokku.me" > "$DOKKU_ROOT/HOSTNAME"
deploy_app
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
NGINX_PORT="$(config_get $TEST_APP DOKKU_NGINX_PORT)"
assert_http_success http://${HOSTNAME}:${NGINX_PORT}
}
@test "(nginx-vhosts) nginx:build-config (without global VHOST and IPv4 address set as HOSTNAME)" {
rm "$DOKKU_ROOT/VHOST"
echo "127.0.0.1" > "$DOKKU_ROOT/HOSTNAME"
deploy_app
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
NGINX_PORT="$(config_get $TEST_APP DOKKU_NGINX_PORT)"
assert_http_success http://${HOSTNAME}:${NGINX_PORT}
}
@test "(nginx-vhosts) nginx:build-config (without global VHOST and IPv6 address set as HOSTNAME)" {
rm "$DOKKU_ROOT/VHOST"
echo "fda5:c7db:a520:bb6d::aabb:ccdd:eeff" > "$DOKKU_ROOT/HOSTNAME"
deploy_app
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
}
@test "(nginx-vhosts) nginx:build-config (without global VHOST and domains:add pre deploy)" {
rm "$DOKKU_ROOT/VHOST"
create_app
add_domain "www.test.app.dokku.me"
deploy_app
assert_nonssl_domain "www.test.app.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (without global VHOST and domains:add post deploy)" {
rm "$DOKKU_ROOT/VHOST"
deploy_app
add_domain "www.test.app.dokku.me"
check_urls http://www.test.app.dokku.me
assert_http_success http://www.test.app.dokku.me
}
@test "(nginx-vhosts) nginx:build-config (xip.io style hostnames)" {
echo "127.0.0.1.xip.io" > "$DOKKU_ROOT/VHOST"
deploy_app
check_urls http://${TEST_APP}.127.0.0.1.xip.io
assert_http_success http://${TEST_APP}.127.0.0.1.xip.io
}
@test "(nginx-vhosts) nginx:build-config (dockerfile expose)" {
deploy_app dockerfile
add_domain "www.test.app.dokku.me"
check_urls http://${TEST_APP}.dokku.me:3000
check_urls http://${TEST_APP}.dokku.me:3003
check_urls http://www.test.app.dokku.me:3000
check_urls http://www.test.app.dokku.me:3003
assert_http_success http://${TEST_APP}.dokku.me:3000
assert_http_success http://${TEST_APP}.dokku.me:3003
assert_http_success http://www.test.app.dokku.me:3000
assert_http_success http://www.test.app.dokku.me:3003
}

View File

@@ -1,124 +0,0 @@
#!/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"
DOCKERFILE="$BATS_TMPDIR/Dockerfile"
}
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"
}
check_urls() {
local PATTERN="$1"
run bash -c "dokku --quiet urls $TEST_APP | egrep \"${1}\""
echo "output: "$output
echo "status: "$status
assert_success
}
@test "(core) 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=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep -q '[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
check_urls http://www.test.app.dokku.me
}
@test "(core) 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
run dokku ps:restart $TEST_APP
echo "output: "$output
echo "status: "$status
assert_success
CONTAINER_ID=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep -q '[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
check_urls http://www.test.app.dokku.me
}
@test "(core) port exposure (xip.io style hostnames)" {
echo "127.0.0.1.xip.io" > "$DOKKU_ROOT/VHOST"
deploy_app
run bash -c "response=\"$(curl -s -S my-cool-guy-test-app.127.0.0.1.xip.io)\"; echo \$response; test \"\$response\" == \"nodejs/express\""
echo "output: "$output
echo "status: "$status
assert_success
check_urls http://my-cool-guy-test-app.127.0.0.1.xip.io
}
@test "(core) dockerfile port exposure" {
deploy_app dockerfile
run bash -c "grep -A1 upstream $DOKKU_ROOT/$TEST_APP/nginx.conf | grep -q 3000"
echo "output: "$output
echo "status: "$status
assert_success
check_urls http://${TEST_APP}.dokku.me
}
@test "(core) port exposure (dockerfile raw port)" {
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
cat<<EOF > $DOCKERFILE
EXPOSE 3001/udp
EXPOSE 3003
EXPOSE 3000/tcp
EOF
run get_dockerfile_exposed_port $DOCKERFILE
echo "output: "$output
echo "status: "$status
assert_output 3003
}
@test "(core) port exposure (dockerfile tcp port)" {
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
cat<<EOF > $DOCKERFILE
EXPOSE 3001/udp
EXPOSE 3000/tcp
EXPOSE 3003
EOF
run get_dockerfile_exposed_port $DOCKERFILE
echo "output: "$output
echo "status: "$status
assert_output 3000
}

View File

@@ -9,7 +9,6 @@ setup() {
teardown() {
rm -rf /home/dokku/$TEST_APP/tls /home/dokku/tls
destroy_app
disable_tls_wildcard
}
assert_urls() {
@@ -17,6 +16,7 @@ assert_urls() {
run dokku urls $TEST_APP
echo "output: "$output
echo "status: "$status
echo "urls:" $(tr ' ' '\n' <<< "${urls}")
assert_output < <(tr ' ' '\n' <<< "${urls}")
}
@@ -50,27 +50,27 @@ build_nginx_config() {
build_nginx_config
assert_urls "http://${TEST_APP}.dokku.me"
add_domain "test.dokku.me"
assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me"
assert_urls "http://test.dokku.me" "http://${TEST_APP}.dokku.me"
}
@test "(core) urls (app ssl)" {
setup_test_tls
assert_urls "https://dokku.me"
build_nginx_config
assert_urls "http://${TEST_APP}.dokku.me"
assert_urls "https://${TEST_APP}.dokku.me"
add_domain "test.dokku.me"
assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me"
assert_urls "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
}
@test "(core) urls (wildcard ssl)" {
setup_test_tls_wildcard
setup_test_tls wildcard
assert_urls "https://dokku.me"
build_nginx_config
assert_urls "https://${TEST_APP}.dokku.me"
add_domain "test.dokku.me"
assert_urls "https://${TEST_APP}.dokku.me" "https://test.dokku.me"
assert_urls "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
add_domain "dokku.example.com"
assert_urls "https://${TEST_APP}.dokku.me" "https://test.dokku.me" "http://dokku.example.com"
assert_urls "https://dokku.example.com" "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
}
@test "(core) git-remote (off-port)" {

View File

@@ -1,56 +1,18 @@
#!/usr/bin/env bats
load test_helper
source "$PLUGIN_CORE_AVAILABLE_PATH/config/functions"
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"
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
[[ -f "$DOKKU_ROOT/HOSTNAME" ]] && cp -fp "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/HOSTNAME.bak"
create_app
}
teardown() {
destroy_app 0 $TEST_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"
disable_tls_wildcard
}
assert_ssl_domain() {
local domain=$1
assert_app_domain "${domain}"
assert_http_redirect "http://${domain}" "https://${domain}:443/"
assert_http_success "https://${domain}"
}
assert_nonssl_domain() {
local domain=$1
assert_app_domain "${domain}"
assert_http_success "http://${domain}"
}
assert_app_domain() {
local domain=$1
run /bin/bash -c "dokku domains $TEST_APP | grep -xF ${domain}"
echo "output: "$output
echo "status: "$status
assert_output "${domain}"
}
assert_http_redirect() {
local from=$1
local to=$2
run curl -kSso /dev/null -w "%{redirect_url}" "${from}"
echo "output: "$output
echo "status: "$status
assert_output "${to}"
}
assert_http_success() {
local url=$1
run curl -kSso /dev/null -w "%{http_code}" "${url}"
echo "output: "$output
echo "status: "$status
assert_output "200"
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
[[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME" && chown dokku:dokku "$DOKKU_ROOT/HOSTNAME"
}
assert_access_log() {
@@ -80,38 +42,26 @@ assert_error_log() {
}
@test "(nginx-vhosts) nginx:build-config (wildcard SSL)" {
setup_test_tls_wildcard
setup_test_tls wildcard
add_domain "wildcard1.dokku.me"
add_domain "wildcard2.dokku.me"
add_domain "www.test.dokku.me"
deploy_app
cat /home/dokku/${TEST_APP}/nginx.conf
assert_ssl_domain "wildcard1.dokku.me"
assert_ssl_domain "wildcard2.dokku.me"
assert_nonssl_domain "www.test.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (wildcard SSL & custom nginx template)" {
setup_test_tls_wildcard
add_domain "wildcard1.dokku.me"
add_domain "wildcard2.dokku.me"
custom_ssl_nginx_template
deploy_app
assert_ssl_domain "wildcard1.dokku.me"
assert_ssl_domain "wildcard2.dokku.me"
assert_http_success "customssltemplate.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (wildcard SSL & unrelated domain)" {
destroy_app
TEST_APP="${TEST_APP}.example.com"
setup_test_tls_wildcard
setup_test_tls wildcard
deploy_app nodejs-express dokku@dokku.me:$TEST_APP
run /bin/bash -c "egrep '*.dokku.me' $DOKKU_ROOT/${TEST_APP}/nginx.conf | wc -l"
assert_output "0"
}
@test "(nginx-vhosts) nginx:build-config (with SSL and Multiple SANs)" {
setup_test_tls_with_sans
setup_test_tls sans
add_domain "test.dokku.me"
add_domain "www.test.dokku.me"
add_domain "www.test.app.dokku.me"
@@ -121,27 +71,36 @@ assert_error_log() {
assert_ssl_domain "www.test.app.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (custom nginx template)" {
@test "(nginx-vhosts) nginx:build-config (wildcard SSL & custom nginx template)" {
setup_test_tls wildcard
add_domain "wildcard1.dokku.me"
add_domain "wildcard2.dokku.me"
deploy_app nodejs-express dokku@dokku.me:$TEST_APP custom_ssl_nginx_template
assert_ssl_domain "wildcard1.dokku.me"
assert_ssl_domain "wildcard2.dokku.me"
assert_http_redirect "http://${CUSTOM_TEMPLATE_SSL_DOMAIN}" "https://${CUSTOM_TEMPLATE_SSL_DOMAIN}:443/"
assert_http_success "https://${CUSTOM_TEMPLATE_SSL_DOMAIN}"
}
@test "(nginx-vhosts) nginx:build-config (custom nginx template - default path)" {
add_domain "www.test.app.dokku.me"
custom_nginx_template
deploy_app
deploy_app nodejs-express dokku@dokku.me:$TEST_APP custom_nginx_template
assert_nonssl_domain "www.test.app.dokku.me"
assert_http_success "customtemplate.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (no global VHOST and domains:add)" {
destroy_app
rm "$DOKKU_ROOT/VHOST"
create_app
@test "(nginx-vhosts) nginx:build-config (custom nginx template - custom path)" {
add_domain "www.test.app.dokku.me"
deploy_app
dokku config:set --no-restart $TEST_APP NGINX_CUSTOM_TEMPLATE_PATH=/app/.dokku
echo "output: "$output
echo "status: "$status
deploy_app nodejs-express dokku@dokku.me:$TEST_APP custom_nginx_template .dokku/
assert_nonssl_domain "www.test.app.dokku.me"
assert_http_success "customtemplate.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (validate_nginx)" {
deploy_app
echo "some lame nginx config" > "$DOKKU_ROOT/$TEST_APP/nginx.conf.template"
run /bin/bash -c "dokku nginx:build-config $TEST_APP"
@test "(nginx-vhosts) nginx:build-config (failed validate_nginx)" {
run deploy_app nodejs-express dokku@dokku.me:$TEST_APP bad_custom_nginx_template
echo "output: "$output
echo "status: "$status
assert_failure

64
tests/unit/40_proxy.bats Normal file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env bats
load test_helper
setup() {
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
[[ -f "$DOKKU_ROOT/HOSTNAME" ]] && cp -fp "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/HOSTNAME.bak"
create_app
}
teardown() {
destroy_app 0 $TEST_APP
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
[[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME" && chown dokku:dokku "$DOKKU_ROOT/HOSTNAME"
}
assert_nonssl_domain() {
local domain=$1
assert_app_domain "${domain}"
assert_http_success "http://${domain}"
}
assert_app_domain() {
local domain=$1
run /bin/bash -c "dokku domains $TEST_APP | grep -xF ${domain}"
echo "output: "$output
echo "status: "$status
assert_output "${domain}"
}
assert_external_port() {
local CID="$1"; local exit_status="$2"
local EXTERNAL_PORT_COUNT=$(docker port $CID | wc -l)
run /bin/bash -c "[[ $EXTERNAL_PORT_COUNT -gt 0 ]]"
if [[ "$exit_status" == "success" ]]; then
assert_success
else
assert_failure
fi
}
@test "(proxy) proxy:enable/disable" {
deploy_app
assert_nonssl_domain "${TEST_APP}.dokku.me"
run dokku proxy:disable $TEST_APP
echo "output: "$output
echo "status: "$status
assert_success
for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do
assert_external_port $(< $CID_FILE) success
done
run dokku proxy:enable $TEST_APP
echo "output: "$output
echo "status: "$status
assert_success
assert_http_success "${TEST_APP}.dokku.me"
for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do
assert_external_port $(< $CID_FILE) failure
done
}

View File

@@ -8,7 +8,8 @@ PLUGIN_AVAILABLE_PATH=${PLUGIN_AVAILABLE_PATH:="$PLUGIN_PATH/available"}
PLUGIN_ENABLED_PATH=${PLUGIN_ENABLED_PATH:="$PLUGIN_PATH/enabled"}
PLUGIN_CORE_PATH=${PLUGIN_CORE_PATH:="$DOKKU_LIB_ROOT/core-plugins"}
PLUGIN_CORE_AVAILABLE_PATH=${PLUGIN_CORE_AVAILABLE_PATH:="$PLUGIN_CORE_PATH/available"}
TEST_APP=my-cool-guy-test-app
TEST_APP=testsuiteapp
CUSTOM_TEMPLATE_SSL_DOMAIN=customssltemplate.dokku.me
# test functions
flunk() {
@@ -21,6 +22,7 @@ flunk() {
# ShellCheck doesn't know about $status from Bats
# shellcheck disable=SC2154
# shellcheck disable=SC2120
assert_success() {
if [[ "$status" -ne 0 ]]; then
flunk "command failed with exit status $status"
@@ -115,8 +117,7 @@ create_app() {
destroy_app() {
local RC="$1"; local RC=${RC:=0}
local TEST_APP="$2"; local TEST_APP=${TEST_APP:=my-cool-guy-test-app}
echo $TEST_APP | dokku apps:destroy $TEST_APP
dokku --force apps:destroy $TEST_APP
return $RC
}
@@ -124,12 +125,62 @@ add_domain() {
dokku domains:add $TEST_APP $1
}
# shellcheck disable=SC2119
check_urls() {
local PATTERN="$1"
run bash -c "dokku --quiet urls $TEST_APP | egrep \"${1}\""
echo "output: "$output
echo "status: "$status
assert_success
}
assert_http_success() {
local url=$1
run curl -kSso /dev/null -w "%{http_code}" "${url}"
echo "output: "$output
echo "status: "$status
assert_output "200"
}
assert_ssl_domain() {
local domain=$1
assert_app_domain "${domain}"
assert_http_redirect "http://${domain}" "https://${domain}:443/"
assert_http_success "https://${domain}"
}
assert_nonssl_domain() {
local domain=$1
assert_app_domain "${domain}"
assert_http_success "http://${domain}"
}
assert_app_domain() {
local domain=$1
run /bin/bash -c "dokku domains $TEST_APP | grep -xF ${domain}"
echo "output: "$output
echo "status: "$status
assert_output "${domain}"
}
assert_http_redirect() {
local from=$1
local to=$2
run curl -kSso /dev/null -w "%{redirect_url}" "${from}"
echo "output: "$output
echo "status: "$status
assert_output "${to}"
}
deploy_app() {
APP_TYPE="$1"; APP_TYPE=${APP_TYPE:="nodejs-express"}
GIT_REMOTE="$2"; GIT_REMOTE=${GIT_REMOTE:="dokku@dokku.me:$TEST_APP"}
TMP=$(mktemp -d -t "dokku.me.XXXXX")
local APP_TYPE="$1"; local APP_TYPE=${APP_TYPE:="nodejs-express"}
local GIT_REMOTE="$2"; local GIT_REMOTE=${GIT_REMOTE:="dokku@dokku.me:$TEST_APP"}
local CUSTOM_TEMPLATE="$3"; local TMP=$(mktemp -d -t "dokku.me.XXXXX")
local CUSTOM_PATH="$4"
rmdir $TMP && cp -r ./tests/apps/$APP_TYPE $TMP
cd $TMP || exit 1
[[ -n "$CUSTOM_TEMPLATE" ]] && $CUSTOM_TEMPLATE $TEST_APP $TMP/$CUSTOM_PATH
git init
git config user.email "robot@example.com"
git config user.name "Test Robot"
@@ -143,7 +194,7 @@ deploy_app() {
}
setup_client_repo() {
TMP=$(mktemp -d -t "dokku.me.XXXXX")
local TMP=$(mktemp -d -t "dokku.me.XXXXX")
rmdir $TMP && cp -r ./tests/apps/nodejs-express $TMP
cd $TMP || exit 1
git init
@@ -156,93 +207,114 @@ setup_client_repo() {
}
setup_test_tls() {
TLS="/home/dokku/$TEST_APP/tls"
local TLS_TYPE="$1"; local 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
}
setup_test_tls_with_sans() {
TLS="/home/dokku/$TEST_APP/tls"
mkdir -p $TLS
tar xf $BATS_TEST_DIRNAME/server_ssl_sans.tar -C $TLS
sudo chown -R dokku:dokku $TLS
}
setup_test_tls_wildcard() {
TLS="/home/dokku/tls"
mkdir -p $TLS
tar xf $BATS_TEST_DIRNAME/server_ssl_wildcard.tar -C $TLS
sudo chown -R dokku:dokku $TLS
sed -i -e "s:^# ssl_certificate $DOKKU_ROOT/tls/server.crt;:ssl_certificate $DOKKU_ROOT/tls/server.crt;:g" \
-e "s:^# ssl_certificate_key $DOKKU_ROOT/tls/server.key;:ssl_certificate_key $DOKKU_ROOT/tls/server.key;:g" /etc/nginx/conf.d/dokku.conf
kill -HUP "$(< /var/run/nginx.pid)"; sleep 5
}
disable_tls_wildcard() {
TLS="/home/dokku/tls"
rm -rf $TLS
sed -i -e "s:^ssl_certificate $DOKKU_ROOT/tls/server.crt;:# ssl_certificate $DOKKU_ROOT/tls/server.crt;:g" \
-e "s:^ssl_certificate_key $DOKKU_ROOT/tls/server.key;:# ssl_certificate_key $DOKKU_ROOT/tls/server.key;:g" /etc/nginx/conf.d/dokku.conf
kill -HUP "$(< /var/run/nginx.pid)"; sleep 5
case "$TLS_TYPE" in
wildcard)
local TLS_ARCHIVE=server_ssl_wildcard.tar
;;
sans)
local TLS_ARCHIVE=server_ssl_sans.tar
;;
*)
local TLS_ARCHIVE=server_ssl.tar
;;
esac
tar xf $BATS_TEST_DIRNAME/$TLS_ARCHIVE -C $TLS
sudo chown -R dokku:dokku ${TLS}/..
}
custom_ssl_nginx_template() {
APP="$1"
[[ -z "$APP" ]] && APP="$TEST_APP"
cat<<EOF > $DOKKU_ROOT/$APP/nginx.conf.template
local APP="$1"; local APP_REPO_DIR="$2"
[[ -z "$APP" ]] && local APP="$TEST_APP"
mkdir -p $APP_REPO_DIR
echo "injecting custom_ssl_nginx_template -> $APP_REPO_DIR/nginx.conf.sigil"
cat<<EOF > "$APP_REPO_DIR/nginx.conf.sigil"
server {
listen [::]:\$NGINX_PORT;
listen \$NGINX_PORT;
server_name \$NOSSL_SERVER_NAME customssltemplate.dokku.me;
return 301 https://\\\$host:\$NGINX_SSL_PORT\\\$request_uri;
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }} $CUSTOM_TEMPLATE_SSL_DOMAIN;
return 301 https://\$host:{{ .NGINX_SSL_PORT }}\$request_uri;
}
server {
listen [::]:\$NGINX_SSL_PORT ssl spdy;
listen \$NGINX_SSL_PORT ssl spdy;
server_name \$SSL_SERVER_NAME customssltemplate.dokku.me;
\$SSL_DIRECTIVES
listen [::]:{{ .NGINX_SSL_PORT }} ssl spdy;
listen {{ .NGINX_SSL_PORT }} ssl spdy;
server_name \$SSL_SERVER_NAME $CUSTOM_TEMPLATE_SSL_DOMAIN;
ssl_certificate {{ .APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ .APP_SSL_PATH }}/server.key;
keepalive_timeout 70;
add_header Alternate-Protocol \$NGINX_SSL_PORT:npn-spdy/2;
add_header Alternate-Protocol {{ .NGINX_SSL_PORT }}:npn-spdy/2;
location / {
proxy_pass http://\$APP;
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade \\\$http_upgrade;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \\\$http_host;
proxy_set_header X-Forwarded-Proto \\\$scheme;
proxy_set_header X-Forwarded-For \\\$remote_addr;
proxy_set_header X-Forwarded-Port \\\$server_port;
proxy_set_header X-Request-Start \\\$msec;
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Port \$server_port;
proxy_set_header X-Request-Start \$msec;
}
include \$DOKKU_ROOT/\$APP/nginx.conf.d/*.conf;
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
}
{{ if .DOKKU_APP_LISTENERS }}
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }} server {{ . }};
{{ end }}}
{{ else if .PASSED_LISTEN_IP_PORT }}
upstream {{ .APP }} {
server {{ .DOKKU_APP_LISTEN_IP }}:{{ .DOKKU_APP_LISTEN_PORT }};
}
{{ end }}
EOF
}
custom_nginx_template() {
APP="$1"
[[ -z "$APP" ]] && APP="$TEST_APP"
cat<<EOF > $DOKKU_ROOT/$APP/nginx.conf.template
local APP="$1"; local APP_REPO_DIR="$2"
[[ -z "$APP" ]] && local APP="$TEST_APP"
mkdir -p $APP_REPO_DIR
echo "injecting custom_nginx_template -> $APP_REPO_DIR/nginx.conf.sigil"
cat<<EOF > "$APP_REPO_DIR/nginx.conf.sigil"
server {
listen [::]:\$NGINX_PORT;
listen \$NGINX_PORT;
server_name \$NOSSL_SERVER_NAME customtemplate.dokku.me;
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }} customtemplate.dokku.me;
location / {
proxy_pass http://\$APP;
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade \\\$http_upgrade;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \\\$http_host;
proxy_set_header X-Forwarded-Proto \\\$scheme;
proxy_set_header X-Forwarded-For \\\$remote_addr;
proxy_set_header X-Forwarded-Port \\\$server_port;
proxy_set_header X-Request-Start \\\$msec;
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Port \$server_port;
proxy_set_header X-Request-Start \$msec;
}
include \$DOKKU_ROOT/\$APP/nginx.conf.d/*.conf;
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
}
{{ if .DOKKU_APP_LISTENERS }}
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }} server {{ . }};
{{ end }}}
{{ else if .PASSED_LISTEN_IP_PORT }}
upstream {{ .APP }} {
server {{ .DOKKU_APP_LISTEN_IP }}:{{ .DOKKU_APP_LISTEN_PORT }};
}
{{ end }}
EOF
}
bad_custom_nginx_template() {
local APP="$1"; local APP_REPO_DIR="$2"
[[ -z "$APP" ]] && local APP="$TEST_APP"
echo "injecting bad_custom_nginx_template -> $APP_REPO_DIR/nginx.conf.sigil"
cat<<EOF > "$APP_REPO_DIR/nginx.conf.sigil"
some lame nginx config
EOF
}