这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/appendices/0.31.0-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
- The `traefik` integration now mounts config to `/data` instead of the path `/acme.json`, fixing permissions issues under certain architectures. To take advantage of the new functionality, the traefik container should be stopped (via `dokku traefik:stop`) and then started (via `dokku traefik:start`).
- Users no longer need to clear the `source-image` git property when transitioning from image-based deploys (`git:from-image` and `git:load-image`) to other deployment methods (git push, `git:from-archive`, `git:sync`).
- For deploys via the `git:from-image` and `git:load-image` commands, the `CHECKS` file is now extracted from the configured `WORKDIR` property of the image. For all other deploys - git push, `git:from-archive`, `git:sync` - will have the `CHECKS` extracted directly from the source code. The filename in both cases is `CHECKS` and cannot be modified.
- The `common#get_app_raw_tcp_ports()` function has been deprecated and will be removed in the next release. Users should avoid interacting with this function for dockerfile ports and instead use the `ports-get` plugin trigger for fetching ports for an app.
- The `common#get_available_port()` function has been deprecated and will be removed in the next release. Users should avoid interacting with this function and instead use the `ports-get-available` plugin trigger for fetching an available port.

## Deprecations

- The `proxy:ports*` commands have been replaced with the new `ports` plugin. Users will be able to use the old `proxy:ports*` commands for a single minor release, and they will be removed in the next minor release.
- The `common#get_app_raw_tcp_ports()` function has been deprecated and will be removed in the next release. Users should avoid interacting with this function for dockerfile ports and instead use the `ports-get` plugin trigger for fetching ports for an app.
- The `common#get_available_port()` function has been deprecated and will be removed in the next release. Users should avoid interacting with this function and instead use the `ports-get-available` plugin trigger for fetching an available port.
- The `proxy-configure-ports` plugin trigger has been deprecated and will be removed in the next release. Users should instead trigger the `ports-configure` plugin trigger.

## Un-Deprecations

Expand Down
17 changes: 17 additions & 0 deletions docs/development/plugin-triggers.md
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,21 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
# TODO
```

### `ports-configure`

- Description: Configures the port mapping
- Invoked by: `internally triggered by proxy plugins`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `ports-dockerfile-raw-tcp-ports`

> Warning: This trigger is for internal use and will be removed in a future release. Do not use it in your codebase.
Expand Down Expand Up @@ -1934,6 +1949,8 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

### `proxy-configure-ports`

> Warning: Deprecated, please use `ports-configure` instead

- Description: Configures the port mapping
- Invoked by: `internally triggered by proxy plugins`
- Arguments: `$APP`
Expand Down
1 change: 1 addition & 0 deletions plugins/20_events/ports-configure
2 changes: 1 addition & 1 deletion plugins/caddy-vhosts/docker-args-process-deploy
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ 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
Expand Down
6 changes: 6 additions & 0 deletions plugins/common/ports-get-available
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x

get_available_port "$@"
2 changes: 1 addition & 1 deletion plugins/haproxy-vhosts/docker-args-process-deploy
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ trigger-haproxy-vhosts-docker-args-process-deploy() {
plugn trigger domains-setup "$APP" >/dev/null

# 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
Expand Down
2 changes: 1 addition & 1 deletion plugins/nginx-vhosts/functions
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ 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=$(plugn trigger ports-get "$APP")
Expand Down
2 changes: 1 addition & 1 deletion plugins/ports/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
SUBCOMMANDS = subcommands/list subcommands/add subcommands/clear subcommands/remove subcommands/set subcommands/report
TRIGGERS = triggers/ports-clear triggers/ports-dockerfile-raw-tcp-ports triggers/ports-get triggers/ports-get-available triggers/post-certs-remove triggers/post-certs-update triggers/report
TRIGGERS = triggers/ports-clear triggers/ports-configure triggers/ports-dockerfile-raw-tcp-ports triggers/ports-get triggers/ports-get-available triggers/post-certs-remove triggers/post-certs-update triggers/report
BUILD = commands subcommands triggers
PLUGIN_NAME = ports

Expand Down
65 changes: 60 additions & 5 deletions plugins/ports/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ func clearPorts(appName string) error {
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
}

func doesCertExist(appName string) bool {
b, _ := common.PlugnTriggerOutput("certs-exists", []string{appName}...)
certsExists := strings.TrimSpace(string(b[:]))
return certsExists == "true"
}

func filterAppPortMaps(appName string, scheme string, hostPort int) []PortMap {
var filteredPortMaps []PortMap
for _, portMap := range getPortMaps(appName) {
Expand Down Expand Up @@ -90,12 +96,59 @@ func getDockerfileRawTCPPorts(appName string) []int {
return ports
}

func getGlobalProxyPort() int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
port = intVar
}

return port
}

func getGlobalProxySSLPort() int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_SSL_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
port = intVar
}

return port
}

func getPortMaps(appName string) []PortMap {
value := config.GetWithDefault(appName, "DOKKU_PROXY_PORT_MAP", "")
portMaps, _ := parsePortMapString(value)
return portMaps
}

func getProxyPort(appName string) int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
port = intVar
}

return port
}

func getProxySSLPort(appName string) int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_SSL_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
port = intVar
}

return port
}

func isAppVhostEnabled(appName string) bool {
if err := common.PlugnTrigger("domains-vhost-enabled", []string{appName}...); err != nil {
return false
}
return true
}

func inRange(value int, min int, max int) bool {
return min < value && value < max
}
Expand Down Expand Up @@ -223,11 +276,13 @@ func setPortMaps(appName string, portMaps []PortMap) error {
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)
return common.EnvWrap(func() error {
sort.Strings(value)
entries := map[string]string{
"DOKKU_PROXY_PORT_MAP": strings.Join(value, " "),
}
return config.SetMany(appName, entries, false)
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
}

func uniquePortMaps(portMaps []PortMap) []PortMap {
Expand Down
54 changes: 2 additions & 52 deletions plugins/ports/proxy-configure-ports
Original file line number Diff line number Diff line change
@@ -1,65 +1,15 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x

trigger-ports-proxy-configure-ports() {
declare desc="ports proxy-configure-ports plugin trigger"
declare trigger="proxy-configure-ports"
declare APP="$1"
local RAW_TCP_PORTS="$(plugn trigger ports-dockerfile-raw-tcp-ports "$APP" | xargs)"
local DOKKU_PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
local DOKKU_PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP)
local IS_APP_VHOST_ENABLED=true
local UPSTREAM_PORT="5000"

plugn trigger domains-vhost-enabled "$APP" 2>/dev/null || IS_APP_VHOST_ENABLED=false

if [[ -z "$DOKKU_PROXY_PORT" ]] && [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "No port set, setting to random open high port"
local PROXY_PORT=$(plugn trigger ports-get-available)
else
local PROXY_PORT=$(config_get --global DOKKU_PROXY_PORT)
PROXY_PORT=${PROXY_PORT:=80}
fi
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_PORT="$PROXY_PORT"
fi
if [[ -z "$DOKKU_PROXY_SSL_PORT" ]]; then
if [[ "$(plugn trigger certs-exists "$APP")" == "true" ]]; then
local PROXY_SSL_PORT=$(config_get --global DOKKU_PROXY_SSL_PORT)
PROXY_SSL_PORT=${PROXY_SSL_PORT:=443}
if [[ -z "$RAW_TCP_PORTS" ]] && [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "No ssl port set, setting to random open high port"
PROXY_SSL_PORT=$(plugn trigger ports-get-available)
fi
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_SSL_PORT="$PROXY_SSL_PORT"
fi
fi
if [[ -z "$DOKKU_PROXY_PORT_MAP" ]]; then
if [[ -n "$RAW_TCP_PORTS" ]]; then
local RAW_TCP_PORT
for RAW_TCP_PORT in $RAW_TCP_PORTS; do
local PROXY_PORT_MAP+=" http:${RAW_TCP_PORT}:${RAW_TCP_PORT} "
done
else
local PROXY_PORT=${PROXY_PORT:-$DOKKU_PROXY_PORT}
local PROXY_SSL_PORT=${PROXY_SSL_PORT:-$DOKKU_PROXY_SSL_PORT}
[[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]] && local UPSTREAM_PORT="$(<"$DOKKU_ROOT/$APP/PORT.web.1")"
if [[ -n "$PROXY_PORT" ]] && [[ -n "$PROXY_SSL_PORT" ]]; then
local PROXY_PORT_MAP+=" http:${PROXY_PORT}:$UPSTREAM_PORT https:${PROXY_SSL_PORT}:$UPSTREAM_PORT "
elif [[ -n "$PROXY_PORT" ]]; then
local PROXY_PORT_MAP+=" http:${PROXY_PORT}:$UPSTREAM_PORT "
fi
fi
if [[ -n "$PROXY_PORT_MAP" ]]; then
local PROXY_PORT_MAP="$(echo "$PROXY_PORT_MAP" | xargs)"
local PROXY_PORT_MAP+=" $(merge_dedupe_list "$(remove_val_from_list "$PORT_MAP" "$DOKKU_PROXY_PORT_MAP" " ")" " ") "
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP"
fi
fi
dokku_log_warn "Deprecated: please use the 'ports-configure' plugin trigger instead"
plugn trigger ports-configure "$APP"
}

trigger-ports-proxy-configure-ports "$@"
3 changes: 3 additions & 0 deletions plugins/ports/src/triggers/triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ func main() {
case "ports-clear":
appName := flag.Arg(0)
err = ports.TriggerPortsClear(appName)
case "ports-configure":
appName := flag.Arg(0)
err = ports.TriggerPortsConfigure(appName)
case "ports-dockerfile-raw-tcp-ports":
appName := flag.Arg(0)
err = ports.TriggerPortsDockerfileRawTCPPorts(appName)
Expand Down
106 changes: 106 additions & 0 deletions plugins/ports/triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package ports

import (
"fmt"
"path/filepath"
"strconv"

"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
Expand All @@ -12,6 +14,110 @@ func TriggerPortsClear(appName string) error {
return clearPorts(appName)
}

// TriggerPortsConfigure ensures we have a port mapping
func TriggerPortsConfigure(appName string) error {
rawTCPPorts := getDockerfileRawTCPPorts(appName)

dokkuProxyPort := getProxyPort(appName)
dokkuProxySSLPort := getProxySSLPort(appName)
portMaps := getPortMaps(appName)

vhostEnabled := isAppVhostEnabled(appName)

if dokkuProxyPort == 0 && len(rawTCPPorts) == 0 {
proxyPort := 80
if !vhostEnabled {
common.LogInfo1("No port set, setting to random open high port")
proxyPort = getAvailablePort()
} else {
proxyPort = getGlobalProxyPort()
}

if proxyPort == 0 {
proxyPort = 80
}

dokkuProxyPort = proxyPort
err := common.EnvWrap(func() error {
entries := map[string]string{
"DOKKU_PROXY_PORT": fmt.Sprint(proxyPort),
}
return config.SetMany(appName, entries, false)
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
if err != nil {
return err
}
}

if dokkuProxySSLPort == 0 {
if doesCertExist(appName) {
proxySSLPort := getGlobalProxySSLPort()
if proxySSLPort == 0 {
proxySSLPort = 443
}

if len(rawTCPPorts) == 0 && !vhostEnabled {
common.LogInfo1("No ssl port set, setting to random open high port")
proxySSLPort = getAvailablePort()
}

dokkuProxySSLPort = proxySSLPort
err := common.EnvWrap(func() error {
entries := map[string]string{
"DOKKU_PROXY_SSL_PORT": fmt.Sprint(proxySSLPort),
}
return config.SetMany(appName, entries, false)
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
if err != nil {
return err
}
}
}

if len(portMaps) == 0 {
if len(rawTCPPorts) > 0 {
for _, rawTcpPort := range rawTCPPorts {
portMaps = append(portMaps, PortMap{
ContainerPort: rawTcpPort,
HostPort: rawTcpPort,
Scheme: "http",
})
}
} else {
upstreamPort := 5000
portFile := filepath.Join(common.AppRoot(appName), "PORT.web.1")
if common.FileExists(portFile) {
if port, err := strconv.Atoi(common.ReadFirstLine(portFile)); err == nil {
upstreamPort = port
}
}

if dokkuProxyPort != 0 {
portMaps = append(portMaps, PortMap{
ContainerPort: upstreamPort,
HostPort: dokkuProxyPort,
Scheme: "http",
})
}
if dokkuProxySSLPort != 0 {
portMaps = append(portMaps, PortMap{
ContainerPort: upstreamPort,
HostPort: dokkuProxySSLPort,
Scheme: "https",
})
}
}

if len(portMaps) > 0 {
return setPortMaps(appName, portMaps)
}

return nil
}

return nil
}

// TriggerRawTCPPorts extracts raw tcp port numbers from DOCKERFILE_PORTS config variable
func TriggerPortsDockerfileRawTCPPorts(appName string) error {
ports := getDockerfileRawTCPPorts(appName)
Expand Down
2 changes: 1 addition & 1 deletion plugins/traefik-vhosts/docker-args-process-deploy
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ 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
Expand Down