23 min read

Self-Host Waline and Connect It with Localtonet

Install and verify a self-hosted Waline comment system, then make it remotely accessible through a Localtonet HTTP tunnel.

A local Waline service connected to a remote browser through a Localtonet HTTP tunnel.
Localtonet carries public HTTP traffic to the self-hosted Waline service.
Self-Hosting ยท Waline ยท Localtonet ยท 2026

Run your own comment backend locally, verify it, and expose only the required HTTP service

Waline is an open-source comment system with a separate client, server, and storage layer. This guide explains how to plan a self-hosted Waline deployment, validate its database and server configuration, confirm the service locally, and then publish the working HTTP endpoint with Localtonet. Exact Waline commands, environment-variable names, container image references, and listening ports can change between releases, so we deliberately avoid inventing values that are not established by the available project documentation. The result is an evidence-safe workflow that helps you identify and use the endpoint produced by your actual Waline configuration.

๐Ÿ”’ Expose the comment service, not its database ๐ŸŒ Publish a verified local HTTP endpoint โšก No inbound router port forwarding required

Understand the Waline architecture before installing it

Waline clients communicate with a self-hosted server that stores comment data in a database.
Waline separates the browser client, server API, and persistent database.

Waline describes itself as a comment system with backend support. Its architecture separates the browser-facing client, the server application, and persistent storage. The client renders the comment interface on a website and sends requests to the server. The server processes those requests and reads or writes the corresponding information in its configured database.

This separation matters when self-hosting. Installing a frontend package alone does not create a complete comment service. Website visitors must be able to reach the Waline server endpoint, and the server must be able to reach its storage backend. A locally running server can be useful for testing, but it will not serve public website visitors until it has a stable, reachable address.

๐Ÿ’ฌ Waline client The browser component renders the comment interface and communicates with the configured Waline server address.
โš™๏ธ Waline server The backend handles comment-related requests, account functionality, moderation features, and communication with storage.
๐Ÿ—„๏ธ Persistent storage Waline documents support for multiple storage systems, including PostgreSQL, MySQL, SQLite, MongoDB, TiDB, and CloudBase.
๐ŸŒ Public HTTP endpoint A public website needs a reachable server URL. With Localtonet, the client device creates an outbound connection and receives a public address for the local service.

Waline also advertises Markdown support, anonymous comments, account registration, social login, anti-spam capabilities, content verification, comment management, article reactions, and page-view counting. Some of these capabilities can require additional configuration or external services. Do not assume that every feature becomes active merely because the server process starts.

Keep the two configurations separate

Waline controls the application, database, comment policy, and frontend integration. Localtonet controls how the already-running local HTTP service becomes reachable from the internet. A tunnel does not install Waline, initialize its database, or configure its application features.

Prerequisites and deployment decisions

Begin with a machine that can run the Waline server continuously for as long as comments need to remain available. This can be a workstation for testing, a home server, a small server on a private network, or another compatible environment. The same device, or another device with network access to it, must also be able to run the Localtonet client.

Waline officially lists Docker and self-hosting among its supported deployment choices. Its project materials also identify multiple database technologies and hosted deployment platforms. This guide focuses on the self-hosted server workflow rather than a managed platform deployment.

Requirement Why it is needed What to confirm
Waline runtime or container environment Runs the server application Use a method supported by the current Waline release and your operating system
Persistent database Stores comments and associated application data Confirm the selected database is supported and reachable from Waline
Persistent application configuration Preserves the settings needed after restarts Record values securely without committing credentials to a public repository
Known listening address and port Identifies the local HTTP target Read these values from the actual startup output or deployment configuration
Localtonet client Establishes an outbound connection to our relay Run it on a device that can reach the Waline address and port
Website administration access Allows the site to reference the public Waline endpoint Confirm where your theme or client integration expects the server URL

Choose storage before exposing the service

Database selection is not merely a deployment detail. It determines how comments survive restarts, how backups are performed, and what recovery process is available. Waline lists support for PostgreSQL, MySQL, SQLite, MongoDB, TiDB, and CloudBase, among other deployment combinations. The correct choice depends on the Waline version, expected workload, and your operational environment.

A file-based database can reduce the number of services in a small installation, while a separate database server can fit environments that already operate managed storage. Whichever option you select, keep its data on persistent storage. A container that starts successfully but stores its database only in an ephemeral writable layer can lose data when it is recreated.

Decide where each component will run

The Waline server and database can run on the same machine or on separate systems. If they are separated, allow only the network path required between them. The Localtonet HTTP tunnel should target the Waline web service. It should not target the database port.

Never publish the database as the comment endpoint

Website visitors need access to the Waline HTTP service, not direct access to PostgreSQL, MySQL, MongoDB, or another storage engine. Keep database listeners private, use dedicated database credentials, and restrict network access to the Waline server wherever possible.

Install the self-hosted Waline server

Waline's project repository explicitly identifies Docker and self-hosting as supported deployment options. However, the evidence available for this draft does not establish a current canonical container image reference, package installation command, exact entry point, required runtime version, or default port. Those details are version-sensitive, so substituting guessed commands would create an unreliable installation.

Use the current deployment method shown in the official Waline documentation for your chosen release. Complete the following installation workflow while preserving the exact image name, package version, variables, mounts, and startup command documented for that release.

1

Select a documented self-hosting method

Choose the current Docker workflow or another self-hosting path supported by the Waline release you intend to run. Do not mix instructions from different release lines.

2

Prepare the required runtime

Install the exact runtime or container engine required by the selected deployment method. Verify that it starts correctly before adding Waline.

3

Provision persistent storage

Create the supported database or persistent data location selected for this deployment. Record its connection details securely and make sure the Waline server can reach it.

4

Create the Waline configuration

Add the exact required configuration values from the current Waline deployment documentation. Do not guess environment-variable names, database connection formats, secrets, or optional integration settings.

5

Start the Waline server

Launch the server using the documented command or container definition. Capture the startup output so you can identify configuration errors and the actual listening address and port.

6

Record the confirmed local endpoint

Write down the protocol, host address, and port that the running service reports. This verified endpoint becomes the target for local tests and, later, the Localtonet HTTP tunnel.

Why this guide does not provide a copy-and-paste container command

A command would require a verified image reference, tag policy, port mapping, storage mount, and current configuration variables. Those details are not established by the supplied project evidence. Check them against the current Waline deployment documentation and pin the version you reviewed rather than relying on an invented or stale example.

Use persistent and reproducible configuration

Whether you use a container definition, service manager, or another supported installation method, keep the deployment reproducible. Record the selected Waline version, storage choice, listening configuration, restart behavior, and required secrets in an appropriately protected operational document.

Do not place database passwords, application secrets, or provider credentials directly in a public source repository. Apply file permissions that limit who can read the configuration. If your deployment platform supports a dedicated secret store, use its documented mechanism.

For a containerized installation, distinguish the immutable application image from persistent data. Recreating the application container should not silently erase the database. Back up both the application configuration and all data required to reconstruct the database.

Configure Waline for a public comment workflow

A running process is only the first milestone. Before exposing it, confirm that Waline is connected to the intended database and that its application behavior matches the site where comments will appear.

Confirm database connectivity

Review the server startup output for database authentication, schema, connectivity, or permission failures. A process may bind to an HTTP port even when its storage layer is unavailable, so an open port alone is not sufficient evidence of a healthy deployment.

Confirm that the database account has the permissions required by Waline but is not unnecessarily privileged. If the database is on another machine, restrict its listener and firewall rules to the Waline server or private network that needs it.

Configure only the application features you need

Waline supports a broad set of capabilities, including anonymous comments, registration, social login, comment management, Markdown content, anti-spam controls, keyword restrictions, IP-based controls, duplicate-content checks, notifications, reactions, and page-view counting. Individual features can have their own prerequisites. For example, social login and notifications generally require provider-specific configuration.

Activate features deliberately. Start with a minimal working comment flow, verify persistence and moderation, and then add optional integrations one at a time. This makes failures easier to isolate and reduces the number of credentials that must be managed during initial deployment.

Identify the real server endpoint

The endpoint must come from your running deployment, not from a tutorial's assumed default. Record all three parts:

  • The local protocol used by the server, typically HTTP unless your deployment terminates TLS locally.
  • The local IP address or hostname reachable from the Localtonet client device.
  • The listening port confirmed by configuration, container mapping, or startup output.

If Localtonet runs on the same host as Waline, a loopback address may be appropriate when Waline is reachable there. If the Localtonet client runs on a different device, a loopback address will point to that other device itself and will not reach Waline. In that case, use a private address or resolvable hostname that the client device can actually access.

Container ports have two sides

A container may listen on one internal port while the host publishes a different port. Localtonet must target the address and port reachable from the Localtonet client. If the client runs on the host, that normally means the host-side published endpoint, not an unverified internal container address.

Verify Waline locally before creating a tunnel

A localhost Waline test comment returns a successful HTTP response before tunneling.
Local verification confirms that Waline accepts comments before public exposure.

Local verification separates application problems from tunnel problems. If Waline does not work on the private network, publishing it will not fix the database, runtime, or application configuration.

Check the process and logs

Confirm that the process remains running after startup. Review its logs for immediate crashes, repeated restart loops, database failures, malformed configuration, missing secrets, or address conflicts. If a service manager or container engine is responsible for restarts, check both the application logs and the supervisor's status.

Request the confirmed endpoint

Test from the machine running Waline first. Set the shell variable below to the complete endpoint you discovered from your deployment. The placeholder intentionally contains no assumed Waline port.

WALINE_LOCAL_URL="http://confirmed-host:confirmed-port"
curl -i "$WALINE_LOCAL_URL/"

The exact response depends on the Waline release and route being requested. The important observations are whether a TCP connection is established, whether an HTTP response is returned, and whether the logs show a correctly processed request. Do not interpret every non-200 response as a network failure. A route can return a client or method error while still proving that the HTTP server is reachable.

Next, repeat the request from the device that will run the Localtonet client. Use the exact local IP address and port that you plan to enter as the tunnel target:

WALINE_TARGET_URL="http://reachable-private-address:confirmed-port"
curl -i "$WALINE_TARGET_URL/"

If the first request works but the second one does not, investigate the listening address, host firewall, container port publication, routing, and private-network connectivity. Do not create the public tunnel until the second test succeeds.

Verify persistence, not just reachability

Exercise the application using the supported Waline client or management workflow. Confirm that a permitted test comment can be created, retrieved after a page refresh, and retained after an application restart. Remove test content when finished.

A restart test is especially important for container deployments. If comments disappear after recreating the service, the database or volume is not persistent even though the HTTP endpoint appears healthy.

Create a verification record

Before moving on, record the working local target, selected Waline version, database type, configuration location, startup mechanism, and basic recovery procedure. Do not put passwords or tokens in an unprotected record. This information makes later troubleshooting much faster.

Connect the verified Waline service through Localtonet

Once Waline works through the exact address that the Localtonet client can reach, create an HTTP tunnel. Our client establishes an outbound connection to a Localtonet relay server, so the workflow does not require inbound router port forwarding, firewall changes, a public IP address, or VPN setup.

An HTTP tunnel is appropriate because website visitors interact with Waline through its web-facing server endpoint. The tunnel should point to the local Waline IP address and port that passed the previous test.

1

Install and run the Localtonet client

Install our client on the Waline host or another device that can reach the verified Waline endpoint. Keep the client running while the comment service needs to be publicly accessible.

2

Authenticate or select the client device

Use the device-specific authentication token through the supported client and dashboard workflow. Treat the token as a secret and never paste it into public configuration, screenshots, logs, or frontend code.

3

Select an available relay server

Choose a currently available server or region in the Localtonet dashboard. Availability can vary, so obtain the value from the current product rather than copying a server code from an old tutorial.

4

Create an HTTP tunnel to Waline

Select an HTTP tunnel and enter the local IP address and port that you already verified from the Localtonet client device. For HTTP tunnels, select the available Process Type that fits your address requirements.

5

Start the tunnel

Creating the tunnel does not make it run automatically. Press Start, wait for the client and tunnel to be connected, and copy the public HTTPS address assigned by the configuration.

6

Test the public address

Request the public address from a network outside the Waline host, watch the Waline logs, and verify the complete comment workflow before adding the address to a production website.

For the current dashboard workflow and field names, consult our HTTP tunnel documentation. HTTP Process Type options can include Random Sub Domain, Custom Sub Domain, or Custom Domain. These options serve the same local content at a public HTTPS address, but availability can vary. Custom-domain DNS details should always be taken from the current dashboard and documentation rather than guessed.

A tunnel is available only while both sides are running

Waline must remain healthy, and the selected Localtonet client must remain connected with the tunnel running. If the application, host, client, network connection, or tunnel stops, visitors will not be able to reach the comment service.

Test independently of your website

Before changing the site's Waline configuration, test the public URL directly. Confirm that the request reaches the intended Waline process and does not resolve to an unrelated service on the same machine. Watch the Waline logs while making the request to correlate public activity with local processing.

Test from a device that is not using the same local network, such as a phone on mobile data. This checks the public path rather than accidentally reusing local routing or cached development settings.

Connect the Waline client to the public endpoint

Update the website's Waline client integration so that its server setting references the public HTTPS address assigned to the tunnel. The exact option name and code structure depend on the Waline client version and the framework or theme used by the website. Use the current Waline client documentation for that specific integration rather than guessing a configuration key.

After deploying the frontend change, open the browser's developer tools and inspect requests from the comment interface. Confirm that requests go to the intended public hostname. Check for browser security errors, rejected origins, application errors, and failed requests. Resolve those at the relevant layer instead of repeatedly recreating the tunnel.

Operate the public service safely

Publishing a comment backend creates an internet-facing application. Treat the Waline server, its runtime, and its database as production infrastructure if real visitors depend on it.

๐Ÿ” Protect credentials Keep database passwords, application secrets, provider keys, and the Localtonet device token out of browser code and public repositories.
๐Ÿ›ก๏ธ Apply comment controls Review Waline's supported moderation, anti-spam, content verification, frequency limiting, keyword restrictions, and IP controls for your site.
๐Ÿ’พ Back up persistent data Back up the database and deployment configuration, then test restoration instead of assuming a backup is usable.
๐Ÿ“‹ Monitor application logs Look for database errors, restart loops, rejected requests, abuse patterns, and failures after upgrades.
โฌ†๏ธ Upgrade deliberately Review Waline release notes, back up data, test the new version privately, and preserve a rollback path.
โน๏ธ Stop unused exposure Stop or delete the Localtonet tunnel when remote access is no longer required.

Plan for service restarts

Decide how Waline and the Localtonet client will start after a host reboot. Use the supported mechanisms for your operating system, container engine, or service manager. Confirm dependency ordering where necessary, especially if the database is local and must become ready before Waline connects.

Test a controlled reboot. Verify that storage mounts are present, the database is healthy, Waline starts successfully, the Localtonet client reconnects, and the selected tunnel returns to its intended state. Do not assume that creating a tunnel means it is automatically running in every restart scenario.

Maintain backups and restoration instructions

A reliable backup strategy includes more than copying a configuration file. Protect the database contents, the Waline configuration, any persistent uploaded assets used by your deployment, and enough version information to reproduce the runtime.

Store backups separately from the host. Periodically restore into an isolated environment and verify that comments, accounts, and application behavior are intact. A backup that has never been restored is only an untested assumption.

Minimize the exposed surface

Publish only the Waline HTTP target required by the website. Do not create additional TCP tunnels for a database, remote shell, or administration service unless there is a separate justified workflow with appropriate access controls.

Waline's own authentication, moderation, and abuse controls remain important after tunneling. Public HTTPS reachability does not replace application authorization. Review anonymous posting, registration, social login, upload behavior, content rules, and administrative access according to your site's threat model.

Troubleshooting Waline and Localtonet

The Waline process exits immediately

Read the earliest application error rather than only the final exit message. Common categories include invalid configuration, inaccessible storage, database authentication failure, missing runtime dependencies, unsupported versions, and a port already in use. Correct the application issue before investigating Localtonet.

Waline works on the host but not from the Localtonet client device

This usually indicates a local reachability problem. Check whether Waline listens only on a loopback address, whether the host publishes the container port, whether the private address is correct, and whether a host firewall blocks the connection. From the Localtonet client device, test the same target IP address and port entered in the tunnel.

The tunnel starts, but the public URL returns an error

Confirm that the tunnel target exactly matches the locally verified service. Check for transposed port numbers, an incorrect local IP address, a stopped Waline process, or a container mapping that changed after recreation. Review both the Localtonet connection state and Waline's logs while making a fresh public request.

The public endpoint works, but the comment widget does not

Inspect browser network requests. Make sure the website uses the correct public server URL and does not retain a development address such as a loopback hostname. Check the browser console for blocked mixed content, rejected cross-origin requests, malformed frontend configuration, or application errors. Because exact Waline client options vary, validate the relevant setting against the documentation for the installed client version.

Comments disappear after a restart

Treat this as a persistence problem. Verify that Waline is reconnecting to the same database and that container volumes or database files are mounted to persistent storage. Check whether the application silently created a new empty database because the intended path or connection configuration was unavailable.

The public URL stops working later

Check the full dependency chain: host power, local network, database, Waline process, Localtonet client, and tunnel state. The public endpoint is available only while the selected client is connected and the tunnel is running. Restarting Waline alone will not help if the client is offline, and restarting the tunnel will not help if Waline is unhealthy.

The database is healthy, but requests are slow or fail intermittently

Compare direct local requests with public requests. If both are affected, investigate Waline, database load, storage, memory pressure, and host networking. If only public requests are affected, verify the Localtonet client connection and retest from multiple external networks. Do not claim a performance cause until measurements isolate the failing layer.

Use a layer-by-layer test order

Verify the database first, then Waline on its own host, then Waline from the Localtonet client device, then the public tunnel URL, and finally the website widget. This order identifies the first broken boundary and prevents unrelated configuration changes.

Frequently asked questions

Can Waline be self-hosted with Docker?

Yes. Waline's official project materials list Docker and self-hosting as supported deployment choices. Use the current Waline deployment documentation for the exact image reference, version, variables, mounts, and startup command because those details are not established by the evidence available for this draft and can change between releases.

Which port does Waline use?

Do not assume a port from an unrelated example. Read the listening port from your current Waline configuration, container mapping, or startup output. If a container maps an internal port to a different host port, Localtonet must target the endpoint reachable from the device running our client.

Which database can I use with Waline?

Waline's project materials identify support for multiple storage systems, including PostgreSQL, MySQL, SQLite, MongoDB, TiDB, and CloudBase. Confirm the exact requirements and configuration syntax for your chosen Waline release before provisioning storage.

Should I expose the Waline database through Localtonet?

No. A public website needs access to the Waline HTTP service, not direct database access. Keep the database private, restrict it to the Waline server where possible, and create the Localtonet HTTP tunnel for the verified Waline web endpoint.

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

No. The Localtonet client establishes an outbound connection to our relay server. This lets you expose the local Waline service without configuring inbound router port forwarding, changing firewall rules for an inbound public listener, setting up a VPN, or obtaining a public IP address.

Does creating a Localtonet tunnel start it automatically?

No. Creating a tunnel and running it are separate lifecycle actions. After creating the HTTP tunnel, press Start. The public endpoint remains available only while the selected client is connected and the tunnel is running.

Can the Localtonet client run on a different device from Waline?

Yes, provided that the Localtonet client device can reach Waline at the configured private IP address and port. Test that endpoint directly from the client device before creating the tunnel. Do not use a loopback address when Waline runs on another machine.

Does the tunnel replace Waline authentication and moderation?

No. The tunnel provides public connectivity to the local HTTP service. Waline remains responsible for application-level login, registration, comment policy, moderation, anti-spam configuration, content controls, and administrative access.

Publish your verified Waline endpoint with Localtonet

After Waline is running, connected to persistent storage, and reachable from the Localtonet client device, create an HTTP tunnel and test the assigned public address before adding it to your website.

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