Merge pull request #7608 from dragonhunt02/label

Add commands to proxy implementations for managing labels
This commit is contained in:
Jose Diaz-Gonzalez
2025-11-17 00:20:03 -05:00
committed by GitHub
39 changed files with 880 additions and 54 deletions

View File

@@ -5,3 +5,4 @@
- Support for the `DOKKU_DOCKERFILE_CACHE_BUILD` environment variable has been removed. Use the `docker-options` plugin to set build arguments for your app instead.
- Support for the `DOKKU_DOCKER_BUILD_OPTS` environment variable has been removed. Use the `docker-options` plugin to set build arguments for your app instead.
- Support for the `no-cache` nixpacks property has been removed. Use the `docker-options` plugin to set build arguments for your app instead.
- Support for customizing the label-key for the caddy proxy has been removed. Always use `caddy.` as a prefix for your caddy directives.

View File

@@ -3,7 +3,7 @@
> [!IMPORTANT]
> New as of 0.28.0
Dokku provides integration with the [Caddy](https://caddyserver.com/) proxy service by utilizing the Docker label-based integration implemented by Caddy.
Dokku provides integration with the [Caddy](https://caddyserver.com/) proxy service by utilizing the Docker label-based integration implemented by [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy).
```
caddy:report [<app>] [<flag>] # Displays a caddy report for one or more apps
@@ -117,15 +117,53 @@ dokku caddy:set --global log-level DEBUG
After modifying, the Caddy container will need to be restarted.
### Changing the label key for the app
### Label Management
The default label key for the app is `caddy`. This can be changed by setting the `label-key` property:
The Caddy plugin allows you to add custom container labels to apps. These labels are injected into containers during deployment and can be used to configure Caddy behavior beyond what the plugin provides by default.
Refer to the upstream [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) documentation for more information on what labels are available.
#### Adding a label
To add a custom container label to an app, use the `caddy:labels:add` command:
```shell
dokku caddy:set node-js-app label-key caddy_0
dokku caddy:labels:add node-js-app caddy.directive value
```
This will update the app's label key to `caddy_0`. The label key is used to identify the app in the Caddy configuration. If you change the label key, you will need to restart or rebuild the app to apply the updates.
This will add the label `caddy.directive=value` to the app's containers. After adding a label, you will need to rebuild or redeploy the app for the label to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Removing a label
To remove a custom container label from an app, use the `caddy:labels:remove` command:
```shell
dokku caddy:labels:remove node-js-app caddy.directive
```
This will remove the specified label from the app. After removing a label, you will need to rebuild or redeploy the app for the change to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Showing labels
To view all custom container labels for an app, use the `caddy:labels:show` command:
```shell
dokku caddy:labels:show node-js-app
```
To view a specific label value, provide the label name:
```shell
dokku caddy:labels:show node-js-app caddy.directive
```
### SSL Configuration

View File

@@ -113,6 +113,54 @@ dokku haproxy:set --global log-level DEBUG
After modifying, the Haproxy container will need to be restarted.
### Label Management
The Haproxy plugin allows you to add custom container labels to apps. These labels are injected into containers during deployment and can be used to configure Haproxy behavior beyond what the plugin provides by default.
Refer to the upstream [EasyHaproxy](https://github.com/byjg/docker-easy-haproxy) documentation for more information on what labels are available.
#### Adding a label
To add a custom container label to an app, use the `haproxy:labels:add` command:
```shell
dokku haproxy:labels:add node-js-app haproxy.directive value
```
This will add the label `haproxy.directive=value` to the app's containers. After adding a label, you will need to rebuild or redeploy the app for the label to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Removing a label
To remove a custom container label from an app, use the `haproxy:labels:remove` command:
```shell
dokku haproxy:labels:remove node-js-app haproxy.directive
```
This will remove the specified label from the app. After removing a label, you will need to rebuild or redeploy the app for the change to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Showing labels
To view all custom container labels for an app, use the `haproxy:labels:show` command:
```shell
dokku haproxy:labels:show node-js-app
```
To view a specific label value, provide the label name:
```shell
dokku haproxy:labels:show node-js-app haproxy.directive
```
### SSL Configuration
The haproxy plugin only supports automatic ssl certificates from it's letsencrypt integration. Managed certificates provided by the `certs` plugin are ignored.

View File

@@ -124,6 +124,54 @@ The following folders within an app repository may have `*.conf` files that will
- `openresty/http-includes/`: Injected in the `server` block serving http(s) requests for the app.
- `openresty/http-location-includes/`: Injected in the `location` block that proxies to the app in the app's respective `server` block.
### Label Management
The OpenResty plugin allows you to add custom container labels to apps. These labels are injected into containers during deployment and can be used to configure OpenResty behavior beyond what the plugin provides by default.
Refer to the upstream [openresty-docker-proxy](https://github.com/dokku/openresty-docker-proxy) documentation for more information on what labels are available.
#### Adding a label
To add a custom container label to an app, use the `openresty:labels:add` command:
```shell
dokku openresty:labels:add node-js-app openresty.directive value
```
This will add the label `openresty.directive=value` to the app's containers. After adding a label, you will need to rebuild or redeploy the app for the label to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Removing a label
To remove a custom container label from an app, use the `openresty:labels:remove` command:
```shell
dokku openresty:labels:remove node-js-app openresty.directive
```
This will remove the specified label from the app. After removing a label, you will need to rebuild or redeploy the app for the change to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Showing labels
To view all custom container labels for an app, use the `openresty:labels:show` command:
```shell
dokku openresty:labels:show node-js-app
```
To view a specific label value, provide the label name:
```shell
dokku openresty:labels:show node-js-app openresty.directive
```
### SSL Configuration
The OpenResty plugin only supports automatic ssl certificates from it's letsencrypt integration. Managed certificates provided by the `certs` plugin are ignored.

View File

@@ -127,6 +127,54 @@ dokku traefik:set --global log-level DEBUG
After modifying, the Traefik container will need to be restarted.
### Label Management
The Traefik plugin allows you to add custom container labels to apps. These labels are injected into containers during deployment and can be used to configure Traefik behavior beyond what the plugin provides by default.
Refer to the upstream [Traefik](https://doc.traefik.io/traefik/) documentation for more information on what labels are available.
#### Adding a label
To add a custom container label to an app, use the `traefik:labels:add` command:
```shell
dokku traefik:labels:add node-js-app traefik.directive value
```
This will add the label `traefik.directive=value` to the app's containers. After adding a label, you will need to rebuild or redeploy the app for the label to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Removing a label
To remove a custom container label from an app, use the `traefik:labels:remove` command:
```shell
dokku traefik:labels:remove node-js-app traefik.directive
```
This will remove the specified label from the app. After removing a label, you will need to rebuild or redeploy the app for the change to be applied to running containers.
```shell
dokku ps:rebuild node-js-app
```
#### Showing labels
To view all custom container labels for an app, use the `traefik:labels:show` command:
```shell
dokku traefik:labels:show node-js-app
```
To view a specific label value, provide the label name:
```shell
dokku traefik:labels:show node-js-app traefik.directive
```
### SSL Configuration
The traefik plugin only supports automatic ssl certificates from it's letsencrypt integration. Managed certificates provided by the `certs` plugin are ignored.

View File

@@ -1,9 +1,34 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions"
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-caddy-labels-add() {
declare desc="adds container label to app for specified proxy"
declare cmd="caddy:labels:add"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-add "proxy:labels:add" "caddy" "$@"
}
cmd-caddy-labels-remove() {
declare desc="removes container label from app for specified proxy"
declare cmd="caddy:labels:remove"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-remove "proxy:labels:remove" "caddy" "$@"
}
cmd-caddy-labels-show() {
declare desc="shows container labels for app for specified proxy"
declare cmd="caddy:labels:show"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-show "proxy:labels:show" "caddy" "$@"
}
cmd-caddy-report() {
declare desc="displays a caddy report for one or more apps"
declare cmd="caddy:report"

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
[[ " caddy:help help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " caddy:help caddy:labels:add caddy:labels:remove caddy:labels:show help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/help-functions"
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/command-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -9,6 +10,18 @@ case "$1" in
cmd-caddy-help "$@"
;;
caddy:labels:add)
cmd-caddy-labels-add "$@"
;;
caddy:labels:remove)
cmd-caddy-labels-remove "$@"
;;
caddy:labels:show)
cmd-caddy-labels-show "$@"
;;
*)
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
;;

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -8,7 +9,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_scheme proxy_schemes scheme tls_internal label_key
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)
@@ -88,14 +89,13 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
if [[ -n "$is_app_listening" ]] && [[ -n "$caddy_domains" ]]; then
has_443_mapping=false
tls_internal="$(fn-caddy-tls-internal)"
label_key="$(fn-caddy-label-key "$APP")"
if [[ -n "$proxy_container_https_port" ]] || [[ -n "$proxy_container_https_port_candidate" ]]; then
has_443_mapping=true
fi
ssl_warning_mapping="https:443"
if [[ "$tls_internal" == "true" ]]; then
output="--label ${label_key}.tls=internal"
output="--label caddy.tls=internal"
if [[ "$has_443_mapping" == "false" ]]; then
ssl_warning_mapping="http:80"
proxy_host_https_port_candidate="$proxy_host_http_port_candidate"
@@ -106,7 +106,7 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
scheme="http"
if [[ -n "$letsencrypt_email" ]] && [[ "$has_443_mapping" == "true" ]]; then
output="--label '${label_key}=${caddy_domains}'"
output="--label 'caddy=${caddy_domains}'"
scheme="https"
if [[ -z "$proxy_container_https_port" ]]; then
warning_scheme="$(awk -F ':' '{ print $1 }' <<<"$ssl_warning_mapping")"
@@ -115,20 +115,28 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
proxy_container_https_port="$proxy_container_https_port_candidate"
fi
output="$output --label \"${label_key}.reverse_proxy={{ upstreams $proxy_container_https_port }}\""
output="$output --label \"caddy.reverse_proxy={{ upstreams $proxy_container_https_port }}\""
elif [[ -n "$proxy_container_http_port" ]] || [[ -n "$proxy_container_http_port_candidate" ]]; then
caddy_domains="${caddy_domains//, /:80, }"
output="--label '${label_key}=${caddy_domains}:80'"
output="--label 'caddy=${caddy_domains}:80'"
if [[ -z "$proxy_container_http_port" ]]; then
dokku_log_warn "Warning: http:80 port mapping not found"
dokku_log_warn "Utilizing first http port mapping, http:$proxy_host_http_port_candidate:$proxy_container_http_port_candidate"
proxy_container_http_port="$proxy_container_http_port_candidate"
fi
output="$output --label \"${label_key}.reverse_proxy={{ upstreams $proxy_container_http_port }}\""
output="$output --label \"caddy.reverse_proxy={{ upstreams $proxy_container_http_port }}\""
fi
fi
local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "caddy" "$APP")
if [[ -f "$proxy_labels_file_path" ]]; then
while read -r line; do
[[ -z "$line" ]] && continue
output="$output --label '$line'"
done <"$proxy_labels_file_path"
fi
echo -n "$STDIN$output"
}

View File

@@ -30,6 +30,9 @@ fn-help-content() {
caddy:report [<app>] [<flag>], Displays an caddy report for one or more apps
caddy:set <app> <property> (<value>), Set or clear an caddy property for an app
caddy:show-config <app>, Display caddy compose config
caddy:labels:add <app> <label> <value>, Add a label to an caddy app
caddy:labels:remove <app> <label>, Remove a label from an caddy app
caddy:labels:show <app> [<label>], Show labels for an caddy app
caddy:start, Starts the caddy server
caddy:stop, Stops the caddy server
help_content

View File

@@ -71,8 +71,3 @@ fn-caddy-tls-internal() {
declare APP="$1"
fn-plugin-property-get-default "caddy" "$APP" "tls-internal" "false"
}
fn-caddy-label-key() {
declare APP="$1"
fn-plugin-property-get-default "caddy" "$APP" "label-key" "caddy"
}

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
trigger-caddy-vhosts-post-create() {
declare desc="caddy-vhosts post-create trigger"
declare trigger="post-create"
declare APP="$1"
fn-plugin-property-setup-app "caddy" "$APP"
}
trigger-caddy-vhosts-post-create "$@"

View File

@@ -9,13 +9,13 @@ cmd-caddy-set() {
declare cmd="caddy:set"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" KEY="$2" VALUE="$3"
local VALID_KEYS=("image" "letsencrypt-email" "letsencrypt-server" "log-level" "polling-interval" "label-key" "tls-internal")
local VALID_KEYS=("image" "letsencrypt-email" "letsencrypt-server" "log-level" "polling-interval" "tls-internal")
local GLOBAL_KEYS=("image" "letsencrypt-email" "letsencrypt-server" "log-level" "polling-interval")
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
dokku_log_fail "Invalid key specified, valid keys include: image letsencrypt-email letsencrypt-server log-level polling-interval label-key tls-internal"
dokku_log_fail "Invalid key specified, valid keys include: image letsencrypt-email letsencrypt-server log-level polling-interval tls-internal"
fi
if ! fn-in-array "$KEY" "${GLOBAL_KEYS[@]}"; then

View File

@@ -540,6 +540,14 @@ func PropertySetup(pluginName string) error {
})
}
func PropertySetupApp(pluginName string, appName string) error {
if err := makePluginAppPropertyPath(pluginName, appName); err != nil {
return fmt.Errorf("Unable to create %s config directory for %s: %s", pluginName, appName, err.Error())
}
return nil
}
func getPropertyPath(pluginName string, appName string, property string) string {
pluginAppConfigRoot := getPluginAppPropertyPath(pluginName, appName)
return filepath.Join(pluginAppConfigRoot, property)

View File

@@ -104,3 +104,9 @@ fn-plugin-property-setup() {
declare PLUGIN="$1"
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" "setup" "$PLUGIN"
}
fn-plugin-property-setup-app() {
declare desc="setup the properties for an app"
declare PLUGIN="$1" APP="$2"
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" "setup-app" "$PLUGIN" "$APP"
}

View File

@@ -194,5 +194,12 @@ func main() {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
case "setup-app":
appName := flag.Arg(2)
err := common.PropertySetupApp(pluginName, appName)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}
}

View File

@@ -24,7 +24,7 @@ Additional commands:`
config:clear [--no-restart] (<app>|--global), Clears environment variables
config:export [--format=FORMAT] [--merged] (<app>|--global), Export a global or app environment
config:get [--quoted] (<app>|--global) KEY, Display a global or app-specific config value
config:import [--no-restart] [--replace] (<app>|--global) [FILE|-], Import environment from file
config:import [--no-restart] [--replace] (<app>|--global) [FILE|-], Import environment from file
config:keys [--merged] (<app>|--global), Show keys set in environment
config:show [--merged] (<app>|--global), Show keys set in environment
config:set [--encoded] [--no-restart] (<app>|--global) KEY1=VALUE1 [KEY2=VALUE2 ...], Set one or more config vars

View File

@@ -1,9 +1,34 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions"
source "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-haproxy-labels-add() {
declare desc="adds container label to app for specified proxy"
declare cmd="haproxy:labels:add"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-add "proxy:labels:add" "haproxy" "$@"
}
cmd-haproxy-labels-remove() {
declare desc="removes container label from app for specified proxy"
declare cmd="haproxy:labels:remove"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-remove "proxy:labels:remove" "haproxy" "$@"
}
cmd-haproxy-labels-show() {
declare desc="shows container labels for app for specified proxy"
declare cmd="haproxy:labels:show"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-show "proxy:labels:show" "haproxy" "$@"
}
cmd-haproxy-report() {
declare desc="displays a haproxy report for one or more apps"
declare cmd="haproxy:report"

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
[[ " haproxy:help help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " haproxy:help haproxy:labels:add haproxy:labels:remove haproxy:labels:show help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
source "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/help-functions"
source "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/command-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -9,6 +10,18 @@ case "$1" in
cmd-haproxy-help "$@"
;;
haproxy:labels:add)
cmd-haproxy-labels-add "$@"
;;
haproxy:labels:remove)
cmd-haproxy-labels-remove "$@"
;;
haproxy:labels:show)
cmd-haproxy-labels-show "$@"
;;
*)
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
;;

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -123,6 +124,14 @@ trigger-haproxy-vhosts-docker-args-process-deploy() {
fi
fi
local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "haproxy" "$APP")
if [[ -f "$proxy_labels_file_path" ]]; then
while read -r line; do
[[ -z "$line" ]] && continue
output="$output --label '$line'"
done <"$proxy_labels_file_path"
fi
echo -n "$STDIN$output"
}

View File

@@ -30,6 +30,9 @@ fn-help-content() {
haproxy:report [<app>] [<flag>], Displays an haproxy report for one or more apps
haproxy:set <app> <property> (<value>), Set or clear an haproxy property for an app
haproxy:show-config <app>, Display haproxy compose config
haproxy:labels:add <app> <label> <value>, Add a label to an haproxy app
haproxy:labels:remove <app> <label>, Remove a label from an haproxy app
haproxy:labels:show <app> [<label>], Show labels for an haproxy app
haproxy:start, Starts the haproxy server
haproxy:stop, Stops the haproxy server
help_content

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
trigger-haproxy-vhosts-post-create() {
declare desc="haproxy-vhosts post-create trigger"
declare trigger="post-create"
declare APP="$1"
fn-plugin-property-setup-app "haproxy" "$APP"
}
trigger-haproxy-vhosts-post-create "$@"

View File

@@ -1,9 +1,34 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions"
source "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-openresty-labels-add() {
declare desc="adds container label to app for specified proxy"
declare cmd="openresty:labels:add"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-add "proxy:labels:add" "openresty" "$@"
}
cmd-openresty-labels-remove() {
declare desc="removes container label from app for specified proxy"
declare cmd="openresty:labels:remove"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-remove "proxy:labels:remove" "openresty" "$@"
}
cmd-openresty-labels-show() {
declare desc="shows container labels for app for specified proxy"
declare cmd="openresty:labels:show"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-show "proxy:labels:show" "openresty" "$@"
}
cmd-openresty-report() {
declare desc="displays a openresty report for one or more apps"
declare cmd="openresty:report"

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
[[ " openresty:help help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " openresty:help openresty:labels:add openresty:labels:remove openresty:labels:show help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
source "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/help-functions"
source "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/command-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -9,6 +10,18 @@ case "$1" in
cmd-openresty-help "$@"
;;
openresty:labels:add)
cmd-openresty-labels-add "$@"
;;
openresty:labels:remove)
cmd-openresty-labels-remove "$@"
;;
openresty:labels:show)
cmd-openresty-labels-show "$@"
;;
*)
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
;;

View File

@@ -2,6 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/internal-functions"
trigger-openresty-vhosts-docker-args-process-deploy() {
@@ -181,6 +182,14 @@ trigger-openresty-vhosts-docker-args-process-deploy() {
value="$(fn-openresty-x-forwarded-ssl "$APP")"
[[ -n "$value" ]] && output="$output '--label=openresty.x-forwarded-ssl=$value'"
local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "openresty" "$APP")
if [[ -f "$proxy_labels_file_path" ]]; then
while read -r line; do
[[ -z "$line" ]] && continue
output="$output --label '$line'"
done <"$proxy_labels_file_path"
fi
echo -n "$STDIN$output"
}

View File

@@ -30,6 +30,9 @@ fn-help-content() {
openresty:report [<app>] [<flag>], Displays an openresty report for one or more apps
openresty:set <app> <property> (<value>), Set or clear an openresty property for an app
openresty:show-config <app>, Display openresty compose config
openresty:labels:add <app> <label> <value>, Add a label to an openresty app
openresty:labels:remove <app> <label>, Remove a label from an openresty app
openresty:labels:show <app> [<label>], Show labels for an openresty app
openresty:start, Starts the openresty server
openresty:stop, Stops the openresty server
help_content

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
trigger-openresty-vhosts-post-create() {
declare desc="openresty-vhosts post-create trigger"
declare trigger="post-create"
declare APP="$1"
fn-plugin-property-setup-app "openresty" "$APP"
}
trigger-openresty-vhosts-post-create "$@"

62
plugins/proxy/command-functions Executable file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-proxy-labels-show() {
declare desc="show a proxy label for an app"
declare cmd="proxy:labels:show"
[[ "$1" == "$cmd" ]] && shift 1
declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3"
[[ -z "$PROXY" ]] && dokku_log_fail "Error invoking proxy:labels:show command"
verify_app_name "$APP"
if [[ -n "$PASSED_LABEL_NAME" ]]; then
fn-proxy-show-label "$PROXY" "$APP" "$PASSED_LABEL_NAME"
return
fi
fn-proxy-display-labels "$PROXY" "$APP"
}
cmd-proxy-labels-add() {
declare desc="adds container label to app for specified proxy"
declare cmd="proxy:labels:add"
[[ "$1" == "$cmd" ]] && shift 1
declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3" PASSED_LABEL_VALUE="$4"
[[ -z "$PROXY" ]] && dokku_log_fail "Error invoking proxy:labels:add command"
[[ -z "$PASSED_LABEL_NAME" ]] && dokku_log_fail "Please specify a container label for the app"
[[ -z "$PASSED_LABEL_VALUE" ]] && dokku_log_fail "Please specify a value for the container label"
verify_app_name "$APP"
local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")"
touch "$proxy_labels_file_path"
cmd-proxy-labels-remove "$PROXY" "$APP" "$PASSED_LABEL_NAME" >/dev/null
echo "${PASSED_LABEL_NAME}=${PASSED_LABEL_VALUE}" >>"$proxy_labels_file_path"
local all_proxy_labels="$(<"$proxy_labels_file_path")"
echo -e "${all_proxy_labels}" | sed '/^$/d' | sort -u >"$proxy_labels_file_path"
}
cmd-proxy-labels-remove() {
declare desc="removes container label from app for specified proxy"
declare cmd="proxy:labels:remove"
[[ "$1" == "$cmd" ]] && shift 1
declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3"
[[ -z "$PROXY" ]] && dokku_log_fail "Error invoking proxy:labels:remove command"
[[ -z "$PASSED_LABEL_NAME" ]] && dokku_log_fail "Please specify a container label for the app"
verify_app_name "$APP"
local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")"
if [[ ! -s "$proxy_labels_file_path" ]]; then
return
fi
local all_proxy_labels="$(<"$proxy_labels_file_path")"
local escaped_label_name="$(fn-proxy-escape-extended-sed "$PASSED_LABEL_NAME")"
local all_proxy_labels="$(echo -e "${all_proxy_labels}" | sed -E "s/^${escaped_label_name}=.*\$//")"
echo -e "${all_proxy_labels}" | sed '/^$/d' | sort -u >"$proxy_labels_file_path"
}

58
plugins/proxy/functions Executable file
View File

@@ -0,0 +1,58 @@
#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
fn-proxy-escape-extended-sed() {
# Escaped delimiter is '/'
local input="$1"
echo "$input" | sed -E 's#[][()\.^$?*+{}|/]#\\&#g'
}
fn-proxy-get-labels-file-path() {
declare desc="return proxy labels config file path for specified proxy"
declare PROXY="$1" APP="$2"
local PROXY_FILE="${DOKKU_LIB_ROOT}/config/${PROXY}/${APP}/labels"
echo "$PROXY_FILE"
}
fn-proxy-display-labels() {
declare desc="print user-set app container labels for specified proxy"
declare PROXY="$1" APP="$2"
local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")"
if [[ -s "$proxy_labels_file_path" ]]; then
dokku_log_info2_quiet "${APP} ${PROXY} labels"
while read -r line; do
[[ -z "$line" ]] && continue
case "$line" in
\#*)
continue
;;
*)
dokku_log_verbose "$line"
;;
esac
done <"$proxy_labels_file_path"
else
dokku_log_warn_quiet "No ${PROXY} labels set for ${APP}"
fi
}
fn-proxy-show-label() {
declare desc="print single user-set app container label for specified proxy"
declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3"
local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")"
if [[ ! -s "$proxy_labels_file_path" ]]; then
return
fi
local all_proxy_labels="$(<"$proxy_labels_file_path")"
local escaped_label_name="$(fn-proxy-escape-extended-sed "$PASSED_LABEL_NAME")"
local proxy_label_value="$(echo -e "${all_proxy_labels}" | sed -E -n "s/^${escaped_label_name}=(.*)\$/\1/p")"
echo "$proxy_label_value"
}

View File

@@ -22,7 +22,7 @@ Additional commands:`
scheduler-k3s:cluster-add [--insecure-allow-unknown-hosts] [--server-ip SERVER_IP] [--taint-scheduling] <ssh://user@host:port>, Adds a server node to a Dokku-managed cluster
scheduler-k3s:cluster-list [--format json|stdout], Lists all nodes in a Dokku-managed cluster
scheduler-k3s:cluster-remove [node-id], Removes client node to a Dokku-managed cluster
scheduler-k3s:ensure-charts, Ensures the k3s charts are installed
scheduler-k3s:ensure-charts, Ensures the k3s charts are installed
scheduler-k3s:initialize [--server-ip SERVER_IP] [--taint-scheduling], Initializes a cluster
scheduler-k3s:labels:set <app|--global> <property> (<value>) [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear a label for a given app/process-type/resource-type combination
scheduler-k3s:report [<app>] [<flag>], Displays a scheduler-k3s report for one or more apps

View File

@@ -1,9 +1,34 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions"
source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-traefik-labels-add() {
declare desc="adds container label to app for specified proxy"
declare cmd="traefik:labels:add"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-add "proxy:labels:add" "traefik" "$@"
}
cmd-traefik-labels-remove() {
declare desc="removes container label from app for specified proxy"
declare cmd="traefik:labels:remove"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-remove "proxy:labels:remove" "traefik" "$@"
}
cmd-traefik-labels-show() {
declare desc="shows container labels for app for specified proxy"
declare cmd="traefik:labels:show"
[[ "$1" == "$cmd" ]] && shift 1
cmd-proxy-labels-show "proxy:labels:show" "traefik" "$@"
}
cmd-traefik-report() {
declare desc="displays a traefik report for one or more apps"
declare cmd="traefik:report"

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
[[ " traefik:help help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " traefik:help traefik:labels:add traefik:labels:remove traefik:labels:show help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/help-functions"
source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/command-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -9,6 +10,18 @@ case "$1" in
cmd-traefik-help "$@"
;;
traefik:labels:add)
cmd-traefik-labels-add "$@"
;;
traefik:labels:remove)
cmd-traefik-labels-remove "$@"
;;
traefik:labels:show)
cmd-traefik-labels-show "$@"
;;
*)
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
;;

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -130,6 +131,14 @@ trigger-traefik-vhosts-docker-args-process-deploy() {
fi
fi
local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "traefik" "$APP")
if [[ -f "$proxy_labels_file_path" ]]; then
while read -r line; do
[[ -z "$line" ]] && continue
output="$output --label '$line'"
done <"$proxy_labels_file_path"
fi
echo -n "$STDIN$output"
}

View File

@@ -30,6 +30,9 @@ fn-help-content() {
traefik:report [<app>] [<flag>], Displays an traefik report for one or more apps
traefik:set <app> <property> (<value>), Set or clear an traefik property for an app
traefik:show-config <app>, Display traefik compose config
traefik:labels:add <app> <label> <value>, Add a label to an traefik app
traefik:labels:remove <app> <label>, Remove a label from an traefik app
traefik:labels:show <app> [<label>], Show labels for an traefik app
traefik:start, Starts the traefik server
traefik:stop, Stops the traefik server
help_content

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
trigger-traefik-vhosts-post-create() {
declare desc="traefik-vhosts post-create trigger"
declare trigger="post-create"
declare APP="$1"
fn-plugin-property-setup-app "traefik" "$APP"
}
trigger-traefik-vhosts-post-create "$@"

View File

@@ -50,34 +50,6 @@ teardown() {
assert_output_contains "python/http.server"
}
@test "(caddy) custom label key" {
run /bin/bash -c "dokku builder-herokuish:set $TEST_APP allowed true"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku proxy:set $TEST_APP caddy"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku caddy:set $TEST_APP label-key caddy_0"
echo "output: $output"
echo "status: $status"
assert_success
run deploy_app
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"caddy_0\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$TEST_APP.${DOKKU_DOMAIN}:80"
}
@test "(caddy) multiple domains" {
run /bin/bash -c "dokku proxy:set $TEST_APP caddy"
echo "output: $output"
@@ -175,3 +147,72 @@ teardown() {
echo "status: $status"
assert_output "http:80:5000 https:443:5000"
}
@test "(caddy) label management" {
run /bin/bash -c "dokku proxy:set $TEST_APP caddy"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku caddy:labels:add $TEST_APP caddy.directive value"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku caddy:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "caddy.directive=value"
run /bin/bash -c "dokku caddy:labels:show $TEST_APP caddy.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku caddy:labels:show $TEST_APP caddy.directive2"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run deploy_app
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"caddy.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku caddy:labels:remove $TEST_APP caddy.directive"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku caddy:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_contains "caddy.directive=value"
run /bin/bash -c "dokku caddy:labels:show $TEST_APP caddy.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"caddy.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
}

View File

@@ -172,3 +172,72 @@ teardown() {
echo "status: $status"
assert_output "http:80:5000 https:443:5000"
}
@test "(haproxy) label management" {
run /bin/bash -c "dokku proxy:set $TEST_APP haproxy"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku haproxy:labels:add $TEST_APP haproxy.directive value"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku haproxy:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "haproxy.directive=value"
run /bin/bash -c "dokku haproxy:labels:show $TEST_APP haproxy.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku haproxy:labels:show $TEST_APP haproxy.directive2"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run deploy_app
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"haproxy.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku haproxy:labels:remove $TEST_APP haproxy.directive"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku haproxy:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_contains "haproxy.directive=value"
run /bin/bash -c "dokku haproxy:labels:show $TEST_APP haproxy.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"haproxy.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
}

View File

@@ -245,6 +245,75 @@ teardown() {
assert_output_contains "charset UTF-8;"
}
@test "(openresty) label management" {
run /bin/bash -c "dokku proxy:set $TEST_APP openresty"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:labels:add $TEST_APP openresty.directive value"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "openresty.directive=value"
run /bin/bash -c "dokku openresty:labels:show $TEST_APP openresty.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku openresty:labels:show $TEST_APP openresty.directive2"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run deploy_app
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"openresty.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku openresty:labels:remove $TEST_APP openresty.directive"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_contains "openresty.directive=value"
run /bin/bash -c "dokku openresty:labels:show $TEST_APP openresty.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"openresty.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
}
add_openresty_include() {
local APP="$1"
local APP_REPO_DIR="$2"

View File

@@ -31,7 +31,7 @@ global_setup() {
global_teardown() {
[[ -n "$BATS_TEST_COMPLETED" ]] || touch "${BATS_PARENT_TMPNAME}.skip"
rm "${BATS_PARENT_TMPNAME}.skip" || true
rm -f "${BATS_PARENT_TMPNAME}.skip" || true
cleanup_apps
cleanup_containers
}
@@ -151,6 +151,10 @@ assert_output_contains() {
assert_equal "$count" "$found"
}
assert_output_not_contains() {
assert_output_contains "$1" 0
}
# ShellCheck doesn't know about $lines from Bats
assert_line() {
if [[ "$1" -ge 0 ]] 2>/dev/null; then

View File

@@ -299,3 +299,72 @@ teardown() {
assert_success
assert_output "websecure"
}
@test "(traefik) label management" {
run /bin/bash -c "dokku proxy:set $TEST_APP traefik"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku traefik:labels:add $TEST_APP traefik.directive value"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku traefik:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "traefik.directive=value"
run /bin/bash -c "dokku traefik:labels:show $TEST_APP traefik.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku traefik:labels:show $TEST_APP traefik.directive2"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run deploy_app
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "value"
run /bin/bash -c "dokku traefik:labels:remove $TEST_APP traefik.directive"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku traefik:labels:show $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_contains "traefik.directive=value"
run /bin/bash -c "dokku traefik:labels:show $TEST_APP traefik.directive"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.directive\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_not_exists
}