From 3f139493376dd84b98406b2ee2663b2ea7303420 Mon Sep 17 00:00:00 2001 From: youdie006 Date: Wed, 22 Jul 2026 01:55:18 +0900 Subject: [PATCH 1/2] feat: add pre-parsed json string version of port mappings --- plugins/ports/report.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/plugins/ports/report.go b/plugins/ports/report.go index 855de7f06..c1a65fd7e 100644 --- a/plugins/ports/report.go +++ b/plugins/ports/report.go @@ -1,6 +1,7 @@ package ports import ( + "encoding/json" "strings" "github.com/dokku/dokku/plugins/common" @@ -19,8 +20,10 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { flags = map[string]common.ReportFunc{} } else { flags = map[string]common.ReportFunc{ - "--ports-map": reportPortMap, - "--ports-map-detected": reportPortMapDetected, + "--ports-map": reportPortMap, + "--ports-map-json": reportPortMapAsJSON, + "--ports-map-detected": reportPortMapDetected, + "--ports-map-detected-json": reportPortMapDetectedAsJSON, } } @@ -52,6 +55,15 @@ func reportPortMap(appName string) string { return strings.Join(portMaps, " ") } +func reportPortMapAsJSON(appName string) string { + json, err := json.Marshal(getPortMaps(appName)) + if err != nil { + return "" + } + + return string(json) +} + func reportPortMapDetected(appName string) string { var portMaps []string for _, portMap := range getDetectedPortMaps(appName) { @@ -60,3 +72,12 @@ func reportPortMapDetected(appName string) string { return strings.Join(portMaps, " ") } + +func reportPortMapDetectedAsJSON(appName string) string { + json, err := json.Marshal(getDetectedPortMaps(appName)) + if err != nil { + return "" + } + + return string(json) +} From 9c61031f3ee2dedfa0ac4c9f30a3b5437744ff10 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 22 Jul 2026 03:45:32 -0400 Subject: [PATCH 2/2] docs: add docs and tests for this feature --- docs/networking/port-management.md | 54 ++++++++++++++++++++++++++++++ tests/unit/ports.bats | 35 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/docs/networking/port-management.md b/docs/networking/port-management.md index f22e9c737..bdd179677 100644 --- a/docs/networking/port-management.md +++ b/docs/networking/port-management.md @@ -221,8 +221,61 @@ You can pass flags which will output only the value of the specific information dokku ports:report node-js-app --ports-map ``` +Use `--ports-map-json` or `--ports-map-detected-json` to get the same data as a JSON array of objects. Each object has the following fields: + +- `scheme`: the port scheme (e.g. `http`, `https`, `udp`) +- `host_port`: the host/listener port +- `container_port`: the container port + +```shell +dokku ports:report node-js-app --ports-map-json +``` + +```json +[ + { + "scheme": "http", + "host_port": 80, + "container_port": 5000 + }, + { + "scheme": "https", + "host_port": 443, + "container_port": 5000 + } +] +``` + +The JSON output can be processed with tools such as `jq`: + +```shell +dokku ports:report node-js-app --ports-map-json | jq '.[].host_port' +``` + +``` +80 +443 +``` + +```shell +dokku ports:report node-js-app --ports-map-detected-json | jq '.[0].container_port' +``` + +``` +5000 +``` + ## Properties +### Configured flags + +The following flags surface configured port mappings managed by `ports:set` / `ports:add` / `ports:remove` / `ports:clear`: + +| Flag | Description | +|---|---| +| `--ports-map` | Configured port mappings as space-separated `scheme:host-port:container-port` values | +| `--ports-map-json` | Configured port mappings as a JSON array of `{scheme, host_port, container_port}` objects | + ### Read-only flags The following flags surface in `ports:report` but are not managed by `ports:set` - they are derived from the deploy: @@ -230,3 +283,4 @@ The following flags surface in `ports:report` but are not managed by `ports:set` | Flag | Description | |---|---| | `--ports-map-detected` | Port mapping inferred from `EXPOSE` directives or the running container | +| `--ports-map-detected-json` | Detected port mappings as a JSON array of `{scheme, host_port, container_port}` objects | diff --git a/tests/unit/ports.bats b/tests/unit/ports.bats index 99860b958..e09440b60 100644 --- a/tests/unit/ports.bats +++ b/tests/unit/ports.bats @@ -50,6 +50,11 @@ teardown() { echo "status: $status" assert_output "http:1234:5001" + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 1 and .[0].scheme == \"http\" and .[0].host_port == 1234 and .[0].container_port == 5001'" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku ports:add $TEST_APP http:8080:5002 https:8443:5003" echo "output: $output" echo "status: $status" @@ -60,6 +65,11 @@ teardown() { echo "status: $status" assert_output "http:1234:5001 http:8080:5002 https:8443:5003" + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 3 and any(.scheme == \"http\" and .host_port == 1234 and .container_port == 5001) and any(.scheme == \"http\" and .host_port == 8080 and .container_port == 5002) and any(.scheme == \"https\" and .host_port == 8443 and .container_port == 5003)'" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku ports:set $TEST_APP http:8080:5000 https:8443:5000 http:1234:5001" echo "output: $output" echo "status: $status" @@ -90,6 +100,11 @@ teardown() { echo "status: $status" assert_output "http:1234:5001 http:8080:5000 https:8443:5000" + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 3 and any(.scheme == \"http\" and .host_port == 1234 and .container_port == 5001) and any(.scheme == \"http\" and .host_port == 8080 and .container_port == 5000) and any(.scheme == \"https\" and .host_port == 8443 and .container_port == 5000)'" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku ports:remove $TEST_APP 8080" echo "output: $output" echo "status: $status" @@ -100,6 +115,11 @@ teardown() { echo "status: $status" assert_output "http:1234:5001 https:8443:5000" + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 2 and any(.scheme == \"http\" and .host_port == 1234 and .container_port == 5001) and any(.scheme == \"https\" and .host_port == 8443 and .container_port == 5000)'" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku ports:remove $TEST_APP http:1234:5001" echo "output: $output" echo "status: $status" @@ -110,6 +130,11 @@ teardown() { echo "status: $status" assert_output "https:8443:5000" + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 1 and .[0].scheme == \"https\" and .[0].host_port == 8443 and .[0].container_port == 5000'" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku ports:clear $TEST_APP" echo "output: $output" echo "status: $status" @@ -120,10 +145,20 @@ teardown() { echo "status: $status" assert_output_not_exists + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e '. == [] or . == null'" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected" echo "output: $output" echo "status: $status" assert_output "http:80:5000" + + run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected-json | jq -e 'length == 1 and .[0].scheme == \"http\" and .[0].host_port == 80 and .[0].container_port == 5000'" + echo "output: $output" + echo "status: $status" + assert_success } @test "(ports:add) post-deploy add" {