
Run a self-hosted voice AI stack locally, verify every service, and publish only the HTTP endpoint you need
VoicEra combines a dashboard, REST API, real-time voice runtime, storage, workers, telephony integrations, and interchangeable AI providers in a Docker-based stack. This guide walks through the official repository installation workflow, explains what the startup script does, identifies the local service addresses, and shows how to verify the deployment before adding remote access. Once the API works locally, we configure a Localtonet HTTP tunnel as a separate step so authorized remote clients can reach it without inbound router port forwarding, firewall changes, VPN setup, or a public IP address.
๐ What's in this guide
What VoicEra installs and how the stack fits together

VoicEra is open-source infrastructure for self-hosted, real-time voice AI. It connects speech-to-text, a large language model, text-to-speech, and telephony through a single platform. The project is API-first: its dashboard is a client of the same HTTP API that developers can use directly, and a running API provides an interactive OpenAPI interface.
The platform separates its control plane from real-time voice execution. The API manages agents, configuration, campaigns, authentication, and orchestration. The runtime handles live call audio and model interaction. The dashboard provides an operator interface, while workers process asynchronous jobs and campaign work. FerretDB, PostgreSQL, MinIO, and Redis support the stack's database, media, artifact, and queue requirements.
VoicEra does not supply telephony accounts or AI inference as part of the software. For a real phone deployment, an operator must provide supported speech, language-model, and voice capabilities through cloud accounts or self-hosted models. A telephony account is also required for real inbound or outbound phone calls. The project currently documents Vobiz and Plivo integrations. Telephony is not required for browser-based testing.
http://localhost:3000 after the stack starts successfully.
http://localhost:8000 and provides the application surface used by the dashboard and API clients.
http://localhost:8000/docs.
http://localhost:7860.
Local access and remote access are separate milestones
Installing VoicEra does not automatically make it reachable from outside the host. The documented addresses use localhost, which refers to the machine running the Docker stack. This is the correct starting point because it lets you validate the application before introducing internet exposure.
A Localtonet tunnel should come only after the selected endpoint works locally. Our client establishes an outbound connection from the VoicEra host to a Localtonet relay server. The HTTP tunnel then provides a public HTTPS address that forwards requests to the selected local IP address and port. The tunnel is available only while the chosen client device is connected and the tunnel is running.
Exposing the API on port 8000 and exposing the dashboard on port 3000 are different tasks. API integrations normally need port 8000. Human operators who need the web console may require a separate tunnel to port 3000. Do not assume that one HTTP tunnel automatically publishes every VoicEra service.
Prerequisites for the Docker-based installation
The official quick-start workflow requires Docker to be installed and running before the startup script is launched. Docker Desktop is suitable where it is supported, while a Docker daemon can be used on an appropriate server. The VoicEra script checks access to the Docker daemon and fails if it cannot reach it.
You also need Git because the documented installation starts by cloning the repository. The commands use a shell script, so run them in a shell environment capable of executing the repository's .sh files. The available evidence does not establish a complete operating-system compatibility matrix or a native Windows PowerShell installation procedure. If the host cannot directly execute shell scripts, use a compatible environment supported by your deployment rather than translating commands or file paths by guesswork.
| Requirement | Why it is needed | What to confirm |
|---|---|---|
| Docker | VoicEra starts as a Docker Compose stack. | Docker is installed and its daemon is running. |
| Git | The official quick start clones the VoicEra repository. | The git command is available in the installation shell. |
| Compatible shell | Application lifecycle commands are provided as shell scripts. | The shell can execute files under the repository's scripts directory. |
| Available local ports | The stack publishes several local services. | Ports 3000, 8000, 7860, 9001, and 27018 are not already occupied by conflicting applications. |
| AI provider or local models | A functional voice agent needs STT, LLM, and TTS capabilities. | Obtain appropriate provider access or prepare supported self-hosted models. |
| Telephony account, if needed | Real phone calls require a telephony carrier integration. | Prepare a supported Vobiz or Plivo account for telephony use. It is not required for browser testing. |
Plan capacity before treating the quick start as production
The quick start is useful for bringing up the complete application stack, but it is not evidence that a particular host has enough CPU, memory, storage, or GPU resources for a production workload. Resource needs depend heavily on whether speech and language models run locally, which providers are selected, expected call concurrency, media retention, campaign activity, and other operational choices.
No universal minimum hardware specification is established by the supplied installation evidence. Avoid choosing production infrastructure from an invented baseline. Measure the services and model workloads you actually intend to run, then consult the project's production deployment and configuration guidance before placing live calls or storing sensitive data.
A successful Docker startup is not the same as a safely configured voice platform. Confirm the dashboard, API, required providers, credentials, storage, and intended authentication behavior locally first. Public access should be limited to the smallest necessary endpoint.
Install and start VoicEra
The official Docker quick start is intentionally short. It clones the source repository, changes into the project directory, and runs the supplied startup script. That script creates the environment, generates required secrets, and starts the stack.
Start Docker
Launch Docker Desktop or start the Docker daemon appropriate for the host. Do this before running any VoicEra command because the startup script stops when it cannot contact Docker.
Clone the VoicEra repository
Open a compatible shell and clone the official repository:
git clone https://github.com/COSS-India/VoicEra.git
Enter the project directory
Change into the cloned repository so that the lifecycle script runs with the expected project files:
cd VoicEra
Start the application services
Run the repository's startup script. It creates the environment, generates required secrets, and starts the Docker stack:
./scripts/start-application-services.sh
Allow the containers enough time to initialize before testing the web addresses. A service may be starting even though Docker has already created its container. Keep the terminal output available during the first launch because it can reveal an unavailable Docker daemon, a port conflict, or a service that fails during initialization.
What the startup script does not provide for you
Automatic secret generation should not be confused with provisioning external provider accounts. VoicEra does not resell telephony or model capacity. You still bring the accounts, API credentials, models, and infrastructure needed for your chosen speech-to-text, language-model, text-to-speech, and calling workflow.
The extracted quick-start evidence does not establish every generated variable, secret filename, or production value. Do not copy guessed environment variables into the deployment. Use the repository's current configuration reference and its generated environment as the authority when a provider or production setting must be changed.
Verify the local VoicEra deployment

Verification should move from basic container health to user-facing services. Start with Docker, then test the dashboard and API from a browser on the VoicEra host. Finally, inspect the API documentation and runtime endpoint relevant to your planned integration.
Confirm that Docker containers are running
Use Docker Desktop's container view or inspect running containers from the command line:
docker ps
If expected containers repeatedly restart or disappear, investigate that condition before testing remote access.
Open the dashboard
On the host running VoicEra, visit http://localhost:3000. A rendered dashboard confirms that the frontend is reachable. It does not by itself prove that every provider or calling workflow is configured.
Check the API and OpenAPI console
Visit http://localhost:8000, then open http://localhost:8000/docs. The documentation page is especially useful because it confirms that the API service is responding and provides the interactive route definitions generated by the running application.
Check the voice runtime
Confirm that the documented runtime address, http://localhost:7860, is reachable from the host. A reachable runtime is only one part of a working voice pipeline. End-to-end operation also depends on configured STT, LLM, TTS, and, for phone calls, telephony providers.
| Local service | Documented address | Verification purpose |
|---|---|---|
| Dashboard | http://localhost:3000 |
Confirms that the operator-facing frontend is reachable. |
| API | http://localhost:8000 |
Confirms access to the HTTP control-plane service. |
| OpenAPI | http://localhost:8000/docs |
Provides the interactive API console and current route definitions. |
| Voice runtime | http://localhost:7860 |
Checks the local real-time voice runtime surface. |
| MinIO | http://localhost:9001 |
Identifies the local object-storage management service used for media and artifacts. |
| FerretDB | localhost:27018 |
Identifies the documented local database endpoint. It is not the HTTP API to publish for normal API clients. |
The API, database, object storage, and runtime serve different roles. A client that needs VoicEra's REST API should not be given direct public access to FerretDB or MinIO. Expose only the application endpoint required by the workflow and keep internal data services private unless a reviewed architecture explicitly requires otherwise.
Configure VoicEra for an actual voice workflow
Installation produces a running platform, but a useful voice agent still requires provider configuration. A typical voice pipeline accepts audio, converts it to text, sends that text to an LLM, and converts the response back to speech. VoicEra places those components behind provider interfaces, allowing operators to use cloud APIs, local models, or an appropriate combination.
Choose speech and language providers
Prepare supported STT, LLM, and TTS access before expecting an agent to conduct a conversation. Provider credentials should be entered only through the project's documented configuration or dashboard workflow. Do not hardcode secrets into source files, shell history, public examples, or Localtonet tunnel descriptions.
VoicEra can also use an optional model server to expose self-hosted STT, TTS, or LLM capabilities through a common gateway. Running models locally can change the host's GPU, memory, storage, and operational requirements substantially. The basic Docker installation should not be treated as proof that a machine is sized for local inference.
Add telephony only when phone calls are required
Browser-based testing does not require telephony. Real inbound and outbound calls require a supported telephony account, currently documented as Vobiz or Plivo. Configure the provider through VoicEra's supported workflow rather than assuming that exposing port 8000 automatically enables calling.
The available evidence does not identify a single public endpoint that every carrier should use for callbacks, and it does not establish a universal callback path. Therefore, this guide does not invent one. If a telephony integration needs a public callback URL, determine the exact route from VoicEra's current provider-specific documentation and the carrier's configuration requirements. Only then should that route be mapped to a public hostname.
A public base URL for a developer or dashboard client does not automatically establish the correct webhook or media callback configuration for a carrier. Confirm the provider-specific path, protocol, authentication, and URL requirements before configuring production telephony.
Expose the VoicEra API with a Localtonet HTTP tunnel

Once http://localhost:8000 and http://localhost:8000/docs work on the VoicEra host, you can create an HTTP tunnel for the API. With Localtonet, the client application on that machine creates an outbound connection to our relay infrastructure. This avoids inbound router port forwarding, firewall changes, VPN setup, and the need for a public IP address.
An HTTP tunnel points to a local IP address and port. For this workflow, the target is the VoicEra API on port 8000. If the Localtonet client runs on the same machine as VoicEra, use the loopback address that reaches the verified service, such as 127.0.0.1, with local port 8000. If the client runs on another device, the target must instead be an address that device can reach. Confirm that network path locally before creating the tunnel.
Install and run the Localtonet client on the appropriate device
Run our client on the VoicEra host or on another trusted device that can reach the local VoicEra API. The client must remain connected for the tunnel to remain available.
Authenticate or select the client device
Use the device-specific authentication token associated with the client that will run the tunnel. Treat this token as a secret. Do not paste it into documentation, logs, screenshots, source control, or shared commands.
Select an available relay server
Choose a currently available relay server or region from the Localtonet dashboard. Available server codes and regions can vary, so obtain the value from the current product interface rather than copying a hardcoded example.
Create an HTTP tunnel for the API
Select the HTTP tunnel family and configure the local target as the verified VoicEra API address and port. For a same-host client, the intended target is 127.0.0.1:8000. HTTP tunnels can use Random Sub Domain, Custom Sub Domain, or Custom Domain process types, subject to current availability and configuration requirements.
Start the tunnel
Creating a tunnel does not start it. Use the Start button after reviewing the selected device, relay, local address, local port, and process type. Localtonet then assigns or uses the configured public HTTPS address.
Test the public API address
Open the assigned public URL and append /docs when appropriate to test the same OpenAPI interface previously verified at http://localhost:8000/docs. Test from a network outside the VoicEra host, and confirm that expected authorization requirements remain in effect.
For the current dashboard workflow and field names, consult our Localtonet HTTP tunnel documentation. Exact custom-domain DNS requirements should be taken from the current documentation rather than inferred from a generic DNS example.
Expose the dashboard separately when it is genuinely needed
If trusted operators need remote access to the web dashboard, create a separate HTTP tunnel targeting port 3000. Keeping API and dashboard access separate makes each public endpoint easier to understand, stop, rotate, and audit. Do not point one tunnel at port 3000 and assume API clients can use it as a substitute for the service on port 8000.
| Remote requirement | Local target | Recommended approach |
|---|---|---|
| REST API client | 127.0.0.1:8000 |
Create an HTTP tunnel for the API after local verification. |
| Interactive OpenAPI console | 127.0.0.1:8000/docs |
Use the API tunnel and navigate to its /docs path, subject to application access controls. |
| Operator dashboard | 127.0.0.1:3000 |
Use a separate HTTP tunnel only when remote dashboard access is required. |
| Database or object storage | Internal service ports | Keep private unless a separately reviewed architecture has a specific requirement. |
Secure the public API before relying on it
A tunnel solves reachability, not application authorization. Any public URL should be treated as internet-reachable. VoicEra is API-first and can handle configuration, campaigns, agents, provider credentials, call data, and other operational functions. Those capabilities make access control, credential handling, and endpoint selection important.
Verify VoicEra's current authentication and role configuration before distributing the URL. Apply least privilege to users and integrations. An automation client should receive only the access it needs, while operator accounts should be limited according to their responsibilities. Never place API credentials, provider keys, telephony credentials, device tokens, or private endpoints directly in a public URL.
The /docs interface is useful during development because it describes and exercises API routes. Decide whether remote users actually need it. The supplied evidence does not establish a universal VoicEra setting for disabling or separately protecting that route, so follow the project's current production hardening guidance instead of relying on an undocumented switch.
Validate the full request path
A sound verification sequence starts locally and then repeats through the public address. First confirm the local API, application authentication, and intended route. Next start the Localtonet tunnel and test the corresponding public route. Finally, verify failure behavior by making an unauthenticated or insufficiently privileged request where the application is expected to reject it.
Do not use a successful homepage response as the only security test. Confirm that protected operations remain protected, invalid credentials fail, request bodies reach the correct service, and the application returns expected errors without disclosing secrets. For telephony callbacks, also verify the exact provider-specific authentication or signature requirements documented by VoicEra and the carrier.
Routine operation, shutdown, and troubleshooting
Stop the VoicEra application stack
Run the repository's supplied stop script from the VoicEra project directory:
./scripts/stop-application-services.sh
Stopping VoicEra makes its local endpoints unavailable. A Localtonet tunnel can still appear configured, but it cannot deliver useful requests when the local target is not listening. For a planned shutdown, stop the public tunnel as well so its state clearly reflects the unavailable application.
Inspect Docker state and logs
If a service fails to load, begin with Docker rather than changing the tunnel. The tunnel cannot repair a container that is stopped, restarting, or unable to bind its local port. Check running containers:
docker ps
Because the repository contains a Docker Compose configuration, you can inspect Compose service state and aggregated logs from the project directory with standard Docker Compose commands:
docker compose ps
docker compose logs
Container names and individual service behavior can change across project revisions, so this guide does not invent service-specific log commands. Use the current Compose output to identify the affected service.
The startup script cannot reach Docker
Confirm that Docker Desktop or the host's Docker daemon is running. Then verify that the account executing the script can access Docker. This is a local Docker problem, not a Localtonet tunnel issue. Rerun the VoicEra startup script only after Docker commands work in the same environment.
A documented port is already in use
Another process may already be listening on one of VoicEra's published ports. Stop the conflicting application or follow VoicEra's current configuration reference for supported port customization. Do not edit Compose mappings blindly because the frontend, API, runtime, and provider configuration may refer to related addresses.
The dashboard loads but API features fail
A working page on port 3000 proves only that the frontend is reachable. Check port 8000 and the OpenAPI page separately. Inspect Docker service state and logs, then verify provider configuration. A missing model credential, unavailable provider, or unhealthy backend can cause application operations to fail even when the dashboard itself renders.
The API works locally but not through Localtonet
Recheck the selected client device, local target, relay selection, and tunnel state. Confirm that the tunnel was started, not merely created. If the Localtonet client runs on the VoicEra host, verify 127.0.0.1:8000 from that host. If it runs elsewhere, remember that 127.0.0.1 would refer to the client device itself, not the VoicEra machine. In that topology, configure a reachable local-network address only after confirming the route between the two devices.
The public URL works only intermittently
Check both sides of the path. The Localtonet client must remain connected, the selected tunnel must remain running, and the VoicEra API containers must remain healthy. Also inspect the host for sleep, restart, Docker, or resource-pressure events. No uptime guarantee or universal capacity figure should be inferred from a development quick start.
Voice interactions fail after the web services pass verification
Web reachability does not prove that STT, LLM, TTS, and telephony integrations are ready. Check the configured provider accounts or local model services, associated credentials, supported models, and relevant VoicEra logs. For phone calls, verify the telephony account and the exact provider-specific callback configuration. Do not troubleshoot this by exposing additional internal ports without evidence that a documented integration requires them.
Keep deployment details current
The supplied evidence does not establish a latest release number or release cadence. Before updating a production installation, review the repository's current changelog, configuration changes, migration instructions, and deployment documentation. Back up persistent application data according to the project's current operational guidance before applying changes.
Frequently asked questions
What is the official command for starting VoicEra?
After cloning the repository and changing into its directory, run ./scripts/start-application-services.sh. Docker must already be installed, running, and accessible from the same shell. The script creates the environment, generates required secrets, and starts the stack.
Which port should I expose for the VoicEra REST API?
The documented local API address is http://localhost:8000, with OpenAPI documentation at http://localhost:8000/docs. For a Localtonet client on the same host, create an HTTP tunnel targeting 127.0.0.1 on port 8000.
Can the same tunnel expose both the dashboard and the API?
The dashboard and API listen on different local ports, 3000 and 8000 respectively. An HTTP tunnel points to one local target. Use a tunnel for port 8000 when clients need the API, and create a separate tunnel for port 3000 only when authorized users need remote dashboard access.
Does VoicEra include AI models and telephony service?
No. Operators bring STT, LLM, and TTS access through supported cloud providers or self-hosted models. Real phone deployments also need a supported telephony account, currently documented as Vobiz or Plivo. Browser-based testing does not require telephony.
Does Localtonet require router port forwarding for this setup?
No. Our client establishes an outbound connection to a Localtonet relay server, so the workflow does not require inbound router port forwarding, firewall changes, VPN setup, or a public IP address. The client must remain connected and the tunnel must be running for the public endpoint to work.
Does a Localtonet tunnel secure every VoicEra API operation automatically?
A tunnel provides reachability to the configured local service. It does not replace VoicEra's application authentication, authorization, organization roles, provider-secret handling, or data-retention controls. Verify those controls before sharing the public URL and apply least privilege to every user and integration.
Can I use the public API URL as a telephony callback URL?
Not without confirming the integration requirements. The available evidence does not establish a universal callback path for every VoicEra telephony provider. Consult VoicEra's current provider-specific documentation and the carrier's requirements to identify the exact path, protocol, authentication, and public URL format.
How do I stop VoicEra and its remote endpoint?
Run ./scripts/stop-application-services.sh from the VoicEra repository directory to stop the application services. In the Localtonet dashboard, stop or delete the associated tunnel when remote access is no longer needed. Stopping the application alone leaves no healthy local target, while stopping the tunnel explicitly removes public reachability through that configuration.
Connect your verified VoicEra API with Localtonet
Install VoicEra, confirm its API locally on port 8000, and then create a focused HTTP tunnel for the authorized clients that need remote access. Keep provider credentials private, expose only the required service, and stop the tunnel when the workflow is no longer active.
Get Started Free โ