- Simplify test location documentation
- Add documentation surrounding our existing CI environment
- Dedent items that shouldn't be in a list
[ci skip]
- Add missing "New as of" banner
- Ensure we list commands at the top
- Add reference to sshcommand
- Callout that the NAME must be unique
- Add an example for removing keys
[ci skip]
When configuring domains/ssl certificates, the port mappings for an application may be automatically set. This can cause issues for applications which will use non-standard ports - ie. for Dockerfile deploys.
[ci skip]
An application which has not been deployed will not have an image
available, and therefore attempting to remove an (empty) cache directory
will fail. Rather than checking for the image - which we should
still do, as not having an image for a deployed app is an error state -
we should instead only attempt the docker cache removal if the directory
cannot be removed via rmdir.
Closes#2294
Rather than removing all port mappings, we simply remap port 80 mappings to 443. The previous behavior would remove custom port mappings for all applications and reset them on any certificate change, preventing automation from plugins such as letsencrypt. While this behavior doesn't matter for buildpack deploys - which only expose a single port on container port 5000 - Dockerfile deploys would frequently be affected by such a change, requiring a remapping of all custom ports.
This commit also standardizes on the method used to source the proxy functions
Checks can be run in several ways:
- checks:run APP
- checks:run APP PROCESS_TYPE
- checks:run APP PROCESS_TYPE.CONTAINER_INDEX
This will reuse the existing checks infrastructure as defined by the checks plugin, and therefore if no checks file is defined, it will default to the normal Dokku container check.
Closes#2218
Edited the "unattended script" in the documentation so that apt-get
doesn't wait for input on the Dokku install.
modified: getting-started/install/debian.md
This hook will allow users to modify the repo in use for deployed applications. An example use case would be one where the image being deployed is from a remote docker registry where the `dokku` username is taken and the app will be deployed from a separate username.
- Ensure we document all commands being run
- Highlight that we are mapping the same port twice
- Clarify how dokku binds containers to listening interfaces
[ci skip]
Applications without a restart-policy will have their policies set to `on-failure:10`. Users can completely unset the restart-policy using the `docker-options` plugin, though this will be equivalent to setting it explicitly to `no`.
Restart policies must be explicitly set, and the following are all valid:
- no
- unless-stopped
- always
- on-failure
- on-failure:NUMBER
Fixesdokku/dokku-letsencrypt#67
Change the certs:add command to use a file import without trying to
detect a piped-in tarball if server.crt and server.key files were passed
in as arguments and those files exist.
Fixes hangs on certificate imports by filename when the check for a
STDIN pipe fails e.g. when running dokku remotely using a SSH command.
- note that the port changes on every deploy when the proxy is disabled
- make it clear that the proxy is being disabled for the app
- note that the nginx-vhosts plugin supports the proxy plugin mapping
- minor formatting changes
[ci skip]
This allows users to specify port 80 after an application has had domain added. Normally, when we first add an extra domain, the following tuple is added:
http:80:5000
A user might then want to remap port 80 to another port, such as port 8080:
dokku proxy:ports-add APP http:80:8080
The application would then have the following proxy map:
http:80:5000 http:80:8080
As nginx vhosts are resolved in FIFO order, the "correct" upstream of 8080 would basically be ignored. The workaround would be to remove the original port mapping, but the following:
dokku proxy:ports-remove APP 80
Would remove *both* entries and then re-add the default of `http:80:5000`. Thus it was not possible to use the porcelain to correct the port mapping and a user would have to fall back to using the following hack to fix their mapping:
dokku config:set APP DOKKU_PROXY_PORT_MAP='http:80:8080'
You can now use the previous syntax *as well as* the following to remove a port mapping:
dokku proxy:ports-remove APP http:80:5000
Newer versions of nginx drop spdy support in favor of http2, and thus the nginx config that we bundle with dokku causes nginx to fail to reload in certain cases. This change drops spdy support in favor of http2 for versions of nginx greater than 1.9.5.
Closes#2216
These are helper plugins that mimic the repo plugin: https://github.com/heroku/heroku-repo
The following commands will remain unimplemented:
- `clone`: not useful for the host client to clone
- `download`: currently not possible for us to "host" a tarball of the repo
- `reset`: we still store files in the repo (though we shouldn't) so we cannot easily reinitialize the repository.
Also fixes a potential race condition if two separate processes create an application's `$CACHE_DIR`.
Closes#1570
In at least one case a customer of ours added a domain including
a schema, as in “http://domain.tld/”. That is obviously incorrect, but
then they couldn't remove it using the dokku command:
$ dokku domains:remove app7 http://domain.tld/
sed: -e expression #1, char 9: unknown command: `/'
This patch changes the sed command to use the "\CregexpC" syntax. The
character used is a vertical pipe, which is far less likely to be used
in a URL. After the change:
$ dokku domains:remove app7 http://domain.tld/
-----> Removed http://domain.tld/ from app7
Signed-off-by: Michael Hanselmann <hansmi@vshn.ch>
When rebooting a Dokku host the init process tries to restore all apps
using `dokku ps:restore`, alphabetically. If an app is defined but not
deployed, the function `ps_start` called by `dokku ps:restore` will
exit 0 and stop trying to restore the other apps later in the alphabet.
This change fixes the restore behaviour.
Currently we exit when trying to add a duplicated domain, even if we give a list
of domain names. This behaviour is not as it suppose to work.
**Expected behaviour**
When adding a domain, and the domain already exists, just skip that domain, and
continue with the world. This is no problem since we are already in the state we
want to be in.
**New behaviour**
When you try to add a domain that is already added, we notify the user of this
by showing a log message: `Skipping: example.com already added to example app`,
and then we continue with the list of domain names.
Fixes#2165
Clearly stress the fact, that there are more steps than only running the bash commands. You also have to navigate to the website and finish the configuration.
- unified css between home and template layouts
- use same version of bootstrap everywhere
- add our cute whale sushi logo to the homepage
- use fewer styles
- add a better installation section to point out different installation methods
- add navigation bar items
[ci skip]
- Tone down "new as of version" boxes
- Replace all "New as of 0.5" with "yet to be released" text
- Use strong red only for "yet to be released" boxes
Fixes#1989
- Briefly cover sshcommand internals
- Show several examples for using sshcommand
- Split out docs onto a new page and relink to it where necessary
- Refer to user-auth plugin trigger for scoping commands to specific users.
[ci skip]
This will allow a user to browse the documentation as it was at any point in time. In doing so, this allows us to more easily deprecate/remove features without worrying about having to duplicate old documentation in the future.
[ci skip]
- Refer to checks plugin in zero-downtime deploy link
- Refer to cron in one off processes link
- Add an "Advanced Usage" section
- Add links to proxy management and deployment tasks
- Move container options and persistent storage to advanced usage
[ci skip]
This change sets a DOKKU_APP_NAME env var, which can be used by plugins as a replacement for the `app` param if specified. Note that each plugin will have to manually shift it's arguments if necessary
* fix rsyslog handling
* don't hardcode dokku path
* add documentation for ArchLinux package build
* add vagrant machine to run the ArchLinux specific steps
* add step in release process for ArchLinux
* enhance docs for easy ArchLinux steps
This pr makes it slightly easier to support dockerfile installations
- "simplifies" the bootstrap process by dividing it into distinct chunks
- Allows specifying `--no-install-recommends` when a dockerfile installation is detected
- Uses functions everywhere
- Removes global variables where possible
- Fixes shellcheck issues
- Allows specifying debconf via the command-line
[ci skip]
There are cases where we don't want the check for keyfile, this will add a
config option, that allows you to skip this particular check.
Fixes#1851
Signed-off-by: Jeroen van Baarsen <jeroenvanbaarsen@gmail.com>
OSX creates hidden files: `./._server.key` and `./._server.crt`. The Dokku cert
plugin is choking on those files. We should probably just ignore them, and go on
with our lives
Signed-off-by: Jeroen van Baarsen <jeroenvanbaarsen@gmail.com>
I was running into issues with the IP addresses, and it seems
that it's using an incorrect/outdated syntax for retrieving
the container's IP Address. In multi-host networking
`NetworkSettings.IPAddress` is empty.
The docker documentation at https://docs.docker.com/engine/reference/commandline/inspect/
uses a different syntax which I've tested to work both on multi-host and
standard bridge networking.
If you're interested in the other issues and the work/hacks I've been doing related
to #1795, let me know. In the meantime, I think this fix is needed.
- remove deployed applications during dpkg purge
- disable all core plugins during dpkg purge
- ensure init files are removed
- ensure motd is removed
- remove all core plugins, dokku config files (including tls/sshcommand entries etc.) during purge
- remove all empty directories and broken symlinks in the DOKKU_ROOT and DOKKU_LIB_ROOT directories during purge
Note that we do not delete the dokku user itself as there might be other data we don't know about in this directory.
We previously assumed that systemd was detectable by the existence of certain directories. Unfortunately, it seems 14.04 already has these directories, so we need to handle this case separately.
One other note is that dokku-installer will fail to "start" if already started on certain systems, thus the previous grep was more accurate in it's running.
- Use the nginx.conf file's existence as a check for whether we should start the service or not
- Create the init files with the dokku-installer.py file. This adds actual systemd support.
- Also ensure we *always* start the service, regardless of it's status. This fixes an issue with processing systemd output
Fixes the following warning:
```
dpkg: warning: parsing file '/var/lib/dpkg/tmp.ci/control' near line 6 package 'dokku':
`Depends' field, reference to `lxc-docker':
`>' is obsolete, use `>=' or `>>' instead
```
Refs #1776
The python version should allow us to remove any ruby dependencies and should also slightly speed up dokku installation. All LSB-compliant distributions should have python, so we should be okay depending upon it.
Closes#1783Closes#1786
It's not possible to checkout a specific commit into a new repository
using ``git fetch`` and so a temporary tag is added to the host
repository, then fetched.
This adds a hook that will send in the $APP, action name and config vars.
By adding this, we allow plugin creators to handle this kind of events as well.
Signed-off-by: Jeroen van Baarsen <jeroenvanbaarsen@gmail.com>
The version of docker.io in jessie-backports is 1.6.2~dfsg1-1~bpo8+1.
This is regarded as lower than 1.6.2 by dpkg because `~` has a special meaning
in regards to version sort in dpkg.
This leads to:
```
The following packages have unmet dependencies:
dokku : Depends: docker-engine-cs but it is not installable or
docker-engine but it is not installable or
lxc-docker (>= 1.6.2) but it is not installable or
docker.io (>= 1.6.2) but 1.6.2~dfsg1-1~bpo8+1 is to be installed
Recommends: herokuish but it is not going to be installed
```
By changing the contraints the version in backports will be accepted by dpkg.
Add this point you only get information that "something" happend on the given
hook. By adding more information to the hook, plugin creators can do more
interesting stuff.
* The first params remains the $APP name (to maintain backwards compatability)
* The second params sends in the action that happend, for domain this can be:
"add", "clear" or "remove"
* The third param sends in the argument that was passed to the original
function, for domain that would be a list of all the domains that was given.
One reason this addition would be great for plugin owners, is that when you have
a web tool over Dokku, and someone creates a domain over the CLI, we a plugin
can send back information about the event to the webapp over an API. That way
the webapp is always up-to-date with the Dokku installation.
Signed-off-by: Jeroen van Baarsen <jeroenvanbaarsen@gmail.com>
In order to be one step closer to lintian compliance, lets remove the shebang
from this file so it doesn;t have to be executable
See #1641
Signed-off-by: Jeroen van Baarsen <jeroenvanbaarsen@gmail.com>
Changing the herokuish package to Recommends instead of Depends allows users to skip the installation of that package by specifying --no-install-recommends. Herokuish will still be installed by default using apt-get
Adds unit test for new apps:rename function.
Add example in the docs for new apps:rename function.
Add apps:rename command to help command.
Delete cache directory before copying old app directory to new app directory.
deploy_app instead of create_app for apps:rename testing.
Change app url to match new name. Fix unit tests.
Add some more tests, plugn triggers.
As of 15.10, we are graced with a relatively recent version of nginx, and thus no longer need access to the ppa. Assuming this is the only such issue, this should also allow us to support Ubuntu 16.04 without any future changes.
I have created a plugin for installing a specific library that is not working properly when installed using dokku-apt.
It took me a lot of time to figure out how to properly install it and therefore I wanted to share it.
- Add note to avoid problems with shared volumes permissions
- Restructure the doc to help comprehension
- Make command examples consistent
- Improve wording in some places
- Advanced usage: remove "avoid if possible". It made little sense.
- docker (project) --> Docker
- dokku (project) --> Dokku
- dokku (command) --> `dokku`
- add `shell` to code blocks
This should consolidate a lot of knowledge around how dokku deals with buildpacks, as well as clears up a few misconceptions - mainly that dokku doesn't support multiple/custom buildpacks.
By bringing this information front-and-center, we can avoid a lot of questions by users trying to use dokku.
[ci skip]
This plugin trigger should allow users to pair down the available commands for a given user. While this does not affect help output - or any output at all - this is a good first step in allowing administrative access to certain commands while still allowing users to deploy/manage given applications.
Note that because of how dokku works, all parsing of commands must be done within the pluginhook, and we cannot give visibility into the actual command or application that will be affected by a given run.
* Bump `Version` field.
* Set minimum nginx version to 1.4.6, per #1654
* Depend on both `rubygem-foo` (Ubuntu) and `ruby-foo` (Debian).
* Add distro-default `docker.io (>= 1.6.2)` as an alternative.
Version 1.6.2 is in both `trusty-updates` and `jessie-backports`,
while `trusty` itself has `0.9.1`. We seriously want to avoid that.
This also updates the docs so people don't forget to bump the version
field in the future. Even though we really do that for them with sed.
In this case, Bats sets $status, $output, and $lines, but ShellCheck
doesn't statically know that. Therefore, we ignore SC2154 when those
variables are first introduced in ./tests/unit/test_helper.bash
https://github.com/koalaman/shellcheck/wiki/SC2154
New version of the logs plugin broke compatibility (as reported in #1534).
So options have been added to handle display:
* -t/--tail to tail logs (already existed)
* -n/--num NUM to display only this number of lines
* -p/--ps PS to display logs only from provided process
* -q/--quiet to display raw logs without color, time and names
This should close#1534
Which is quite useful in some situations, for example when you want each app to point to a DB with the same name as the app (reducing the amount of app-specific config).
I've not yet tested with 0.4.x but asap we upgrade our environment I'll ensure it's compatible (should be super simple since it's a super simple plugin).
This ensures that we can call apt-get update after adding a new apt source. Debian needs a bit more time to refresh it's own caches, so we just force it's cache to be clean before calling apt-get update again.
This package is the version we use for as a dokku dependency, and thus there is no need to specify a *specific* version when building the deb packages.
Refs #976
Blockquote elements that call out a new feature are given a "pink" background, whereas all others are given a "blue" background. This is to help avoid cases where users expect a feature to work for their version when they are several versions behind when a feature was introduced.
Fixes#1495
Log user name and fingerprint in events
Clarify bootstrap installation documentation
We actually have the reverse situation where the bootstrap.sh uses the web installer by default.
[ci skip]
dokku-apt compatibility
Fix for issue #1487:
Created a separated VM environments for developers and users.
Changing default to linux users
Fix for issue #1487:
Created a separated VM environments for developers and users.
Adjusting space
Clarify bootstrap installation documentation
We actually have the reverse situation where the bootstrap.sh uses the web installer by default.
[ci skip]
dokku-apt compatibility
Fix for issue #1487:
Created a separated VM environments for developers and users.
Changing default to linux users
Fix for issue #1487:
Created a separated VM environments for developers and users.
Changing default to linux users
Making dokku the default
Adjusting space
Because of how plugin commands are implemented, their output can be incredibly verbose. Rather than executing even the `set -eo pipefail` parts of a plugin, we immediately check if the command is implemented by a plugin. If it is not, then we continue on as normal.
One side-effect of this change is that plugin commands need to be duplicated again:
- once in the command array
- once for the actual body of the command
- once in the help output
This is also quite hackish, and probably not the best way to decrease trace output. Note that we drop approximately 2k lines worth of logs with this change.
This reduces deploy output by moving `config:get` calls out of the main loop. Since the values are the same for each iteration, it does not make sense to re-retrieve them each time.
Previously a crashed container would stay down, regardless of exit status. In some cases, it may be useful to restart the container. For example, an application may not be correctly implementing their error handling, or the crash may be caused by a transient error.
By setting the restart policy to `on-failure:N` - where N is a number of max restarts - we can help developers guard against crashing applications. Note that this is not a replacement for proper error handling, nor does this include notifications to a developer when a container is restarted. Those patterns should be implemented application side, or via a feature request to docker.
The value is configurable at the app-level by setting DOKKU_RESTART_LIMIT to a number. By default, containers will be restarted a max of 10 times. If a container crashes during the check-deploy plugin trigger, then the deploy will be marked as a failure.
Closes#216Closes#398Closes#1327
This will allow developers to run an `upgrade` on existing installations without breaking because docker-engine isn't yet in their apt lists...
[ci skip]
Rather than having a one-off hack for "blessed" containers, we should solve the issue properly. As that would take a bit more work, reverting to the previous state is preferred.
Better that we solve a problem problem than with a hack that we'll need to roll back in the future.
Refs #1220
[ci skip]
We had an issue with third party plugins installing things via apt while
already installing dokku itself via apt.
To resolve this, `plugins-install` and `plugins-install-dependencies`
now can take a `--core` flag allowing to execute the install hook only
on core plugins and not on third party plugins.
Another feature with this modification is the ability to disable/enable
plugins. Two new commands now exist:
* `plugins:enable <name>` to enable a previously disabled plugin
* `plugins:disable <name>` to disable an installed plugin. This won’t
work on core plugins.
Rather than having a one-off hack for "blessed" containers, we should solve the issue properly. As that would take a bit more work, reverting to the previous state is preferred.
Better that we solve a problem problem than with a hack that we'll need to roll back in the future.
Refs #1220
[ci skip]
This can be used as an alternative to importing via stdin, which may be preferred when working directly on a server, or via scripted installation/deployments.
This should theoretically be safe, as "--export" forces the `dokku config` command to return 0 in all cases, and it should only output lines that are "valid" environment variables
This function - `is_container_status` - can be used to inspect whether a container is any of the following:
- Dead
- OOMKilled
- Paused
- Restarting
- Running
It can be useful for deeper inspection as to plugin state
As briefly discussed in #1425, source the `common/functions` file via an
absolute path, rather than determining the relative path by using
`dirname`. 3rd-party plugins should follow suit and use the new
`$PLUGIN_PATH` convention too.
This will allow users to inspect the underlying environment and conditionally run different commands based upon the `DYNO_TYPE_NUMBER`. The values will be set in the following format:
web.1
web.2
worker.1
worker.2
clock.1
Users of process managing plugins and dockerfiles can check the `DYNO_TYPE_NUMBER` and set a specific command to run.
Closes#1350
This command can be used to enter a running container. The following variations of the command exist:
dokku enter api web
dokku enter api web.1
dokku enter api --container-id ID
By default, it runs a `/bin/bash`, but can also be used to run a custom command:
# just echo hi
dokku enter api web echo hi
# run a long-running command, as one might for a cron task
dokku enter api web python script/background-worker.py
Closes#1332
You can now use the following to narrow down the search for a container id:
get_app_container_ids app web
get_app_container_ids app worker
You can also specify a specific type "id" like so:
get_app_container_ids app web.1
get_app_container_ids app worker.3
Specifying an invalid type or id will result in an empty response
This should allow installation of the dokku packages on debian jessie. Upstream docker created this package in response to an issue where `cgroup-bin` could not be installed at the same time as lxc.
Closes#1236
Refs #1076
[ci skip]
This reverts commit 1bf30bdcb1.
Commit was reverted as this breaks installs of core plugins. It is also a hack around broken plugins that don't use the `dependencies` pluginhook.
All core plugins that require debian packages already have those packages specified in the `depends` stanza of the `control` file, so no need to respecify them here.
`bootstrap.sh` fails to acknowledge the `DEBIAN_FRONTEND=noninteractive` envvar because of the use of `sudo`, because the -E flag is not set. However, the script also assumes that it will be run with `sudo` in the first place, so it shouldn't be needed. In the event that it is needed, it can be run with -E instead.
Setting `DOKKU_SKIP_ALL_CHECKS` globally or for a given app will skip
all checks.
Setting `DOKKU_SKIP_DEFAULT_CHECKS` globally or for a given app will skip
default checks only.
Record events (i.e. pluginhook's calls) as syslog entries and
provide a shortcut command to display the last part of the log
file.
A brief summary of the changes follows:
dokku:
- New DOKKU_EVENTS_LOGFILE envvar to hold logfile location.
plugins/20_events/commands:
- events output log entries, a tail's follow-like mode is
provided too.
- events:[on|off] enables/disables logging.
- events:list lists events that are logged.
plugins/20_events/hook:
- Generic hook that writes log entries. All the events are
registered via symlink to this script.
plugins/common/functions:
- dokku_log_event() writes log entries via logger.
- dokku_log_pluginhook_call() formats log entries and writes
them via dokku_log_event().
Since `docker build` is only invoked when actually building a new image
from a Dockerfile, using `--no-cache` allows to have an updated image
even if the Dockerfile hasn't changed.
This works well with Dockerfiles using `git` or packages referencing
latest versions instead of "static" ones.
My changes may not be quite correct, but as far as I can tell, DOCKER_OPTIONS now requires specifying a phase explicitly.
Also updated references to `--link` since `-link` has been deprecated in Docker.
When we will use `kill` command on `docker` main process will receive
`SIGKILL` signal. This will result in immediate termination of
processes. We need to send a signal `SIGTERM` to main process and give
the opportunity to close application in correct way.
Piping the output of `curl` or `wget -O-` to a shell is a very bad idea for multiple reasons; security concerns aside, doing so provides no opportunity for the script's download to finish before execution starts, so if the download is interrupted for some reason (perhaps because of an intermittent network failure), the incompletely-downloaded script will still run with potentially disastrous results. See [here](http://www.seancassidy.me/dont-pipe-to-your-shell.html) for a more in-depth description.
ATTEMPTS=0 means don't run the checks. Useful if you want to skip the checks and can be overridden by DOKKU_CHECKS_ATTEMPTS
ATTEMPTS=1 means run only once
Previously this script was matching for a remote named 'dokku' even
when DOKKU_HOST is provided and completely custom. I have a case where
I have 2 remotes with dokku, one on a staging server and another on a
production server.
So by matching for 'dokku@$DOKKU_HOST' instead, the script can determine
correctly which remote to use.
http://xip.io
xip.io is a service by Basecamp that provides a wildcard DNS service on the public internet. Any <ip address>.xip.io will return a DNS response for the IP address, same with <subdomain>.<ip address>.xip.io.
The domains plugin in dokku uses a regex to match IP4 and IP6 addresses in the VHOST file, and disables VHOST support if found. This PR changes those patterns to require that the VHOST entry **ends with** the IP address.
This is a gist where my VHOST setting is "127.0.0.1.xip.io" that demonstrates the original output, linked directly to the line from `plugins/domains/commands`: https://gist.github.com/anonymous/c529177f20b36beda80d#file-debug-log-L1373
- Specify how long to wait before running first check
- Specify timeout for each check
- Check specific hosts, e.g. http://signin.example.com
- Check both HTTP and HTTPS resources
As per RFC 2818 [0], a CN of *.dokku.me will only match direct
subdomains of dokku.me, not sub-subdomains like www.test.dokku.me, but
Dokku currently enables TLS for subdomains of all levels.
I have changed the regex from .*\.dokku\.me to [^.]*\.dokku\.me so TLS
is only enabled for direct subdomains.
[0] - http://tools.ietf.org/html/rfc2818#section-3.1
Signed-off-by: Lewis Marshall <lewis@lmars.net>
Previously, the presence of TLS certificates would cause `dokku urls` to
output all https URLs, even for domains which were not configured to use
TLS.
This change introduces a URLS file in the app's directory which contains
the URLs with schemes based on whether they have been configured to use
TLS in the nginx config.
Signed-off-by: Lewis Marshall <lewis@lmars.net>
Previous to this change, each TLS domain would be written to nginx.conf
using the nginx.ssl.conf template (lines 69-73) but with an empty
"server_name" directive (because NOSSL_SERVER_NAME was not set).
This would then become irrelevant because nginx.conf would get truncated
on line 88, and a single parsing of the template would then be written to
nginx.conf on line 89, meaning only the last TLS domain would be set up to
actually use TLS.
This patch changes this behaviour so that all TLS domains get added to
nginx.conf using the nginx.ssl.conf template (which includes redirecting
HTTP -> HTTPS), and all non-TLS domains get added using the nginx.conf
template, so do not get redirected to a TLS domain.
Signed-off-by: Lewis Marshall <lewis@lmars.net>
Placing `COPY` (or `ADD`) of the application directory after the `RUN apt-get install ...` statements will allow the layers created from those statements to be retrieved from docker's cache on subsequent runs.
During an upgrade, the output of `git describe --tags` is written to the VERSION file, so we need to pull the tags otherwise it looks like we're running an old version.
herokuish defaults to /tmp/cache, so the build cache don't work without giving the CACHE_PATH environment variable. You can test it with buildstep herokuish branch. cc @progrium
- don't match substrings in VHOSTS
- handle case where NOSSL_SERVER_NAME is \' \'
- rebuild nginx config on ssl import
- prevent cwd errors after we rm the temp dir
This allows us to configure dokku env-vars individually. Such a feature is useful if a developer would like to enable or disable DOKKU_TRACE without parsing a dokkurc file.
The URL file is being rewritten on every deploy by `dokku deploy` and thus that file was incorrect. Instead, we just reuse the old logic from the nginx-vhosts plugin to handle creation of the VHOST file
This helps remove duplication and also ensures that all hosts have a proper setup after running `make copyfiles`
Note that this command is not exposed in help as it is not generally useful to developers
Adding a hostname to the $APP/VHOST file will enable it as a virtualhost for the application.
In addition, any hostname set that matches an associated ssl certificate will also be set as an ssl host. Note that if a hostname does not have a matching SSL host, then it will result in an erroring application.
For the moment, running `dokku url` on an app may not correctly display the current hostnames for said app.
This fixes a bug introduced when deploying apps where the
nginx-vhosts plugin runs ``dokku config:get $APP NO_VHOST``. The initial
run of this actually was creating the ``ENV`` file and dumping to
stdout the value "NO_VHOST=-----> Creating /home/dokku/foo/ENV". This
was obviously no good because nginx-vhosts was considering this to be a
value of true.
I've modified this to simply not return anything when the value does not
exist. A better update may be to output the messages to stderr instead
of stdout.
- Uses ENV and APP/ENV files
- Supports old BUILD_ENV files (which are likely in wide-use)
- Allows user's to override globals with app-specific configuration
Closes#284Closes#683Closes#763
Refs #503
Refs #678
To be able to switch the plugin path i have removed the hard coded
plugin path from the catch all section of the switch within the main
dokku executable.
To be able to set some other environment variables even if dokku gets
called from a different user we have to keep the environment with sudo
intact, so i added the -E option.
Plugins with commands will need to implement a catch-all command that exits with the `DOKKU_NOT_IMPLEMENTED_EXIT`` code (10). This signals to dokku that a given plugin has indeed not executed anything for a plugin (which may not always be the case).
Using plugins that do not implement this pattern will result in those plugins silencing the error message.
I have done the first steps to get dokku running for other distros like
openSUSE. I have simply replaced the important places within the core
plugins with a check for DOKKU_DISTRO that gets exported by dokku
itself. It just replaces the apt-get and service start/restart/reload
functionality with the openSUSE counterparts.
In order to be able to use a different base image i have added another
environment variable where everybody can switch the used base container
for the applications directly through the environment variable
DOKKU_IMAGE or with the help of the dokkurc configuration.
This creates the following commands:
- apps
- apps:create <app>
- apps:destroy <app>
It also:
- makes `delete` an alias for `apps:destroy`
- adds confirmation to `apps:destroy`
- allows a developer to remove apps that have been created via apps:create but have not been deployed
Refs #87
Refs #543
Refs #586Closes#599
Refs #655
Refs #656
Refs #685Closes#757
Since curl is running quietly it may give the impression that the installation hanged with the last message on the terminal being: "sleep 2 # give docker a moment i guess". In my case I thought it gave it a huge moment and not 2 seconds. It wasn't until the third time that I actually checked the processes on the machine and saw there it was curl downloading stuff quietly.
Avoids
```
Permission denied (publickey).
fatal: The remote end hung up unexpectedly
```
that can occur on certain Vagrant images. Since we need readonly anyway, might as well use HTTPS instead of SSH.
This is adapted from the one I use in my shell profile scripts. This
kinda-sorta-maybe acts like the `heroku` or `deis` commands and does
some clever reorganization of data before sending it to the server.
To use the app name generator, install the `elfs` rock from Moonrocks.
This change makes Dokku start up the new container, run a set of checks
against it, and only switch traffic over to the new containers if all
checks complete successfully. No requests are dropped during the switch
over.
To specify checks, add a CHECKS file to the root of your project
directory. This is a text file with one line per check. Empty lines and
lines starting with # are ignored.
A check is a relative URL and may be followed by expected content from
the page, for example:
/about Our Amazing Team
Even if you don’t use any checks, this change will prevent downtime
during switching from old to new container.
See: https://labnotes.org/zero-downtime-deploy-with-dokku/
-`docker run -ti gliderlabs/herokuish:latest herokuish version`:
-`dokku version`:
-`dokku plugin`:
-`docker inspect CONTAINER_ID` (if applicable):
(BEWARE: `docker inspect` will print environment variables for some commands, be sure you're not exposing any sensitive information when posting issues. You may replace these values with XXXXXXX):
- Link to the exact repository being deployed (if possible/applicable):
- If a deploy is failing or behaving unexpectedly:
- Application name
- The type of application being deployed (node, php, python, ruby, etc.)
- If using buildpacks, which custom buildpacks are in use
- If using a `Dockerfile`, the contents of that file
- If it exists, the contents of your `Procfile`.
- Output of failing dokku commands after running `dokku trace on`
(BEWARE: `trace on` will print environment variables for some commands, be sure you're not exposing any sensitive information when posting issues. You may replace these values with XXXXXXX):
Assumes Ubuntu 13 or 12.04 x64 right now. Ideally have a domain ready to point to your host. It's designed for and is probably
best to use a fresh VM. The bootstrapper will install everything it needs.
**Note: There are known issues with docker and Ubuntu 13.10 ([1](https://github.com/dotcloud/docker/issues/1300), [2](https://github.com/dotcloud/docker/issues/1906)) - use of 12.04 is recommended until these issues are resolved.**
- A fresh VM running `Debian 8.2 x64`, `Ubuntu 14.04 x64`, or `Ubuntu 16.04 x64`
## Installing
### Stable
To install the latest stable release, you can run the following commands as a user that has access to `sudo`:
This may take around 5 minutes. Certainly better than the several hours it takes to bootstrap Cloud Foundry.
You may also wish to take a look at the [advanced installation](http://progrium.viewdocs.io/dokku/advanced-installation) document for additional installation options.
## Configuring
Set up a domain and a wildcard domain pointing to that host. Make sure `/home/dokku/VHOST` is set to this domain. By default it's set to whatever hostname the host has. This file is only created if the hostname can be resolved by dig (`dig +short $(hostname -f)`). Otherwise you have to create the file manually and set it to your preferred domain. If this file still is not present when you push your app, dokku will publish the app with a port number (i.e. `http://example.com:49154` - note the missing subdomain).
You'll have to add a public key associated with a username by doing something like this from your local machine:
Now you can deploy apps on your Dokku. Let's deploy the [Heroku Node.js sample app](https://github.com/heroku/node-js-sample). All you have to do is add a remote to name the app. It's created on-the-fly.
Dokku only supports deploying from its master branch, so if you'd like to deploy a different local branch use: ```git push progrium <local branch>:master```
Right now Buildstep supports buildpacks for Node.js, Ruby, Python, [and more](https://github.com/progrium/buildstep#supported-buildpacks). It's not hard to add more, [go add more](https://github.com/progrium/buildstep#adding-buildpacks)!
Please check the documentation for your particular build pack as you may need to include configuration files (such as a Procfile) in your project root.
## Remote commands
Dokku commands can be run over ssh. Anywhere you would run `dokku <command>`, just run `ssh -t dokku@progriumapp.com <command>`
The `-t` is used to request a pty. It is highly recommended to do so.
To avoid the need to type the `-t` option each time, simply create/modify a section in the `.ssh/config` on the client side, as follows :
Host progriumapp.com
RequestTTY yes
## Run a command in the app environment
It's possible to run commands in the environment of the deployed application:
$ dokku run node-js-app ls -alh
$ dokku run <app> <cmd>
## Plugins
Dokku itself is built out of plugins. Checkout the wiki for information about
creating your own and a list of existing plugins:
https://github.com/progrium/dokku/wiki/Plugins
## Removing a deployed app
SSH onto the server, then execute:
$ dokku delete myapp
## Environment variable management
Typically an application will require some environment variables to run properly. Environment variables may contain private data, such as passwords or API keys, so it is not recommend to store them in your application's repository.
The `config` plugin provides the following commands to manage your variables:
```
config <app> - display the config vars for an app
config:get <app> KEY - display a config value for an app
config:set <app> KEY1=VALUE1 [KEY2=VALUE2 ...] - set one or more config vars
config:unset <app> KEY1 [KEY2 ...] - unset one or more config vars
```
## TLS/SPDY support
Dokku provides easy TLS/SPDY support out of the box. This can be done app-by-app or for all subdomains at once. Note that whenever TLS support is enabled SPDY is also enabled.
### Per App
To enable TLS connection to to one of your applications, copy or symlink the `.crt`/`.pem` and `.key` files into the application's `/home/dokku/:app/tls` folder (create this folder if it doesn't exist) as `server.crt` and `server.key` respectively.
Redeployment of the application will be needed to apply TLS configuration. Once it is redeployed, the application will be accessible by `https://` (redirection from `http://` is applied as well).
### All Subdomains
To enable TLS connections for all your applications at once you will need a wildcard TLS certificate.
To enable TLS across all apps, copy or symlink the `.crt`/`.pem` and `.key` files into the `/home/dokku/tls` folder (create this folder if it doesn't exist) as `server.crt` and `server.key` respectively. Then, enable the certificates by editing `/etc/nginx/conf.d/dokku.conf` and uncommenting these two lines (remove the #):
ssl_certificate /home/dokku/tls/server.crt;
ssl_certificate_key /home/dokku/tls/server.key;
The nginx configuration will need to be reloaded in order for the updated TLS configuration to be applied. This can be done either via the init system or by re-deploying the application. Once TLS is enabled, the application will be accessible by `https://` (redirection from `http://` is applied as well).
**Note**: TLS will not be enabled unless the application's VHOST matches the certificate's name. (i.e. if you have a cert for *.example.com TLS won't be enabled for something.example.org or example.net)
### HSTS Header
The [HSTS header](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) is an HTTP header that can inform browsers that all requests to a given site should be made via HTTPS. dokku does not, by default, enable this header. It is thus left up to you, the user, to enable it for your site.
Beware that if you enable the header and a subsequent deploy of your application results in an HTTP deploy (for whatever reason), the way the header works means that a browser will not attempt to request the HTTP version of your site if the HTTPS version fails.
## Upgrading
Dokku is in active development. You can update the deployment step and the build step separately.
**Note**: If you are upgrading from a revision prior to [27d4bc8c3c](https://github.com/progrium/dokku/commit/27d4bc8c3c19fe580ef3e65f2f85b85101cd83e4), follow the instructions in [this wiki entry](https://github.com/progrium/dokku/wiki/Migrating-to-Dokku-0.2.0).
To update the deploy step (this is updated less frequently):
$ cd ~/dokku
$ git pull origin master
$ sudo make install
Nothing needs to be restarted. Changes will take effect on the next push / deployment.
This will build a fresh Ubuntu Quantal image, install a number of packages, and
eventually replace the Docker image for buildstep.
Full documentation - including advanced installation docs - are available online at [docs](http://dokku.viewdocs.io/dokku/)
## Support
You can use [Github Issues](https://github.com/progrium/dokku/issues), check [Troubleshooting](https://github.com/progrium/dokku/wiki/Troubleshooting) on the wiki, or join us on [freenode in #dokku](https://webchat.freenode.net/?channels=%23dokku)
You can use [Github Issues](https://github.com/dokku/dokku/issues), check [Troubleshooting](http://dokku.viewdocs.io/dokku/getting-started/troubleshooting/) in the documentation, or join us on [freenode in #dokku](https://webchat.freenode.net/?channels=%23dokku)
## Components
## Contribution
* [Docker](https://github.com/dotcloud/docker) - Container runtime and manager
* [pluginhook](https://github.com/progrium/pluginhook) - Shell based plugins and hooks
* [sshcommand](https://github.com/progrium/sshcommand) - Fixed commands over SSH
After checking [Github Issues](https://github.com/dokku/dokku/issues), the [Troubleshooting Guide](http://dokku.viewdocs.io/dokku/getting-started/troubleshooting/) or having a chat with us on [freenode in #dokku](https://webchat.freenode.net/?channels=%23dokku), feel free to fork and create a Pull Request.
Looking to keep codebase as simple and hackable as possible, so try to keep your line count down.
While we may not merge your PR as is, they serve to start conversations and improve the general dokku experience for all users.
## Things this project won't do
## Sponsors
* **Multi-host.** Not a huge leap, but this isn't the project for it. Have a look at [Flynn](https://flynn.io/).
* **Multitenancy.** It's ready for it, but again, have a look at [Flynn](https://flynn.io/).
* **Client app.** Given the constraints, running commands remotely via SSH is fine.
See our list of past sponsors in the [SPONSORS](https://github.com/dokku/dokku/blob/master/SPONSORS.md) file.
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/dokku#sponsor)]
<label><input id="vhost" name="vhost" type="checkbox" value="true"> Use <abbr title="Nginx will be run on port 80 and backend to your apps based on hostname">virtualhost naming</abbr> for apps</label>
<label><input id="vhost" name="vhost" type="checkbox" value="true"> Use <abbr title="Nginx will be run on port 80 and backend to your apps based on hostname">virtualhost naming</abbr> for apps</label>
> The backup plugin was deprecated in 0.4.x, below are backup recommendations for 0.5.x and later.
## Backup and Migration Tutorial
Because Dokku is git based, rebuilding a deployed app is as easy as pushing from git. You can push to a new server by updating the dokku remote in you local app's repo.
```shell
git remote rm dokku
git remote add dokku dokku@[dokku.me:dokku.me]
git push dokku [master]
```
## Databases
Some plugins, like the official [dokku-postgres](https://github.com/dokku/dokku-postgres) plugin, have built-in commands that allow non-volatile data be exported and imported.
For [dokku-postgres](https://github.com/dokku/dokku-postgres), use:
```shell
dokku postgres:export [db_name] > [db_name].dump
dokku postgres:import [db_name] < [db_name].dump
```
## Volumes and Static Assets
Dokku doesn't enforce a [300mb](https://devcenter.heroku.com/articles/slug-compiler#slug-size) limit on apps, but it's best practice to keep binary assets outside of git. Since containers are considered volatile in Dokku, external stores like s3 or storage mounts should be used for non-volatile items like user uploads. The dokku storage core plugin can be used to mount local directories / volumes inside the docker container.
See the [persistent storage documentation](/dokku/advanced-usage/persistent-storage/) for more details.
## Disaster Recovery
The best plan for disaster recovery is to always keep multiple (remote) copies of your local repo, static assets and periodic database dumps. In case of an emergency when your git repo and backups are completely lost, you can recover the last pushed copy from your remote dokku server (assuming you still have the ssh key).
Sometimes you need to run a command on at deployment time, but before an app is completely deployed.
Common use cases include:
* Checking a database is initialised
* Running database migrations
* Any commands required to set up the server (e.g. something like a Django `collectstatic`)
## `app.json` and `scripts.dokku`
Dokku accomplishes this by using an `app.json` file. The format in use is similar to format of Heroku's [app.json](https://devcenter.heroku.com/articles/app-json-schema).
However, dokku currently only supports the nodes `scripts.dokku.predeploy` and `scripts.dokku.postdeploy`.
For buildpack apps, simply place an `app.json` file in the root of your repository.
For dockerfile apps, place `app.json` in the configured `WORKDIR` directory; otherwise dokku defaults to the buildpack app behavior of looking in `/app`.
>NOTE: postdeploy changes are *NOT* committed to the app image.
### Example app.json
```json
{
"name":"barebones nodejs",
"description":"A barebones Node.js app using Express 4.",
dokku docker-options:add myapp run "-v /home/dokku/logs/myapp:/app/logs"
```
> Note: When [mounting a host directory](https://docs.docker.com/engine/reference/run/#volume-shared-filesystems) in a Dokku app you should first create that directory as user `dokku` and then mount the directory under `/app` in the container using `docker-options` as above. Otherwise the app will lack write permission in the directory.
### Output Docker options
```shell
dokku docker-options myapp
```
```
Deploy options:
-v /home/dokku/logs/myapp:/app/logs
Run options:
-v /home/dokku/logs/myapp:/app/logs
```
### Remove a Docker option
```shell
dokku docker-options:remove myapp run "-v /home/dokku/logs/myapp:/app/logs"
```
## Advanced usage
In your applications folder `/home/dokku/app_name` create a file called `DOCKER_OPTIONS_RUN` (or `DOCKER_OPTIONS_BUILD` or `DOCKER_OPTIONS_DEPLOY`).
Inside this file list one Docker option per line. For example:
```shell
--link container_name:alias
-v /host/path:/container/path
-v /another/container/path
```
The above example will result in the following options being passed to Docker during `dokku run`:
Docker provides an _events_ command to show system's real time events. Likewise, Dokku can record events as syslog entries and also provides a plugin to display the last ones.
```
events [-t] # Show the last events (-t follows)
events:list # List logged events
events:on # Enable events logger
events:off # Disable events logger
```
## Usage
Enable the plugin:
```shell
dokku events:on
```
```
Enabling dokku events logger
```
Dokku will then write log entries to `/var/log/syslog` as well as a Dokku-specific logs sub-directory `/var/log/dokku/events.log`, which can be easily displayed with the command `dokku events`:
The preferred method to mount external containers to a dokku managed container, is to use the dokku storage plugin.
```
storage:list <app> # List bind mounts for app's container(s) (host:container)
storage:mount <app> <host-dir:container-dir> # Create a new bind mount
storage:unmount <app> <host-dir:container-dir> # Remove an existing bind mount
```
## Ideology and Background
The storage plugin requires explicit paths on the host side. This is intentional to ensure that new users avoid running into unexpected results with implicit paths that may not exist (a feature deprecate in [Docker 1.9.0](https://github.com/docker/docker/releases/tag/v1.9.0])). The container directory is created for the mount point in the container. Any existing directory contents are not accessible after a mount is added to the container. Dokku creates a new directory `/var/lib/dokku/data/storage` during installation, it's the general consensus that new users should use this directory. Mounts are only available at run and deploy times, you must redeploy (restart) an app to mount or unmount to an existing app's container.
## Usage
This example demonstrates how to mount the recommended directory to `/storage` inside the container:
Dokku will then mount the shared contents of `/var/lib/dokku/data/storage` to `/storage` inside the container.
A more complete workflow may require making a custom directory for your application and mounting it within your `/app/storage` directory instead. The mount point is *not* relative to your application's working directory, and is instead relative to the root of the container.
```shell
# creating storage for the app 'ruby-rails-sample'
You can mount one or more directories as desired by following the above pattern.
## Use Cases
### Persistent storage
Dokku is powered by Docker containers, which recommends in their [best practices](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#containers-should-be-ephemeral) that containers be treated as ephemeral. In order to manage persistent storage for web applications, like user uploads or large binary assets like images, a directory outside the container should be mounted.
### Shared storage between containers
When scaling your app, you may require a common location to access shared assets between containers, a storage mount can be used in this situation.
### Shared storage across environments
Your app may be used in a cluster that requires containers or resources not running on the same host access your data. Mounting a shared file service (like S3FS or EFS) inside your container will give you great flexibility.
### Backing up
Your app may have services that are running in memory and need to be backed up locally (like a key store). Mount a non ephemeral storage mount will allow backups that are not lost when the app is shut down.
### Build phase
By default, dokku will only bind storage mounts during the deploy and run phases. Under certain conditions, one might want to bind a storage mount during the build phase. This can be accomplished by using the `docker-options` plugin directly.
You cannot use mounted volumes during the build phase of a Dockerfile deploy. This is because Docker does not support volumes when executing `docker build`.
> Note: **This can cause data loss** if you bind a mount under `/app` in buildpack apps as herokuish will attempt to remove the original app path during the build phase.
## Docker-Options Note
The storage plugin is compatible with storage mounts created with the docker-options. The storage plugin will only list mounts from the deploy phase.
> New as of 0.7.1
## Application User and Persistent Storage file ownership (buildpack apps only)
By default, dokku will execute your buildpack application processes as the `herokuishuser` user. You may override this by setting the `DOKKU_APP_USER` config variable.
> NOTE: this user must exist in your herokuish image.
Additionally, dokku will ensure your storage mounts are owned by either `herokuishuser` or the overridden value you have set in `DOKKU_APP_USER`.
plugin:disable <name> # Disable an installed plugin (third-party only)
plugin:enable <name> # Enable a previously disabled plugin
plugin:install [--core|git-url [--committish tag|branch|commit|--name custom-plugin-name]] # Optionally download git-url (with custom tag/committish) & run install trigger for active plugins (or only core ones)
plugin:install-dependencies [--core] # Run install-dependencies trigger for active plugins (or only core ones)
plugin:uninstall <name> # Uninstall a plugin (third-party only)
plugin:update [name [committish]] # Optionally update named plugin from git (with custom tag/committish) & run update trigger for active plugins
```
```shell
# for 0.3.x
cd /var/lib/dokku/plugins
git clone <git url>
dokku plugins-install
```
> These commands require `root` permissions as the `install` and `install-dependencies` plugin triggers may utilize commands such as `apt-get`. For non-core plugins, please inspect those plugins before running the following command as `root` user.
## Usage
You can list all installed plugins using the `plugin` command:
```shell
dokku plugin
```
```
plugn: dev
00_dokku-standard 0.7.1 enabled dokku core standard plugin
Installing a plugin is easy as well using the `plugin:install` command. This command will also trigger the `install` pluginhook on all existing plugins.
You can also uninstall a third-party plugin using the `plugin:uninstall` command:
```shell
dokku plugin:uninstall postgres
```
```
-----> Plugin postgres uninstalled
```
Enabling or disabling a plugin can also be useful in cases where you are debugging whether a third-party plugin is causing issues in your Dokku installation:
```shell
```shell
dokku plugin:disable postgres
```
```
-----> Plugin postgres disabled
```
```shell
dokku plugin:enable postgres
```
```
-----> Plugin postgres enabled
```
Finally, you can update an installed third-party plugin. This should be done after any upgrades of Dokku as there may be changes in the internal api that require an update of how the plugin interfaces with Dokku.
proxy:ports <app> # List proxy port mappings for app
proxy:ports-add <app> <scheme>:<host-port>:<container-port> [<scheme>:<host-port>:<container-port>...] # Set proxy port mappings for app
proxy:ports-clear <app> # Clear all proxy port mappings for app
proxy:ports-remove <app> <host-port> [<host-port>|<scheme>:<host-port>:<container-port>...] # Unset proxy port mappings for app
proxy:set <app> <proxy-type> # Set proxy type for app
```
In Dokku 0.5.0, port proxying was decoupled from the `nginx-vhosts` plugin into the proxy plugin. Dokku 0.6.0 introduced the ability to map host ports to specific container ports. In the future this will allow other proxy software - such as HAProxy or Caddy - to be used in place of nginx.
## Container network interface binding
> New as of 0.5.0
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.
> If a proxy is disabled, dokku will bind your container's port to a random port on the host for every deploy, e.g. `0.0.0.0:32771->5000/tcp`.
By way of example, in the default case, each container is bound to the docker interface:
```shell
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
```
As such, the container's IP address will be an internal IP, and thus it is only accessible on the host itself:
However, you can disable the internal proxying via the `proxy:disable` command so that it will listen on the host's IP address:
```shell
dokku proxy:disable node-js-app
# container bound to all interfaces
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
```
## Proxy port mapping
> New as of 0.6.0
You can now configure `host -> container` port mappings with the `proxy:ports-*` commands. This mapping is currently supported by the built-in nginx-vhosts plugin.
To inspect the port mapping for a given application, use the `proxy:ports` command:
```shell
dokku proxy:ports node-js-app
```
```
-----> Port mappings for node-js-app
-----> scheme host port container port
http 80 5000
```
The above application is listening on the host's port `80`, which we can test via curl:
```shell
curl http://node-js-app.dokku.me
```
```
Hello World!
```
There are cases where we may wish for the service to be listening on more than one port, such as port 8080. Normally, this would not be possible:
```shell
curl http://node-js-app.dokku.me:8080
```
```
curl: (7) Failed to connect to node-js-app.dokku.me port 8080: Connection refused
```
However, we can use the `proxy:ports-add` command to add a second external port mapping - `8080` - to our application's port `5000`.
We can now test that port 80 still responds properly:
```shell
curl http://node-js-app.dokku.me
```
```
Hello World!
```
And our new listening port of `8080` also works:
```shell
curl http://node-js-app.dokku.me:8080
```
```
Hello World!
```
You can also remove a port mapping that is no longer necessary:
```shell
dokku proxy:ports-remove node-js-app http:80:5000
```
By default, buildpack apps and dockerfile apps **without** explicitly exposed ports (i.e. using the `EXPOSE` directive) will be configured with a listener on port `80` (and additionally a listener on 443 if ssl is enabled) that will proxy to the application container on port `5000`. Dockerfile apps **with** explicitly exposed ports will be configured with a listener on each exposed port and will proxy to that same port of the deployed application container.
> Note: This default behavior **will not** be automatically changed on subsequent pushes and must be manipulated with the `proxy:ports-*` syntax detailed above.
## Proxy Port Scheme
The proxy port scheme is as follows:
-`SCHEME:HOST_PORT:CONTAINER_PORT`
The scheme metadata can be used by proxy implementations in order to properly handle proxying of requests. For example, the built-in `nginx-vhosts` proxy implementation supports both the `http` and `https` schemes.
Developers of proxy implementations are encouraged to use whatever schemes make the most sense, and ignore configurations which they do not support. For instance, a `udp` proxy implementation can safely ignore `http` and `https` port mappings.
To change the proxy implementation in use for an application, use the `proxy:set` command:
repo:gc <app> # Runs 'git gc --agressive' against the application's repo
repo:purge-cache <app> # Deletes the contents of the build cache stored in the repository
```
The repository plugin is meant to allow users to perform management commands against a repository.
## Git Garbage Collection
This will run a git gc --agressive against the applications repo. This is performed on the Dokku host, and not within an application container.
```shell
dokku repo:gc node-js-app
```
```
Counting objects: 396, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (365/365), done.
Writing objects: 100% (396/396), done.
Total 396 (delta 79), reused 315 (delta 0)
```
## Clearing Application cache
Building containers with buildpacks currently results in a persistent `cache` directory between deploys. If you need to clear this cache directory for any reason, you may do so by running the following shell command:
- You can now **actually** disable zero-downtime deployments per-app and per-process-type
- Some config variables have been moved around
-`DOKKU_CHECKS_ENABLED` has been migrated to `DOKKU_CHECKS_SKIPPED`
-`DOKKU_CHECKS_DISABLED` is now a thing
- The values for the above can be a comma-separated list of process-types or the literal string `_all_`
- See the [updated `checks`](/dokku/deployment/zero-downtime-deploys/) docs for more info
## proxy port mapping
- You can now configure host -> container proxy port mappings
- The UI is handled by the [proxy](/dokku/advanced-usage/proxy-management/) interface plugin by setting the `DOKKU_PROXY_PORT_MAP` config variable in the format of `scheme:host-port:container-port`. The default `nginx-vhosts` proxy plugin supports both the `http` and `https` schemes.
- Default port mappings
- buildpack apps will be set to `http:80:5000` and will also include `https:443:5000` if SSL is enabled.
- dockerfile apps with explicitly exposed ports (i.e. using the `EXPOSE` directive) will be configured with a listener on each exposed port that proxies to the same port of the deployed application container.
- You may override this behavior with the [`proxy:ports-*` commands](/dokku/advanced-usage/proxy-management/) or by directly setting `DOKKU_PROXY_PORT_MAP` with the `config:set` command
- dockerfile apps without explicitly exposed ports will behave the same as a buildpack app
- NOTE: These defaults **are not** automatically changed on subsequent pushes and must be manipulated with the aforementioned commands
## calling the dokku binary
- Plugins should *not* call the dokku binary directly. Clients using the `--app` argument are potentially broken, amongst others, when doing so. Instead, please source the `functions` file for a given plugin when attempting to call dokku internal functions. As a result, the following dokku commands are no longer publicly exposed:
We should now properly handle file ownership for mounted directories. This was enhanced in 0.7.1. See the [persistent storage documentation](/dokku/advanced-usage/persistent-storage/) for more details.
## Restart Policies
If you previously managed container restart policies via docker-options, these can now be managed natively via the built-in `ps` plugin. There is no migration necessary. See the [restart policy documentation](/dokku/deployment/process-management/#restart-policies) for more details.
## SSH Keys
Dokku now has an `ssh-keys` plugin that can be used to manage ssh keys for the `dokku` user on the host operating system. See the [user management documentation](/dokku/deployment/user-management/) for more details.
Given the constraints, running dokku commands remotely via SSH is fine. For certain configurations, the extra complication of manually invoking ssh can be a burden.
While dokku does not yet have an official client, there are a multitude of ways in which you can interact with your dokku installation. The easiest is to use the **bash** client, though you may wish to use another.
## (bash, zsh, etc.) `dokku_client.sh`
Of all methods, this is the *most* official method of interacting with your dokku installation. It is a bash script that interacts with a remote dokku installation via ssh. It is available in `contrib/dokku_client.sh` in the root of the dokku repository.
To install, simply clone the dokku repository down and add the `dokku` alias pointing at the script:
```shell
git clone git@github.com:dokku/dokku.git ~/.dokku
# optional: make sure that the dokku_client.sh version matches your dokku version
cd ~/.dokku
git checkout <tag/branch>
# add the following to either your
# .bashrc, .bash_profile, or .profile file
aliasdokku='$HOME/.dokku/contrib/dokku_client.sh'
```
Alternatively, if using another shell such as **zsh**, create an alias command which invokes the script using **bash**:
```shell
# zsh: add the following to either .zshenv or .zshrc
# fish: add the following to ~/.config/fish/config.fish
alias dokku 'bash $HOME/.dokku/contrib/dokku_client.sh'
# csh: add the following to .cshrc
alias dokku 'bash $HOME/.dokku/contrib/dokku_client.sh'
```
Configure the `DOKKU_HOST` environment variable or run `dokku` from a repository with a git remote named dokku pointed at your dokku host in order to use the script as normal.
You can also configure a `DOKKU_PORT` environment variable if you are running ssh on a non-standard port. This defaults to `22`.
## (nodejs) dokku-toolbelt
Dokku-toolbelt is a node-based cli wrapper that proxies requests to the dokku command running on remote hosts. You can install it via the following shell command (assuming you have nodejs and npm installed):
```shell
npm install -g dokku-toolbelt
```
See [documentation here](https://www.npmjs.com/package/dokku-toolbelt) for more information.
## (python) dokku-client
dokku-client is an extensible python-based cli wrapper for remote dokku hosts. You can install it via the following shell command (assuming you have python and pip installed):
```shell
pip install dokku-client
```
See [documentation here](https://github.com/adamcharnock/dokku-client) for more information.
## (ruby) Dokku CLI
Dokku CLI is a rubygem that acts as a client for your dokku installation. You can install it via the following shell command (assuming you have ruby and rubygems installed):
```shell
gem install dokku-cli
```
See [documentation here](https://github.com/SebastianSzturo/dokku-cli) for more information.
## (ruby) DokkuClient
DokkuClient is another rubygem that acts as a client for your dokku installation with built-in support for certain external plugins. You can install it via the following shell command (assuming you have ruby and rubygems installed):
```shell
gem install dokku_client
```
See [documentation here](https://github.com/netguru/dokku_client) for more information.
## (ruby) Dokkufy
Dokkufy is a rubygem that handles automation of certain tasks, such as dokku setup, plugin installation, etc. You can install it via the following shell command (assuming you have ruby and rubygems installed):
```shell
gem install dokkufy
```
See [documentation here](https://github.com/cbetta/dokkufy) for more information.
## (ruby) Dockland
Dockland is a rubygem that acts as a client for your dokku installation. You can install it via the following shell command (assuming you have ruby and rubygems installed):
```shell
gem install dockland
```
See [documentation here](https://github.com/uetchy/dockland) for more information.
Dokku itself is built out of plugins and uses [plugn](https://github.com/dokku/plugn) for its plugin system. In essence a plugin is a collection of scripts that will be run based on naming convention.
Let's take a quick look at the current dokku nginx plugin that's shipped with dokku by default.
nginx-vhosts/
├── plugin.toml # plugin metadata
├── commands # contains additional commands
├── install # runs on dokku installation
└── post-deploy # runs after an app is deployed
## Installing a plugin
[See the plugin management documentation](/dokku/advanced-usage/plugin-management/).
## Creating your own plugin
[See the full documentation](/dokku/development/plugin-creation/).
## Official Plugins (Beta)
The following plugins are available and provided by dokku maintainers. Where noted, these plugins should be considered beta software and may not have been used as thoroughly as community plugins. Please file issues against their respective issue trackers.
<sup>1</sup> On Heroku similar functionality is offered by the [heroku-labs pipeline feature](https://devcenter.heroku.com/articles/labs-pipelines), which allows you to promote builds across multiple environments (staging -> production)
<sup>2</sup> Extends app.json support to include creating volumes and creating / linking databases on push
<sup>3</sup> Adds the possibility to add SSH deployment keys to receive private hosted packages
<sup>4</sup> Adds the ability to add custom hosts to the containers known_hosts file to be able to ssh them easily (useful with deployment keys)
<sup>1</sup> Forked from [jezdez/dokku-elasticsearch-plugin](https://github.com/jezdez/dokku-elasticsearch-plugin): uses Elasticsearch 1.2 (instead of 0.90), doesn't depend on dokku-link, runs as elasticsearch user instead of root, and turns off multicast autodiscovery for use in a VPS environment.
### Deprecated Plugins
The following plugins have been removed as their functionality is now in Dokku Core.
| [PostgreSQL (single container)](https://github.com/jeffutter/dokku-postgresql-plugin) | [jeffutter][] | This plugin creates a single postgresql container that all your apps can use. Thus only one instance of postgresql running (good for servers without a ton of memory). |
| [RiakCS (single container)](https://github.com/jeffutter/dokku-riakcs-plugin) | [jeffutter][] | Incompatible with 0.2.0 (checked at [dccee02][]) |
There are many different DNS servers 'in the wild'. Some of the popular ones on Linux are BIND, dnsmasq, and pdns. Windows has its own built-in DNS server as well as Unbound, Posadis, and more. A full list of DNS packages can be found on Wikipedia under [Comparison of DNS Server Software](http://en.wikipedia.org/wiki/Comparison_of_DNS_server_software). In addition to the various DNS packages, there are tens of thousands of [Managed DNS Providers](http://en.wikipedia.org/wiki/List_of_managed_DNS_providers) out that all have different DNS interfaces.
## Focus
Because there are so many different DNS server packages out there as well as a tremendous number of Managed DNS Providers, we will focus on the concepts of DNS as well as providing examples in the 'BIND' format so you can adapt the information to your own server package or managed DNS provider.
## Assumptions
* We assume you have a passing familiarity with DNS. If not, you can read an [in-depth article](http://www.diaryofaninja.com/blog/2012/03/03/devops-dns-for-developers-ndash-now-therersquos-no-excuse-not-to-know) on DNS. But basically you need to know that DNS changes names (like example.tld) into addresses (like 127.0.0.1)
* We assume you already have a domain name registered and pointed to your favorite Managed DNS Provider or have your own BIND DNS server running.
* You have a server on the internet and are about to follow the instructions in the [README](https://github.com/dokku/dokku/blob/master/README.md) to get dokku installed. Don't do the install just yet though.
## Caching
Please remember that DNS relies heavily on _caching_. Changes you make to DNS could take anywhere from a few seconds to a few *days* to propagate. If you tried surfing to example.tld, then changed the IP address in DNS, it could be a while before your computer picks up on the changes.
## HELP!
Don't be afraid to ask if you need help. Create a [new issue](https://github.com/dokku/dokku/issues) and someone will be glad to assist you.
## Getting started
For the examples, we will use the domain name `example.tld` and the IP address `127.0.0.1`.
Dokku uses DNS to differentiate between apps on your dokku-powered server. If you are using the domain `example.tld`, and you have two apps `myapp1` and `myapp2`, dokku will make them available at `myapp1.example.tld` and `myapp2.example.tld`.
To get started, you need to know the IP address of your dokku server. Connect to it and run `ifconfig` or `ip addr` to see the IP address.
Now you have to make a decision about your domain. Do you want everything and anything at `example.tld` to go to your dokku server, or would you rather use a 'sub domain' for your dokku server?
In other words, do you want your applications on your dokku server accessible via `myapp.example.tld` or via `myapp.myserver.example.tld`?
#### Using a sub-domain (myapp.myserver.example.tld)
Using a sub-domain is easy. When you set up your server, you probably gave it a name like `myserver.example.tld`.
Go in to your Managed DNS provider and create an `A` record named `myserver` and put in the IP address you got from your server a few moments ago.
Hopefully your managed DNS provider also supports wildcards. Create a second `A` record named `*.myserver` along with the IP address you got from your server a few moments ago.
If you are using BIND, your zone file will look similar to this:
```
$ORIGIN example.tld
$TTL 5m
myserver IN A 127.0.0.1
*.myserver IN A 127.0.0.1
```
You can verify your changes in Linux by trying one or more of the following commands:
*`host myserver.example.tld`
*`dig -t A myserver.example.tld`
*`nslookup myserver.example.tld`
Now is a good time to remind you that the answers you get MAY BE CACHED.
If everything is working correctly, you should also be able to query for any other name under `myserver.example.tld` and get back the IP address of your server. Try:
*`host test.myserver.example.tld`
*`host xyzzy.myserver.example.tld`
If they all return your IP address, you have set DNS up properly for dokku. You should also be able to `ssh root@myserver.example.tld` and access your server.
Proceed with the setup instructions in the [installation documentation](/dokku/getting-started/installation/)
#### Using the root of your domain (myapp.example.tld)
This section is a work in progress. It is incomplete.
Using the 'root' of your domain is nearly identical to the previous example.
* hostname is under `example.tld`, still needs `A` record
* Need to modify `/home/dokku/HOSTNAME` and `/home/dokku/VHOST`
domains:add-global <domain> # Add global domain name
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:remove-global <domain> # Remove global domain name
```
> Adding a domain before deploying an application will result in port mappings being set. This may cause issues for applications that use non-standard ports, as those will not be automatically detected. Please refer to the [proxy documentation](/dokku/advanced-usage/proxy-management/) for information as to how to reconfigure the mappings.
## Customizing hostnames
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.tld` is set during initial configuration and stored in the `$DOKKU_ROOT/VHOST` file. It can then be modified with `dokku domains:add-global` and `dokku domains:remove-global`. This value is used as a default TLD for all applications on a host.
If a FQDN such as `other.tld` is used as the application name, the default `$DOKKU_ROOT/VHOST` will be ignored and the resulting vhost URL for that application will be `other.tld`. The exception to this rule being that if the FQDN has the same ending as the default vhost (such as `subdomain.domain.tld`), then the entire FQDN will be treated as a subdomain. The application will therefore be deployed at `subdomain.domain.tld.domain.tld`.
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:
```shell
#!/usr/bin/env bash
set -eo pipefail;[[$DOKKU_TRACE]]&&set -x
APP="$1";SUBDOMAIN="$2";VHOST="$3"
NEW_SUBDOMAIN=`echo$SUBDOMAIN| rev`
echo"$NEW_SUBDOMAIN.$VHOST"
```
If the `nginx-hostname` has no output, the normal hostname algorithm will be executed.
## Disabling VHOSTS
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
# add a domain to an app
dokku domains:add myapp example.com
# list custom domains for app
dokku domains myapp
# clear all custom domains for app
dokku domains:clear myapp
# remove a custom domain from app
dokku domains:remove myapp example.com
```
## Default site
By default, dokku will route any received request with an unknown HOST header value to the lexicographically first site in the nginx config stack. If this is not the desired behavior, you may want to add the following configuration to the global nginx configuration. This will catch all unknown HOST header values and return a `410 Gone` response. You can replace the `return 410;` with `return 444;` which will cause nginx to not respond to requests that do not match known domains (connection refused).
```nginx
server{
listen80default_server;
listen[::]:80default_server;
server_name_;
return410;
log_not_foundoff;
}
```
You may also wish to use a separate vhost in your `/etc/nginx/sites-enabled` directory. To do so, create the vhost in that directory as `/etc/nginx/sites-enabled/00-default.conf`. You will also need to change two lines in the main `nginx.conf`:
```nginx
# Swap both conf.d include line and the sites-enabled include line. From:
include/etc/nginx/conf.d/*.conf;
include/etc/nginx/sites-enabled/*;
# to the following
include/etc/nginx/sites-enabled/*;
include/etc/nginx/conf.d/*.conf;
```
Alternatively, you may push an app to your dokku host with a name like "00-default". As long as it lists first in `ls /home/dokku/*/nginx.conf | head`, it will be used as the default nginx vhost.
Typically an application will require some configuration to run properly. Dokku supports application configuration via environment variables. Environment variables may contain private data, such as passwords or API keys, so it is not recommended to store them in your application's repository.
The `config` plugin provides the following commands to manage your variables:
```
config (<app>|--global) Display all global or app-specific config vars
config:get (<app>|--global) KEY Display a global or app-specific config value
config:set (<app>|--global) KEY1=VALUE1 [KEY2=VALUE2 ...] Set one or more config vars
config:unset (<app>|--global) KEY1 [KEY2 ...] Unset one or more config vars
```
The variables are available both at run time and during the application build/compilation step for buildpack-based deploys. For security reasons - and as per [docker recommendations](https://github.com/docker/docker/issues/13490) - Dockerfile-based deploys have variables available *only* during runtime, as noted in [this issue](https://github.com/dokku/dokku/issues/1860).
For buildpack deploys, Dokku will create a `/app/.env` file that can be used for legacy buildpacks. Note that this is *not* updated when `config:set` or `config:unset` is called, and is only written during a `deploy` or `ps:rebuild`. Developers are encouraged to instead read from the application environment directly, as the proper values will be available then.
> Note: Global `ENV` files are sourced before app-specific `ENV` files. This means that app-specific variables will take precedence over global variables. Configuring your global `ENV` file is manual, and should be considered potentially dangerous as configuration applies to all applications.
You can set multiple environment variables at once:
When setting or unsetting environment variables, you may wish to avoid an application restart. This is useful when developing plugins or when setting multiple environment variables in a scripted manner. To do so, use the `--no-restart` flag:
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:error-logs <app> [-t] # Show the nginx error logs for an application (-t follows)
```
## Customizing the nginx configuration
> New as of 0.5.0
Dokku uses a templating library by the name of [sigil](https://github.com/gliderlabs/sigil) to generate nginx configuration for each app. You may also provide a custom template for your application as follows:
- Copy the following example template to a file named `nginx.conf.sigil` and either:
- check it into the root of your app repo for buildpack applications
-`ADD` it to your dockerfile `WORKDIR`
- if your dockerfile has no `WORKDIR`, `ADD` it to the `/app` folder
> When using a custom `nginx.conf.sigil` file, depending upon your application configuration, you *may* be exposing the file externally. As this file is extracted before the container is run, you can, safely delete it in a custom `entrypoint.sh` configured in a Dockerfile `ENTRYPOINT`.
{{ .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
{{ .PROXY_PORT_MAP }} List of port mappings (same as `DOKKU_PROXY_PORT_MAP` config var)
{{ .PROXY_UPSTREAM_PORTS }} List of configured upstream ports (derived from `DOKKU_PROXY_PORT_MAP` config var)
{{ .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
```
> Note: Application config variables are available for use in custom templates. To do so, use the form of `{{ var "FOO" }}` to access a variable named `FOO`.
### Example HTTP to HTTPS Custom Template
Use case: a simple dockerfile app that includes `EXPOSE 80`
The example above uses additional configuration files directly on the dokku host. Unlike the `nginx.conf.sigil` file, these additional files will not be copied over from your application repo, and thus need to be placed in the `/home/dokku/myapp/nginx.conf.d/` directory manually.
## Domains plugin
See the [domain configuration documentation](/dokku/configuration/domains/).
## Customizing hostnames
See the [customizing hostnames documentation](/dokku/configuration/domains/#customizing-hostnames).
## Disabling VHOSTS
See the [disabling vhosts documentation](/dokku/configuration/domains/#disabling-vhosts).
## Default site
See the [default site documentation](/dokku/configuration/domains/#default-site).
## Running behind a load balancer
See the [load balancer documentation](/dokku/configuration/ssl/#running-behind-a-load-balancer).
## HSTS Header
See the [HSTS documentation](/dokku/configuration/ssl/#hsts-header).
## SSL Configuration
See the [ssl documentation](/dokku/configuration/ssl/).
## Disabling Nginx
See the [proxy documentation](/dokku/advanced-usage/proxy-management/).
## Managing Proxy Port mappings
See the [proxy documentation](/dokku/advanced-usage/proxy-management/#proxy-port-mapping).
Dokku supports SSL/TLS certificate inspection and CSR/Self-signed certificate generation via the `certs` plugin. Note that whenever SSL/TLS support is enabled SPDY is also enabled.
```
certs:add <app> CRT KEY # Add an ssl endpoint to an app. Can also import from a tarball on stdin.
certs:generate <app> DOMAIN # Generate a key and certificate signing request (and self-signed certificate)
certs:info <app> # Show certificate information for an ssl endpoint.
certs:remove <app> # Remove an SSL Endpoint from an app.
certs:update <app> CRT KEY # Update an SSL Endpoint on an app. Can also import from a tarball on stdin
```
```shell
# for 0.3.x
dokku nginx:import-ssl <app> < certs.tar
```
> Adding an ssl certificate before deploying an application will result in port mappings being updated. This may cause issues for applications that use non-standard ports, as those may not be automatically detected. Please refer to the [proxy documentation](/dokku/advanced-usage/proxy-management/) for information as to how to reconfigure the mappings.
## Per-application certificate management
Dokku provides built-in support for managing SSL certificates on a per-application basis. SSL is managed via nginx outside of application containers, and as such can be updated on-the-fly without rebuilding containers. At this time, applications only support a single SSL certificate at a time. To support multiple domains for a single application, wildcard certificate usage is encouraged.
### Certificate setting
The `certs:add` command can be used to push a `tar` containing a certificate `.crt` and `.key` file to a single application. The command should correctly handle cases where the `.crt` and `.key` are not named properly or are nested in a subdirectory of said `tar` file. You can import it as follows:
```shell
tar cvf cert-key.tar server.crt server.key
# replace APP with the name of your application
dokku certs:add <app> < cert-key.tar
```
> Note: If your `.crt` file came alongside a `.ca-bundle`, you'll want to concatenate those into a single `.crt` file before adding it to the `.tar`.
When an SSL certificate is associated to an application, the certificate will be associated with *all* domains currently associated with said application. Your certificate _should_ be associated with all of those domains, otherwise accessing the application will result in SSL errors. If you wish to remove one of the domains from the application, refer to the [domain configuration documentation](/dokku/configuration/domains/).
Note that with the default nginx template, requests will be redirected to the `https` version of the domain. If this is not the desired state of request resolution, you may customize the nginx template in use. For more details, see the [nginx documentation](/dokku/configuration/nginx/).
### Certificate generation
> Note: Using this method will create a self-signed certificate, which is only recommended for development or staging use, not production environments.
The `certs:generate` command will walk you through the correct `openssl` commands to create a key, csr and a self-signed cert for a given app/domain. We automatically put the self-signed cert in place as well as add the specified domain to the application configuration.
If you decide to obtain a CA signed certficate, you can import that certificate using the aformentioned `dokku certs:add` command.
### Certificate information
The `certs:info` command will simply inspect the install SSL cert and print out details. NOTE: The server-wide certificate will be inspect if installed and no app-specific certificate exists.
```shell
dokku certs:info node-js-app
```
```
-----> Fetching SSL Endpoint info for node-js-app...
The `certs:remove` command only works on app-specific certificates. It will `rm` the app-specific tls directory, rebuild the nginx configuration, and reload nginx.
## HSTS Header
The [HSTS header](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) is an HTTP header that can inform browsers that all requests to a given site should be made via HTTPS. dokku does not, by default, enable this header. It is thus left up to you, the user, to enable it for your site.
Beware that if you enable the header and a subsequent deploy of your application results in an HTTP deploy (for whatever reason), the way the header works means that a browser will not attempt to request the HTTP version of your site if the HTTPS version fails.
## Running behind a load balancer
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 using the following [nginx custom template](/dokku/configuration/nginx/#customizing-the-nginx-configuration)
1. All requests are terminated at the load balancer, and forwarded to Nginx
2. The load balancer is configured to send the `X-Forwarded-` headers (this may be off by default)
If it's possible to make HTTP/S requests directly to Nginx, bypassing the load balancer, or if the load balancer is not configured to set these headers, then it becomes possible for a client to set these headers to arbitrary values.
This could result in security issue, for example, if your application looks at the value of the `X-Forwarded-Proto` to determine if the request was made over HTTPS.
Once Dokku has been configured with at least one user, applications can be deployed via a `git push` command. To quickly see Dokku deployment in action, you can use the Heroku Ruby on Rails example app.
Create the application on the Dokku host. You will need to ssh onto the host to run this command.
```shell
# on your dokku host
dokku apps:create ruby-rails-sample
```
### Create the backing services
When you create a new app, Dokku by default *does not* provide any datastores such as MySQL or PostgreSQL. You will need to install plugins to handle that, but fortunately [Dokku has official plugins](/dokku/community/plugins/#official-plugins-beta) for common datastores. Our sample app requires a PostgreSQL service:
```shell
# on your dokku host
# install the postgres plugin
# plugin installation requires root, hence the user change
> You can link a single service to multiple applications or use one service per application.
### Deploy the app
Now you can deploy the `ruby-rails-sample` app to your Dokku server. All you have to do is add a remote to name the app. Applications are created on-the-fly on the Dokku server.
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Using rake 10.4.2
...
=====> Application deployed:
http://ruby-rails-sample.dokku.me
```
When the deploy finishes, the application's URL will be shown as seen above.
Dokku supports deploying applications via [Heroku buildpacks](https://devcenter.heroku.com/articles/buildpacks) with [Herokuish](https://github.com/gliderlabs/herokuish#buildpacks) or using a project's [dockerfile](https://docs.docker.com/reference/builder/).
### Deploying non-master branch
Dokku only supports deploying from its master branch, so if you'd like to deploy a different local branch use: ```git push dokku <local branch>:master```
You can also support pushing multiple branches using the [receive-branch](/dokku/development/plugin-triggers/#receive-branch) plugin trigger in a custom plugin.
### Skipping deployment
If you only want to rebuild and tag a container, you can skip the deployment phase by setting `$DOKKU_SKIP_DEPLOY` to `true` by running:
Dokku uses git locally (i.e. not a docker image) to build its own copy of your app repo, including submodules. This is done as the `dokku` user. Therefore, in order to deploy private git submodules, you'll need to drop your deploy key in `/home/dokku/.ssh/` and potentially add github.com (or your VCS host key) into `/home/dokku/.ssh/known_hosts`. The following test should help confirm you've done it correctly.
Dokku is, at its core, a docker container manager. Thus, it does not necessarily play well with other out-of-band processes interacting with the docker daemon. One thing to note as in [issue #1220](https://github.com/dokku/dokku/issues/1220), dokku executes a cleanup function prior to every deployment.
As of 0.5.x, this function removes all containers with the label `dokku` where the status is either `dead` or `exited`, as well as all `dangling` images. Previous versions would remove `dead` or `exited` containers, regardless of their label.
## Adding deploy users
See the [user management documentation](/dokku/deployment/user-management).
## Default vhost
See the [nginx documentation](/dokku/configuration/nginx/#default-site).
## Dockerfile deployment
See the [dockerfile documentation](/dokku/deployment/methods/dockerfiles/).
## Specifying a custom buildpack
See the [buildpack documentation](/dokku/deployment/methods/buildpacks/).
## Image tagging
See the [image tagging documentation](/dokku/deployment/methods/images/).
## Removing a deployed app
See the [application management documentation](/dokku/deployment/application-management/#removing-a-deployed-app).
### Renaming a deployed app
See the [application management documentation](/dokku/deployment/application-management/#renaming-a-deployed-app).
## Zero downtime deploy
See the [zero-downtime deploy documentation](/dokku/deployment/zero-downtime-deploys/).
You can easily list all available applications using the `apps` command:
```shell
dokku apps
```
```
=====> My Apps
node-js-app
python-app
```
Note that you can easily hide extra output from dokku commands by using the `--quiet` flag, which makes it easier to parse on the command-line.
```shell
dokku --quiet apps
```
```
node-js-app
python-app
```
## Manually creating an application
A common pattern for deploying applications to Dokku is to configure an application before deploying it. You can do so via the `apps:create` command:
```shell
dokku apps:create node-js-app
```
```
Creating node-js-app... done
```
Once created, you can configure the application as normal, and deploy the application whenever ready. This is useful for cases where you may wish to do any of the following kinds of tasks:
- configure domain names and ssl certificates
- create and link datastores
- set environment variables
## Removing a deployed app
In some cases, you may need to destroy an application, whether it is because the application is temporary or because it was misconfigured. In these cases, you can use the `apps:destroy` command. Performing any destructive actions in Dokku requires confirmation, and this command will ask for the name of the application being deleted before doing so.
```shell
dokku apps:destroy node-js-app
```
```
! WARNING: Potentially Destructive Action
! This command will destroy node-js-app (including all add-ons).
! To proceed, type "node-js-app"
> node-js-app
Destroying node-js-app (including all add-ons)
```
This will prompt you to verify the application's name before destroying it. You may also use the `--force` flag to circumvent this verification process:
```shell
dokku --force apps:destroy node-js-app
```
```
Destroying node-js-app (including all add-ons)
```
Destroying an application will unlink all linked services and destroy any config related to the application. Note that linked services will retain their data for later use (or removal).
## Renaming a deployed app
> New as of 0.4.7
You can rename a deployed app using the `apps:rename` command. Note that the application *must* have been deployed at least once, or the rename will not complete successfully:
```shell
dokku apps:rename node-js-app io-js-app
```
```
Destroying node-js-app (including all add-ons)
-----> Cleaning up...
-----> Building io-js-app from herokuish...
-----> Adding BUILD_ENV to build environment...
-----> Node.js app detected
-----> Creating runtime environment
...
=====> Application deployed:
http://io-js-app.ci.dokku.me
Renaming node-js-app to io-js-app... done
```
This will copy all of your app's contents into a new app directory with the name of your choice, delete your old app, then rebuild the new version of the app and deploy it. All of your config variables, including database urls, will be preserved.
Dokku normally defaults to using [heroku buildpacks](https://devcenter.heroku.com/articles/buildpacks) for deployment, though this may be overridden by committing a valid `Dockerfile` to the root of your repository and pushing the repository to your Dokku installation. To avoid this automatic `Dockerfile` deployment detection, you may do one of the following:
- Use `dokku config:set` to set the `BUILDPACK_URL` environment variable.
- Add `BUILDPACK_URL` to a committed `.env` file in the root of your repository.
- See the [environment variable documentation](/dokku/configuration/environment-variables/) for more details.
- Create a `.buildpacks` file in the root of your repository.
## Specifying a custom buildpack
In certain cases you may want to specify a custom buildpack. While dokku uses herokuish to support all the [official heroku buildpacks](https://github.com/gliderlabs/herokuish#buildpacks), it is possible that the buildpack detection does not work well for your application. As well, you may wish to use a custom buildpack to handle specific application logic.
To use a specific buildpack, you can run the following dokku command:
```shell
# replace APPwith the name of your application
# replace REPOSITORY_URL with your buildpack's url
dokku config:set APP BUILDPACK_URL=REPOSITORY_URL
# example: using a specific ruby buildpack version
Please check the documentation for your particular buildpack as you may need to include configuration files (such as a Procfile) in your project root.
## Using multiple buildpacks
You can only set a single buildpack using the `BUILDPACK_URL`, though there may be times when you wish to use multiple buildpacks. To do so, simply create a `.buildpacks` file in the base of your repository. This file should list all the buildpacks, one-per-line. For instance, if you wish to use both the `nodejs` and `ruby` buildpacks, your `.buildpacks` file should contain the following:
> Always remember to pin your buildpack versions when using the multi-buildpacks method, or you may find deploys changing your deployed environment.
You may also choose to set just a single buildpack in this file, though that is up to you.
Please check the documentation for your particular buildpack(s) as you may need to include configuration files (such as a Procfile) in your project root.
## Using a specific buildpack version
As Dokku pins all buildpacks via herokuish releases, there may be occasions where a local buildpack version is out of date. If you wish to use a more recent version of the buildpack, you may use any of the above methods to specify a buildpack **without** the git sha attached like so:
While many buildpacks have a default command that is run when a detected repository is pushed, it is possible to override this command via a Procfile. A Procfile can also be used to specify multiple commands, each of which is subject to process scaling. See the [process scaling documentation](/dokku/deployment/process-management/) for more details around scaling individual processes.
A Procfile is a file named `Procfile`. It should be named `Procfile` exactly, and not anything else. For example, `Procfile.txt` is not valid. The file should be a simple text file.
The file must be placed in the root directory of your application. It will not function if placed in a subdirectory.
If the file exists, it should not be empty, as doing so may result in a failed deploy.
The syntax for declaring a `Procfile` is as follows. Note that the format is one process type per line, with no duplicate process types.
```
<process type>: <command>
```
If, for example, you have multiple queue workers and wish to scale them separately, the following would be a valid way to work around the requirement of not duplicating process types:
The `web` process type holds some significance in that it is the only process type that is automatically scaled to `1` on the initial application deploy. See the [process scaling documentation](/dokku/deployment/process-management/) for more details around scaling individual processes.
## Curl Build Timeouts
Certain buildpacks may time out in retrieving dependencies via curl. This can happen when your network connection is poor or if there is significant network congestion. You may see a message similar to `gzip: stdin: unexpected end of file` after a curl command.
If you see output similar this when deploying , you may need to override the curl timeouts to increase the length of time allotted to those tasks. You can do so via the `config` plugin:
```shell
dokku config:set --global CURL_TIMEOUT=600
dokku config:set --global CURL_CONNECT_TIMEOUT=30
```
## Clearing buildpack cache
See the [repository management documentation](/dokku/advanced-usage/repository-management/#clearing-app-cache).
While Dokku normally defaults to using [heroku buildpacks](https://devcenter.heroku.com/articles/buildpacks) for deployment, you can also use docker's native `Dockerfile` system to define a container.
> Dockerfile support is considered a **Power User** feature. By using Dockerfile-based deployment, you agree that you will not have the same comfort as that enjoyed by Buildpack users, and Dokku features may work differently. Differences between the two systems will be documented here.
To use a dockerfiles for deployment, commit a valid `Dockerfile` to the root of your repository and push the repository to your Dokku installation. If this file is detected, Dokku will default to using it to construct containers **except** in the following two cases:
- The application has a `BUILDPACK_URL` environment variable set via the `dokku config:set` command or in a committed `.env` file. In this case, Dokku will use your specified buildpack.
- The application has a `.buildpacks` file in the root of the repository. In this case, Dokku will use your specified buildpack(s).
## Exposed ports
> Changed as of 0.5.0
Dokku will extract all tcp ports exposed using the `EXPOSE` directive (one port per line) and setup nginx to proxy the same port numbers to listen publicly. If you would like to change the exposed port, you should do so within your `Dockerfile` and app.
> Note: Nginx does not support proxying UDP. UDP ports can be exposed by disabling the nginx proxy with `dokku proxy:disable myapp`
If you do not explicitly `EXPOSE` a port in your `Dockerfile`, dokku will configure the nginx proxy to listen on port 80 (and 443 for TLS) and forward traffic to your app listening on port 5000 inside the container. Just like buildpack apps, you can also use the `$PORT` environment variable in your app to maintain portability.
When ports are exposed through the default nginx proxy, they are proxied externally as HTTP ports. At this time, in no case do we proxy plain TCP or UDP ports. If you would like to investigate alternative proxy methods, please refer to our [proxy management documentation](/dokku/advanced-usage/proxy-management/).
## Customizing the run command
By default no arguments are passed to `docker run` when deploying the container and the `CMD` or `ENTRYPOINT` defined in the `Dockerfile` are executed. You can take advantage of docker ability of overriding the `CMD` or passing parameters to your `ENTRYPOINT` setting `$DOKKU_DOCKERFILE_START_CMD`. Let's say for example you are deploying a base nodejs image, with the following `ENTRYPOINT`:
Setting `$DOKKU_DOCKERFILE_CACHE_BUILD` to `true` or `false` will enable or disable docker's image layer cache. Lastly, for more granular build control, you may also pass any `docker build` option to `docker`, by setting `$DOKKU_DOCKER_BUILD_OPTS`.
### Procfiles and Multiple Processes
> New as of 0.5.0
You can also customize the run command using a `Procfile`, much like you would on Heroku or
with a buildpack deployed app. The `Procfile` should contain one or more lines defining [process
types and associated commands](https://devcenter.heroku.com/articles/procfile#declaring-process-types).
When you deploy your app a Docker image will be built, the `Procfile` will be extracted from the image
(it must be in the folder defined in your `Dockerfile` as `WORKDIR` or `/app`) and the commands
in it will be passed to `docker run` to start your process(es). Here's an example `Procfile`:
```Procfile
web: bin/run-prod.sh
worker: bin/run-worker.sh
```
And `Dockerfile`:
```Dockerfile
FROMdebian:jessie
WORKDIR/app
COPY . ./
CMD["bin/run-dev.sh"]
```
When you deploy this app the `web` process will automatically be scaled to 1 and your Docker container
will be started basically using the command `docker run bin/run-prod.sh`. If you want to also run
a worker container for this app, you can run `dokku ps:scale worker=1` and a new container will be
started by running `docker run bin/run-worker.sh` (the actual `docker run` commands are a bit more
complex, but this is the basic idea). If you use an `ENTRYPOINT` in your `Dockerfile`, the lines
in your `Procfile` will be passed as arguments to the `ENTRYPOINT` script instead of being executed.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.