diff --git a/docs/appendices/0.30.0-migration-guide.md b/docs/appendices/0.30.0-migration-guide.md
index 2944c4c140d..76b719564b1 100644
--- a/docs/appendices/0.30.0-migration-guide.md
+++ b/docs/appendices/0.30.0-migration-guide.md
@@ -1,5 +1,10 @@
# 0.30.0 Migration Guide
+## Changes
+
+- The `port` management commands from the `proxy` plugin have been moved to a new `ports` plugin.
+- The `proxy-configure-ports` plugin trigger was renamed to `ports-configure`.
+
## Removals
- Support for [SPDY](https://en.wikipedia.org/wiki/SPDY) has been removed. No major browser supports it as of 2021. Custom `nginx.conf.sigil` templates referencing spdy-related variables will continue to build until the 1.0.0 release.
@@ -10,3 +15,7 @@
- `post-release-dockerfile`
- `post-release-pack`
- The ability to call `logs:failed` without specifying an app or `--all` flag has been removed. This was deprecated in 0.22.0. Please see the [logs:failed](/docs/deployment/logs.md#failed-deploy-logs).
+- `proxy#is_app_proxy_enabled()` is removed in favor of `plugn trigger proxy-is-enabled`.
+- `proxy#get_app_proxy_type()` is removed in favor of `plugn trigger proxy-type`.
+- The `DOKKU_NGINX_PORT` env var is no longer migrated to `DOKKU_PROXY_PORT` on upgrade.
+- The `DOKKU_NGINX_SSL_PORT` env var is no longer migrated to `DOKKU_PROXY_SSL_PORT` on upgrade.
\ No newline at end of file
diff --git a/docs/configuration/environment-variables.md b/docs/configuration/environment-variables.md
index c4498062fe8..e48084557dd 100644
--- a/docs/configuration/environment-variables.md
+++ b/docs/configuration/environment-variables.md
@@ -116,7 +116,7 @@ The following config variables have special meanings and can be set in a variety
| `DOKKU_PARALLEL_ARGUMENTS`. | none | `dokku config:set` | Allows passing custom arguments to parallel for `ps:*all` commands |
| `DOKKU_PROXY_PORT` | automatically assigned | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*`
`dokku config:set` | |
| `DOKKU_PROXY_SSL_PORT` | automatically assigned | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*`
`dokku config:set` | |
-| `DOKKU_PROXY_PORT_MAP` | automatically assigned | `dokku proxy:ports-add`
`dokku proxy:ports-remove`, `dokku proxy:ports-clear` | |
+| `DOKKU_PROXY_PORT_MAP` | automatically assigned | `dokku ports:add`
`dokku ports:remove`, `dokku ports:clear` | |
| `DOKKU_SKIP_ALL_CHECKS` | none | `dokku config:set` | |
| `DOKKU_SKIP_CLEANUP` | | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*` | When a deploy is triggered, if this is set to a non-empty value, then old docker containers and images will not be removed. |
| `DOKKU_SKIP_DEFAULT_CHECKS` | | `dokku config:set` | |
diff --git a/docs/configuration/ssl.md b/docs/configuration/ssl.md
index 5402154cf25..761982c74ae 100644
--- a/docs/configuration/ssl.md
+++ b/docs/configuration/ssl.md
@@ -165,4 +165,4 @@ dokku nginx:set node-js-app x-forwarded-ssl
### SSL Port Exposure
-When your app is served from port `80` then the `/home/dokku/APP/nginx.conf` file will automatically be updated to instruct nginx to respond to ssl on port 443 as a new cert is added. If your app uses a non-standard port (perhaps you have a dockerfile deploy exposing port `99999`) you may need to manually expose an ssl port via `dokku proxy:ports-add https:443:99999`.
+When your app is served from port `80` then the `/home/dokku/APP/nginx.conf` file will automatically be updated to instruct nginx to respond to ssl on port 443 as a new cert is added. If your app uses a non-standard port (perhaps you have a dockerfile deploy exposing port `99999`) you may need to manually expose an ssl port via `dokku ports:add https:443:99999`.
diff --git a/docs/deployment/builders/dockerfiles.md b/docs/deployment/builders/dockerfiles.md
index f6f0e5a71d3..52fc2fde482 100644
--- a/docs/deployment/builders/dockerfiles.md
+++ b/docs/deployment/builders/dockerfiles.md
@@ -29,7 +29,7 @@ Dokku will only select the `dockerfile` builder if both the `herokuish` and `pac
If an application was previously deployed via buildpacks, the following commands should be run before a Dockerfile deploy will succeed:
```shell
-dokku config:unset --no-restart node-js-app DOKKU_PROXY_PORT_MAP
+dokku ports:clear node-js-app
```
### Changing the `Dockerfile` location
diff --git a/docs/deployment/builders/herokuish-buildpacks.md b/docs/deployment/builders/herokuish-buildpacks.md
index 31b9976b6a3..d917244947e 100644
--- a/docs/deployment/builders/herokuish-buildpacks.md
+++ b/docs/deployment/builders/herokuish-buildpacks.md
@@ -301,7 +301,7 @@ false
If an application was previously deployed via Dockerfile, the following commands should be run before a buildpack deploy will succeed:
```shell
-dokku config:unset --no-restart node-js-app DOKKU_PROXY_PORT_MAP
+dokku ports:clear node-js-app
```
### Using a specific buildpack version
diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md
index 9f3b2f098ca..05241476681 100644
--- a/docs/development/plugin-triggers.md
+++ b/docs/development/plugin-triggers.md
@@ -1210,6 +1210,36 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
nginx -t
```
+### `ports-clear`
+
+- Description: Clears the ports for a given app without triggering further restarts or rebuilds
+- Invoked by: internally
+- Arguments: `$APP`
+- Example:
+
+```shell
+#!/usr/bin/env bash
+
+set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
+
+# TODO
+```
+
+### `ports-get`
+
+- Description: Returns the port map for a given application in newline-delimited format
+- Invoked by: internally
+- Arguments: `$APP`
+- Example:
+
+```shell
+#!/usr/bin/env bash
+
+set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
+
+# TODO
+```
+
### `post-app-clone`
- Description: Allows you to run commands after an app was cloned.
@@ -1480,10 +1510,10 @@ echo "clock: some-command" >> Procfile
popd &>/dev/null
```
-### `post-proxy-ports-update`
+### `post-ports-update`
- Description: Allows you to run commands once the proxy port mappings for an app have been updated. It also sends the invoking command. This can be "add", "clear" or "remove".
-- Invoked by: `dokku proxy:ports-add`, `dokku proxy:ports-clear`, `dokku proxy:ports-remove`
+- Invoked by: `dokku ports:add`, `dokku ports:clear`, `dokku ports:remove`
- Arguments: `$APP` `action name`
- Example:
@@ -1824,7 +1854,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
# TODO
```
-### `proxy-configure-ports`
+### `ports-configure`
- Description: Configures the proxy port mapping
- Invoked by: `internally triggered by proxy plugins`
diff --git a/docs/getting-started/troubleshooting.md b/docs/getting-started/troubleshooting.md
index 9402c91e864..18612404e04 100644
--- a/docs/getting-started/troubleshooting.md
+++ b/docs/getting-started/troubleshooting.md
@@ -78,8 +78,8 @@ The proxy port mapping will be `http:8000:8000`.
To avoid this issue, either of the following can be done:
-- Remove `EXPOSE` directive: This will require respecting the `$PORT` environment variable (automatically set by Dokku). Once that change is deployed, the port mapping should be cleared via the `dokku proxy:ports-clear $APP` command (where `$APP` is your app name).
-- Update the port mapping: Updating the port mapping to redirect port `80` to your app's exposed port via `dokku proxy:ports-set $APP http:80:$EXPOSED_PORT` can also fix the issue. This will also allow certificate management and the letsencrypt plugin to work correctly.
+- Remove `EXPOSE` directive: This will require respecting the `$PORT` environment variable (automatically set by Dokku). Once that change is deployed, the port mapping should be cleared via the `dokku ports:clear $APP` command (where `$APP` is your app name).
+- Update the port mapping: Updating the port mapping to redirect port `80` to your app's exposed port via `dokku ports:set $APP http:80:$EXPOSED_PORT` can also fix the issue. This will also allow certificate management and the letsencrypt plugin to work correctly.
See the [port management documentation](/docs/networking/port-management.md) for more information on how Dokku exposes ports for applications and how you can configure these for your app.
@@ -240,4 +240,4 @@ This could be a result of a bad proxy configuration (`http:5000:5000` may be inc
Proxy type: nginx
```
-Set `dokku proxy:ports-set front http:80:5000` to get proxy correctly configured for http endpoint.
+Set `dokku ports:set front http:80:5000` to get proxy correctly configured for http endpoint.
diff --git a/docs/networking/port-management.md b/docs/networking/port-management.md
index 61f3d66833c..28aff827c58 100644
--- a/docs/networking/port-management.md
+++ b/docs/networking/port-management.md
@@ -1,16 +1,16 @@
# Port Management
-> New as of 0.5.0, Enhanced in 0.6.0
+> New as of 0.30.0
```
-proxy:ports # List proxy port mappings for an app
-proxy:ports-add :: [::...] # Add proxy port mappings to an app
-proxy:ports-clear # Clear all proxy port mappings for an app
-proxy:ports-remove [|::...] # Remove specific proxy port mappings from an app
-proxy:ports-set :: [::...] # Set proxy port mappings for an app
+ports:list # List port mappings for an app
+ports:add :: [::...] # Add port mappings to an app
+ports:clear # Clear all port mappings for an app
+ports:remove [|::...] # Remove specific port mappings from an app
+ports:set :: [::...] # Set port mappings for an 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.
+The `ports` plugin can be used to map host ports to specific container ports. Proxy implementations can then consume those port mappings as necessary
## Usage
@@ -18,20 +18,18 @@ In Dokku 0.5.0, port proxying was decoupled from the `nginx-vhosts` plugin into
>
> Users should also avoid setting the `PORT` environment variable. Dokku will use port mappings to set this value. Overriding this manually may cause issues in application routing.
-> 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.
+You can now configure `host -> container` port mappings with the `ports:*` commands. This mapping is currently supported by the built-in nginx-vhosts plugin.
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-*` commands detailed below.
+> Note: This default behavior **will not** be automatically changed on subsequent pushes and must be manipulated with the `ports:*` commands detailed below.
### Listing port mappings
-To inspect the port mapping for a given application, use the `proxy:ports` command:
+To inspect the port mapping for a given application, use the `ports:list` command:
```shell
-dokku proxy:ports node-js-app
+dokku ports:list node-js-app
```
```
@@ -62,10 +60,10 @@ 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`.
+However, we can use the `ports:add` command to add a second external port mapping - `8080` - to our application's port `5000`.
```shell
-dokku proxy:ports-add node-js-app http:8080:5000
+dokku ports:add node-js-app http:8080:5000
```
```
@@ -98,10 +96,10 @@ Hello World!
### Setting all port mappings at once
-Port mappings can also be force set using the `proxy:ports-set` command.
+Port mappings can also be force set using the `ports:set` command.
```shell
-dokku proxy:ports-set node-js-app http:8080:5000
+dokku ports:set node-js-app http:8080:5000
```
```
@@ -114,21 +112,21 @@ dokku proxy:ports-set node-js-app http:8080:5000
### Removing a port mapping
-A port mapping can be removed using the `proxy:ports-remove` command if it no longer necessary:
+A port mapping can be removed using the `ports:remove` command if it no longer necessary:
```shell
-dokku proxy:ports-remove node-js-app http:80:5000
+dokku ports:remove node-js-app http:80:5000
```
Ports may also be removed by specifying only the `host-port` value. This effectively acts as a wildcard and removes all mappings for that particular host port.
```shell
-dokku proxy:ports-remove node-js-app http:80
+dokku ports:remove node-js-app http:80
```
## Port management by Deployment Method
-> Warning: If you set a proxy port map but _do not have a global domain set_, Dokku will reset that map upon first deployment.
+> Warning: If you set a port map but _do not have a global domain set_, Dokku will reset that map upon first deployment.
### Buildpacks
@@ -136,8 +134,6 @@ For buildpack deployments, your application _must_ respect the `PORT` environmen
### Dockerfile
-> Changed as of 0.5.0
-
Dokku's default proxy implementation - nginx - supports HTTP and GRPC request proxying. At this time, we do not support proxying plain TCP or UDP ports. UDP ports can be exposed by disabling the nginx proxy with `dokku proxy:disable myapp`. If you would like to investigate alternative proxy methods, please refer to our [proxy management documentation](/docs/networking/proxy-management.md).
#### Applications using EXPOSE
@@ -156,10 +152,10 @@ The application would be exposed to the user at `node-js-app.dokku.me:1234`. If
```shell
# add a port mapping to port 80
-dokku proxy:ports-add node-js-app http:80:1234
+dokku ports:add node-js-app http:80:1234
# remove the incorrect port mapping
-dokku proxy:ports-remove node-js-app http:1234:1234
+dokku ports:remove node-js-app http:1234:1234
```
#### Applications not using EXPOSE
@@ -176,7 +172,7 @@ When switching between `EXPOSE` usage modes, it is important to reset your port
```shell
# assuming your application is called `node-js-app`
dokku config:unset --no-restart node-js-app DOKKU_DOCKERFILE_PORTS PORT
-dokku proxy:ports-clear node-js-app
+dokku ports:clear node-js-app
```
### Docker Image
@@ -186,7 +182,7 @@ When deploying an image, we will use `docker inspect` to extract the `ExposedPor
```shell
# assuming your application is called `node-js-app`
dokku config:set node-js-app DOKKU_DOCKERFILE_PORTS="1234/tcp 80/tcp"
-dokku proxy:ports-clear node-js-app
+dokku ports:clear node-js-app
```
All other port-related behavior is the same as when deploying via Dockerfile.
diff --git a/docs/networking/proxies/nginx.md b/docs/networking/proxies/nginx.md
index ae9806a2d98..e5523120693 100644
--- a/docs/networking/proxies/nginx.md
+++ b/docs/networking/proxies/nginx.md
@@ -337,8 +337,8 @@ Unsetting this value is the same as enabling custom nginx config usage.
{{ .PROXY_PORT }} Non-SSL nginx listener port (same as `DOKKU_PROXY_PORT` config var)
{{ .PROXY_SSL_PORT }} SSL nginx listener port (same as `DOKKU_PROXY_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)
+{{ .PROXY_PORT_MAP }} List of port mappings
+{{ .PROXY_UPSTREAM_PORTS }} List of configured upstream ports (derived from port mappings)
{{ .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
diff --git a/docs/networking/proxy-management.md b/docs/networking/proxy-management.md
index a716952fb2b..3cb3bb106eb 100644
--- a/docs/networking/proxy-management.md
+++ b/docs/networking/proxy-management.md
@@ -11,7 +11,7 @@ proxy:report [] [] # Displays a proxy report fo
proxy:set # 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.
+In Dokku 0.5.0, port proxying was decoupled from the `nginx-vhosts` plugin into the proxy plugin. In the future this will allow other proxy software - such as HAProxy or Caddy - to be used in place of nginx.
## Usage
@@ -158,14 +158,14 @@ At this time, the following dokku commands are used to implement a complete prox
- triggers: `proxy-disable`
- `proxy:enable`: Enables the proxy configuration for an app.
- triggers: `proxy-enable`
-- `proxy:ports-add`: Adds one or more port mappings to an app
- - triggers: `post-proxy-ports-update`
-- `proxy:ports-clear`: Clears out all port mappings for an app.
- - triggers: `post-proxy-ports-update`
-- `proxy:ports-remove`: Removes one or more port mappings from an app.
- - triggers: `post-proxy-ports-update`
-- `proxy:ports-set`: Sets all port mappings for an app.
- - triggers: `post-proxy-ports-update`
+- `ports:add`: Adds one or more port mappings to an app
+ - triggers: `post-ports-update`
+- `ports:clear`: Clears out all port mappings for an app.
+ - triggers: `post-ports-update`
+- `ports:remove`: Removes one or more port mappings from an app.
+ - triggers: `post-ports-update`
+- `ports:set`: Sets all port mappings for an app.
+ - triggers: `post-ports-update`
Proxy implementations may decide to omit some functionality here, or use plugin triggers to supplement config with information from other plugins.
diff --git a/plugins/20_events/post-proxy-ports-update b/plugins/20_events/ports-clear
similarity index 100%
rename from plugins/20_events/post-proxy-ports-update
rename to plugins/20_events/ports-clear
diff --git a/plugins/20_events/proxy-configure-ports b/plugins/20_events/ports-configure
similarity index 100%
rename from plugins/20_events/proxy-configure-ports
rename to plugins/20_events/ports-configure
diff --git a/plugins/20_events/ports-get b/plugins/20_events/ports-get
new file mode 120000
index 00000000000..5178a749ff6
--- /dev/null
+++ b/plugins/20_events/ports-get
@@ -0,0 +1 @@
+hook
\ No newline at end of file
diff --git a/plugins/20_events/post-ports-update b/plugins/20_events/post-ports-update
new file mode 120000
index 00000000000..5178a749ff6
--- /dev/null
+++ b/plugins/20_events/post-ports-update
@@ -0,0 +1 @@
+hook
\ No newline at end of file
diff --git a/plugins/caddy-vhosts/docker-args-process-deploy b/plugins/caddy-vhosts/docker-args-process-deploy
index 4fe047894c3..65a9c97963c 100755
--- a/plugins/caddy-vhosts/docker-args-process-deploy
+++ b/plugins/caddy-vhosts/docker-args-process-deploy
@@ -8,7 +8,7 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
declare desc="nginx-vhosts core-post-deploy plugin trigger"
declare trigger="docker-args-process-deploy"
declare APP="$1" IMAGE_SOURCE_TYPE="$2" IMAGE_TAG="$3" PROC_TYPE="$4" CONTAINER_INDEX="$5"
- local app_domains caddy_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_port_map proxy_scheme proxy_schemes scheme tls_internal
+ local app_domains caddy_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_scheme proxy_schemes scheme tls_internal
local proxy_container_http_port proxy_container_http_port_candidate proxy_host_http_port_candidate
local proxy_container_https_port proxy_container_https_port_candidate proxy_host_https_port_candidate
local STDIN=$(cat)
@@ -30,15 +30,14 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
fi
# ensure we have a port mapping
- plugn trigger proxy-configure-ports "$APP"
+ plugn trigger ports-configure "$APP"
# gather port mapping information
# we only support proxying a single port for http and https listeners
# so this block parses the port mappings and tries to find the correct
# mapping to expose
is_app_listening="false"
- proxy_port_map="$(plugn trigger config-get "$APP" DOKKU_PROXY_PORT_MAP)"
- for port_map in $proxy_port_map; do
+ while read -r port_map; do
proxy_scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")"
proxy_host_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")"
proxy_container_port="$(awk -F ':' '{ print $3 }' <<<"$port_map")"
@@ -66,7 +65,7 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
proxy_container_https_port="$proxy_container_port"
fi
fi
- done
+ done < <(plugn trigger ports-get "$APP")
letsencrypt_email="$(fn-caddy-letsencrypt-email)"
if [[ -n "$letsencrypt_email" ]] && [[ -z "$proxy_container_https_port" ]]; then
diff --git a/plugins/domains/internal-functions b/plugins/domains/internal-functions
index 921ac9885bb..f897c444293 100755
--- a/plugins/domains/internal-functions
+++ b/plugins/domains/internal-functions
@@ -136,7 +136,7 @@ fn-domains-generate-urls() {
fn-domains-generate-urls-from-config() {
declare APP="$1" SCHEME="$2" VHOST="$3" DEFAULT_LISTEN_PORT="$4"
- local DOKKU_PROXY_PORT_MAP=$(plugn trigger config-get "$APP" DOKKU_PROXY_PORT_MAP || true)
+ local APP_PORT_MAP="$(plugn trigger ports-get "$APP")"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")"
if [[ "$(plugn trigger proxy-is-enabled "$APP")" == "false" ]]; then
@@ -155,13 +155,13 @@ fn-domains-generate-urls-from-config() {
done
shopt -u nullglob
fi
- elif [[ -n "$DOKKU_PROXY_PORT_MAP" ]]; then
+ elif [[ -n "$APP_PORT_MAP" ]]; then
local port_map
- for port_map in $DOKKU_PROXY_PORT_MAP; do
+ while IFS= read -r port_map; do
local scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")"
local listen_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")"
fn-domains-generate-url "$SCHEME" "$VHOST" "$listen_port"
- done
+ done <<<"$APP_PORT_MAP"
elif [[ -n "$RAW_TCP_PORTS" ]]; then
for listen_port in $RAW_TCP_PORTS; do
fn-domains-generate-url "$SCHEME" "$VHOST" "$listen_port"
diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions
index 25ccdd4e78e..a05cc0b2a0f 100755
--- a/plugins/nginx-vhosts/functions
+++ b/plugins/nginx-vhosts/functions
@@ -318,13 +318,12 @@ nginx_build_config() {
fi
# setup nginx listen ports
- plugn trigger proxy-configure-ports "$APP"
+ plugn trigger ports-configure "$APP"
local PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
local PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
- local PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP)
- local PORT_MAP proxy_port_map
- for PORT_MAP in $PROXY_PORT_MAP; do
+ local PORT_MAP PROXY_PORT_MAP proxy_port_map
+ while read -r PORT_MAP; do
local PROXY_UPSTREAM_SCHEME="$(awk -F ':' '{ print $1 }' <<<"$PORT_MAP")"
if [[ "$PROXY_UPSTREAM_SCHEME" == "https" ]] && [[ "$IS_SSL_ENABLED" == "false" ]]; then
dokku_log_warn "Ignoring detected https port mapping without an accompanying ssl certificate (${PORT_MAP})"
@@ -337,8 +336,8 @@ nginx_build_config() {
if [[ "$(is_val_in_list "$PROXY_UPSTREAM_PORT" "$PROXY_UPSTREAM_PORTS" " ")" == "false" ]]; then
local PROXY_UPSTREAM_PORTS+="$PROXY_UPSTREAM_PORT "
fi
- done
- PROXY_PORT_MAP="$proxy_port_map"
+ done < <(plugn trigger ports-get "$APP")
+ PROXY_PORT_MAP=$(echo "$proxy_port_map" | xargs) # trailing spaces mess up default template
local PROXY_UPSTREAM_PORTS="$(echo "$PROXY_UPSTREAM_PORTS" | xargs)"
local SSL_INUSE=
@@ -379,8 +378,6 @@ nginx_build_config() {
HTTP2_PUSH_SUPPORTED="$(is_http2_push_enabled "$NGINX_VERSION")"
GRPC_SUPPORTED="$(is_grpc_enabled "$NGINX_VERSION")"
- PROXY_PORT_MAP=$(echo "$PROXY_PORT_MAP" | xargs) # trailing spaces mess up default template
-
local NGINX_LOG_ROOT="$(fn-nginx-log-root)"
local NGINX_ACCESS_LOG_FORMAT="$(fn-nginx-access-log-format "$APP")"
local NGINX_ACCESS_LOG_PATH="$(fn-nginx-access-log-path "$APP")"
diff --git a/plugins/nginx-vhosts/install b/plugins/nginx-vhosts/install
index e5f0e7af442..bf98d8cd539 100755
--- a/plugins/nginx-vhosts/install
+++ b/plugins/nginx-vhosts/install
@@ -3,32 +3,8 @@ set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
-source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/internal-functions"
-fn-nginx-vhosts-migrate-env-vars() {
- # @TODO: Remove this after a few versions
- for app in $(dokku_apps "false" 2>/dev/null); do
- nginx_port="$(config_get "$app" DOKKU_NGINX_PORT || true)"
- nginx_ssl_port="$(config_get "$app" DOKKU_NGINX_SSL_PORT || true)"
- if [[ -n "$nginx_port" ]] || [[ -n "$nginx_ssl_port" ]]; then
- dokku_log_info1 "Migrating DOKKU_NGINX env variables. The following variables will be migrated"
- dokku_log_info2 "DOKKU_NGINX_PORT -> DOKKU_PROXY_PORT"
- dokku_log_info2 "DOKKU_NGINX_SSL_PORT -> DOKKU_PROXY_SSL_PORT"
- fi
- if [[ -n "$nginx_port" ]]; then
- dokku_log_info1 "Migrating DOKKU_NGINX_PORT to DOKKU_PROXY_PORT for $app"
- DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$app" DOKKU_PROXY_PORT="$nginx_port"
- DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$app" DOKKU_NGINX_PORT
- fi
- if [[ -n "$nginx_ssl_port" ]]; then
- dokku_log_info1 "Migrating DOKKU_NGINX_SSL_PORT to DOKKU_PROXY_SSL_PORT for $app"
- DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$app" DOKKU_PROXY_SSL_PORT="$nginx_ssl_port"
- DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$app" DOKKU_NGINX_SSL_PORT
- fi
- done
-}
-
fn-nginx-vhosts-migrate-nginx-conf-sigil() {
if [[ "$(fn-plugin-property-get-default "nginx" "--global" "nginx-conf-sigil-migrated" "")" == "true" ]]; then
return
@@ -129,7 +105,6 @@ trigger-nginx-vhosts-install() {
# patch broken nginx 1.8.0 logrotate
[[ -f /etc/logrotate.d/nginx ]] && sed -i -e 's/invoke-rc.d/service/g' /etc/logrotate.d/nginx
- fn-nginx-vhosts-migrate-env-vars
fn-nginx-vhosts-migrate-nginx-conf-sigil
if [[ -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/nginx.stopped" ]]; then
diff --git a/plugins/nginx-vhosts/post-proxy-ports-update b/plugins/nginx-vhosts/post-ports-update
similarity index 72%
rename from plugins/nginx-vhosts/post-proxy-ports-update
rename to plugins/nginx-vhosts/post-ports-update
index 499377c9646..364f671849b 100755
--- a/plugins/nginx-vhosts/post-proxy-ports-update
+++ b/plugins/nginx-vhosts/post-ports-update
@@ -4,9 +4,9 @@ set -eo pipefail
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
-trigger-nginx-vhosts-post-proxy-ports-update() {
+trigger-nginx-vhosts-post-ports-update() {
declare desc="calls nginx build_config when domains are updated"
- declare trigger="post-proxy-ports-update"
+ declare trigger="post-ports-update"
declare APP="$1" ACTION="$2"
if [[ "$(plugn trigger proxy-type "$APP")" == "nginx" ]]; then
@@ -14,4 +14,4 @@ trigger-nginx-vhosts-post-proxy-ports-update() {
fi
}
-trigger-nginx-vhosts-post-proxy-ports-update "$@"
+trigger-nginx-vhosts-post-ports-update "$@"
diff --git a/plugins/nginx-vhosts/pre-disable-vhost b/plugins/nginx-vhosts/pre-disable-vhost
index e786e5322f0..ecfba935c82 100755
--- a/plugins/nginx-vhosts/pre-disable-vhost
+++ b/plugins/nginx-vhosts/pre-disable-vhost
@@ -10,7 +10,8 @@ trigger-nginx-vhosts-pre-disable-vhost() {
declare APP="$1"
if [[ "$(plugn trigger proxy-type "$APP")" == "nginx" ]]; then
- DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_PROXY_PORT DOKKU_PROXY_SSL_PORT DOKKU_PROXY_PORT_MAP
+ DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_PROXY_PORT DOKKU_PROXY_SSL_PORT
+ plugn trigger ports-clear "$APP"
fi
}
diff --git a/plugins/nginx-vhosts/pre-enable-vhost b/plugins/nginx-vhosts/pre-enable-vhost
index bde11f963ac..64808eb3d40 100755
--- a/plugins/nginx-vhosts/pre-enable-vhost
+++ b/plugins/nginx-vhosts/pre-enable-vhost
@@ -10,7 +10,8 @@ trigger-nginx-vhosts-pre-enable-vhost() {
declare APP="$1"
if [[ "$(plugn trigger proxy-type "$APP")" == "nginx" ]]; then
- DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_PROXY_PORT DOKKU_PROXY_SSL_PORT DOKKU_PROXY_PORT_MAP
+ DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_PROXY_PORT DOKKU_PROXY_SSL_PORT
+ plugn trigger ports-clear "$APP"
fi
}
diff --git a/plugins/ports/.gitignore b/plugins/ports/.gitignore
new file mode 100644
index 00000000000..83d7acd2c5b
--- /dev/null
+++ b/plugins/ports/.gitignore
@@ -0,0 +1,9 @@
+/commands
+/subcommands/*
+/triggers/*
+/triggers
+/install
+/post-*
+/ports-*
+/report
+!/ports-configure
\ No newline at end of file
diff --git a/plugins/ports/Makefile b/plugins/ports/Makefile
new file mode 100644
index 00000000000..09ef51751f3
--- /dev/null
+++ b/plugins/ports/Makefile
@@ -0,0 +1,6 @@
+SUBCOMMANDS = subcommands/list subcommands/add subcommands/clear subcommands/remove subcommands/set subcommands/report
+TRIGGERS = triggers/ports-clear triggers/ports-get triggers/post-certs-remove triggers/post-certs-update triggers/report
+BUILD = commands subcommands triggers
+PLUGIN_NAME = ports
+
+include ../../common.mk
diff --git a/plugins/ports/functions.go b/plugins/ports/functions.go
new file mode 100644
index 00000000000..6829e3ddf3b
--- /dev/null
+++ b/plugins/ports/functions.go
@@ -0,0 +1,192 @@
+package ports
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "sort"
+ "strconv"
+ "strings"
+
+ "github.com/dokku/dokku/plugins/common"
+ "github.com/dokku/dokku/plugins/config"
+ "github.com/ryanuber/columnize"
+)
+
+func addPorts(appName string, portMap []PortMap) error {
+ allPortMaps := getPortMaps(appName)
+ allPortMaps = append(allPortMaps, portMap...)
+
+ return setPorts(appName, allPortMaps)
+}
+
+func clearPorts(appName string) error {
+ keys := []string{"DOKKU_PROXY_PORT_MAP"}
+ return config.UnsetMany(appName, keys, false)
+}
+
+func filterAppPorts(appName string, scheme string, hostPort int) []PortMap {
+ var filteredMaps []PortMap
+ for _, portMap := range getPortMaps(appName) {
+ if portMap.Scheme == scheme && portMap.HostPort == hostPort {
+ filteredMaps = append(filteredMaps, portMap)
+ }
+ }
+
+ return filteredMaps
+}
+
+func getPortMaps(appName string) []PortMap {
+ value := config.GetWithDefault(appName, "DOKKU_PROXY_PORT_MAP", "")
+ portMaps, _ := parsePortMapString(value)
+ return portMaps
+}
+
+func inRange(value int, min int, max int) bool {
+ return min < value && value < max
+}
+
+func listAppPorts(appName string) error {
+ portMaps := getPortMaps(appName)
+
+ if len(portMaps) == 0 {
+ return errors.New("No port mappings configured for app")
+ }
+
+ var lines []string
+ if os.Getenv("DOKKU_QUIET_OUTPUT") == "" {
+ lines = append(lines, "-----> scheme:host port:container port")
+ }
+
+ for _, portMap := range portMaps {
+ lines = append(lines, portMap.String())
+ }
+
+ sort.Strings(lines)
+ common.LogInfo1Quiet(fmt.Sprintf("Port mappings for %s", appName))
+ config := columnize.DefaultConfig()
+ config.Delim = ":"
+ config.Prefix = " "
+ config.Empty = ""
+ fmt.Println(columnize.Format(lines, config))
+ return nil
+}
+
+func parsePortMapString(stringPortMap string) ([]PortMap, error) {
+ var portMap []PortMap
+
+ for _, v := range strings.Split(strings.TrimSpace(stringPortMap), " ") {
+ parts := strings.SplitN(v, ":", 3)
+ if len(parts) == 1 {
+ hostPort, err := strconv.Atoi(v)
+ if err != nil {
+ return portMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error())
+ }
+
+ if !inRange(hostPort, 0, 65536) {
+ return portMap, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort)
+ }
+
+ portMap = append(portMap, PortMap{
+ HostPort: hostPort,
+ Scheme: "__internal__",
+ })
+ continue
+ }
+
+ if len(parts) != 3 {
+ return portMap, fmt.Errorf("Invalid port map %s [len=%d]", v, len(parts))
+ }
+
+ hostPort, err := strconv.Atoi(parts[1])
+ if err != nil {
+ return portMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error())
+ }
+
+ containerPort, err := strconv.Atoi(parts[2])
+ if err != nil {
+ return portMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error())
+ }
+
+ if !inRange(hostPort, 0, 65536) {
+ return portMap, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort)
+ }
+
+ if !inRange(containerPort, 0, 65536) {
+ return portMap, fmt.Errorf("Invalid port map %s [containerPort=%d]", v, containerPort)
+ }
+
+ portMap = append(portMap, PortMap{
+ ContainerPort: containerPort,
+ HostPort: hostPort,
+ Scheme: parts[0],
+ })
+ }
+
+ return uniquePortMap(portMap), nil
+}
+
+func removePorts(appName string, portMap []PortMap) error {
+ toRemove := map[string]bool{}
+ toRemoveByPort := map[int]bool{}
+
+ for _, portMap := range portMap {
+ if portMap.AllowsPersistence() {
+ toRemoveByPort[portMap.HostPort] = true
+ continue
+ }
+ toRemove[portMap.String()] = true
+ }
+
+ var toSet []PortMap
+ for _, portMap := range getPortMaps(appName) {
+ if toRemove[portMap.String()] {
+ continue
+ }
+
+ if toRemoveByPort[portMap.HostPort] {
+ continue
+ }
+
+ toSet = append(toSet, portMap)
+ }
+
+ if len(toSet) == 0 {
+ return clearPorts(appName)
+ }
+
+ return setPorts(appName, toSet)
+}
+
+func setPorts(appName string, portMap []PortMap) error {
+ var value []string
+ for _, portMap := range uniquePortMap(portMap) {
+ if portMap.AllowsPersistence() {
+ continue
+ }
+
+ value = append(value, portMap.String())
+ }
+
+ sort.Strings(value)
+ entries := map[string]string{
+ "DOKKU_PROXY_PORT_MAP": strings.Join(value, " "),
+ }
+ return config.SetMany(appName, entries, false)
+}
+
+func uniquePortMap(portMap []PortMap) []PortMap {
+ var unique []PortMap
+ existingPortMaps := map[string]bool{}
+
+ for _, portMap := range portMap {
+ if existingPortMaps[portMap.String()] {
+ continue
+ }
+
+ existingPortMaps[portMap.String()] = true
+ unique = append(unique, portMap)
+ }
+
+ return unique
+}
diff --git a/plugins/ports/go.mod b/plugins/ports/go.mod
new file mode 100644
index 00000000000..a980a7fea24
--- /dev/null
+++ b/plugins/ports/go.mod
@@ -0,0 +1,21 @@
+module github.com/dokku/dokku/plugins/ports
+
+go 1.19
+
+require (
+ github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
+ github.com/dokku/dokku/plugins/config v0.0.0-00010101000000-000000000000
+ github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3
+ github.com/spf13/pflag v1.0.5
+)
+
+require (
+ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
+ github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
+ github.com/joho/godotenv v1.2.0 // indirect
+ golang.org/x/sync v0.1.0 // indirect
+)
+
+replace github.com/dokku/dokku/plugins/common => ../common
+
+replace github.com/dokku/dokku/plugins/config => ../config
diff --git a/plugins/ports/go.sum b/plugins/ports/go.sum
new file mode 100644
index 00000000000..170b00f269b
--- /dev/null
+++ b/plugins/ports/go.sum
@@ -0,0 +1,16 @@
+github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
+github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
+github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA=
+github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE=
+github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc=
+github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
+github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3 h1:utdYOikI1XjNtTFGCwSM6OmFJblU4ld4gACoJsbadJg=
+github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
diff --git a/plugins/ports/plugin.toml b/plugins/ports/plugin.toml
new file mode 100644
index 00000000000..7694a9c275c
--- /dev/null
+++ b/plugins/ports/plugin.toml
@@ -0,0 +1,4 @@
+[plugin]
+description = "dokku core ports plugin"
+version = "0.29.2"
+[plugin.config]
diff --git a/plugins/proxy/proxy-configure-ports b/plugins/ports/ports-configure
similarity index 100%
rename from plugins/proxy/proxy-configure-ports
rename to plugins/ports/ports-configure
diff --git a/plugins/ports/ports.go b/plugins/ports/ports.go
new file mode 100644
index 00000000000..1918a8c531b
--- /dev/null
+++ b/plugins/ports/ports.go
@@ -0,0 +1,21 @@
+package ports
+
+import (
+ "fmt"
+)
+
+// PortMap is a struct that contains a scheme:host-port:container-port mapping
+type PortMap struct {
+ ContainerPort int
+ HostPort int
+ Scheme string
+}
+
+func (p PortMap) String() string {
+ return fmt.Sprintf("%s:%d:%d", p.Scheme, p.HostPort, p.ContainerPort)
+}
+
+// AllowsPersistence returns true if the port map is not to be persisted
+func (p PortMap) AllowsPersistence() bool {
+ return p.Scheme == "__internal__"
+}
diff --git a/plugins/ports/report.go b/plugins/ports/report.go
new file mode 100644
index 00000000000..63b53756d06
--- /dev/null
+++ b/plugins/ports/report.go
@@ -0,0 +1,37 @@
+package ports
+
+import (
+ "strings"
+
+ "github.com/dokku/dokku/plugins/common"
+)
+
+// ReportSingleApp is an internal function that displays the port report for one or more apps
+func ReportSingleApp(appName string, format string, infoFlag string) error {
+ if err := common.VerifyAppName(appName); err != nil {
+ return err
+ }
+
+ flags := map[string]common.ReportFunc{
+ "--ports-map": reportPortMap,
+ }
+
+ flagKeys := []string{}
+ for flagKey := range flags {
+ flagKeys = append(flagKeys, flagKey)
+ }
+
+ trimPrefix := false
+ uppercaseFirstCharacter := true
+ infoFlags := common.CollectReport(appName, infoFlag, flags)
+ return common.ReportSingleApp("ports", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter)
+}
+
+func reportPortMap(appName string) string {
+ var portMap []string
+ for _, pm := range getPortMaps(appName) {
+ portMap = append(portMap, pm.String())
+ }
+
+ return strings.Join(portMap, " ")
+}
diff --git a/plugins/ports/src/commands/commands.go b/plugins/ports/src/commands/commands.go
new file mode 100644
index 00000000000..9231d27bf29
--- /dev/null
+++ b/plugins/ports/src/commands/commands.go
@@ -0,0 +1,60 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+
+ "github.com/dokku/dokku/plugins/common"
+)
+
+const (
+ helpHeader = `Usage: dokku ports[:COMMAND]
+
+Manage ports for an app
+
+Additional commands:`
+
+ helpContent = `
+ ports:list , List port mappings for app
+ ports:add [::...], Add port mappings to an app
+ ports:clear , Clear all port mappings for an app
+ ports:remove [|::...], Remove specific port mappings from an app
+ ports:set [::...], Set port mappings for an app
+ ports:report [] [], Displays a ports report for one or more apps
+`
+)
+
+func main() {
+ flag.Usage = usage
+ flag.Parse()
+
+ cmd := flag.Arg(0)
+ switch cmd {
+ case "ports", "ports:help":
+ usage()
+ case "help":
+ command := common.NewShellCmd(fmt.Sprintf("ps -o command= %d", os.Getppid()))
+ command.ShowOutput = false
+ output, err := command.Output()
+
+ if err == nil && strings.Contains(string(output), "--all") {
+ fmt.Println(helpContent)
+ } else {
+ fmt.Print("\n ports, Manage ports for an app\n")
+ }
+ default:
+ dokkuNotImplementExitCode, err := strconv.Atoi(os.Getenv("DOKKU_NOT_IMPLEMENTED_EXIT"))
+ if err != nil {
+ fmt.Println("failed to retrieve DOKKU_NOT_IMPLEMENTED_EXIT environment variable")
+ dokkuNotImplementExitCode = 10
+ }
+ os.Exit(dokkuNotImplementExitCode)
+ }
+}
+
+func usage() {
+ common.CommandUsage(helpHeader, helpContent)
+}
diff --git a/plugins/ports/src/subcommands/subcommands.go b/plugins/ports/src/subcommands/subcommands.go
new file mode 100644
index 00000000000..14f97ed9418
--- /dev/null
+++ b/plugins/ports/src/subcommands/subcommands.go
@@ -0,0 +1,65 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/dokku/dokku/plugins/common"
+ "github.com/dokku/dokku/plugins/ports"
+
+ flag "github.com/spf13/pflag"
+)
+
+// main entrypoint to all subcommands
+func main() {
+ parts := strings.Split(os.Args[0], "/")
+ subcommand := parts[len(parts)-1]
+
+ var err error
+ switch subcommand {
+ case "list":
+ args := flag.NewFlagSet("ports:list", flag.ExitOnError)
+ args.Parse(os.Args[2:])
+ appName := args.Arg(0)
+ err = ports.CommandList(appName)
+ case "add":
+ args := flag.NewFlagSet("ports:add", flag.ExitOnError)
+ args.Parse(os.Args[2:])
+ appName := args.Arg(0)
+ _, portMaps := common.ShiftString(args.Args())
+ err = ports.CommandAdd(appName, portMaps)
+ case "clear":
+ args := flag.NewFlagSet("ports:clear", flag.ExitOnError)
+ args.Parse(os.Args[2:])
+ appName := args.Arg(0)
+ err = ports.CommandClear(appName)
+ case "remove":
+ args := flag.NewFlagSet("ports:remove", flag.ExitOnError)
+ args.Parse(os.Args[2:])
+ appName := args.Arg(0)
+ _, portMaps := common.ShiftString(args.Args())
+ err = ports.CommandRemove(appName, portMaps)
+ case "set":
+ args := flag.NewFlagSet("ports:set", flag.ExitOnError)
+ args.Parse(os.Args[2:])
+ appName := args.Arg(0)
+ _, portMaps := common.ShiftString(args.Args())
+ err = ports.CommandSet(appName, portMaps)
+ case "report":
+ args := flag.NewFlagSet("ports:report", flag.ExitOnError)
+ format := args.String("format", "stdout", "format: [ stdout | json ]")
+ osArgs, infoFlag, flagErr := common.ParseReportArgs("ports", os.Args[2:])
+ if flagErr == nil {
+ args.Parse(osArgs)
+ appName := args.Arg(0)
+ err = ports.CommandReport(appName, *format, infoFlag)
+ }
+ default:
+ err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
+ }
+
+ if err != nil {
+ common.LogFailWithError(err)
+ }
+}
diff --git a/plugins/ports/src/triggers/triggers.go b/plugins/ports/src/triggers/triggers.go
new file mode 100644
index 00000000000..f199ba8da50
--- /dev/null
+++ b/plugins/ports/src/triggers/triggers.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/dokku/dokku/plugins/common"
+ "github.com/dokku/dokku/plugins/ports"
+)
+
+// main entrypoint to all triggers
+func main() {
+ parts := strings.Split(os.Args[0], "/")
+ trigger := parts[len(parts)-1]
+ flag.Parse()
+
+ var err error
+ switch trigger {
+ case "ports-clear":
+ appName := flag.Arg(0)
+ err = ports.TriggerPortsClear(appName)
+ case "ports-get":
+ appName := flag.Arg(0)
+ err = ports.TriggerPortsGet(appName)
+ case "post-certs-remove":
+ appName := flag.Arg(0)
+ err = ports.TriggerPostCertsRemove(appName)
+ case "post-certs-update":
+ appName := flag.Arg(0)
+ err = ports.TriggerPostCertsUpdate(appName)
+ case "report":
+ appName := flag.Arg(0)
+ err = ports.ReportSingleApp(appName, "", "")
+ default:
+ err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
+ }
+
+ if err != nil {
+ common.LogFailWithError(err)
+ }
+}
diff --git a/plugins/ports/subcommands.go b/plugins/ports/subcommands.go
new file mode 100644
index 00000000000..942fe1e84ad
--- /dev/null
+++ b/plugins/ports/subcommands.go
@@ -0,0 +1,114 @@
+package ports
+
+import (
+ "errors"
+ "strings"
+
+ "github.com/dokku/dokku/plugins/common"
+)
+
+// CommandList is a cmd wrapper to list port mappings for an app
+func CommandList(appName string) error {
+ if err := common.VerifyAppName(appName); err != nil {
+ return err
+ }
+
+ return listAppPorts(appName)
+}
+
+// CommandAdd adds port mappings to an app
+func CommandAdd(appName string, portMaps []string) error {
+ if err := common.VerifyAppName(appName); err != nil {
+ return err
+ }
+
+ if len(portMaps) == 0 {
+ return errors.New("No port mapping specified")
+ }
+
+ portMap, err := parsePortMapString(strings.Join(portMaps, " "))
+ if err != nil {
+ return err
+ }
+
+ if err := addPorts(appName, portMap); err != nil {
+ return err
+ }
+
+ return common.PlugnTrigger("post-ports-update", []string{appName, "add"}...)
+}
+
+// CommandClear clears all port mappings for an app
+func CommandClear(appName string) error {
+ if err := common.VerifyAppName(appName); err != nil {
+ return err
+ }
+
+ if err := clearPorts(appName); err != nil {
+ return err
+ }
+
+ return common.PlugnTrigger("post-ports-update", []string{appName, "clear"}...)
+}
+
+// CommandRemove removes specific port mappings from an app
+func CommandRemove(appName string, portMaps []string) error {
+ if err := common.VerifyAppName(appName); err != nil {
+ return err
+ }
+
+ if len(portMaps) == 0 {
+ return errors.New("No port mapping specified")
+ }
+
+ portMap, err := parsePortMapString(strings.Join(portMaps, " "))
+ if err != nil {
+ return err
+ }
+
+ if err := removePorts(appName, portMap); err != nil {
+ return err
+ }
+
+ return common.PlugnTrigger("post-ports-update", []string{appName, "remove"}...)
+}
+
+// CommandSet sets port mappings for an app
+func CommandSet(appName string, portMaps []string) error {
+ if err := common.VerifyAppName(appName); err != nil {
+ return err
+ }
+
+ if len(portMaps) == 0 {
+ return errors.New("No port mapping specified")
+ }
+
+ portMap, err := parsePortMapString(strings.Join(portMaps, " "))
+ if err != nil {
+ return err
+ }
+
+ if err := setPorts(appName, portMap); err != nil {
+ return err
+ }
+
+ return common.PlugnTrigger("post-ports-update", []string{appName, "set"}...)
+}
+
+// CommandReport displays a report for one or more apps
+func CommandReport(appName string, format string, infoFlag string) error {
+ if len(appName) == 0 {
+ apps, err := common.DokkuApps()
+ if err != nil {
+ return err
+ }
+ for _, appName := range apps {
+ if err := ReportSingleApp(appName, format, infoFlag); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ return ReportSingleApp(appName, format, infoFlag)
+}
diff --git a/plugins/ports/triggers.go b/plugins/ports/triggers.go
new file mode 100644
index 00000000000..86623dd6492
--- /dev/null
+++ b/plugins/ports/triggers.go
@@ -0,0 +1,89 @@
+package ports
+
+import (
+ "fmt"
+
+ "github.com/dokku/dokku/plugins/config"
+)
+
+// TriggerPortsClear removes all ports for the specified app
+func TriggerPortsClear(appName string) error {
+ return clearPorts(appName)
+}
+
+// TriggerPortsGet prints out the port mapping for a given app
+func TriggerPortsGet(appName string) error {
+ for _, portMap := range getPortMaps(appName) {
+ if portMap.AllowsPersistence() {
+ continue
+ }
+ fmt.Println(portMap)
+ }
+ return nil
+}
+
+// TriggerPostCertsRemove unsets port config vars after SSL cert is added
+func TriggerPostCertsRemove(appName string) error {
+ keys := []string{"DOKKU_PROXY_SSL_PORT"}
+ if err := config.UnsetMany(appName, keys, false); err != nil {
+ return err
+ }
+
+ return removePorts(appName, filterAppPorts(appName, "https", 443))
+}
+
+// TriggerPostCertsUpdate sets port config vars after SSL cert is added
+func TriggerPostCertsUpdate(appName string) error {
+ port := config.GetWithDefault(appName, "DOKKU_PROXY_PORT", "")
+ sslPort := config.GetWithDefault(appName, "DOKKU_PROXY_SSL_PORT", "")
+ portMaps := getPortMaps(appName)
+
+ toUnset := []string{}
+ if port == "80" {
+ toUnset = append(toUnset, "DOKKU_PROXY_PORT")
+ }
+ if sslPort == "443" {
+ toUnset = append(toUnset, "DOKKU_PROXY_SSL_PORT")
+ }
+
+ if len(toUnset) > 0 {
+ if err := config.UnsetMany(appName, toUnset, false); err != nil {
+ return err
+ }
+ }
+
+ var http80Ports []PortMap
+ for _, portMap := range portMaps {
+ if portMap.Scheme == "http" && portMap.HostPort == 80 {
+ http80Ports = append(http80Ports, portMap)
+ }
+ }
+
+ if len(http80Ports) > 0 {
+ var https443Ports []PortMap
+ for _, portMap := range portMaps {
+ if portMap.Scheme == "https" && portMap.HostPort == 443 {
+ https443Ports = append(https443Ports, portMap)
+ }
+ }
+
+ if err := removePorts(appName, https443Ports); err != nil {
+ return err
+ }
+
+ var toAdd []PortMap
+ for _, portMap := range http80Ports {
+ toAdd = append(toAdd, PortMap{
+ Scheme: "https",
+ HostPort: 443,
+ ContainerPort: portMap.ContainerPort,
+ })
+ }
+
+ if err := addPorts(appName, toAdd); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/plugins/proxy/.gitignore b/plugins/proxy/.gitignore
index 3b20f2e1cfc..3079acc9d7d 100644
--- a/plugins/proxy/.gitignore
+++ b/plugins/proxy/.gitignore
@@ -2,8 +2,7 @@
/subcommands/*
/triggers/*
/triggers
-/proxy-*
/install
/post-*
/report
-!/proxy-configure-ports
+/proxy-*
diff --git a/plugins/proxy/Makefile b/plugins/proxy/Makefile
index 21cc25c91fd..9ed4ffae5ff 100644
--- a/plugins/proxy/Makefile
+++ b/plugins/proxy/Makefile
@@ -1,5 +1,5 @@
-SUBCOMMANDS = subcommands/build-config subcommands/clear-config subcommands/disable subcommands/enable subcommands/ports subcommands/ports-add subcommands/ports-clear subcommands/ports-remove subcommands/ports-set subcommands/report subcommands/set
-TRIGGERS = triggers/proxy-is-enabled triggers/proxy-type triggers/post-certs-remove triggers/post-certs-update triggers/report
+SUBCOMMANDS = subcommands/build-config subcommands/clear-config subcommands/disable subcommands/enable subcommands/report subcommands/set
+TRIGGERS = triggers/proxy-is-enabled triggers/proxy-type triggers/report
BUILD = commands subcommands triggers
PLUGIN_NAME = proxy
diff --git a/plugins/proxy/functions b/plugins/proxy/functions
deleted file mode 100755
index 910a7a22e91..00000000000
--- a/plugins/proxy/functions
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-set -eo pipefail
-[[ $DOKKU_TRACE ]] && set -x
-source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
-source "$PLUGIN_AVAILABLE_PATH/config/functions"
-
-is_app_proxy_enabled() {
- declare desc="return true if proxy is enabled; otherwise return false"
- declare APP="$1"
- declare deprecated=true
- dokku_log_warn "Deprecated: Use plugn#proxy-is-enabled"
-
- plugn trigger proxy-is-enabled "$APP"
-}
-
-get_app_proxy_type() {
- declare desc="return app proxy type"
- declare APP="$1"
- declare deprecated=true
- dokku_log_warn "Deprecated: Use plugn#proxy-type"
-
- plugn trigger proxy-type "$APP"
-}
diff --git a/plugins/proxy/functions.go b/plugins/proxy/functions.go
index bc12f32a9e6..4b5467f50e3 100644
--- a/plugins/proxy/functions.go
+++ b/plugins/proxy/functions.go
@@ -1,192 +1,9 @@
package proxy
import (
- "errors"
- "fmt"
- "os"
- "sort"
- "strconv"
- "strings"
-
- "github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
- "github.com/ryanuber/columnize"
)
-func addProxyPorts(appName string, proxyPortMap []PortMap) error {
- allPortMaps := getProxyPortMap(appName)
- allPortMaps = append(allPortMaps, proxyPortMap...)
-
- return setProxyPorts(appName, allPortMaps)
-}
-
-func filterAppProxyPorts(appName string, scheme string, hostPort int) []PortMap {
- var filteredProxyMaps []PortMap
- for _, portMap := range getProxyPortMap(appName) {
- if portMap.Scheme == scheme && portMap.HostPort == hostPort {
- filteredProxyMaps = append(filteredProxyMaps, portMap)
- }
- }
-
- return filteredProxyMaps
-}
-
func getAppProxyType(appName string) string {
return config.GetWithDefault(appName, "DOKKU_APP_PROXY_TYPE", "nginx")
}
-
-func getProxyPortMap(appName string) []PortMap {
- value := config.GetWithDefault(appName, "DOKKU_PROXY_PORT_MAP", "")
- portMaps, _ := parseProxyPortMapString(value)
- return portMaps
-}
-
-func inRange(value int, min int, max int) bool {
- return min < value && value < max
-}
-
-func listAppProxyPorts(appName string) error {
- proxyPortMap := getProxyPortMap(appName)
-
- if len(proxyPortMap) == 0 {
- return errors.New("No port mappings configured for app")
- }
-
- var lines []string
- if os.Getenv("DOKKU_QUIET_OUTPUT") == "" {
- lines = append(lines, "-----> scheme:host port:container port")
- }
-
- for _, portMap := range proxyPortMap {
- lines = append(lines, portMap.String())
- }
-
- sort.Strings(lines)
- common.LogInfo1Quiet(fmt.Sprintf("Port mappings for %s", appName))
- config := columnize.DefaultConfig()
- config.Delim = ":"
- config.Prefix = " "
- config.Empty = ""
- fmt.Println(columnize.Format(lines, config))
- return nil
-}
-
-func parseProxyPortMapString(stringPortMap string) ([]PortMap, error) {
- var proxyPortMap []PortMap
-
- for _, v := range strings.Split(strings.TrimSpace(stringPortMap), " ") {
- parts := strings.SplitN(v, ":", 3)
- if len(parts) == 1 {
- hostPort, err := strconv.Atoi(v)
- if err != nil {
- return proxyPortMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error())
- }
-
- if !inRange(hostPort, 0, 65536) {
- return proxyPortMap, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort)
- }
-
- proxyPortMap = append(proxyPortMap, PortMap{
- HostPort: hostPort,
- Scheme: "__internal__",
- })
- continue
- }
-
- if len(parts) != 3 {
- return proxyPortMap, fmt.Errorf("Invalid port map %s [len=%d]", v, len(parts))
- }
-
- hostPort, err := strconv.Atoi(parts[1])
- if err != nil {
- return proxyPortMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error())
- }
-
- containerPort, err := strconv.Atoi(parts[2])
- if err != nil {
- return proxyPortMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error())
- }
-
- if !inRange(hostPort, 0, 65536) {
- return proxyPortMap, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort)
- }
-
- if !inRange(containerPort, 0, 65536) {
- return proxyPortMap, fmt.Errorf("Invalid port map %s [containerPort=%d]", v, containerPort)
- }
-
- proxyPortMap = append(proxyPortMap, PortMap{
- ContainerPort: containerPort,
- HostPort: hostPort,
- Scheme: parts[0],
- })
- }
-
- return uniqueProxyPortMap(proxyPortMap), nil
-}
-
-func removeProxyPorts(appName string, proxyPortMap []PortMap) error {
- toRemove := map[string]bool{}
- toRemoveByPort := map[int]bool{}
-
- for _, portMap := range proxyPortMap {
- if portMap.AllowsPersistence() {
- toRemoveByPort[portMap.HostPort] = true
- continue
- }
- toRemove[portMap.String()] = true
- }
-
- var toSet []PortMap
- for _, portMap := range getProxyPortMap(appName) {
- if toRemove[portMap.String()] {
- continue
- }
-
- if toRemoveByPort[portMap.HostPort] {
- continue
- }
-
- toSet = append(toSet, portMap)
- }
-
- if len(toSet) == 0 {
- keys := []string{"DOKKU_PROXY_PORT_MAP"}
- return config.UnsetMany(appName, keys, false)
- }
-
- return setProxyPorts(appName, toSet)
-}
-
-func setProxyPorts(appName string, proxyPortMap []PortMap) error {
- var value []string
- for _, portMap := range uniqueProxyPortMap(proxyPortMap) {
- if portMap.AllowsPersistence() {
- continue
- }
-
- value = append(value, portMap.String())
- }
-
- sort.Strings(value)
- entries := map[string]string{
- "DOKKU_PROXY_PORT_MAP": strings.Join(value, " "),
- }
- return config.SetMany(appName, entries, false)
-}
-
-func uniqueProxyPortMap(proxyPortMap []PortMap) []PortMap {
- var unique []PortMap
- existingPortMaps := map[string]bool{}
-
- for _, portMap := range proxyPortMap {
- if existingPortMaps[portMap.String()] {
- continue
- }
-
- existingPortMaps[portMap.String()] = true
- unique = append(unique, portMap)
- }
-
- return unique
-}
diff --git a/plugins/proxy/proxy.go b/plugins/proxy/proxy.go
index ec87bf48c5e..26cfee2ffb4 100644
--- a/plugins/proxy/proxy.go
+++ b/plugins/proxy/proxy.go
@@ -1,8 +1,6 @@
package proxy
import (
- "fmt"
-
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
@@ -11,22 +9,6 @@ import (
// and defaults to -1 (false)
const RunInSerial = 0
-// PortMap is a struct that contains a scheme:host-port:container-port mapping
-type PortMap struct {
- ContainerPort int
- HostPort int
- Scheme string
-}
-
-func (p PortMap) String() string {
- return fmt.Sprintf("%s:%d:%d", p.Scheme, p.HostPort, p.ContainerPort)
-}
-
-// AllowsPersistence returns true if the port map is not to be persisted
-func (p PortMap) AllowsPersistence() bool {
- return p.Scheme == "__internal__"
-}
-
// BuildConfig rebuilds the proxy config for the specified app
func BuildConfig(appName string) error {
return common.PlugnTrigger("proxy-build-config", []string{appName}...)
diff --git a/plugins/proxy/report.go b/plugins/proxy/report.go
index bf4c5c917b4..5db7792a2f6 100644
--- a/plugins/proxy/report.go
+++ b/plugins/proxy/report.go
@@ -1,8 +1,6 @@
package proxy
import (
- "strings"
-
"github.com/dokku/dokku/plugins/common"
)
@@ -13,9 +11,8 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
}
flags := map[string]common.ReportFunc{
- "--proxy-enabled": reportEnabled,
- "--proxy-type": reportType,
- "--proxy-port-map": reportPortMap,
+ "--proxy-enabled": reportEnabled,
+ "--proxy-type": reportType,
}
flagKeys := []string{}
@@ -41,12 +38,3 @@ func reportEnabled(appName string) string {
func reportType(appName string) string {
return getAppProxyType(appName)
}
-
-func reportPortMap(appName string) string {
- var proxyPortMap []string
- for _, portMap := range getProxyPortMap(appName) {
- proxyPortMap = append(proxyPortMap, portMap.String())
- }
-
- return strings.Join(proxyPortMap, " ")
-}
diff --git a/plugins/proxy/src/commands/commands.go b/plugins/proxy/src/commands/commands.go
index e2f6c016a81..129cc282082 100644
--- a/plugins/proxy/src/commands/commands.go
+++ b/plugins/proxy/src/commands/commands.go
@@ -22,11 +22,6 @@ Additional commands:`
proxy:clear-config [--all|], Clears config for a given app
proxy:disable , Disable proxy for app
proxy:enable , Enable proxy for app
- proxy:ports , List proxy port mappings for app
- proxy:ports-add [::...], Add proxy port mappings to an app
- proxy:ports-clear , Clear all proxy port mappings for an app
- proxy:ports-remove [|::...], Remove specific proxy port mappings from an app
- proxy:ports-set [::...], Set proxy port mappings for an app
proxy:report [] [], Displays a proxy report for one or more apps
proxy:set , Set proxy type for app
`
diff --git a/plugins/proxy/src/subcommands/subcommands.go b/plugins/proxy/src/subcommands/subcommands.go
index c25db395ccb..d181068da7b 100644
--- a/plugins/proxy/src/subcommands/subcommands.go
+++ b/plugins/proxy/src/subcommands/subcommands.go
@@ -45,34 +45,6 @@ func main() {
args.Parse(os.Args[2:])
appName := args.Arg(0)
err = proxy.CommandEnable(appName, *allApps, *parallelCount)
- case "ports":
- args := flag.NewFlagSet("proxy:ports", flag.ExitOnError)
- args.Parse(os.Args[2:])
- appName := args.Arg(0)
- err = proxy.CommandPorts(appName)
- case "ports-add":
- args := flag.NewFlagSet("proxy:ports-add", flag.ExitOnError)
- args.Parse(os.Args[2:])
- appName := args.Arg(0)
- _, portMaps := common.ShiftString(args.Args())
- err = proxy.CommandPortsAdd(appName, portMaps)
- case "ports-clear":
- args := flag.NewFlagSet("proxy:ports-clear", flag.ExitOnError)
- args.Parse(os.Args[2:])
- appName := args.Arg(0)
- err = proxy.CommandPortsClear(appName)
- case "ports-remove":
- args := flag.NewFlagSet("proxy:ports-remove", flag.ExitOnError)
- args.Parse(os.Args[2:])
- appName := args.Arg(0)
- _, portMaps := common.ShiftString(args.Args())
- err = proxy.CommandPortsRemove(appName, portMaps)
- case "ports-set":
- args := flag.NewFlagSet("proxy:ports-set", flag.ExitOnError)
- args.Parse(os.Args[2:])
- appName := args.Arg(0)
- _, portMaps := common.ShiftString(args.Args())
- err = proxy.CommandPortsSet(appName, portMaps)
case "report":
args := flag.NewFlagSet("proxy:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
diff --git a/plugins/proxy/src/triggers/triggers.go b/plugins/proxy/src/triggers/triggers.go
index 11c5bd277ab..713e1976d0c 100644
--- a/plugins/proxy/src/triggers/triggers.go
+++ b/plugins/proxy/src/triggers/triggers.go
@@ -24,12 +24,6 @@ func main() {
case "proxy-type":
appName := flag.Arg(0)
err = proxy.TriggerProxyType(appName)
- case "post-certs-remove":
- appName := flag.Arg(0)
- err = proxy.TriggerPostCertsRemove(appName)
- case "post-certs-update":
- appName := flag.Arg(0)
- err = proxy.TriggerPostCertsUpdate(appName)
case "report":
appName := flag.Arg(0)
err = proxy.ReportSingleApp(appName, "", "")
diff --git a/plugins/proxy/subcommands.go b/plugins/proxy/subcommands.go
index 1dcb66558a5..58a57a87029 100644
--- a/plugins/proxy/subcommands.go
+++ b/plugins/proxy/subcommands.go
@@ -2,7 +2,6 @@ package proxy
import (
"errors"
- "strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
@@ -60,95 +59,6 @@ func CommandEnable(appName string, allApps bool, parallelCount int) error {
return Enable(appName)
}
-// CommandPorts is a cmd wrapper to list proxy port mappings for an app
-func CommandPorts(appName string) error {
- if err := common.VerifyAppName(appName); err != nil {
- return err
- }
-
- return listAppProxyPorts(appName)
-}
-
-// CommandPortsAdd adds proxy port mappings to an app
-func CommandPortsAdd(appName string, portMaps []string) error {
- if err := common.VerifyAppName(appName); err != nil {
- return err
- }
-
- if len(portMaps) == 0 {
- return errors.New("No port mapping specified")
- }
-
- proxyPortMap, err := parseProxyPortMapString(strings.Join(portMaps, " "))
- if err != nil {
- return err
- }
-
- if err := addProxyPorts(appName, proxyPortMap); err != nil {
- return err
- }
-
- return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "add"}...)
-}
-
-// CommandPortsClear clears all proxy port mappings for an app
-func CommandPortsClear(appName string) error {
- if err := common.VerifyAppName(appName); err != nil {
- return err
- }
-
- keys := []string{"DOKKU_PROXY_PORT_MAP"}
- if err := config.UnsetMany(appName, keys, false); err != nil {
- return err
- }
-
- return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "clear"}...)
-}
-
-// CommandPortsRemove removes specific proxy port mappings from an app
-func CommandPortsRemove(appName string, portMaps []string) error {
- if err := common.VerifyAppName(appName); err != nil {
- return err
- }
-
- if len(portMaps) == 0 {
- return errors.New("No port mapping specified")
- }
-
- proxyPortMap, err := parseProxyPortMapString(strings.Join(portMaps, " "))
- if err != nil {
- return err
- }
-
- if err := removeProxyPorts(appName, proxyPortMap); err != nil {
- return err
- }
-
- return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "remove"}...)
-}
-
-// CommandPortsSet sets proxy port mappings for an app
-func CommandPortsSet(appName string, portMaps []string) error {
- if err := common.VerifyAppName(appName); err != nil {
- return err
- }
-
- if len(portMaps) == 0 {
- return errors.New("No port mapping specified")
- }
-
- proxyPortMap, err := parseProxyPortMapString(strings.Join(portMaps, " "))
- if err != nil {
- return err
- }
-
- if err := setProxyPorts(appName, proxyPortMap); err != nil {
- return err
- }
-
- return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "set"}...)
-}
-
// CommandReport displays a proxy report for one or more apps
func CommandReport(appName string, format string, infoFlag string) error {
if len(appName) == 0 {
diff --git a/plugins/proxy/triggers.go b/plugins/proxy/triggers.go
index 626f95a3009..49c0fef0699 100644
--- a/plugins/proxy/triggers.go
+++ b/plugins/proxy/triggers.go
@@ -2,8 +2,6 @@ package proxy
import (
"fmt"
-
- "github.com/dokku/dokku/plugins/config"
)
// TriggerProxyIsEnabled prints true or false depending on whether the proxy is enabled
@@ -24,69 +22,3 @@ func TriggerProxyType(appName string) error {
return nil
}
-
-// TriggerPostCertsRemove unsets port config vars after SSL cert is added
-func TriggerPostCertsRemove(appName string) error {
- keys := []string{"DOKKU_PROXY_SSL_PORT"}
- if err := config.UnsetMany(appName, keys, false); err != nil {
- return err
- }
-
- return removeProxyPorts(appName, filterAppProxyPorts(appName, "https", 443))
-}
-
-// TriggerPostCertsUpdate sets port config vars after SSL cert is added
-func TriggerPostCertsUpdate(appName string) error {
- port := config.GetWithDefault(appName, "DOKKU_PROXY_PORT", "")
- sslPort := config.GetWithDefault(appName, "DOKKU_PROXY_SSL_PORT", "")
- proxyPortMap := getProxyPortMap(appName)
-
- toUnset := []string{}
- if port == "80" {
- toUnset = append(toUnset, "DOKKU_PROXY_PORT")
- }
- if sslPort == "443" {
- toUnset = append(toUnset, "DOKKU_PROXY_SSL_PORT")
- }
-
- if len(toUnset) > 0 {
- if err := config.UnsetMany(appName, toUnset, false); err != nil {
- return err
- }
- }
-
- var http80Ports []PortMap
- for _, portMap := range proxyPortMap {
- if portMap.Scheme == "http" && portMap.HostPort == 80 {
- http80Ports = append(http80Ports, portMap)
- }
- }
-
- if len(http80Ports) > 0 {
- var https443Ports []PortMap
- for _, portMap := range proxyPortMap {
- if portMap.Scheme == "https" && portMap.HostPort == 443 {
- https443Ports = append(https443Ports, portMap)
- }
- }
-
- if err := removeProxyPorts(appName, https443Ports); err != nil {
- return err
- }
-
- var toAdd []PortMap
- for _, portMap := range http80Ports {
- toAdd = append(toAdd, PortMap{
- Scheme: "https",
- HostPort: 443,
- ContainerPort: portMap.ContainerPort,
- })
- }
-
- if err := addProxyPorts(appName, toAdd); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/plugins/traefik-vhosts/docker-args-process-deploy b/plugins/traefik-vhosts/docker-args-process-deploy
index c81248ceaf1..f9d94ffa46b 100755
--- a/plugins/traefik-vhosts/docker-args-process-deploy
+++ b/plugins/traefik-vhosts/docker-args-process-deploy
@@ -8,7 +8,7 @@ trigger-traefik-vhosts-docker-args-process-deploy() {
declare desc="nginx-vhosts core-post-deploy plugin trigger"
declare trigger="docker-args-process-deploy"
declare APP="$1" IMAGE_SOURCE_TYPE="$2" IMAGE_TAG="$3" PROC_TYPE="$4" CONTAINER_INDEX="$5"
- local app_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_port_map priority proxy_scheme proxy_schemes traefik_domains
+ local app_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map priority proxy_scheme proxy_schemes traefik_domains
local proxy_container_http_port proxy_container_http_port_candidate proxy_host_http_port_candidate
local proxy_container_https_port proxy_container_https_port_candidate proxy_host_https_port_candidate
local STDIN=$(cat)
@@ -30,15 +30,14 @@ trigger-traefik-vhosts-docker-args-process-deploy() {
fi
# ensure we have a port mapping
- plugn trigger proxy-configure-ports "$APP"
+ plugn trigger ports-configure "$APP"
# gather port mapping information
# we only support proxying a single port for http and https listeners
# so this block parses the port mappings and tries to find the correct
# mapping to expose
is_app_listening="false"
- proxy_port_map="$(plugn trigger config-get "$APP" DOKKU_PROXY_PORT_MAP)"
- for port_map in $proxy_port_map; do
+ while read -r port_map; do
proxy_scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")"
proxy_host_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")"
proxy_container_port="$(awk -F ':' '{ print $3 }' <<<"$port_map")"
@@ -66,7 +65,7 @@ trigger-traefik-vhosts-docker-args-process-deploy() {
proxy_container_https_port="$proxy_container_port"
fi
fi
- done
+ done < <(plugn trigger ports-get "$APP")
letsencrypt_email="$(fn-traefik-letsencrypt-email)"
if [[ -n "$letsencrypt_email" ]] && [[ -z "$proxy_container_https_port" ]]; then
diff --git a/tests/unit/apps_2.bats b/tests/unit/apps_2.bats
index 2afb61fa827..966bea44efb 100644
--- a/tests/unit/apps_2.bats
+++ b/tests/unit/apps_2.bats
@@ -108,13 +108,14 @@ teardown() {
}
@test "(apps) apps:clone ssl-app" {
- run /bin/bash -c "dokku config:set --no-restart $TEST_APP DOKKU_PROXY_PORT_MAP=https:443:5000 DOKKU_PROXY_SSL_PORT=443"
+ run /bin/bash -c "dokku ports:set $TEST_APP https:443:5000"
+ run /bin/bash -c "dokku config:set --no-restart $TEST_APP DOKKU_PROXY_SSL_PORT=443"
deploy_app
run /bin/bash -c "dokku apps:clone $TEST_APP app-without-ssl"
echo "output: $output"
echo "status: $status"
assert_success
- run /bin/bash -c "dokku --quiet proxy:ports app-without-ssl | xargs"
+ run /bin/bash -c "dokku --quiet ports:list app-without-ssl | xargs"
echo "output: $output"
echo "status: $status"
assert_output "http 80 5000"
diff --git a/tests/unit/caddy.bats b/tests/unit/caddy.bats
index 1ff68959c9e..e05da79185d 100644
--- a/tests/unit/caddy.bats
+++ b/tests/unit/caddy.bats
@@ -137,7 +137,7 @@ teardown() {
assert_success
assert_output "$TEST_APP.dokku.me"
- run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map"
+ run /bin/bash -c "dokku ports:report $TEST_APP --ports-map"
echo "output: $output"
echo "status: $status"
assert_output "http:80:5000"
diff --git a/tests/unit/nginx-vhosts_3.bats b/tests/unit/nginx-vhosts_3.bats
index babc690c5fd..0a7ad5fa7c2 100644
--- a/tests/unit/nginx-vhosts_3.bats
+++ b/tests/unit/nginx-vhosts_3.bats
@@ -18,14 +18,14 @@ teardown() {
@test "(nginx-vhosts) grpc endpoint" {
deploy_app gogrpc
- dokku proxy:ports-add "$TEST_APP" "grpc:80:50051"
+ dokku ports:add "$TEST_APP" "grpc:80:50051"
run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:80 -name grpc"
assert_output "Greeting: Hello grpc"
}
@test "(nginx-vhosts) grpc endpoint on a port other than 80" {
deploy_app gogrpc
- dokku proxy:ports-add "$TEST_APP" "grpc:8080:50051"
+ dokku ports:add "$TEST_APP" "grpc:8080:50051"
run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:8080 -name grpc8080"
assert_output "Greeting: Hello grpc8080"
}
@@ -33,7 +33,7 @@ teardown() {
@test "(nginx-vhosts) grpcs endpoint" {
setup_test_tls
deploy_app gogrpc
- dokku proxy:ports-add "$TEST_APP" "grpcs:443:50051"
+ dokku ports:add "$TEST_APP" "grpcs:443:50051"
run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:443 -name grpcs -tls"
assert_output "Greeting: Hello grpcs"
}
diff --git a/tests/unit/nginx-vhosts_8.bats b/tests/unit/nginx-vhosts_8.bats
index e1de6ab34ee..f85d56d7dab 100644
--- a/tests/unit/nginx-vhosts_8.bats
+++ b/tests/unit/nginx-vhosts_8.bats
@@ -125,7 +125,7 @@ teardown() {
assert_output_contains "Ignoring detected https port mapping without an accompanying ssl certificate" 0
teardown_test_tls
- run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map"
+ run /bin/bash -c "dokku ports:report $TEST_APP --ports-map"
echo "output: $output"
echo "status: $status"
assert_output "http:80:5000 https:443:5000"
@@ -135,7 +135,7 @@ teardown() {
echo "status: $status"
assert_output_contains "Ignoring detected https port mapping without an accompanying ssl certificate" 1
- run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map"
+ run /bin/bash -c "dokku ports:report $TEST_APP --ports-map"
echo "output: $output"
echo "status: $status"
assert_output "http:80:5000 https:443:5000"
diff --git a/tests/unit/ports.bats b/tests/unit/ports.bats
new file mode 100644
index 00000000000..d982a36496a
--- /dev/null
+++ b/tests/unit/ports.bats
@@ -0,0 +1,106 @@
+#!/usr/bin/env bats
+
+load test_helper
+
+setup() {
+ global_setup
+ [[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
+ create_app
+}
+
+teardown() {
+ destroy_app 0 $TEST_APP
+ [[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
+ global_teardown
+}
+
+@test "(ports) ports:help" {
+ run /bin/bash -c "dokku ports"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output_contains "Manage ports for an app"
+ help_output="$output"
+
+ run /bin/bash -c "dokku ports:help"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output_contains "Manage ports for an app"
+ assert_output "$help_output"
+}
+
+@test "(ports) list/add/set/remove/clear" {
+ run /bin/bash -c "dokku ports:set $TEST_APP http:1234:5001"
+ echo "output: $output"
+ echo "status: $status"
+ assert_success
+
+ run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output "http 1234 5001"
+
+ run /bin/bash -c "dokku ports:add $TEST_APP http:8080:5002 https:8443:5003"
+ echo "output: $output"
+ echo "status: $status"
+ assert_success
+
+ run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output "http 1234 5001 http 8080 5002 https 8443 5003"
+
+ run /bin/bash -c "dokku ports:set $TEST_APP http:8080:5000 https:8443:5000 http:1234:5001"
+ echo "output: $output"
+ echo "status: $status"
+ assert_success
+
+ run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output "http 1234 5001 http 8080 5000 https 8443 5000"
+
+ run /bin/bash -c "dokku ports:remove $TEST_APP 8080"
+ echo "output: $output"
+ echo "status: $status"
+ assert_success
+
+ run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output "http 1234 5001 https 8443 5000"
+
+ run /bin/bash -c "dokku ports:remove $TEST_APP http:1234:5001"
+ echo "output: $output"
+ echo "status: $status"
+ assert_success
+
+ run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output "https 8443 5000"
+
+ run /bin/bash -c "dokku ports:clear $TEST_APP"
+ echo "output: $output"
+ echo "status: $status"
+ assert_success
+
+ run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs"
+ echo "output: $output"
+ echo "status: $status"
+ assert_output "http 80 5000"
+}
+
+@test "(ports) ports:add (post-deploy add)" {
+ deploy_app
+ run /bin/bash -c "dokku ports:add $TEST_APP http:8080:5000 http:8081:5000"
+ echo "output: $output"
+ echo "status: $status"
+ assert_success
+
+ URLS="$(dokku --quiet urls "$TEST_APP")"
+ for URL in $URLS; do
+ assert_http_success $URL
+ done
+ assert_http_success "http://$TEST_APP.dokku.me:8080"
+ assert_http_success "http://$TEST_APP.dokku.me:8081"
+}
diff --git a/tests/unit/proxied-app.bats b/tests/unit/proxied-app.bats
index e16928634dd..3d4ed454842 100644
--- a/tests/unit/proxied-app.bats
+++ b/tests/unit/proxied-app.bats
@@ -29,7 +29,7 @@ teardown() {
echo "status: $status"
assert_success
- run /bin/bash -c "dokku proxy:ports-set $TEST_APP http:80:8080"
+ run /bin/bash -c "dokku ports:set $TEST_APP http:80:8080"
echo "output: $output"
echo "status: $status"
assert_success
diff --git a/tests/unit/proxy.bats b/tests/unit/proxy.bats
index be69693fde1..1de3c9db0c4 100644
--- a/tests/unit/proxy.bats
+++ b/tests/unit/proxy.bats
@@ -113,80 +113,3 @@ teardown() {
assert_not_external_port $(<$CID_FILE)
done
}
-
-@test "(proxy) proxy:ports (list/add/set/remove/clear)" {
- run /bin/bash -c "dokku proxy:ports-set $TEST_APP http:1234:5001"
- echo "output: $output"
- echo "status: $status"
- assert_success
-
- run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
- echo "output: $output"
- echo "status: $status"
- assert_output "http 1234 5001"
-
- run /bin/bash -c "dokku proxy:ports-add $TEST_APP http:8080:5002 https:8443:5003"
- echo "output: $output"
- echo "status: $status"
- assert_success
-
- run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
- echo "output: $output"
- echo "status: $status"
- assert_output "http 1234 5001 http 8080 5002 https 8443 5003"
-
- run /bin/bash -c "dokku proxy:ports-set $TEST_APP http:8080:5000 https:8443:5000 http:1234:5001"
- echo "output: $output"
- echo "status: $status"
- assert_success
-
- run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
- echo "output: $output"
- echo "status: $status"
- assert_output "http 1234 5001 http 8080 5000 https 8443 5000"
-
- run /bin/bash -c "dokku proxy:ports-remove $TEST_APP 8080"
- echo "output: $output"
- echo "status: $status"
- assert_success
-
- run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
- echo "output: $output"
- echo "status: $status"
- assert_output "http 1234 5001 https 8443 5000"
-
- run /bin/bash -c "dokku proxy:ports-remove $TEST_APP http:1234:5001"
- echo "output: $output"
- echo "status: $status"
- assert_success
-
- run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
- echo "output: $output"
- echo "status: $status"
- assert_output "https 8443 5000"
-
- run /bin/bash -c "dokku proxy:ports-clear $TEST_APP"
- echo "output: $output"
- echo "status: $status"
- assert_success
-
- run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
- echo "output: $output"
- echo "status: $status"
- assert_output "http 80 5000"
-}
-
-@test "(proxy) proxy:ports (post-deploy add)" {
- deploy_app
- run /bin/bash -c "dokku proxy:ports-add $TEST_APP http:8080:5000 http:8081:5000"
- echo "output: $output"
- echo "status: $status"
- assert_success
-
- URLS="$(dokku --quiet urls "$TEST_APP")"
- for URL in $URLS; do
- assert_http_success $URL
- done
- assert_http_success "http://$TEST_APP.dokku.me:8080"
- assert_http_success "http://$TEST_APP.dokku.me:8081"
-}
diff --git a/tests/unit/test_helper.bash b/tests/unit/test_helper.bash
index 2c1f34a8b1c..a6a3aaa9560 100644
--- a/tests/unit/test_helper.bash
+++ b/tests/unit/test_helper.bash
@@ -288,7 +288,7 @@ assert_url() {
echo "VHOST: $(cat $DOKKU_ROOT/$TEST_APP/VHOST | xargs)"
echo "tls: $(ls $DOKKU_ROOT/$TEST_APP/tls || true)"
echo "proxy-is-enabled: $(dokku plugin:trigger proxy-is-enabled "$TEST_APP")"
- echo "port-map: $(dokku config:get "$TEST_APP" DOKKU_PROXY_PORT_MAP)"
+ echo "port-map: $(dokku ports:report "$TEST_APP" --ports-map)"
echo "url: $(dokku urls $TEST_APP)"
echo "output: $output"
echo "status: $status"
@@ -302,7 +302,7 @@ assert_urls() {
echo "VHOST: $(cat $DOKKU_ROOT/$TEST_APP/VHOST | xargs)"
echo "tls: $(ls $DOKKU_ROOT/$TEST_APP/tls || true)"
echo "proxy-is-enabled: $(dokku plugin:trigger proxy-is-enabled "$TEST_APP")"
- echo "port-map: $(dokku config:get "$TEST_APP" DOKKU_PROXY_PORT_MAP)"
+ echo "port-map: $(dokku ports:report "$TEST_APP" --ports-map)"
echo "urls: $(dokku urls $TEST_APP)"
echo "output: $output"
echo "status: $status"
diff --git a/tests/unit/traefik.bats b/tests/unit/traefik.bats
index 4c3b0e82c57..d7cdb647e2d 100644
--- a/tests/unit/traefik.bats
+++ b/tests/unit/traefik.bats
@@ -177,7 +177,7 @@ teardown() {
assert_success
assert_output "5000"
- run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map"
+ run /bin/bash -c "dokku ports:report $TEST_APP --ports-map"
echo "output: $output"
echo "status: $status"
assert_output "http:80:5000"