rfswift config ports
Expose and publish ports on an existing container.
rfswift config ports opens or closes network ports on a container you already created. Use it to reach a service running in the container (a web interface, an API, a collector) from your computer or from other containers.
The most common use publishes a web interface on your computer only:
rfswift config ports bind -c web -b "127.0.0.1:8080:80/tcp"Publishing ports matters when the container uses an isolated network such as bridge or nat. The default host mode has no network isolation, so a service in the container already uses your computer’s ports. See the network modes.
What happens when you apply a change
The container restarts, so save your work first. On Linux with Docker, the change is applied in place after one sudo prompt. On Podman, the container is committed and created again; add --recreate to use that method on Docker too. The shorter spelling rfswift ports also works. See config.
Synopsis
Expose a port to other containers, or stop exposing it:
rfswift config ports expose -c CONTAINER -p "PORT/PROTOCOL"
rfswift config ports unexpose -c CONTAINER -p "PORT/PROTOCOL"Publish a container port on a host port, or remove it:
rfswift config ports bind -c CONTAINER -b "HOST_PORT:CONTAINER_PORT/PROTOCOL"
rfswift config ports unbind -c CONTAINER -b "HOST_PORT:CONTAINER_PORT/PROTOCOL"Subcommands
expose and unexpose
expose makes a port available to other containers on the same network. unexpose removes it.
| Flag | What it does | Required | Example |
|---|---|---|---|
-c, --container STRING |
The container, by name or ID | Yes | -c my_container |
-p, --port STRING |
The port and protocol | Yes | -p "8080/tcp" |
bind and unbind
bind publishes a container port on a port of your computer, so you can reach the service from the host. unbind removes it.
| Flag | What it does | Required | Example |
|---|---|---|---|
-c, --container STRING |
The container, by name or ID | Yes | -c my_container |
-b, --binding STRING |
The binding, see the format below | Yes | -b "8080:80/tcp" |
Binding format
[host_ip:]host_port:container_port/protocol- host_ip (optional): the address on your computer to listen on. The default is
0.0.0.0, which means every network interface. - host_port: the port on your computer.
- container_port: the port inside the container.
- protocol:
tcp,udporsctp. Always write it; a service that needs two protocols needs one binding for each.
Examples:
"8080:80/tcp" # Host port 8080 -> Container port 80 (TCP)
"5000:5000/udp" # Host port 5000 -> Container port 5000 (UDP)
"3000:3000/tcp" # Port 3000 on both sides
"127.0.0.1:8080:80/tcp" # Only accessible from localhostSeveral services at once, one binding each:
"8080:80/tcp" # HTTP
"8443:443/tcp" # HTTPS
"3000:3000/udp" # Custom UDP serviceExamples
Expose a port to other containers:
rfswift config ports expose -c web_server -p "80/tcp"Publish it on port 8080 of your computer:
rfswift config ports bind -c web_server -b "8080:80/tcp"Remove the published port, then stop exposing it:
rfswift config ports unbind -c web_server -b "8080:80/tcp"
rfswift config ports unexpose -c web_server -p "80/tcp"A web server on a custom port
Publish port 80 of the container on port 8080, start a web server inside, then open http://localhost:8080 on your computer:
rfswift container create -i penthertz/rfswift_resolute:sdr_full -n web_service
rfswift config ports bind -c web_service -b "8080:80/tcp"
rfswift container shell -c web_service
python3 -m http.server 80
exitSeveral services
Publish HTTP, HTTPS and a metrics port, and expose the same ports to other containers:
rfswift container create -i penthertz/rfswift_resolute:sdr_full -n api_server
rfswift config ports bind -c api_server -b "8080:80/tcp"
rfswift config ports bind -c api_server -b "8443:443/tcp"
rfswift config ports bind -c api_server -b "9090:9090/tcp"
rfswift config ports expose -c api_server -p "80/tcp"
rfswift config ports expose -c api_server -p "443/tcp"
rfswift config ports expose -c api_server -p "9090/tcp"A UDP service
Publish a UDP port, then start a NetFlow collector on it:
rfswift container create -i penthertz/rfswift_resolute:sdr_full -n netflow
rfswift config ports bind -c netflow -b "2055:2055/udp"
rfswift container shell -c netflow
nfcapd -p 2055
exitA development setup
Publish the ports of a front-end server, an API backend and LiveReload:
rfswift container create -i penthertz/rfswift_resolute:sdr_full -n dev_env
rfswift config ports bind -c dev_env -b "3000:3000/tcp" # React dev server
rfswift config ports bind -c dev_env -b "5000:5000/tcp" # API backend
rfswift config ports bind -c dev_env -b "35729:35729/tcp" # LiveReloadA temporary port for testing
Publish a port, test it, and remove it when you are done:
rfswift container create -i penthertz/rfswift_resolute:sdr_full -n test_service
rfswift config ports bind -c test_service -b "9999:80/tcp"
curl http://localhost:9999
rfswift config ports unbind -c test_service -b "9999:80/tcp"Moving a service to another port
Remove the old binding and add the new one. The service is then on port 8081:
rfswift config ports unbind -c service -b "8080:80/tcp"
rfswift config ports bind -c service -b "8081:80/tcp"Common port numbers
Standard services
| Service | Port | Protocol | Used for |
|---|---|---|---|
| HTTP | 80 | TCP | Web servers |
| HTTPS | 443 | TCP | Secure web servers |
| SSH | 22 | TCP | Remote access |
| FTP | 21 | TCP | File transfer |
| SMTP | 25 | TCP | |
| DNS | 53 | TCP/UDP | Domain name service |
| MySQL | 3306 | TCP | Database |
| PostgreSQL | 5432 | TCP | Database |
| Redis | 6379 | TCP | Cache or database |
| MongoDB | 27017 | TCP | Database |
Development servers
| Service | Port | Used for |
|---|---|---|
| React Dev | 3000 | React development server |
| Node.js | 3000, 8000 | Node applications |
| Python HTTP | 8000 | Python’s built-in web server |
| Flask | 5000 | Flask development |
| Django | 8000 | Django development |
| LiveReload | 35729 | Live reload |
| Webpack | 8080 | Webpack dev server |
| Vite | 5173 | Vite dev server |
Ports often used by tool interfaces
| Service | Port | Used for |
|---|---|---|
| Web UI | 8080 | Web interfaces |
| API | 8000 | REST APIs |
| WebSocket | 9000 | Real-time data |
| Metrics | 9090 | Prometheus metrics |
| Status | 8081 | Health checks |
Security
Choose who can reach the port
By default a published port listens on every network interface (0.0.0.0), so other machines on your network can reach it:
rfswift config ports bind -c service -b "8080:80/tcp"To allow only your own computer, bind to localhost:
rfswift config ports bind -c service -b "127.0.0.1:8080:80/tcp"To allow only one network interface, bind to its address:
rfswift config ports bind -c service -b "192.168.1.100:8080:80/tcp"Choose the host port
Ports 1024 to 49151 are fine for normal use, and 49152 to 65535 suit temporary services:
rfswift config ports bind -c service -b "8080:80/tcp"
rfswift config ports bind -c service -b "50000:80/tcp"Avoid host ports below 1024
Host ports below 1024 need special privileges. Use a higher port (8080 instead of 80), and put a reverse proxy in front if you need the standard port.
rfswift config ports bind -c service -b "8080:80/tcp" # Good
# Not: rfswift config ports bind -c service -b "80:80/tcp" # Requires privilegesTroubleshooting
“port is already allocated”
Another program already uses that port on your computer. Find it, then either use another port or stop that program:
netstat -tuln | grep :8080
lsof -i :8080rfswift config ports bind -c service -b "8081:80/tcp"sudo systemctl stop service-using-8080
rfswift config ports bind -c service -b "8080:80/tcp"Binding fails without a clear error
Check that the container is running, use a port above 1024, and look at the firewall:
docker ps | grep container_name
rfswift config ports bind -c service -b "8080:80/tcp"
sudo iptables -L -n | grep 8080
sudo ufw statusThe port is published but the service does not answer
Test from inside the container first. If it works there, test from your computer, then check the container’s network mode and the firewall:
rfswift container shell -c container
curl localhost:80
exit
curl localhost:8080
docker inspect container | grep -A5 NetworkMode
sudo iptables -L -n
sudo ufw statusIt works over TCP but not UDP (or the reverse)
Bind the protocol the service really uses. Some services, such as DNS, need both:
rfswift config ports bind -c service -b "5000:5000/udp"
rfswift config ports bind -c service -b "53:53/tcp"
rfswift config ports bind -c service -b "53:53/udp"Removing a binding fails
Use exactly the same binding string as when you added it. As a last resort, restart the container:
rfswift config ports unbind -c container -b "8080:80/tcp"