Install docker:
sudo yum -y install docker
# Start Docker service
sudo systemctl start docker
# Enable Docker to start on boot (optional but recommended)
sudo systemctl enable docker
# Add your user to the docker group so you don't need sudo for docker commands
sudo usermod -aG docker $USER
# Log out and back in, or run this to apply the group change immediately
newgrp dockerInstall docker-compose:
# Download the latest docker-compose binary
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Make it executable
sudo chmod +x /usr/local/bin/docker-compose
# Verify installation
docker-compose --versionFrom within deployment/asterisk-server/, run:
docker-compose up -dStop:
docker-compose down # or: docker stop asterisk-serverOnce the server is running, view logs and access the Asterisk CLI via:
docker exec -it asterisk-server asterisk -rvvvvvEnsure the files in deployment/asterisk-server/asterisk-config/ are configured properly:
ari.conf: Asterisk REST Interface (ARI) configuration for external API access. To be used by shim server.- Configure ARI username/password and allowed origins.
asterisk.conf: Core Asterisk daemon settings and directory paths.extensions.conf: Dialplan configuration defining call routing logic.- Configure inbound/outbound call handling and contexts.
http.conf: HTTP server settings for ARI and web interfaces.- Configure bind address and port for HTTP access.
logger.conf: Logging configuration for console and syslog output.modules.conf: Module loading configuration specifying which Asterisk modules to load.pjsip.conf: PJSIP stack configuration for SIP endpoints and transports.- Configure TLS certificates, Chime endpoints, Chime phone number, media encryption, etc.
rtp.conf: RTP media configuration for audio/video transport .
Our Asterisk server needs a valid TLS certificate for SIP over TLS (TCP/5061). We use Let's Encrypt with the HTTP-01 challenge. The EC2 VM manages certs; certs are mounted read-only into the Dockerized Asterisk. Renewal is handled by systemd's certbot-renew.timer on Amazon Linux 2023.
sudo yum update -y
sudo yum install -y certbot-
In the EC2 VM's Security Group, allow inbound TCP 80 from
0.0.0.0/0. -
Ensure
sip.client0.vectorly.apppoints to the EC2 VM's Elastic IP (EIP). -
Stop anything bound to port 80 (usually nothing on this box):
sudo systemctl stop asterisk || true
sudo certbot certonly --standalone \
--preferred-challenges http \
-d sip.client0.vectorly.app \
--agree-tos -m admin@vectorly.app \
--force-renewalCert paths (mounted into the container):
/etc/letsencrypt/live/sip.client0.vectorly.app/fullchain.pem
/etc/letsencrypt/live/sip.client0.vectorly.app/privkey.pem
sudo systemctl enable --now certbot-renew.timer
systemctl list-timers --all | grep certbot- Note: No cron needed on Amazon Linux 2023.
Create a deploy hook so Asterisk picks up new certs only when they actually change.
Reload (preferred; no container bounce):
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-asterisk.sh > /dev/null <<'EOF'
#!/bin/sh
docker exec asterisk-server asterisk -rx "core reload"
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-asterisk.shOr, if you prefer a full container restart:
sudo tee /etc/letsencrypt/renewal-hooks/deploy/restart-asterisk.sh > /dev/null <<'EOF'
#!/bin/sh
docker restart asterisk-server
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/restart-asterisk.shTest end-to-end:
sudo certbot renew --dry-runSee docker-compose.yml; the Asterisk service mounts /etc/letsencrypt:/etc/letsencrypt:ro.
In pjsip.conf:
[transport-tls]
type=transport
protocol=tls
bind=0.0.0.0:5061
method=tlsv1_2
cert_file=/etc/letsencrypt/live/sip.client0.vectorly.app/fullchain.pem
priv_key_file=/etc/letsencrypt/live/sip.client0.vectorly.app/privkey.pemWe include a Compose healthcheck that runs:
asterisk -rx 'core show uptime'
This keeps orchestration honest and surfaces if Asterisk is responsive.
To restart the Asterisk server:
docker exec -it asterisk-server asterisk -rvvvvv
...
*CLI> core restart nowdocker exec -it asterisk-server asterisk -rvvvvv
...
*CLI> core set verbose 10
*CLI> pjsip set logger on
*CLI> rtp set debug onInitiate outbound call and play audio:
docker exec -it asterisk-server asterisk -rvvvvv
*CLI> channel originate PJSIP/+1XXXXXXXXXX@chime-out application Statsis voice-agentBuild:
docker build -t asterisk_shim_server -f deployment/shim-server/Dockerfile .Run in the background:
docker run -d --env-file .env --network host --name asterisk-shim asterisk_shim_server-d: Runs image in background (no attached terminal).--network host: Puts the container on the host's network stack. This means:- It shares the host's IP.
- Ports inside the container are directly accessible on the host (no need for
-pport mappings). - Useful for SIP/RTP because you don't have to map a giant range of UDP ports; Asterisk can just use host networking.
- One downside is that the container can see all host interfaces, and you can't run two host-mode containers that bind the same ports.
View logs of the container:
docker logs -f asterisk-shim