Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/signalwire/freeswitch/llms.txt

Use this file to discover all available pages before exploring further.

Docker is a convenient way to run FreeSWITCH in a self-contained, reproducible environment — ideal for development, testing, CI/CD pipelines, and cloud deployments where you want isolated, version-pinned instances. The FreeSWITCH repository ships official Dockerfile examples that build the switch and all its dependencies entirely from source, with no dependency on the SignalWire package repository. Configuration and log directories can be mounted from the host for persistence across container restarts.
FreeSWITCH requires large UDP port ranges — 16384–32768 and 64535–65535 — for RTP media streams. Mapping these ranges with individual -p flags via Docker’s userspace NAT incurs significant overhead and can cause audio quality issues or failed calls at scale. For production deployments, run the container with --network host so FreeSWITCH binds directly to the host network stack. See the Docker networking note and the upstream Docker issue for details.

Official Docker Images

The docker/ directory of the FreeSWITCH repository contains official Docker configuration:
  • docker/README.md — Volume mount instructions, port reference, and networking guidance.
  • docker/examples/Debian11/Dockerfile — A complete, multi-stage Dockerfile that clones all required libraries (libks, sofia-sip, spandsp, signalwire-c) and builds FreeSWITCH from source on Debian 11 (Bullseye).
Browse the examples directory on GitHub: github.com/signalwire/freeswitch/tree/master/docker/examples

Build from Dockerfile

1

Clone the FreeSWITCH repository

git clone https://github.com/signalwire/freeswitch.git
cd freeswitch
2

Change to the Debian 11 example directory

cd docker/examples/Debian11
The Dockerfile here installs all build dependencies, clones the required support libraries, compiles them, then compiles FreeSWITCH itself — producing a self-contained image with no external package repository requirements.
3

Build the Docker image

docker build -t freeswitch .
The build clones and compiles libks, sofia-sip, spandsp, and signalwire-c before building FreeSWITCH, so expect the initial build to take several minutes. Subsequent builds use the Docker layer cache for unchanged steps.
4

Run the container

For a quick smoke test, run the image interactively with host networking:
docker run --rm -it --name freeswitch --network host freeswitch
FreeSWITCH starts in foreground mode (-c) with the built-in console. You should see the startup log and the freeswitch@hostname> prompt when the switch is ready.

Run with explicit port mappings

If you prefer to publish ports individually rather than using --network host, map the following ports. Be aware of performance considerations for the large RTP range:
docker run --rm -it \
  --name freeswitch \
  -p 5060:5060/udp \
  -p 5060:5060/tcp \
  -p 5080:5080/udp \
  -p 5080:5080/tcp \
  -p 5061:5061/tcp \
  -p 5081:5081/tcp \
  -p 5066:5066/tcp \
  -p 7443:7443/tcp \
  -p 8021:8021/tcp \
  -p 16384-32768:16384-32768/udp \
  -p 64535-65535:64535-65535/udp \
  freeswitch
Port(s)ProtocolPurpose
5060TCP / UDPSIP signaling — internal profile
5080TCP / UDPSIP signaling — external/outbound profile
5061TCPSIPS (SIP over TLS) — internal
5081TCPSIPS — external
5066TCPWebSocket (WS) for WebRTC signaling
7443TCPWebSocket Secure (WSS) for WebRTC
8021TCPEvent Socket Library (ESL) — fs_cli and API clients
16384–32768UDPRTP / SRTP media streams (primary range)
64535–65535UDPRTP / SRTP media streams (secondary range)

Docker Compose Example

For a more complete deployment with persistent configuration and log volumes, use Docker Compose:
version: "3.9"

services:
  freeswitch:
    image: freeswitch          # built locally from docker/examples/Debian11
    # build:
    #   context: ./docker/examples/Debian11
    container_name: freeswitch
    restart: unless-stopped
    network_mode: host         # recommended for RTP — avoids large port range NAT overhead
    volumes:
      - ./config:/etc/freeswitch          # persistent configuration
      - ./logs:/var/log/freeswitch        # persistent logs
      - ./recordings:/var/lib/freeswitch/recordings
      - ./storage:/var/lib/freeswitch/storage
    environment:
      - TZ=America/Chicago
    healthcheck:
      test: ["CMD", "fs_cli", "-x", "status"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s
Start the stack:
docker compose up -d
Tail the FreeSWITCH log:
docker compose logs -f freeswitch
Connect with fs_cli from inside the container:
docker exec -it freeswitch fs_cli -H 127.0.0.1 -P 8021 -p ClueCon

Environment and Volumes

Configuration (/etc/freeswitch)

FreeSWITCH reads its entire configuration from /etc/freeswitch at startup. Mount a host directory here to use your own dialplan, directory, and module configuration:
-v $(pwd)/config:/etc/freeswitch
If the mounted directory is empty on first start, FreeSWITCH will not have a configuration and will fail to initialize. Copy the vanilla config as a starting point:
# Copy vanilla config from a running container before mounting
docker run --rm freeswitch cat /etc/freeswitch/freeswitch.xml > ./config/freeswitch.xml
# Or copy the entire directory
docker create --name tmp_fs freeswitch
docker cp tmp_fs:/etc/freeswitch ./config
docker rm tmp_fs

Logs (/var/log/freeswitch)

FreeSWITCH writes freeswitch.log and the compiled XML snapshot (freeswitch.xml.fsxml) to /var/log/freeswitch. Mount this directory to persist logs across container restarts and make them accessible to log aggregation tools:
-v $(pwd)/logs:/var/log/freeswitch

Temporary files and recordings

For recordings, voicemail storage, and other runtime data, mount the appropriate paths:
-v $(pwd)/recordings:/var/lib/freeswitch/recordings
-v $(pwd)/storage:/var/lib/freeswitch/storage
-v $(pwd)/tmp:/tmp

Health check

The official Docker setup includes a health check that runs fs_cli status against the running instance. The container is reported as healthy only when FreeSWITCH is fully initialized and accepting Event Socket connections. This integrates correctly with docker compose depends_on: condition: service_healthy for orchestrated stacks.

Build docs developers (and LLMs) love