PortRelay is a native macOS menu bar app for managing SSH local port forwarding tunnels to services running inside Docker containers on remote hosts.
The SSH transport, remote command execution, and TCP forwarding run in-process
with SwiftNIO and SwiftNIO SSH. PortRelay does not launch the system ssh
client or a shell helper.
PortRelay is fundamentally an SSH tunnel manager with a Docker-focused workflow. It is intended for people who administer remote containers and already understand their SSH access, Docker networks, exposed services, firewall rules, and the security implications of forwarding remote traffic to local ports.
PortRelay is an independent project and is not affiliated with, sponsored by, or endorsed by Docker, Inc. Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.
All connections, hosts, users, and endpoints shown below are fictitious.
- PortRelay connects to the configured SSH host and verifies its host key.
- It authenticates with a Keychain password or an unencrypted ED25519 private
key from
~/.ssh/id_ed25519. - It runs
docker container inspectremotely and reads the container address from the selected Docker network. - It binds the configured local IP and port.
- Each local client is forwarded through an SSH
direct-tcpipchannel to the container IP and service port.
The first connection to an SSH host displays its SHA-256 fingerprint for confirmation. A changed host key always requires explicit approval.
After an established tunnel is interrupted, PortRelay resolves the container address again and reconnects automatically with delays of 2, 4, 8, 16, and then 30 seconds between attempts. Retries continue until the tunnel is restored or stopped manually. Initial authentication and configuration errors remain visible instead of entering the retry loop.
- macOS 13 or later.
- SSH access to the remote host.
- Permission to run
docker container inspecton the remote host. - Password authentication or an unencrypted OpenSSH ED25519 key at
~/.ssh/id_ed25519. - Swift 6.1 or later to build from source.
Encrypted private keys and other private-key formats are not supported yet.
cd port-relay
./Scripts/run.shThe app appears in the macOS menu bar. From the menu you can start or stop saved connections, open the connection manager, add connections, open settings, and view the help diagram.
Swift Package Manager downloads the pinned dependencies on the first build.
Connection profiles are stored in:
~/Library/Application Support/PortRelay/connections.json
Settings are stored in:
~/Library/Application Support/PortRelay/settings.json
By default, connection logs are written to:
~/Library/Application Support/PortRelay/Logs/
Logs are appended across application launches and include connection losses, failed attempts, scheduled retries, and successful recovery.
Each profile stores the SSH user, host and port, Docker container and network, remote service port, local IP and port, and automatic-start preference. Passwords are stored in the macOS Keychain and are never written to the profile or log files.
The log location, SSH connection timeout, KeepAlive interval, allowed
KeepAlive failures, and UI language can be changed from Settings....
On its first launch, PortRelay copies existing DockerBridge profiles, settings, logs, host fingerprints, and Keychain credentials into its new application identity. The original data is retained for rollback.
PortRelay supports English, Spanish, and Portuguese. English is the base and
fallback language, while the default setting follows the macOS language. It can
be changed from Settings....
Application strings live in Resources/en.lproj/Localizable.strings and
the corresponding es.lproj and pt.lproj files. The help diagram is localized
as overview.svg inside each .lproj directory.
cd port-relay
./Scripts/build.shThe generated app bundle is:
build/PortRelay.app
cd port-relay
./Scripts/package-dmg.shThe installer image is:
build/PortRelay.dmg
The static product website lives in Website/ and is published at
tecnologica.ar/port-relay. It
includes the localized product page, screenshots, DMG download, and privacy
policy used for App Store Connect.
Run it locally with:
python3 -m http.server 8765 --directory WebsiteThe distributable DMG is copied to Website/downloads/PortRelay.dmg for
deployment but remains excluded from Git because GitHub Releases is the source
of versioned binaries.
PortRelay can enable or disable its login item from the Settings window.
The helper is embedded in the signed application bundle and registered with
Apple's ServiceManagement framework. PortRelay does not invoke launchctl
or install property lists in the user's Library/LaunchAgents directory.
Runtime networking and cryptography are provided by Apple open-source Swift
packages pinned in Package.resolved: SwiftNIO, SwiftNIO SSH, and Swift Crypto,
plus their transitive Swift packages.
See THIRD_PARTY_NOTICES.md for dependency versions, licenses, and notices.
PortRelay is released under the MIT License.




