run
rfswift run
Create and start a new container from an RF Swift image.
Synopsis
rfswift run -i IMAGE -n CONTAINER_NAME [options]The run command is the primary way to create new containers in RF Swift. It pulls the specified image (if not already available), creates a container with the given name, and starts it with an interactive shell.
-i and -n flags in an interactive terminal, RF Swift launches a guided wizard that walks you through all options step by step. See Interactive Wizard below.Options
Required Flags
| Flag | Description | Example |
|---|---|---|
-i, --image STRING |
Image name or tag to use | -i sdr_full |
-n, --name STRING |
Name for the new container | -n my_container |
Security Options
| Flag | Description | Default | Example |
|---|---|---|---|
-u, --privileged INT |
Privilege level (1=privileged, 0=unprivileged) | 0 |
-u 0 |
-a, --capabilities STRING |
Additional capabilities (comma-separated) | None | -a NET_ADMIN,NET_RAW |
-g, --cgroups STRING |
Cgroup device rules (comma-separated) | See config | -g "c 189:* rwm" |
-m, --seccomp STRING |
Custom seccomp profile path | Default | -m /path/to/profile.json |
Performance Options
| Flag | Description | Default | Example |
|---|---|---|---|
--realtime |
Enable realtime mode for SDR operations | false |
--realtime |
--ulimits STRING |
Set custom ulimits (comma-separated) | None | --ulimits "rtprio=95,memlock=-1" |
Device & Volume Options
| Flag | Description | Example |
|---|---|---|
-s, --devices STRING |
Device mappings (comma-separated) | -s /dev/ttyUSB0:/dev/ttyUSB0 |
-b, --bind STRING |
Volume bindings (comma-separated) | -b ~/projects:/root/projects |
Network Options
| Flag | Description | Default | Example |
|---|---|---|---|
-t, --network STRING |
Network mode | host |
-t bridge |
-z, --exposedports STRING |
Expose ports for inter-container communication | None | -z 8080,3000 |
-w, --bindedports STRING |
Bind ports to host | None | -w 8080:80/tcp |
-x, --extrahosts STRING |
Add extra host entries | None | -x pluto.local:192.168.1.2 |
Display & Audio Options
| Flag | Description | Default | Example |
|---|---|---|---|
-d, --display STRING |
X11 display setting | DISPLAY=:0 |
-d DISPLAY=:1 |
-p, --pulseserver STRING |
PulseAudio server address | tcp:127.0.0.1:34567 |
-p tcp:127.0.0.1:4713 |
--no-x11 |
Disable X11 forwarding and remove X11 socket binding | false | --no-x11 |
--desktop |
Enable remote desktop via VNC/noVNC | false | --desktop |
--desktop-config STRING |
Desktop config as proto:host:port |
http:127.0.0.1:6080 |
--desktop-config "http:0.0.0.0:6080" |
--desktop-pass STRING |
Set VNC password for desktop access | None | --desktop-pass "mypassword" |
--desktop-ssl |
Enable SSL/TLS for desktop connections | false | --desktop-ssl |
Profile Options
| Flag | Description | Example |
|---|---|---|
--profile STRING |
Use a preset profile | --profile sdr-full |
Profiles bundle image, network, features, devices, ports, capabilities, and cgroup rules into a single named preset. CLI flags override profile values. See rfswift profile for details.
# Use a profile
rfswift run --profile sdr-full -n my_sdr
# Profile with CLI overrides
rfswift run --profile wifi -n my_wifi -t nat --realtimeVPN Options
| Flag | Description | Example |
|---|---|---|
--vpn STRING |
Enable VPN inside container | --vpn tailscale |
Format: --vpn TYPE[:ARGUMENT]
| Type | Argument | Example |
|---|---|---|
wireguard |
Config file path (required) | --vpn wireguard:./wg0.conf |
openvpn |
Config file path (required) | --vpn openvpn:./client.ovpn |
tailscale |
Auth key (optional) | --vpn tailscale or --vpn tailscale:tskey-auth-xxx |
netbird |
Setup key (optional) | --vpn netbird or --vpn netbird:nb-setup-xxx |
-u 1. Tailscale and Netbird work without privileges (userspace mode with SOCKS5 proxy). See VPN Inside Containers for details.Recording Options
| Flag | Description | Example |
|---|---|---|
--record |
Enable session recording | --record |
--record-output STRING |
Custom recording filename | --record-output session.cast |
Examples
Basic Usage
Create a simple SDR container:
rfswift run -i sdr_full -n my_sdrCreate with default image from config:
# Requires imagename set in ~/.config/rfswift/config.ini
rfswift run -n my_containerWith Realtime Mode
Create container optimized for SDR operations:
rfswift run -i sdr_full -n sdr_realtime --realtimeThis automatically configures:
SYS_NICEcapabilityrtprio=95ulimitmemlock=unlimitedulimitnice=40ulimit
With custom ulimits:
rfswift run -i sdr_full -n custom_limits --ulimits "rtprio=95,memlock=-1,nofile=65536"Combine realtime with custom overrides:
rfswift run -i sdr_full -n sdr_pro --realtime --ulimits "rtprio=99"Professional SDR setup with all optimizations:
rfswift run -i sdr_full -n rf_pentest \
--realtime \
-s /dev/bus/usb:/dev/bus/usb \
-g "c 189:* rwm" \
-b ~/captures:/root/captures \
--recordWith Profiles
Quick container from a profile:
rfswift run --profile sdr-full -n my_sdrProfile with image override:
rfswift run --profile wifi -n wifi_custom -i penthertz/rfswift_noble:sdr_fullProfile with NAT isolation:
rfswift run --profile pentest-full -n pentest_sessionWith Devices
All USB devices:
rfswift run -i sdr_full -n rtlsdr_work \
-s /dev/bus/usb:/dev/bus/usb \
-g "c 189:* rwm"Multiple USB serial devices:
rfswift run -i hardware -n multi_device \
-s /dev/ttyUSB0:/dev/ttyUSB0,/dev/ttyACM0:/dev/ttyACM0 \
-g "c 189:* rwm,c 166:* rwm"With Security Configuration
Unprivileged container with specific capabilities:
rfswift run -i wifi -n wifi_scan \
-u 0 \
-a NET_ADMIN,NET_RAW \
-t bridgeWith custom seccomp profile:
rfswift run -i pentest -n secure_assessment \
-u 0 \
-m ~/seccomp-profiles/restricted.json \
-g "c 189:* rwm"Privileged mode (use sparingly):
rfswift run -i hardware -n hardware_debug \
-u 1With Network Configuration
Bridge network with port binding:
rfswift run -i web_tools -n web_server \
-t bridge \
-w 8080:80/tcpMultiple ports exposed and bound:
rfswift run -i api_server -n backend \
-t bridge \
-z 3000,3001,3002 \
-w 8080:3000/tcp,8081:3001/tcpNetwork isolation (no network):
rfswift run -i analysis -n offline_analysis \
-t none \
-b ~/data:/root/dataCustom host entries:
rfswift run -i penthertz/rfswift_noble:telecom -n network_test \
-x "device1.local:192.168.1.10,device2.local:192.168.1.11"With Session Recording
Record with auto-generated filename:
rfswift run -i bluetooth -n bt_assessment \
--recordRecord with custom filename:
rfswift run -i sdr_full -n client_pentest \
--record \
--record-output client-assessment-2024-01-12.castCombined: Recording with security and devices:
rfswift run -i wifi -n wifi_audit \
-u 0 \
-a NET_ADMIN,NET_RAW \
-t bridge \
-s /dev/wlan0:/dev/wlan0 \
--record \
--record-output wifi-audit-session.castWith Remote Desktop
Enable noVNC desktop (browser-based GUI):
rfswift run -i sdr_full -n sdr_desktop --desktopThen open http://127.0.0.1:6080 in your browser to access the GUI desktop.
Expose desktop on all interfaces:
rfswift run -i sdr_full -n sdr_desktop \
--desktop --desktop-config "http:0.0.0.0:6080"Use raw VNC instead of noVNC:
rfswift run -i sdr_full -n sdr_desktop \
--desktop --desktop-config "vnc::5900"Then connect with a VNC client (e.g., TigerVNC, RealVNC) to 127.0.0.1:5900.
Custom port:
rfswift run -i sdr_full -n sdr_desktop \
--desktop --desktop-config "http:0.0.0.0:8080"With VNC password (recommended when exposing on network):
rfswift run -i sdr_full -n sdr_desktop \
--desktop --desktop-config "http:0.0.0.0:6080" \
--desktop-pass "mysecretpass"Desktop with SDR devices and no X11 forwarding:
rfswift run -i sdr_full -n sdr_desktop \
--desktop \
--desktop-config "http:0.0.0.0:6080" \
--desktop-pass "mysecretpass" \
-s /dev/bus/usb:/dev/bus/usb \
-g "c 189:* rwm" \
--no-x11With VPN
Tailscale mesh (interactive login):
rfswift run -i sdr_full -n mesh_sdr --vpn tailscaleTailscale with auth key (headless):
rfswift run -i sdr_full -n mesh_sdr \
--vpn tailscale:tskey-auth-xxxxxxxxxxxxWireGuard tunnel (requires privileged mode):
rfswift run -i sdr_full -n vpn_sdr \
-u 1 \
--vpn wireguard:./wg0.confOpenVPN with bridge network:
rfswift run -i sdr_full -n corp_sdr \
-u 1 \
-t bridge \
--vpn openvpn:./client.ovpnNetbird mesh (interactive login):
rfswift run -i sdr_full -n nb_sdr --vpn netbirdVPN + Remote Desktop + SDR (full remote setup):
rfswift run -i sdr_full -n remote_sdr \
-u 1 \
--vpn tailscale \
--desktop --desktop-config "http:0.0.0.0:6080" \
-s /dev/bus/usb:/dev/bus/usb \
-g "c 189:* rwm" \
--recordComplex Real-World Examples
Complete SDR assessment setup:
rfswift run -i sdr_full -n site_survey \
-u 0 \
--realtime \
-s /dev/bus/usb:/dev/bus/usb \
-b /pathto/captures:/root/captures \
-b /pathto/projects:/root/projects:ro \
-g "c 189:* rwm,c 116:* rwm" \
-t bridge \
-w 8080:80/tcp \
--record \
--record-output site-survey-2024-01-12.castBluetooth security assessment:
rfswift run -i bluetooth -n bt_pentest \
-u 0 \
-a NET_ADMIN,NET_RAW \
-s /dev/ttyACM0:/dev/ttyACM0 \
-b /pathto/bt-captures:/root/captures \
-g "c 166:* rwm" \
-t bridge \
--recordHigh-performance signal capture:
rfswift run -i sdr_full -n high_perf_capture \
--realtime \
-s /dev/bus/usb:/dev/bus/usb \
-g "c 189:* rwm" \
-b ~/captures:/root/capturesDetailed Option Explanations
Image Selection (-i, --image)
Specifies which RF Swift image to use for the container.
Formats:
# Full registry path
-i penthertz/rfswift_noble:sdr_full
# Short name (resolves to penthertz/rfswift_noble:IMAGE)
-i sdr_full
# Custom registry
-i myregistry.com/rfswift:customCommon images:
sdr_full- Complete SDR toolkitsdr_light- Lightweight SDR toolsbluetooth- Bluetooth security toolswifi- Wi-Fi assessment toolshardware- Hardware hacking toolsautomotive- Vehicle protocol tools
See List of Images for all available images.
Container Naming (-n, --name)
Assigns a unique name to the container. Names must be unique across all containers (running or stopped).
Naming conventions:
# Good names (descriptive, unique)
-n rtlsdr_capture_session_1
-n client_assessment_2024_01
-n wifi_audit_conference_room
-n bluetooth_pentest_device_a
# Avoid generic names
-n test # Too generic
-n container1 # Not descriptiveRealtime Mode (--realtime)
Enables optimized settings for low-latency SDR operations. This is a convenience flag that automatically configures:
| Setting | Value | Purpose |
|---|---|---|
| SYS_NICE capability | Added | Allows real-time scheduling |
| rtprio ulimit | 95 | Enables chrt -f 1 through chrt -f 95 |
| memlock ulimit | unlimited | Prevents sample buffers from being swapped |
| nice ulimit | 40 | Allows nice -20 to +19 |
When to use:
- High sample rate captures (avoid buffer underruns)
- Real-time signal processing with GNU Radio, SDR++, GQRX
- Time-critical protocols (RFID, NFC, automotive)
- Professional pentesting where reliability is critical
# Simple usage
rfswift run -i sdr_full -n sdr_work --realtime
# Verify inside container
rfswift exec -c sdr_work -e "ulimit -r"
# Output: 95
# Use real-time scheduling
rfswift exec -c sdr_work
chrt -f 50 rtl_sdr -f 433920000 -s 2048000 output.binCustom Ulimits (--ulimits)
Set specific resource limits for fine-grained control.
Format: name=value or name=soft:hard (comma-separated for multiple)
| Name | Description | Example |
|---|---|---|
rtprio |
Real-time scheduling priority (0-99) | rtprio=95 |
memlock |
Max locked memory (-1 = unlimited) | memlock=-1 |
nice |
Nice priority range | nice=40 |
nofile |
Max open file descriptors | nofile=65536 |
nproc |
Max processes | nproc=4096 |
Examples:
# Single ulimit
--ulimits "rtprio=95"
# Multiple ulimits
--ulimits "rtprio=95,memlock=-1,nofile=65536"
# With soft:hard format
--ulimits "nofile=1024:65536"
# Combine with realtime (custom values override defaults)
--realtime --ulimits "rtprio=99"Privilege Level (-u, --privileged)
Controls container privilege level:
0(default): Unprivileged - Recommended for most use cases1: Privileged - Full host access, use only when necessary
When to use privileged mode:
- Kernel module loading required
- Low-level hardware access
- Complex network operations
-u 1 only when absolutely necessary and remove the container after use.Capabilities (-a, --capabilities)
Add specific Linux capabilities for fine-grained privilege control.
Common capabilities:
# Network operations
-a NET_ADMIN,NET_RAW
# Process debugging
-a SYS_PTRACE
# Real-time scheduling (added automatically with --realtime)
-a SYS_NICE
# Low port binding
-a NET_BIND_SERVICE
# File ownership changes
-a CHOWN,DAC_OVERRIDESee Capabilities Reference for complete list.
Cgroups (-g, --cgroups)
Control which device types the container can access.
Format: type major:minor permissions
type:c(character) orb(block)major:minor: Device numbers (use*for all)permissions:r(read),w(write),m(mknod)
Common rules:
# USB serial (RTL-SDR, HackRF)
-g "c 189:* rwm"
# ACM devices (Proxmark3, Arduino)
-g "c 166:* rwm"
# USB converters
-g "c 188:* rwm"
# Audio devices
-g "c 116:* rwm"
# GPU devices
-g "c 226:* rwm"
# Multiple devices
-g "c 189:* rwm,c 166:* rwm,c 188:* rwm"Find device major numbers:
ls -l /dev/your_device
# Example output: crw-rw---- 1 root dialout 189, 0 ...
# ^^^ major numberDevice Mappings (-s, --devices)
Make specific host devices available in the container.
Format: host_device:container_device or just host_device (same path in container)
# Single device
-s /dev/ttyUSB0:/dev/ttyUSB0
# Multiple devices
-s /dev/ttyUSB0:/dev/ttyUSB0,/dev/ttyACM0:/dev/ttyACM0Volume Bindings (-b, --bind)
Share directories between host and container.
Format: host_path:container_path[:options]
Options:
- None (default): Read-write access
:ro: Read-only access
# Read-write binding
-b ~/projects:/root/projects
# Read-only binding
-b ~/samples:/root/samples:ro
# Multiple bindings
-b ~/projects:/root/projects,~/captures:/root/capturesUse cases:
- Share project files
- Save captures to host
- Mount firmware samples (read-only)
- Share tool configurations
Network Modes (-t, --network)
Configure container network isolation:
| Mode | Description | Use Case |
|---|---|---|
host |
No isolation (default) | Most RF tools, full network access |
nat |
Isolated NAT network (RF Swift managed) | Pentesting, desktop mode, network isolation |
nat:NAME |
Join an existing NAT network | Multiple containers on same subnet |
bridge |
Default Docker bridge | Web services, API servers |
none |
No network access | Offline analysis, malware analysis |
container:NAME |
Share network with another container | Linked services |
# Full network access (default)
-t host
# Isolated NAT network (auto-creates subnet)
-t nat
# Join existing NAT network
-t nat:rfswift_nat_mylab
# Isolated with port forwarding
-t bridge -w 8080:80/tcp
# Complete isolation
-t nonePort Configuration
Exposed ports (-z): Make ports available to other containers
-z 8080 # Single port
-z 8080,3000,3001 # Multiple portsBound ports (-w): Publish ports to host
# Format: host_port:container_port/protocol
-w 8080:80/tcp
# With host IP
-w 127.0.0.1:8080:80/tcp
# Multiple ports
-w 8080:80/tcp,8443:443/tcpDisplay Options
X11 Display (-d): Configure X11 forwarding for GUI applications
-d DISPLAY=:0 # Default display
-d DISPLAY=:1 # Alternate displayPulseAudio (-p): Configure audio server
-p tcp:127.0.0.1:34567 # Default
-p tcp:localhost:4713 # Custom portDisable X11 (--no-x11): Disables X11 forwarding and removes the /tmp/.X11-unix socket binding from the container for improved security.
--no-x11 # No X11 forwarding, no X11 socket bindingRemote Desktop (--desktop)
Enable a remote desktop inside the container, accessible via a web browser (noVNC) or a VNC client. This is useful for running GUI tools (SDR++, SDRangel, GQRX, etc.) without requiring X11 forwarding on the host.
When enabled, RF Swift:
- Injects
RFSWIFT_DESKTOP_PROTO,RFSWIFT_DESKTOP_HOST, andRFSWIFT_DESKTOP_PORTenvironment variables into the container - Uses an entrypoint wrapper that starts the VNC server before launching the shell
- Sets up port bindings automatically for non-host network modes
- Prints the access URL to the terminal
- Adds an
org.rfswift.desktoplabel to the container
Desktop config format (--desktop-config): proto:host:port
All parts are optional and fall back to defaults:
| Part | Options | Default |
|---|---|---|
proto |
http (noVNC), vnc (raw VNC) |
http |
host |
Bind address | 127.0.0.1 |
port |
Listen port | 6080 (http) or 5900 (vnc) |
# Browser access (default, localhost only)
--desktop
--desktop --desktop-config "http:0.0.0.0:6080"
# VNC client access
--desktop --desktop-config "vnc::5900"
# Custom port on all interfaces
--desktop --desktop-config "http:0.0.0.0:8080"Password protection (--desktop-pass):
Set a VNC password to secure the desktop session. Recommended when binding to 0.0.0.0:
# Password-protected desktop on all interfaces
--desktop --desktop-config "http:0.0.0.0:6080" --desktop-pass "mysecretpass"When a password is set, both noVNC (browser) and VNC clients will prompt for it before connecting. Without a password, access is unauthenticated — safe when bound to 127.0.0.1 (default), but a security risk when exposed on the network.
SSL/TLS encryption (--desktop-ssl):
Enable SSL/TLS to encrypt the desktop connection. A self-signed certificate is automatically generated inside the container:
# SSL-encrypted desktop with password
--desktop --desktop-config "http:0.0.0.0:6080" --desktop-pass "mysecretpass" --desktop-ssl
# SSL with VNC client
--desktop --desktop-config "vnc:0.0.0.0:5900" --desktop-pass "mysecretpass" --desktop-sslWith SSL enabled, noVNC uses https:// and VNC clients connect via vncs:// (TLS-wrapped VNC). The self-signed certificate will trigger a browser warning on first connection — this is expected.
The password and SSL can also be set in the config file (~/.config/rfswift/config.ini):
[desktop]
password = mysecretpass
ssl = true--desktop with --no-x11 when you only need browser-based GUI access — this removes the X11 socket binding entirely, improving security and avoiding the need for xhost or X11 configuration on the host.Recording Options
Enable recording (--record): Records terminal session
--record # Auto-generated filenameCustom filename (--record-output): Specify recording filename
--record-output client-session.cast
--record-output /path/to/recordings/$(date +%Y%m%d)-session.castRecordings are saved in asciinema format (.cast files) and can be replayed with rfswift log replay.
Auto-generated filenames: When --record is used without --record-output, the filename is automatically generated as:
rfswift-run-{container_name}-{YYYYMMDD-HHMMSS}.castRecording indicator: During recording, the terminal title changes to ⏺ REC | RF Swift as a visual reminder. The environment variable RFSWIFT_RECORDING=1 is also set inside the container, which can be used by scripts to detect recording mode.
Interactive Wizard
When you run rfswift run without specifying -i (image) and -n (name) in an interactive terminal, RF Swift launches a step-by-step guided wizard using a TUI (Terminal User Interface).
Launch the wizard:
rfswift runWizard Steps
The wizard guides you through the following steps:
-
Profile Selection (if profiles are available) – Choose a profile to pre-fill settings, or select “No profile” for manual configuration. If a profile is selected, you’re asked whether to use it as-is (fast path: only asks for container name) or customize all settings with profile values pre-filled.
-
Image Selection – If a profile was selected, its image appears first with all local images available as alternatives, plus “Other (enter manually)”. Without a profile, shows a scrollable picker of local images.
-
Container Name – Required text input (placeholder:
my_sdr). -
Volume Bindings – Asks if you want to add volume bindings, then prompts for comma-separated
host:containerpaths. -
Device Mappings – Asks if you want to add device mappings, then prompts for comma-separated device paths.
-
Port Mappings – Simplified port binding step. Enter
hostPort:containerPortpairs (e.g.,8080:80,4443:443). RF Swift auto-generates both exposed ports and port bindings from this input. -
Network Mode – Select from host, NAT (create new isolated network), join existing NAT network, or bridge.
-
Feature Toggles – Multi-select checklist:
- Remote Desktop (VNC/noVNC)
- Desktop SSL/TLS
- Disable X11 forwarding
- Privileged mode
- Realtime mode (audio/SDR)
- VPN (WireGuard/OpenVPN/Tailscale/Netbird)
-
Desktop Port Configuration (if desktop enabled with non-host network) – Choose the host bind address (
127.0.0.1or0.0.0.0) and port for the desktop service. -
VPN Configuration (if VPN selected) – Prompts for VPN type, then type-specific input.
-
Capabilities – Multi-select from 18 common Linux capabilities with descriptions (NET_ADMIN, NET_RAW, SYS_RAWIO, SYS_ADMIN, SYS_PTRACE, SYS_NICE, etc.).
-
Cgroup Rules – Multi-select from common device cgroup rules with descriptions:
c 189:* rwm— USB devices (SDR dongles, serial adapters)c 188:* rwm— USB serial (ttyUSB)c 166:* rwm— ACM modems (ttyACM)c 116:* rwm— ALSA sound devicesc 226:* rwm— DRI/GPU renderingc 13:* rwm— Input devices (HID, joystick)c 137:* rwm— VHCI (virtual HCI for Bluetooth)- And more…
-
Configuration Recap – Displays a summary of all selected options.
-
CLI Equivalent – Shows the equivalent
rfswift runcommand. -
Final Confirmation –
Create this container?Yes/No prompt.
Example: Wizard with Profile (Fast Path)
? Start from a profile?
> sdr-full — Full SDR suite with all tools and device support
? Use profile 'sdr-full' as-is?
> Yes, use as-is
? Container name: my_sdr_work
──────────────────────────────────────────────────
Container Configuration (from profile):
Image: penthertz/rfswift_noble:sdr_full
Name: my_sdr_work
Network: host
Realtime: enabled
──────────────────────────────────────────────────
? Create this container? YesExample: Wizard without Profile
? Start from a profile?
> No profile (manual configuration)
? Select an image:
> penthertz/rfswift_noble:sdr_full
? Container name: my_sdr_work
? Add volume bindings? Yes
? Volume bindings: ~/captures:/root/captures
? Add device mappings? Yes
? Device paths: /dev/bus/usb
? Expose ports? No
? Network mode: Host
? Select features:
[x] Realtime mode (audio/SDR)
[x] VPN (WireGuard/OpenVPN/Tailscale/Netbird)
? VPN type: tailscale
? Auth key (optional):
? Add extra Linux capabilities? Yes
? Select capabilities:
[x] NET_ADMIN — network config, monitor mode, packet capture
[x] NET_RAW — raw sockets, packet injection
? Add device cgroup rules? Yes
? Select cgroup rules:
[x] c 189:* rwm — USB devices (SDR dongles, serial adapters)
──────────────────────────────────────────────────
Container Configuration:
Image: penthertz/rfswift_noble:sdr_full
Name: my_sdr_work
Bindings: ~/captures:/root/captures
Devices: /dev/bus/usb
Capabilities: NET_ADMIN,NET_RAW
Cgroups: c 189:* rwm
Realtime: enabled
VPN: tailscale
──────────────────────────────────────────────────
Equivalent CLI command:
rfswift run -i penthertz/rfswift_noble:sdr_full -n my_sdr_work \
-b ~/captures:/root/captures -s /dev/bus/usb \
-a NET_ADMIN,NET_RAW -g "c 189:* rwm" --realtime --vpn tailscale
? Create this container? Yes-i and -n flags explicitly.Common Patterns
Quick Container for Testing
# Minimal setup
rfswift run -i sdr_light -n test
# With one device
rfswift run -i sdr_full -n quick_test -s /dev/bus/usb:/dev/bus/usbHigh-Performance SDR Container
rfswift run -i sdr_full -n high_perf \
--realtime \
-s /dev/bus/usb:/dev/bus/usb \
-g "c 189:* rwm" \
-b ~/captures:/root/capturesRepeatable Assessment Container
# Save as script: setup_assessment.sh
#!/bin/bash
CONTAINER_NAME="assessment_$(date +%Y%m%d)"
rfswift run -i pentest -n "$CONTAINER_NAME" \
-u 0 \
--realtime \
-t bridge \
-b ~/assessments:/root/work \
--record \
--record-output "${CONTAINER_NAME}.cast"Development Container
rfswift run -i sdr_full -n sdr_dev \
-b ~/code:/root/code \
-b ~/.ssh:/root/.ssh:ro \
-b ~/.gitconfig:/root/.gitconfig:ro \
-w 8888:8888/tcpRemote Desktop SDR Workstation
rfswift run -i sdr_full -n remote_sdr \
--desktop \
--desktop-config "http:0.0.0.0:6080" \
--no-x11 \
--realtime \
-s /dev/bus/usb:/dev/bus/usb \
-g "c 189:* rwm" \
-b ~/captures:/root/captures \
--recordIsolated Analysis Container
rfswift run -i reversing -n isolated_analysis \
-u 0 \
-t none \
-b ~/samples:/root/samples:ro \
-b ~/output:/root/output \
--no-x11Troubleshooting
Container Name Already Exists
Error: container name 'X' is already in use. Use a different name with -n, or exec into the existing container with: rfswift exec -c X
Solution:
# Exec into the existing container
rfswift exec -c container_name
# Or remove it and recreate
rfswift remove -c container_name
# Or use a different name
rfswift run -i image -n container_name_2Image Not Found
Error: Error: No such image: penthertz/rfswift_noble:image_name
Solution:
# Pull image first
rfswift images pull -i image_name
# Or let run pull automatically (if network available)
rfswift run -i image_name -n containerDevice Not Accessible
Problem: Device binding added but can’t access device in container
Solution:
# Add cgroup rule for device type
rfswift run -i image -n container \
-s /dev/ttyUSB0:/dev/ttyUSB0 \
-g "c 189:* rwm"
# Or add dynamically
rfswift cgroups add -c container -g "c 189:* rwm"Permission Denied for Device
Problem: Permission denied when accessing device
Solution:
# Check host permissions
ls -l /dev/your_device
# Add user to device group on host
sudo usermod -aG dialout $USER
newgrp dialout
# Then run container
rfswift run -i image -n container -s /dev/your_device:/dev/your_deviceNetwork Operations Fail
Problem: Wi-Fi/Bluetooth tools can’t configure interfaces
Solution:
# Add network capabilities
rfswift run -i wifi -n wifi_tools \
-a NET_ADMIN,NET_RAW \
-t bridgeX11 Not Working
Problem: GUI applications won’t start or display
Solution:
# On host (Linux)
xhost +local:
# Then run container
rfswift run -i image -n container -d DISPLAY=$DISPLAY
# Or disable X11 for headless operation
rfswift run -i image -n container --no-x11Audio Not Working
Problem: No audio output from container
Solution:
# Enable audio support first
rfswift host audio enable
# Check PulseAudio is running
ps aux | grep pulse
# Run container with correct server
rfswift run -i image -n container -p tcp:127.0.0.1:34567Port Already in Use
Problem: Can’t bind port - already in use
Solution:
# Check what's using the port
sudo lsof -i :8080
# Use different host port
rfswift run -i image -n container -w 8081:80/tcp
# Or stop conflicting service
sudo systemctl stop service_nameBuffer Underruns with SDR
Problem: Experiencing sample drops or buffer underruns
Solution:
# Enable realtime mode
rfswift run -i sdr_full -n sdr_work --realtime
# Or add to existing container
rfswift realtime enable -c existing_container
# Verify inside container
rfswift exec -c sdr_work -e "ulimit -r"
# Should show: 95
# Use real-time scheduling
chrt -f 50 your_sdr_commandBest Practices
1. Use Descriptive Names
# Good
rfswift run -i sdr_full -n rtlsdr_spectrum_analysis_2024_01
# Not recommended
rfswift run -i sdr_full -n test12. Start Unprivileged
Always start with -u 0 and add capabilities as needed:
# Start unprivileged
rfswift run -i wifi -n wifi_scan -u 0
# Add capabilities if needed
rfswift capabilities add -c wifi_scan -a NET_ADMIN3. Use Realtime Mode for SDR Work
# Always use --realtime for SDR captures
rfswift run -i sdr_full -n hackrf_capture --realtime4. Use Read-Only Mounts for Reference Data
rfswift run -i analysis -n data_analysis \
-b ~/samples:/root/samples:ro \
-b ~/output:/root/output5. Record Important Sessions
rfswift run -i pentest -n client_assessment \
--record \
--record-output client-$(date +%Y%m%d).cast6. Use Bridge Network for Services
rfswift run -i web_tools -n web_server \
-t bridge \
-w 127.0.0.1:8080:80/tcp7. Organize Project Directories
# Create organized structure
mkdir -p /pathto/rf-assessments/{captures,projects,recordings}
# Use in containers
rfswift run -i sdr_full -n assessment \
-b /pathto/rf-assessments/captures:/root/captures,/pathto/rf-assessments/projects:/root/projects \
--record-output /pathto/rf-assessments/recordings/session.castRelated Commands
profile- Manage container profiles (presets)exec- Enter an existing containerstop- Stop a running containerremove- Remove a containerbindings- Dynamically add devices/volumescapabilities- Modify capabilities after creationcgroups- Modify cgroup rules after creationports- Manage ports after creationrealtime- Enable/disable realtime mode on existing containersulimits- Manage ulimits on existing containers- VPN Inside Containers - Detailed VPN setup guide
- Using Podman - Podman-specific guidance
--realtime flag for optimal SDR performance. It automatically configures rtprio, memlock, nice ulimits and SYS_NICE capability to eliminate buffer underruns!rfswift run --help to see all options with their current default values from your config file.