Criando Chamadas WebRTC com Asterisk em Docker
Quer permitir chamadas de voz diretamente pelo navegador usando WebRTC e integrá-las ao Asterisk? Neste post, vou te mostrar passo a passo como rodar o Asterisk dentro de um container Docker, configurar os transportes necessários e conectar um frontend WebRTC usando JavaScript (com JsSIP).
A ideia aqui é montar um ambiente completo, mas simples o suficiente para você testar localmente ou em um servidor de homologação. Vamos começar configurando o Asterisk no Docker.
🐳Subindo o Asterisk com Docker (com WebRTC)
Para ter controle total sobre os módulos e dependências do Asterisk — incluindo suporte ao WebRTC e ao codec Opus — usaremos uma imagem personalizada baseada no Debian Bookworm.
📦Dockerfile
Crie um arquivo Dockerfile
com o conteúdo abaixo:
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y \
wget curl build-essential \
libedit-dev uuid-dev libjansson-dev libxml2-dev \
unixodbc unixodbc-dev odbc-postgresql libpq-dev \
&& apt-get clean
WORKDIR /usr/src
RUN wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-20-current.tar.gz \
&& tar xvf asterisk-20-current.tar.gz \
&& cd asterisk-20.* \
&& contrib/scripts/install_prereq install \
&& ./configure --with-pjproject-bundled --with-jansson-bundled \
&& make menuselect.makeopts \
&& menuselect/menuselect --enable codec_opus --enable res_odbc --enable cdr_adaptive_odbc --enable res_config_odbc menuselect.makeopts \
&& make -j$(nproc) && make install && make samples && make config && ldconfig
RUN mkdir -p /opt/asterisk-config
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
CMD ["/entrypoint.sh"]
🔁Script de inicialização
Crie um arquivo entrypoint.sh
ao lado do seu Dockerfile:
#!/bin/bash
CONFIG_SRC="/opt/asterisk-config"
CONFIG_DEST="/etc/asterisk"
cp -r "$CONFIG_SRC/"* "$CONFIG_DEST/"
exec asterisk -vvv -f
🛠️ Build e execução do container
Agora, para construir e rodar o container:
docker build -t asterisk-webrtc .
🌐 Criando uma rede Docker dedicada
Antes de usarmos o Docker Compose, é uma boa prática criar uma rede personalizada para isolar e facilitar a comunicação entre os serviços da stack (como o Asterisk e, futuramente, um possível backend ou frontend).
Execute o seguinte comando para criar uma rede Docker chamada asterisk-webrtc-network
:
docker network create asterisk-webrtc-network
📦 Usando Docker Compose
Agora, vamos substituir o comando manual de docker run
por um docker-compose.yml
, que facilita o gerenciamento da stack como um todo.
Crie um arquivo docker-compose.yml
com o seguinte conteúdo:
name: asterisk-webrtc
services:
asterisk:
image: asterisk-webrtc # Sua image local
container_name: asterisk
ports:
- "8089:8089" # WebSocket TLS (WSS)
- "8088:8088" # WebSocket (WS) ou HTTP API
volumes:
- ./asterisk:/opt/asterisk-config
- ./etc/odbc.ini:/etc/odbc.ini
- ./etc/odbcinst.ini:/etc/odbcinst.ini
networks:
- voip-asterisk
networks:
voip-asterisk:
external: true
💡 Importante: Certifique-se de que o diretório ./asterisk
contenha os arquivos de configuração como pjsip.conf
, http.conf
, etc., e que os arquivos odbc.ini
e odbcinst.ini
estejam na pasta ./etc
.
⚙️ 2. Configurações do Asterisk para WebRTC
Agora que o container está rodando, precisamos configurar o Asterisk para suportar chamadas WebRTC, armazenamento de CDR (Call Detail Records), comunicação via WebSocket, entre outros pontos essenciais.
Vamos começar com os arquivos de configuração um a um. Todos devem ser colocados no diretório ./asterisk
, que é montado dentro do container em /opt/asterisk-config
.
📄 cdr_adaptive_odbc.conf
Este arquivo configura o Asterisk para gravar os registros de chamadas (CDR) diretamente em um banco de dados via ODBC. Neste caso, usamos uma conexão chamada asterisk
que deve ser definida em res_odbc.conf
.
[asterisk]
connection=asterisk
table=cdr
- connection=asterisk: nome da conexão ODBC (deve bater com
res_odbc.conf
) table=cdr
: nome da tabela onde os registros de chamadas serão gravados
💡 Essa configuração é opcional para chamadas WebRTC, mas recomendada em ambientes de produção para registrar todas as ligações.
📄 extconfig.conf
Este arquivo define que algumas configurações do Asterisk devem ser carregadas dinamicamente de um banco de dados via ODBC. Isso é útil para gerenciar endpoints SIP (usuários) de forma centralizada.
[settings]
ps_endpoints => odbc,asterisk
ps_auths => odbc,asterisk
ps_aors => odbc,asterisk
ps_endpoints
,ps_auths
,ps_aors
: são partes do módulo PJSIP, que define usuários, autenticações e associações.odbc,asterisk
: significa que os dados virão de uma fonte ODBC chamadaasterisk
(configurada emres_odbc.conf
).
✅ Essencial para ambientes onde os dados de usuários são armazenados no banco, como sistemas multiusuário ou integrações com backends web.
📄 extensions.conf
Este é o dialplan do Asterisk — a “lógica de chamadas”. No exemplo abaixo, estamos criando um contexto chamado webrtc
, que atende qualquer número (_.
) e tenta discar para o endpoint SIP correspondente.
_.
: coringa que corresponde a qualquer número discado.Dial(PJSIP/${EXTEN},60)
: tenta estabelecer a chamada com o endpoint SIP identificado por${EXTEN}
, com timeout de 60 segundos.Hangup()
: encerra a chamada caso o dial falhe ou termine.
⚠️ Certifique-se de que os usuários/dispositivos WebRTC estejam registrados com nomes que combinem com os valores que você vai discar (ex: ramais como
1001
,alice
, etc.).
📄 http.conf
Este arquivo ativa o servidor HTTP interno do Asterisk e também o suporte a WebSocket (WS/WSS), necessário para que navegadores possam se conectar via WebRTC.
[general]
enabled=yes
bindaddr=0.0.0.0
bindport=8088
tlsenable=yes
tlsbindaddr=0.0.0.0:8089
tlscertfile=/etc/asterisk/keys/asterisk-local-cert.pem
tlsprivatekey=/etc/asterisk/keys/asterisk-local-key.pem
enabled=yes
: ativa o servidor HTTP.bindaddr=0.0.0.0
/bindport=8088
: escuta requisições HTTP normais.tlsenable=yes
: habilita o suporte a HTTPS/WSS.tlsbindaddr=0.0.0.0:8089
: escuta conexões seguras.tlscertfile
etlsprivatekey
: certificados TLS para WebSocket seguro (WSS).
🔒 Importante: para funcionar em navegadores modernos, é obrigatório usar WSS (WebSocket seguro) com certificado válido — inclusive em ambientes de teste. Você pode gerar um autoassinado ou usar Let’s Encrypt.
📄 pjsip.conf
Este é um dos arquivos mais importantes — ele define os transportes, endpoints (usuários), autenticação e associação dos dispositivos SIP. Começamos pelos transportes:
[transport-wss]
type=transport
protocol=wss
bind=0.0.0.0
[transport-ws]
type=transport
protocol=ws
bind=0.0.0.0
transport-wss
: transporte seguro para WebRTC via WSS (WebSocket Secure). Usado pela maioria dos navegadores.transport-ws
: transporte não seguro para ambientes de desenvolvimento (WebSocket simples).bind=0.0.0.0
: escuta em todas as interfaces de rede do container.
⚠️ Para WebRTC em produção, use apenas o WSS. O transporte WS sem TLS é bloqueado por navegadores em conexões HTTPS.
📄 res_odbc.conf
Este arquivo configura a conexão ODBC que o Asterisk usará para acessar dados como CDRs e registros do PJSIP (quando integrados ao banco de dados).
[asterisk]
enabled=yes
dsn=Asterisk-DB
username=postgres
password=postgres
pre-connect=yes
enabled=yes
: ativa essa conexão.dsn=Asterisk-DB
: nome do DSN definido noodbc.ini
.username
epassword
: credenciais de acesso ao banco de dados (exemplo: PostgreSQL).pre-connect=yes
: mantém a conexão ativa durante o tempo de execução.
🧠 Essa seção deve estar alinhada com a configuração no
cdr_adaptive_odbc.conf
e noextconfig.conf
, que fazem referência à conexãoasterisk
.
📄 rtp.conf
Este arquivo configura o intervalo de portas que o Asterisk usará para o tráfego RTP (Real-time Transport Protocol), que é fundamental para o transporte de áudio nas chamadas.
[general]
rtpstart=10000
rtpend=20000
rtpstart=10000
: porta inicial do intervalo de portas RTP.rtpend=20000
: porta final do intervalo de portas RTP.
🔐 Dica: Certifique-se de que o firewall do seu servidor permita o tráfego nas portas que você definir para o RTP. Para WebRTC, é importante garantir que o tráfego UDP seja liberado para esse intervalo.
📄 sorcery.conf
Este arquivo configura o Asterisk para usar sorcery, que é uma estrutura para carregar configurações dinâmicas para os módulos do Asterisk a partir de fontes externas, como um banco de dados via ODBC.
[res_pjsip]
endpoint=realtime,ps_endpoints
auth=realtime,ps_auths
aor=realtime,ps_aors
endpoint=realtime,ps_endpoints
: define que os endpoints (usuários) serão carregados em tempo real de uma tabela no banco de dados (configurado emextconfig.conf
).auth=realtime,ps_auths
: define que as informações de autenticação também virão de uma tabela externa.aor=realtime,ps_aors
: associações de objetos de recursos (AOR) serão obtidas dinamicamente.
💡 O uso de “realtime” significa que o Asterisk está configurado para buscar esses dados de um banco de dados em vez de um arquivo estático, proporcionando maior flexibilidade na gestão dos usuários e configurações.
⚙️ Configurações ODBC para PostgreSQL
Na raiz do seu projeto Docker, a pasta ./etc
deve conter os arquivos:
odbc.ini
: define a conexão com o banco (DSN).odbcinst.ini
: registra o driver PostgreSQL ODBC no sistema.
Esses arquivos serão montados no container e utilizados pelo Asterisk.
📄 odbc.ini
Este arquivo define o DSN (Data Source Name) usado pelo Asterisk para se conectar ao banco PostgreSQL:
[Asterisk-DB]
Description=PostgreSQL Asterisk DB
Driver=PostgreSQL
Servername=postgres # Deve estar conectado a sua network com esse host
Database=asterisk
Username=postgres
Password=postgres
Port=5432
[Asterisk-DB]
: nome do DSN (referenciado emres_odbc.conf
).Driver=PostgreSQL
: nome do driver (deve bater com oodbcinst.ini
).Servername=postgres
: nome do host ou container do PostgreSQL (se estiver nodocker-compose
, o nome do serviço).Database=asterisk
: nome do banco de dados.Username
ePassword
: credenciais do banco.Port=5432
: porta padrão do PostgreSQL.
📄 odbcinst.ini
Este arquivo registra o driver ODBC do PostgreSQL no sistema:
[PostgreSQL]
Description=ODBC for PostgreSQL
Driver=/usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
O caminho do driver (Driver
) pode variar entre distribuições. No Debian (como usamos no Dockerfile
), estes caminhos são comuns. Caso dê erro, use find /usr -name "*psql*.so"
no container para confirmar.
Com isso, você conecta o Asterisk a um banco PostgreSQL com suporte a Realtime e CDRs via ODBC.
📞 Integração WebRTC com Asterisk usando JsSIP
Este código Vue + TypeScript define um serviço de chamadas VoIP usando a biblioteca JsSIP, que implementa o protocolo SIP sobre WebSockets.
🧩 Estrutura do Serviço SIP
O arquivo define a classe SIPService
, que gerencia:
- Registro SIP no Asterisk (via WebSocket seguro
wss
). - Recebimento e realização de chamadas.
- Emissão de eventos para uso no Vue (como
incomingCall
,onCall
,endedCall
, etc). - Controle de mídia (mute, unmute, encerramento).
🔐 Registro SIP
this.user = "4000";
this.password = "4000";
- O número de ramal (
4000
) é usado para registrar o cliente no Asterisk. - A conexão é feita via
wss://localhost:8089/ws
— porta8089
corresponde ao WebSocket TLS configurado nohttp.conf
.
⚙️ Configuração do Asterisk
O funcionamento depende de:
http.conf
comtlsenable=yes
,bindport=8089
.pjsip.conf
com os transportesws
ewss
.extensions.conf
para roteamento de chamadas (Dial(PJSIP/${EXTEN})
).sorcery.conf
eextconfig.conf
configurados para usar ODBC (realtime).
📡 Realizando uma chamada
sipService.makeCall("4001");
- O método verifica se o usuário está registrado e usa o
getUserMedia()
para capturar áudio. - A chamada é feita para outro ramal SIP (
4001
), por exemplo.
📥 Atendendo uma chamada
sipService.answerCall();
- Aceita uma chamada recebida.
- Usa também o
getUserMedia()
para abrir o microfone.
🎙️ Eventos disparados
A classe emite eventos que podem ser usados nos componentes Vue:
"incomingCall"
: chamada recebida."outgoingCall"
: chamada sendo realizada."onCall"
: chamada ativa."endedCall"
: chamada encerrada."canceledCall"
e"rejectedCall"
: cancelamentos/falhas.
🧪 Dicas para testar
- Use o console para instanciar e chamar métodos do serviço.
- Tenha dois navegadores diferentes (ou abas privadas) com ramais distintos registrados para testes de chamada.
✅ Próximos Passos
Com o Asterisk rodando com suporte completo a WebRTC e JsSIP integrado no frontend, você já pode:
- Realizar chamadas entre navegadores
- Conectar dispositivos SIP tradicionais com navegadores
- Gravar CDRs em tempo real em banco de dados
Se quiser dar o próximo passo, considere:
- Adicionar autenticação com backend
- Usar STUN/TURN para suporte em NAT
- Publicar o serviço com domínio e HTTPS via reverse proxy (ex: Traefik ou Nginx)
0 Comments