29 min read

Install Bulwark Webmail and Publish with Localtonet

Install Bulwark Webmail with Docker Compose, connect it to Stalwart, verify it locally, and publish its web interface through Localtonet.

Remote browser reaching Docker-hosted Bulwark Webmail through a Localtonet tunnel, with Stalwart kept private.
Bulwark runs locally with Stalwart while Localtonet publishes the web interface.
Self-Hosting Β· Bulwark Webmail Β· Docker Compose Β· Localtonet Β· 2026

Run a browser-based JMAP client for Stalwart, verify it locally, and make the working interface available remotely

Bulwark Webmail combines mail, calendars, contacts, and files in a self-hosted browser interface backed by Stalwart Mail Server. In this guide, we deploy the full Bulwark edition with Docker Compose, complete its setup wizard, confirm that the local HTTP endpoint works, and cover routine container operations and troubleshooting. Once the local service is healthy, we publish it through a Localtonet HTTP tunnel without requiring inbound router port forwarding, firewall changes, a public IP address, or a VPN.

πŸ”’ Keep the webmail service local until setup and verification are complete 🌐 Connect Bulwark to a compatible Stalwart JMAP server ⚑ Publish the verified HTTP endpoint through Localtonet

Understand what Bulwark Webmail does

Bulwark Webmail is a self-hosted JMAP web client designed for Stalwart Mail Server. It gives users a browser interface for mail, calendars, contacts, and files. The full edition runs as a Node.js application and includes capabilities such as the setup wizard, an administration dashboard, OAuth support, plugins, and settings synchronization.

Bulwark is not a mail server. It does not replace Stalwart, create a complete mail-delivery system by itself, or independently provide SMTP mail transport. Stalwart remains the source of truth for accounts, messages, mail delivery, spam handling, calendars, address books, and file storage. Bulwark connects to that server over JMAP and presents the information in a unified browser application.

Install or identify Stalwart before expecting real mail access

The Bulwark container can start without turning the host into a mail server. To sign in and use real accounts, you need an existing Stalwart deployment with working user accounts and an accessible JMAP endpoint. The documented compatibility information states that an existing Stalwart server should run version 0.16.6 or newer.

βœ‰οΈ Mail Bulwark provides threaded conversations, unified inbox views, cross-account views, full-text search, Sieve filters, templates, scheduled sending, and S/MIME support.
πŸ“… Calendars Calendar views include month, week, day, and agenda layouts, with recurring events, invitations, free and busy information, and CalDAV subscriptions.
πŸ‘₯ Contacts Users can work with multiple address books and groups, including vCard import and export for moving contact data.
πŸ“ Files The interface exposes Stalwart's JMAP file storage with previews, sharing, and folder uploads, keeping file access alongside mail and collaboration data.
πŸ” Shared account experience Mail, calendars, contacts, and files share one browser client, with support for multiple accounts, two-factor authentication, themes, keyboard shortcuts, and 27 languages.
πŸ”„ JMAP synchronization JMAP moves functions such as threading, search, and change tracking to the server, allowing the client to request changes instead of repeatedly downloading an entire mailbox state.

How the components fit together

A normal deployment has three distinct layers. Stalwart stores and processes the mail data. Bulwark provides the web interface and communicates with Stalwart. Localtonet can then provide a public HTTPS address for the local Bulwark HTTP endpoint. Keeping these responsibilities separate makes troubleshooting much easier.

Component Primary responsibility What it does not replace
Stalwart Mail Server Stores messages and accounts, handles mail-server functions, and provides the JMAP service used by Bulwark It does not provide the Bulwark full-edition web interface by itself
Bulwark Webmail Provides the browser interface for mail, calendars, contacts, and files It is not a standalone SMTP mail server and does not replace Stalwart
Docker Compose Defines and operates the Bulwark container on the host It does not configure Stalwart accounts, DNS, or mail delivery
Localtonet HTTP tunnel Connects a public HTTPS address to the reachable local Bulwark HTTP endpoint It does not create the webmail service or configure its user authentication

Full edition compared with Bulwark Lite

This tutorial uses the full Bulwark edition because its official quick start runs a Node.js container on port 3000 and provides the setup wizard and administration dashboard. Bulwark Lite is an alternative build containing static HTML and JavaScript. Lite can be placed on a static web host, but the browser then communicates directly with Stalwart and Stalwart must allow the relevant cross-origin requests.

Deployment option Best fit Important characteristics
Full Bulwark container Docker or Node.js deployments needing the complete server edition Includes the setup wizard, admin console, OAuth, plugins, settings sync, web push, and update notices
Bulwark Lite Environments that already have a static web host and use password sign-in Runs as static files, has no setup wizard or admin console, and requires appropriate CORS configuration on Stalwart
Manual full-edition installation Administrators who intentionally operate the Node.js application without Docker Officially supported as an installation path, but its detailed procedure is outside the supplied evidence for this tutorial
Full edition served near Stalwart Existing Stalwart environments using a conventional reverse-proxy architecture Can be deployed next to Stalwart, but reverse-proxy and sub-path settings must follow Bulwark's current deployment documentation

Prerequisites for this Docker Compose deployment

Complete the following checks before creating the Compose project. The first goal is to make Bulwark work entirely on the local machine. Remote publication should be treated as a separate step after the application and its Stalwart connection have been verified.

A host with Docker and Docker Compose

Use a machine where Docker Engine or Docker Desktop is installed and running. The modern Compose plugin uses the command docker compose. Confirm that the Docker daemon is available and that your user has permission to operate it:

docker --version
docker compose version
docker info

If the version commands work but docker info fails, the Docker service may not be running or the current account may not have permission to access it. Resolve that host-level problem before continuing.

A compatible Stalwart server

You need the URL of the Stalwart server that Bulwark should use. The documented compatibility baseline is Stalwart 0.16.6 or newer. The server should already have the accounts that users will use to sign in. Bulwark does not migrate an existing mailbox into Stalwart and does not manufacture a working mail system from an empty JMAP URL.

Verify the Stalwart side independently. At minimum, confirm that its administrative interface reports a compatible version, that the intended user accounts exist, and that the JMAP service is reachable from the relevant deployment environment. If Stalwart is on another device, container network, or hostname, account for DNS resolution, routing, certificates, and firewall policy between the systems.

Host port 3000 available for Bulwark

The official container quick start maps host port 3000 to container port 3000. The Compose definition in this guide preserves that mapping. Make sure another process or container is not already listening on the same host port.

On a Docker host, an existing container can be found with:

docker ps

Operating-system tools can also identify local listeners, but the exact command varies by platform. If port 3000 is already occupied, do not stop an unfamiliar service without understanding its role. You may choose another host port and still map it to container port 3000, but the official quick-start endpoint and the Localtonet examples in this guide assume host port 3000.

A Localtonet client for the remote-access stage

Install and run the Localtonet client on the Bulwark host or on another device that can reach the Bulwark host over the local network. The client establishes an outbound connection to our relay infrastructure, so the workflow does not require inbound router port forwarding, a public IP address, firewall changes, or a separate VPN.

A Localtonet authentication token identifies the device that runs the tunnel. Treat that token as a secret. Do not place it in the Compose file, screenshots, shell history, public issue reports, or this webmail application's settings.

Use the same-host layout when possible

Running the Localtonet client on the Docker host gives the tunnel a straightforward local target at 127.0.0.1:3000. A client on another device can target an IP address and port reachable from that device, but this adds LAN routing and host firewall variables to the setup.

Install Bulwark Webmail with Docker Compose

Docker Compose flow from the Compose file to a running Bulwark container connected to Stalwart.
Docker Compose starts Bulwark and connects the webmail service to Stalwart.

Bulwark's official quick start uses the published image ghcr.io/bulwarkmail/webmail:latest and maps port 3000 on the host to port 3000 in the container. The following minimal Compose file expresses that documented container configuration without adding unverified volumes, environment variables, health checks, or application flags.

1

Create a dedicated project directory

Keep the Compose definition in its own directory so that future start, stop, status, and log commands consistently target the same project.

2

Create the Compose definition

Define one Bulwark service using the official container image and the documented host-to-container port mapping of 3000:3000.

3

Validate the Compose configuration

Ask Docker Compose to parse the file before starting anything. This catches YAML indentation errors and unsupported syntax.

4

Start the Bulwark container

Launch the project in detached mode. Docker downloads the image if it is not already available on the host.

5

Check the service state and startup logs

Confirm that the container remains running, then inspect its recent output before opening the setup wizard.

1. Create the project directory

mkdir bulwark-webmail
cd bulwark-webmail

Create a file named compose.yaml in this directory:

services:
  bulwark:
    image: ghcr.io/bulwarkmail/webmail:latest
    ports:
      - "3000:3000"

This is intentionally minimal. The available evidence establishes the image and port mapping but does not establish a persistent-volume mount, a container data path, a required restart policy, or additional networking fields. Inventing those values could result in an invalid deployment or accidental data loss.

Review persistence before treating this as a production definition

Bulwark stores mail data in Stalwart, but the full edition also has its own administrative configuration and synchronized settings capabilities. The evidence supplied for this article does not identify the container path that should be persisted. Before recreating a production container, consult the current Bulwark deployment documentation for its supported persistence model. Do not guess a volume destination.

2. Validate and start the project

Validate the effective Compose model:

docker compose config

If the output shows the bulwark service, the expected image, and the port mapping, start it:

docker compose up -d

Check whether the service is running:

docker compose ps

Then inspect its recent logs:

docker compose logs --tail=100 bulwark

The container should stay in a running state. A container that repeatedly exits has not reached the point where an HTTP tunnel can help. Diagnose the container locally before creating any public endpoint.

About the latest image tag

The official quick start uses ghcr.io/bulwarkmail/webmail:latest, which is convenient for an initial installation. However, a mutable tag can point to a different build after a future release. Production operators commonly select and test an explicit release tag so that deployments are reproducible.

We do not hardcode a version here because the correct current release can change, and the supplied release evidence does not establish that one historical version should be selected for every new installation. Choose an explicit currently supported release from Bulwark's release information if reproducibility is required. Container images and release files from version 1.12.0 onward include signed build provenance attestations, and release files also provide SHA-256 checksums.

Complete the Bulwark setup wizard

Open the following address in a browser on the Docker host:

http://localhost:3000

The first-launch wizard asks for the Stalwart server and an administration password. Enter the actual Stalwart address used by your deployment rather than copying a placeholder hostname. Set a unique, strong administration password and store it in an appropriate password manager.

1

Open the local Bulwark interface

Visit http://localhost:3000 from the Docker host. Confirm that the page belongs to the Bulwark container you just started.

2

Enter the Stalwart server

Supply the Stalwart server requested by the wizard. Use the real JMAP-capable server for this environment and make sure it is running Stalwart 0.16.6 or newer.

3

Set the Bulwark administration password

Use a password that is not shared with the Docker host, Stalwart account, Localtonet token, or any other administrative system.

Most installations can be configured through this wizard and changed later through the administration dashboard. Bulwark also recognizes environment-based configuration, which can be useful for immutable deployments. Documented variables include JMAP_SERVER_URL and APP_NAME.

Configuration precedence matters. When an environment variable and the saved administrative configuration set the same key, the value saved through the admin configuration takes priority. An environment variable therefore fills a value only when the admin configuration leaves it unset. If an environment change seems to be ignored, check the saved dashboard setting before assuming that Compose failed to pass the variable.

Do not expose setup before setting the administration password

Finish the local wizard and verify the configured result before starting the Localtonet tunnel. A public endpoint created too early could expose an incomplete first-run workflow. Also avoid placing passwords in the Compose file unless the project's current documentation explicitly defines a secure, supported secret-management method.

What successful configuration should produce

A configured deployment should load the Bulwark interface, recognize the intended Stalwart server, and permit a valid Stalwart account to reach the appropriate webmail experience. Mailboxes, calendars, contacts, and files remain controlled by the permissions and data on Stalwart.

If the Bulwark page loads but account sign-in or data retrieval fails, the container's HTTP service is working. The remaining issue is likely in application configuration, Stalwart compatibility, account credentials, JMAP reachability, DNS, or certificate handling. This distinction is important because publishing a broken application through a tunnel only makes the same broken state remotely reachable.

Verify the local service before publishing it

Docker Compose reports Bulwark running while its web interface loads through localhost.
Confirm the container and local web interface before creating a public tunnel.

Verification should proceed from the lowest layer upward. First check Docker, then the HTTP interface, then Bulwark's connection to Stalwart, and finally real account behavior. This sequence prevents network exposure from obscuring an application problem.

1. Confirm that the container remains running

docker compose ps

The service should not be continuously restarting or exiting. If it is unstable, inspect a live log stream:

docker compose logs -f bulwark

Press Ctrl+C to stop following the output. This ends the log viewer, not the detached container.

2. Confirm the local HTTP endpoint

Open http://localhost:3000 in a browser on the host. A successful page load proves that Docker published the port and that the application is answering HTTP requests. If a command-line HTTP client is installed, a header request can provide another basic reachability check:

curl -I http://localhost:3000

An HTTP response confirms that something is listening. The exact status can vary according to application state and redirects, so use the browser for functional verification rather than treating one specific status code as the only acceptable result.

3. Test the setup and administration workflow

Confirm that the setup wizard accepts the intended Stalwart server and administration password. After setup, ensure that the administration interface can be reopened as expected. Do not rely solely on seeing a Bulwark logo or sign-in page, since those observations do not prove that the JMAP connection works.

4. Sign in with a test account

Use a non-privileged Stalwart account suitable for testing. Verify the functions your deployment actually needs, such as loading the inbox, opening a message, displaying a calendar, showing contacts, or browsing available files. Use least privilege instead of testing ordinary webmail behavior with a server-wide administrator account.

5. Check behavior from the Localtonet client device

If the Localtonet client runs on the same host, test http://127.0.0.1:3000 there. If it runs on another LAN device, open the Bulwark host's reachable local IP address and port from that device. A failure at this stage is a local routing or host-access problem, not a relay problem.

A healthy page and a healthy mailbox are different checks

The Bulwark HTTP service can be reachable while its Stalwart connection is misconfigured. Verify both layers. The tunnel needs only a reachable local HTTP target, but users need the complete Bulwark-to-Stalwart path to work.

Routine Docker Compose operations

Use commands from the directory containing compose.yaml. This helps Compose select the expected project instead of acting on an unrelated deployment.

View status

docker compose ps

Read logs

docker compose logs --tail=200 bulwark

To follow new output:

docker compose logs -f bulwark

Restart the existing container

docker compose restart bulwark

A restart is useful after a transient host or network problem. It should not be used to conceal a recurring configuration error. Inspect the logs if the same failure returns.

Stop and start without intentionally removing the container

docker compose stop
docker compose start

While Bulwark is stopped, the Localtonet tunnel may still be running, but its local target will be unavailable. Stop the tunnel too if remote access is not needed.

Plan updates carefully

An update normally involves selecting a desired image, pulling it, and recreating the service. The precise production procedure must account for Bulwark's supported configuration persistence and backup requirements. Because the supplied evidence does not identify the correct persistent container path, this article does not prescribe a destructive recreation command as a universally safe update method.

Before updating, record the currently deployed image, review Bulwark's release notes, understand whether the selected release introduces configuration changes, and verify the supported backup or persistence procedure. Test the new build locally before restoring public access.

Avoid blind production updates with a mutable tag

Pulling latest can introduce a different application build. Do not assume that recreating the container is risk-free when the deployment's supported persistence path has not been established. Select, verify, and test the intended release, and follow the current Bulwark updating documentation.

Publish Bulwark through a Localtonet HTTP tunnel

Localtonet HTTP tunnel routing a public browser to local Bulwark while Stalwart remains private.
The tunnel exposes Bulwark’s web interface without directly publishing Stalwart.

After the local browser interface and Stalwart integration work, the Bulwark endpoint is ready to become a Localtonet HTTP tunnel target. Our client creates an outbound connection to a Localtonet relay server. The resulting tunnel provides a public HTTPS address without requiring an inbound router rule, a public IP address, firewall changes, or VPN setup.

An HTTP tunnel is the appropriate family for this workflow because Bulwark presents an HTTP web application on local port 3000. Do not configure a File Server tunnel for this purpose. File Server publishes a local folder, while Bulwark is a running web service with its own application behavior.

You can review the current fields and interface in our Localtonet HTTP tunnel documentation. Available relay servers, regions, options, and plan availability can change, so select them from the current dashboard rather than copying a hardcoded server code from an article.

1

Install and run the Localtonet client

Run our client on the Bulwark Docker host or another trusted device that can reach the host's HTTP port. Keep the client running for as long as remote access is required.

2

Authenticate or select the client device

Use the device-specific authentication token associated with the client. Do not publish, share, or embed the token in the Bulwark configuration.

3

Select an available relay server

Choose from the servers or regions currently available in the Localtonet dashboard. Availability can vary, so this guide does not hardcode a server code.

4

Create an HTTP tunnel to Bulwark

Configure the local target as 127.0.0.1 and port 3000 when our client runs on the Docker host. If the client runs elsewhere, use the Bulwark host address that is actually reachable from the client device.

5

Start the tunnel

Creating a tunnel does not start it. Use the Start control, then wait for the tunnel and selected client device to report a connected state.

6

Open and test the assigned public address

Use the public HTTPS URL provided for the running tunnel. Test it in a separate browser session and confirm that the Bulwark sign-in flow and Stalwart-backed functions still work.

Choose the HTTP process type

Localtonet HTTP tunnels can use Random Sub Domain, Custom Sub Domain, or Custom Domain process types. All three publish the same local content through a public HTTPS address. The difference is how the public hostname is selected.

Process type Typical use Important consideration
Random Sub Domain Initial testing or temporary remote access Uses a generated public address and avoids committing to a permanent hostname during verification
Custom Sub Domain A selected Localtonet subdomain where supported Availability and plan applicability must be checked in the current dashboard
Custom Domain Deployments that need an organization-controlled hostname Follow current Localtonet DNS instructions rather than guessing records or targets

Understand the tunnel lifecycle

The public endpoint depends on two active components: the selected Localtonet client must be connected, and the tunnel must be running. Creating the tunnel configuration alone does not make Bulwark public. Likewise, stopping the client, shutting down its host, stopping the tunnel, or stopping the Bulwark container makes the remote service unavailable.

When access is temporary, stop the tunnel after use. Delete it if the public configuration is no longer required. This reduces unnecessary exposure and keeps the dashboard aligned with active services.

Secure the published webmail interface

Webmail is a sensitive service. A tunnel solves connectivity, but it does not remove the need for application authentication, account protection, monitoring, software updates, or least-privilege administration. Treat the public URL as internet-facing even when it is shared with only a small group.

πŸ”‘ Strong independent credentials Use unique passwords for the Bulwark administration interface and Stalwart accounts. Never reuse the Localtonet device token as an application credential.
πŸ›‘οΈ Least-privilege accounts Test ordinary mail access with a normal Stalwart user. Reserve administrative accounts for tasks that actually require elevated permissions.
βœ… Two-factor authentication Bulwark supports two-factor authentication as part of its account experience. Enable appropriate account protections for the deployment rather than relying on an obscure URL.
⬆️ Maintained software Review Bulwark and Stalwart release information, especially security fixes, and test updates before exposing a replacement build.
⏹️ Short exposure windows Stop the Localtonet tunnel when remote access is not needed. A saved tunnel configuration does not need to remain continuously active.
πŸ” Layered verification Check container health, application behavior, Stalwart access, and public behavior separately so that failures can be isolated quickly.
Do not treat the public URL as an authentication control

Anyone who obtains the URL can attempt to reach the exposed interface. Keep Bulwark and Stalwart authentication enabled, use strong credentials and two-factor authentication where appropriate, and apply any available access controls according to your organization's policy.

Protect administrative surfaces

The full Bulwark edition includes an administration dashboard. Set its password during local setup, verify that the password works, and avoid using an ordinary mailbox password for administration. Do not publish screenshots containing server addresses, account names, tokens, or private configuration values.

Protect the Stalwart connection

Bulwark's public page can be healthy while the path to Stalwart is insecure or misconfigured. Use the Stalwart server address appropriate for your environment, validate certificates where HTTPS is used, and avoid weakening certificate checks merely to bypass a hostname or trust problem. Correct DNS and certificate deployment instead.

Limit unnecessary network exposure

The Compose mapping 3000:3000 follows Bulwark's documented quick start. Depending on Docker and host networking, it may listen beyond the loopback interface. Review the host's actual listening interfaces and local security policy. If you later choose a loopback-only bind, confirm that this syntax is supported by your Docker environment and that the Localtonet client runs on the same host.

Troubleshooting Bulwark and Localtonet

The container exits immediately

Start with the Compose status and logs:

docker compose ps
docker compose logs --tail=200 bulwark

Check for a malformed Compose file, image download failure, unsupported architecture, missing Docker daemon access, or an application startup error. Validate the file again with docker compose config. Do not create a tunnel until the container remains running.

Docker reports that port 3000 is already allocated

Another process or container is using the host port. Run docker ps and inspect the host's listeners. Stop or reconfigure only a service you recognize. If you intentionally select another host port, keep container port 3000 as the destination and use the selected host port in the browser and Localtonet target.

The browser cannot open localhost:3000

Confirm that the browser is running on the Docker host. The name localhost always refers to the device on which the browser runs. If you open that URL from another computer, it points to that other computer rather than the Docker host.

Next, verify that the container is running and that Compose reports the port mapping. Review the application logs. Host security software or a conflicting service may also affect access.

The Bulwark page loads, but login or mailbox data fails

This usually means the HTTP service is healthy but the application-to-Stalwart workflow is not. Confirm the Stalwart version, JMAP server address, account credentials, account status, name resolution, network route, and certificate validity. If an environment variable was changed, remember that a saved admin value takes precedence for the same setting.

The environment variable appears to have no effect

Bulwark gives saved administration configuration priority over environment variables when both define the same key. Inspect the corresponding setting in the admin dashboard. An environment variable such as JMAP_SERVER_URL only supplies the value when the admin configuration leaves it unset.

Bulwark works locally but the Localtonet URL does not

Check the layers in order:

  1. Confirm that Bulwark still opens locally on port 3000.
  2. Confirm that the Localtonet client is running and connected.
  3. Confirm that the tunnel has been started, not merely created.
  4. Confirm that the tunnel target uses the correct local IP address and port.
  5. If the client runs on another device, test the target directly from that device.
  6. Confirm that the public address belongs to the active tunnel configuration.

With a same-host client, 127.0.0.1:3000 is the direct target for this deployment. With a separate client device, 127.0.0.1 would refer to that client device, not the Docker host, so use an address that is reachable over the local network.

The public page opens, but some functions fail

Reproduce the same action through the local URL. If it also fails locally, investigate Bulwark or Stalwart. If it works locally but fails only through the public address, compare the browser console, application logs, hostname assumptions, callback configuration, and any feature that depends on an externally visible origin.

OAuth, OIDC, embedded sign-on, reverse-proxy sub-paths, and custom callback behavior can require deployment-specific configuration. The supplied evidence confirms that Bulwark supports OAuth and related deployment guides, but it does not establish exact callback paths or environment variables. Follow Bulwark's current authentication documentation rather than inventing values.

The tunnel disappeared after a reboot

The public endpoint is available only while the selected Localtonet client is connected and the tunnel is running. Also confirm that Docker and the Bulwark container have restarted. This guide does not add an unverified Compose restart policy, so inspect the service state explicitly after a host reboot.

An update caused a startup failure

Identify the exact image that was deployed, review the corresponding release notes, and inspect container logs. Avoid repeatedly recreating the service until you understand how its administrative configuration is persisted. If you used latest, record the resolved image information so that the affected build can be identified.

Frequently asked questions

Is Bulwark Webmail a complete mail server?

No. Bulwark is the browser client. Stalwart is the mail server and remains responsible for messages, accounts, SMTP functions, spam processing, calendars, contacts, and file storage. Install or identify Stalwart first, then configure Bulwark to use its JMAP service.

Which Stalwart version does Bulwark require?

The documented compatibility information says that an existing deployment should run Stalwart 0.16.6 or newer. Check current Bulwark compatibility guidance before upgrading either component in a production environment.

Why does this Compose file contain only an image and port mapping?

Those are the details established by Bulwark's official container quick start: the image is ghcr.io/bulwarkmail/webmail:latest, and host port 3000 maps to container port 3000. The supplied evidence does not establish a volume path, health check, restart policy, or additional required flags, so we do not invent them.

Should I use the latest image tag in production?

The official quick start uses latest, which is convenient for installation. A production deployment often benefits from an explicit, tested release tag because latest can change. Select a currently supported release, review its notes, verify persistence and backup procedures, and test the update before public use.

Can I use Bulwark Lite instead of the container?

Yes, but it is a different deployment model. Bulwark Lite is a static-file build without the full edition's setup wizard, admin console, OAuth, plugins, settings sync, office editing, or web-push features. The browser communicates directly with Stalwart, so the Stalwart HTTP configuration must allow the required cross-origin access.

Does Localtonet replace Bulwark or Stalwart authentication?

No. Our HTTP tunnel provides connectivity from a public HTTPS address to the local Bulwark service. Keep application authentication enabled, use strong unique credentials, enable two-factor authentication where appropriate, and follow least-privilege practices for Stalwart and Bulwark administration.

Do I need router port forwarding or a public IP address?

No. The Localtonet client establishes an outbound connection to our relay server. This allows the running Bulwark endpoint to receive remote browser traffic without inbound router port forwarding, firewall changes, VPN setup, or a public IP address.

What local target should I enter in Localtonet?

If our client runs on the same Docker host, use local IP 127.0.0.1 and port 3000. If it runs on another device, use an IP address and port for the Bulwark host that the client device can actually reach. Test that address from the client device before starting the tunnel.

Why is the public address unavailable even though I created a tunnel?

Creating a Localtonet tunnel does not start it. The selected device must be connected, the tunnel must be started, and Bulwark must be listening on the configured local target. The public address remains available only while those required components are running.

Publish your verified Bulwark interface with Localtonet

Once Bulwark works locally and can communicate with Stalwart, create an HTTP tunnel to the local port, start it, and use the assigned public HTTPS address for remote access. Keep authentication enabled and stop the tunnel whenever public access is no longer required.

Get Started Free β†’

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support