MediumWhat exactly is a mini-VOIP network? | by Ezra Kipyegon | Oct, 2026 | Medium
Sitemap
Ezra Kipyegon

Ezra Kipyegon

What exactly is a mini-VOIP network?

4 min readOct 25, 2026

--

Press enter or click to view image in full size

Imagine having your own private telephone company running entirely inside a single computer. That’s essentially what a mini-VoIP network is: a compact, fully functional Internet telephony system that lets devices talk, stream video, and send messages and all over a local network without relying on traditional phone carriers.

In this article, we’ll build a lightweight, repeatable local SIP setup: a local voice and text server powering two Linphone clients.

Essentials:

  • Asterisk 23.5.0 (image docker.io/andrius/asterisk:latest)
  • Podman 6.1.4 (API version), Podman Desktop 1.30.5 optional
  • Linphone, current desktop and Android releases
  • Two clients on the same network

1. Setup of Asterisk: Install and start

For this, we will use Podman. On Linux it runs containers directly. On macOS and Windows it runs a small Linux VM, created once and started after each reboot. Install Podman from here then proceed with the following steps.

podman machine init — disk-size 20 — cpus 2 — memory 2048 # macOS/Windows only, once
podman machine start # macOS/Windows only, after reboot

The disk size is a ceiling, not reserved space. It can grow later but never shrink.

Keep config outside the container

Copy the default config out once, then mount it. Edits then survive container recreation.

podman run -d — name asterisk — restart unless-stopped docker.io/andrius/asterisk
mkdir -p ~/asterisk-conf
podman cp asterisk:/etc/asterisk/. ~/asterisk-conf/
podman rm -f asterisk

Enable HTTP (optional) and RTP

cat >> ~/asterisk-conf/http.conf <<'EOF'
[general]
enabled=yes
bindaddr=0.0.0.0
bindport=8088
EOF
cat >> ~/asterisk-conf/rtp.conf <<’EOF’
[general]
rtpstart=10000
rtpend=10100
EOF

Run the container

Publish SIP, HTTP and the RTP range. Without the RTP range, calls connect but have no audio.

podman run -d — name asterisk — restart unless-stopped \
-p 5060:5060/udp -p 8088:8088 \
-p 10000–10100:10000–10100/udp \
-v ~/asterisk-conf:/etc/asterisk:Z \
docker.io/andrius/asterisk

SIP config

Run each cat >> block once. Running it twice appends the sections twice.

Change the passwords before exposing this beyond your own network.

Dialplan

Custom script: Auto pick up the current IP of the host device

Asterisk must advertise the host’s current LAN IP for signaling and audio. Transport settings are not applied on a reload, so the script rewrites the file and restarts the container. Run it after boot and after every network change.

Make the file executable

chmod +x ~/asterisk-up.sh

The two local_net lines cover the Podman VM and container networks. On native Linux, adjust them to your Podman network.

Verify

podman ps
podman exec asterisk asterisk -rx “pjsip show transports”
podman exec asterisk asterisk -rx “pjsip show endpoints”

PORTS should include 5060/udp, 8088/tcp and 10000-10100/udp.

2. Client Devices Setup

Install Linphone on each device. Use the third-party SIP account option and fill in

Get Ezra Kipyegon’s stories in your inbox

Join Medium for free to get updates from this writer.

Linphone on the same machine as Asterisk

  • Username: 6001
  • Password: ChangeMe123
  • Domain: 127.0.0.1:5060
  • Transport: UDP

Linphone on another device

  • Username: 6002
  • Password: ChangeMe456
  • Domain: your host’s LAN IP, port 5060
  • Transport: UDP

Leave Registrar URI and Outbound Proxy blank.

Tips

  • Use 127.0.0.1, not localhost. Some clients resolve localhost to IPv6, which the container port mapping does not forward.
  • On the Android client, disable video and keep only PCMU and PCMA audio codecs. A smaller INVITE avoids dropped UDP packets and calls from the phone then work.
  • Both devices must be on the same network without client isolation. Guest networks and some routers block device to device traffic. A phone hotspot is a quick workaround.
  • After a network change, run the script, then update the phone’s domain to the IP it prints.
  • If registration fails with a stale contact, remove_existing=yes and a restart clear it.

Check and test

podman exec asterisk asterisk -rx “pjsip show contacts”

Both contacts should show Avail. Dial 600 and speak to hear the echo, then call 6001 and 6002 from each other.

3. Messages Setup

Asterisk routes SIP text messages only when told how. Two pieces are needed.

1. Endpoint setting. message_context=messages is already in the shared endpoint section of pjsip.conf, from the block in section 1.

2. Dialplan context. Append a [messages] context to extensions.conf. It forwards each message to the dialed extension with MessageSend.

Apply the change:

podman exec asterisk asterisk -rx “dialplan reload”
podman exec asterisk asterisk -rx “module reload res_pjsip.so”

Send a message from each Linphone to the other. In the console, pjsip set logger on shows a MESSAGE request answered by 200 OK or 202 Accepted.

Limits

  • Asterisk does not store messages. The recipient must be registered.
  • Group chat, file sharing and read receipts need a dedicated messaging server such as Flexisip.

Quick reference

Task Command
Start everything ~/asterisk-up.sh
Registered devices podman exec asterisk asterisk -rx “pjsip show contacts”
Live console podman exec -it asterisk asterisk -rvvv
Reload dialplan podman exec asterisk asterisk -rx “dialplan reload”
Apply transport changes podman restart asterisk

Recap

One container, a few config files and a small script gave us a working VoIP system: registration, calls with audio, and messaging between two Linphone clients. It’s a test bed, not a production server, but it’s a solid base. Harden the passwords, add encryption, and move it to a Linux host when you’re ready to take it further.

Thanks!

--

--