Farward — forwarding from afar — is an interactive SSH port-forwarding dashboard for remote services. It can discover published Docker ports, forward ordinary standalone processes, or combine both in one session.
- Discovers published Docker/Compose TCP ports with
docker ps. - Adds arbitrary remote TCP ports for non-Docker applications.
- Selects multiple services with
fzf. - Supports direct
REMOTEandREMOTE:LOCALport specifications. - Binds local forwards explicitly to
localhostby default. - Supports an optional
FARWARD_SSH_CONFIGfor custom SSH identities, ports, and host aliases. - Supports a remote-side target host when the service is not reachable at remote
localhost. - Preserves specific Docker bind addresses such as
10.0.0.5:8080->80/tcpwhen creating forwards. - Can diagnose whether the SSH host can reach the requested remote target before tunneling.
- Can print the resolved SSH forwards without opening a tunnel.
- Probes started forwards and reports SSH channel-open failures before showing the dashboard.
- Prompts when a local port is privileged, invalid, or already occupied.
- Shows all active forwards in a responsive full-screen dashboard.
- Type
:qand press Enter (or typeqand press Enter), or press Ctrl+C, to close every tunnel in the session. - Retains the legacy
dockportandsail-portscommands as aliases.
TCP ports must be between 1 and 65535. A value such as 83473 is not a valid network port. Use the actual listening port, for example 8347, 8343, or another value reported by the application.
./install.shThis installs:
~/.local/bin/farward
~/.local/bin/dockport -> farward
~/.local/bin/sail-ports -> farward
Running Farward without arguments shows the help screen and does not attempt an SSH connection:
farwardRun the smoke test before installing:
tests/smoke.shRun the same test against the installed command:
FARWARD_BIN=~/.local/bin/farward tests/smoke.shAfter installation, you can also run:
farward --self-testThe smoke test uses a mock SSH process and temporary local ports to verify background forwarding, byte-level custom-port traffic, remote-side failure reporting, the foreground dashboard animation, and :q cleanup. When sshd and ssh-keygen are available, it also starts a temporary local SSH server and verifies a real OpenSSH custom-port tunnel end to end.
These are equivalent:
farward help
farward --help
farward -hfarward mattbackup@miniThe selector contains discovered Docker mappings plus:
[add custom port] enter an arbitrary remote TCP port
Select it, enter the remote port, and Farward adds it to the selector as a standalone service. You can then select it with any Docker services and start them in the same dashboard.
Forward remote port 8347 and choose the local port interactively:
farward --port 8347 mattbackup@miniRequest remote 8347 on local 18347:
farward --port 8347:18347 mattbackup@miniAdd several services:
farward \
--port 8347 \
--port 3000:13000 \
--port 8025 \
mattbackup@miniDirectly supplied ports appear alongside Docker ports in the selector, allowing you to deselect any you do not need.
Skip Docker completely and enter one or more ports interactively:
farward --manual mattbackup@miniEnter a blank value when you have finished adding ports. Farward then asks which local port to use for each remote service.
For scripted/manual ports without Docker discovery:
farward --no-docker --port 8347 --port 3000:13000 mattbackup@miniYou can also run farward --no-docker mattbackup@mini and use [add custom port] in the selector.
-p, --port REMOTE[:LOCAL] Add a standalone remote TCP port; repeatable
-t, --target-host HOST Remote-side host to connect to; default localhost
-m, --manual Prompt for standalone ports and skip Docker
--no-docker Disable Docker discovery
-b, --background Run tunnels without the dashboard
-o, --open Open recognised web-service ports
--diagnose Check remote target reachability and exit
--dry-run Print resolved forwards and SSH arguments without tunneling
--self-test Run Farward's local smoke test
-h, --help Show usage
A manual mapping such as:
localhost:18347 -> mattbackup@mini:8347
uses SSH local forwarding equivalent to:
ssh -L localhost:18347:localhost:8347 mattbackup@miniThe remote application must therefore be reachable from the SSH host at localhost:<remote-port>.
For Docker-discovered ports, Farward uses the bind address reported by Docker when it is specific. For example, 10.0.0.5:8080->80/tcp forwards to 10.0.0.5:8080 from the SSH host. Wildcard binds such as 0.0.0.0:8080->80/tcp are treated as remote localhost:8080.
If the service is bound to another interface on the remote machine, provide the remote-side target explicitly:
farward --no-docker --target-host 10.0.0.5 --port 8347:18347 mattbackup@miniThat uses:
ssh -L localhost:18347:10.0.0.5:8347 mattbackup@miniSet FARWARD_BIND_HOST only if you intentionally need a different local bind address. The default keeps the listener on localhost and matches Farward's startup probe.
If your SSH connection needs a custom identity, port, jump host, or host alias, put it in an SSH config file and pass it to Farward:
FARWARD_SSH_CONFIG=/path/to/ssh_config farward --no-docker --port 8347:18347 my-host-aliasTo check reachability from the SSH host before opening a tunnel:
farward --no-docker --diagnose --target-host 10.0.0.5 --port 8347:18347 mattbackup@miniTo inspect the exact SSH forwards Farward would create without opening a tunnel:
farward --no-docker --dry-run --target-host 10.0.0.5 --port 8347:18347 mattbackup@mini