ui(deploy): remove Exposed Ports field from Resources tab
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m25s
CI / docker (push) Successful in 1m4s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 41s

The field was cosmetic — `containerConfig.exposedPorts` only fed Docker's
`Config.ExposedPorts` metadata via `withExposedPorts(...)`. It never
published a host port and Traefik routing uses `appPort` from the label
builder, not this list. Users reading the label "Exposed Ports" reasonably
expected it to expose their port externally; removing it until real
multi-port Traefik routing lands (tracked in #149).

Backend DTOs (`ContainerRequest.exposedPorts`, `ConfigMerger.intList
("exposedPorts")`) are left in place so existing containerConfig JSONB
rows continue to deserialize. New writes from the UI will no longer
include the field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-23 17:51:46 +02:00
parent 0cf64b2928
commit ade1733418
7 changed files with 2 additions and 51 deletions

View File

@@ -11,24 +11,11 @@ interface Props {
}
export function ResourcesTab({ value, onChange, disabled, isProd = false }: Props) {
const [newPort, setNewPort] = useState('');
const [newNetwork, setNewNetwork] = useState('');
const update = <K extends keyof ResourcesFormState>(key: K, v: ResourcesFormState[K]) =>
onChange({ ...value, [key]: v });
function addPort() {
const p = parseInt(newPort);
if (p && !value.ports.includes(p)) {
onChange({ ...value, ports: [...value.ports, p] });
setNewPort('');
}
}
function removePort(port: number) {
if (!disabled) update('ports', value.ports.filter((x) => x !== port));
}
function addNetwork() {
const v = newNetwork.trim();
if (v && !value.extraNetworks.includes(v)) {
@@ -123,35 +110,6 @@ export function ResourcesTab({ value, onChange, disabled, isProd = false }: Prop
<span className={styles.cellMeta}>millicores</span>
</div>
<span className={styles.configLabel}>Exposed Ports</span>
<div className={styles.portPills}>
{value.ports.map((p) => (
<span key={p} className={styles.portPill}>
{p}
<button
className={styles.portPillDelete}
disabled={disabled}
onClick={() => removePort(p)}
>
&times;
</button>
</span>
))}
<input
className={styles.portAddInput}
disabled={disabled}
placeholder="+ port"
value={newPort}
onChange={(e) => setNewPort(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
addPort();
}
}}
/>
</div>
<span className={styles.configLabel}>App Port</span>
<Input
disabled={disabled}