# tcp-echo Minimal .NET 8 TCP echo server. Every reply is prefixed with the instance identifier (`INSTANCE_ID` env var, falling back to the hostname), and a `[] connected` line is sent on connect. Two instances are deployed behind Traefik: | Instance | INSTANCE_ID | External port | |----------|-------------|---------------| | a | echo-a | 9098 | | b | echo-b | 9099 | ## Build and push Requires a prior `docker login gitea.eitczech.com`. ```powershell ./build-push.ps1 -Tag 1.0.0 # pushes gitea.eitczech.com/public/tcp-echo-server:1.0.0 ./build-push.ps1 -Tag 1.0.0 -AlsoLatest # additionally pushes :latest ``` The manifests reference `gitea.eitczech.com/public/tcp-echo-server:latest`. To pin a specific tag either edit `k8s/instance-a.yaml` / `k8s/instance-b.yaml`, or after `kubectl apply -k` run: ```sh kubectl -n tcp-echo set image deploy/tcp-echo-a deploy/tcp-echo-b tcp-echo=gitea.eitczech.com/public/tcp-echo-server:1.0.0 ``` If the Gitea registry is private, create a pull secret in the namespace and reference it via `imagePullSecrets`. ### Package description on Gitea The `Dockerfile` sets the standard OCI labels (`org.opencontainers.image.*`). Gitea reads them from the pushed image and shows them on the package page: | Label | Shown as / effect | |------------------|--------------------------------------------------------------------------------| | `description` | Package description text | | `source` | Links the package to the repository with the same URL (repo must exist first) | | `url`, `documentation`, `licenses`, `authors`, `vendor` | Metadata section on the package page | | `version`, `revision`, `created` | Filled in by `build-push.ps1` from the tag, git commit and current time | To change the description, edit the `LABEL` in `Dockerfile` and rebuild. If the package was pushed before the repository existed, link it manually: package page -> **Settings** -> **Link to repository**. ## Deploy ```sh kubectl apply -k k8s/ kubectl -n tcp-echo rollout status deploy/tcp-echo-a deploy/tcp-echo-b ``` `30-traefik-entrypoint.yaml` adds `tcpechoa` (9098) and `tcpechob` (9099) entrypoints to the k3s-managed Traefik (Traefik restarts once). For a Helm-managed Traefik, drop that file from `kustomization.yaml` and run: ```sh helm upgrade traefik traefik/traefik -n kube-system --reuse-values -f k8s/traefik-values.yaml ``` If Traefik's Service is a LoadBalancer, make sure the cloud/VPS firewall allows TCP 9098 and 9099. ## Test ### Linux / macOS ```sh $ nc 9098 [echo-a] connected hello [echo-a] hello $ nc 9099 [echo-b] connected hello [echo-b] hello ``` ### Windows (PowerShell) Windows has no `nc`. Use the included script, which opens a TCP connection, prints the greeting, sends a message and prints the echoed reply: ```powershell . est-echo.ps1 -Server -Port 9098 . est-echo.ps1 -Server -Port 9099 -Message "ping" ``` Expected output: ``` Connecting to :9098 ... <- [echo-a] connected -> hello <- [echo-a] hello ``` Just to check the port is reachable (no echo): ```powershell Test-NetConnection -ComputerName -Port 9098 ``` For an interactive session, `telnet 9098` works if the Telnet Client feature is enabled (`Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient`), or install `ncat` via `winget install Insecure.Nmap`. ### Local test with Docker ```powershell docker build -t tcp-echo:local . docker run --rm -d --name tcp-echo-test -e INSTANCE_ID=echo-local -p 9099:9099 tcp-echo:local . est-echo.ps1 -Server localhost -Port 9099 docker rm -f tcp-echo-test ```