Verify your AI workspace locally, then publish only the web interface you intend to share
Synaplan is an open-source, self-hosted AI platform for chat, document retrieval, assistants, integrations, and model routing. This guide covers its Docker development quickstart and the separate production deployment contract recommended for durable remote access. We explain local verification, administrator setup, public-address planning, and how to connect the web interface through a Localtonet HTTP tunnel. The development quickstart is suitable for local evaluation, not a production deployment simply because its demonstration password has been changed.
๐ What's in this guide
Choose the right Synaplan deployment path
Synaplan combines web-based AI chat with retrieval-augmented generation over documents, multiple model providers, assistants, tools, approvals, an embeddable website widget, MCP support, and API access. It is distributed under the Apache-2.0 license and can run on infrastructure under your control. Using external model providers can still send information to those providers, so self-hosting the interface is not automatically the same as keeping every inference request local.
Installation and remote access are separate concerns. Docker starts the application and its supporting services. Synaplan controls accounts, permissions, provider credentials, and application behavior. With Localtonet, our client establishes an outbound connection to a relay and makes the selected web endpoint available at a public HTTPS address. This does not require inbound router port forwarding, a public IP address, VPN setup, or changes to inbound firewall rules. Follow your organization's outbound-network and access policies.
The most important installation choice is between Synaplan's development stack and its production deploy/ contract. The Synaplan production documentation explicitly identifies the repository quickstart as a development stack containing source builds, Vite, MailHog, and phpMyAdmin. Changing its administrator password does not remove those development services or make the deployment production-ready.
| Path | Appropriate use | Documented endpoint | Important distinction |
|---|---|---|---|
Repository with make up | Local evaluation and development | http://localhost:5173 | Development stack with an early startup status screen. |
Repository with docker compose up -d | The same evaluation stack without Make | http://localhost:5173 | Not a production alternative to Make; the page can remain quiet during image pulls. |
Production deploy/ contract | Longer-lived single-node Linux deployment | http://127.0.0.1:8000 by default | Published images, generated secrets, pinned releases, persistent data, and backup hooks. |
If you tunnel the development quickstart, treat it as a short, supervised evaluation using non-sensitive test data. Replace demonstration credentials, inspect the development stack's exposure, publish only its intended web endpoint, and stop the tunnel afterward. For ongoing access by a team or real users, use the production contract and complete its security and operational setup.
Prerequisites and deployment planning
For the repository quickstart, prepare Git, Docker, Docker Compose support, and Make if you choose make up. Start Docker Desktop before running commands on a supported desktop system. On Linux, install and start Docker Engine with Compose v2, and ensure your user is authorized to run Docker commands. The direct Compose path does not require Make.
The production contract targets a Linux server with Docker Engine and Docker Compose v2. Its documented cloud-AI baseline is at least 4 vCPUs, 8 GB RAM, and 30 GB free disk. The optional local-ai profile requires at least 16 GB RAM and substantially more disk capacity. These are deployment requirements, not a guarantee of capacity for every model or workload.
The optional office profile adds approximately 2 GB RAM for Collabora CODE and is off by default. Other optional services and downloaded models can add requirements. Plan storage for uploads, generated files, vectors, models, backups, and image updates rather than allocating only enough disk for the first startup.
Decisions to make before you start
- Deployment purpose: choose local evaluation or durable production explicitly.
- Model placement: decide whether cloud providers or optional local models meet your data-handling requirements.
- Users: identify administrators and ordinary users, and avoid sharing an administrator login.
- Client placement: preferably run Localtonet on the Synaplan host so a verified loopback endpoint can remain private to that host.
- Public address: plan a consistent address before finalizing production configuration.
- Recovery: decide where protected backups will live and how you will test restoration.
Initial startup pulls multiple images and initializes multiple services. A working status page is an early progress signal, not proof that every dependency, AI provider, or integration is ready.
Install Synaplan with Docker
Option 1: Local development quickstart with Make
The Synaplan quickstart documents this sequence:
git clone https://github.com/metadist/synaplan.git
cd synaplan
make up
The first command downloads the source tree; the second enters the project directory; the third starts its Docker-based development stack. On the same machine, open:
http://localhost:5173
The live status screen reports startup progress and switches to the application when the stack is ready. First-run image downloads and initialization can take time. Avoid repeatedly restarting containers while they are making progress.
The quickstart's published demonstration administrator is admin@synaplan.com with password admin123. Use it only in a controlled local evaluation, then change the password immediately. These are public demonstration credentials, not private deployment credentials.
Option 2: Start the same checkout directly with Compose
If Make is unavailable, the documented alternative is:
git clone https://github.com/metadist/synaplan.git
cd synaplan
docker compose up -d
If you already cloned the repository, use that checkout rather than cloning it again. The -d flag starts containers in detached mode. Open http://localhost:5173; with this path, the page may remain quiet until images finish pulling.
docker compose ps
docker compose logs
These standard Compose commands show container state and logs for the development configuration. Inspect logs for initialization failures or restart loops. Review output for secrets, email addresses, filenames, and other private information before sharing it.
Option 3: Recommended production contract
For durable internet-reachable access, use the repository's deploy/ contract. It uses published images without development services or source bind mounts. Start from a cloned repository and run commands from its root:
cp deploy/selfhost.env.example deploy/.env
Do not overwrite an existing deployment's environment file. For a new installation, edit deploy/.env, set SYNAPLAN_VERSION to a published immutable semantic version, and configure the deployment's public URL and administrator bootstrap choice. Read the public-address section below before finalizing the URL.
Use the release-specific deployment files and instructions for your chosen version. The current documentation and repository can advance independently, so a version printed in an example is not necessarily the latest compatible release. The production preparation script rejects placeholders and mutable tags; do not substitute latest or invent a version number.
The administrator variables are BOOTSTRAP_ADMIN_EMAIL and BOOTSTRAP_ADMIN_PASSWORD. They create the first administrator only when none exists. Leave both empty to use the first-run wizard at /setup, but complete that wizard locally before enabling public access. Restarting the stack with different bootstrap values does not rotate an existing account's password.
Once the environment configuration is complete, the documented production startup sequence is:
deploy/scripts/prepare.sh
docker compose --env-file deploy/.env -f deploy/compose.yaml pull
deploy/scripts/validate-release.sh
docker compose --env-file deploy/.env -f deploy/compose.yaml up -d
deploy/scripts/smoke-test.sh
Run these commands in order and investigate failures before proceeding. Preparation generates eight deployment secrets on first start and writes them to deploy/data/secrets.env with mode 0600. That file becomes authoritative and is required for restoration. Never regenerate or discard it casually.
By default, only the production web service binds a host port, at 127.0.0.1:8000. Supporting services, including MariaDB, Redis, Centrifugo, Tika, Qdrant, Ollama, and Whisper, remain on the Compose network. The optional local-TLS profile changes the host-port exposure by publishing 443 and 80; it is not required merely to obtain a Localtonet public HTTPS address.
Cloud AI is the default. The optional local-ai profile adds Ollama, the embedding model, and Whisper when configured and redeployed. The optional compute sidecar also has its own deployment requirements. Do not publish its port 8080 as part of this web-interface tutorial.
Resolve the production public-address dependency
A successful tunnel does not automatically configure Synaplan's externally visible URL. Applications can use that URL for redirects, generated links, authentication flows, and integrations. Browser cookie and origin behavior also needs verification when moving from local HTTP to public HTTPS.
Choose the address before inviting users or registering integration callbacks. With Localtonet, HTTP tunnels support Random Sub Domain, Custom Sub Domain, and Custom Domain process types. Available options depend on the current product and account. For an ongoing deployment, choose a supported address you intend to retain and verify its behavior in the dashboard rather than assuming a generated address will remain unchanged through every configuration change.
A safe configuration order
- Plan the production host, local binding, and intended HTTP tunnel. Keep public access stopped while the application is unconfigured.
- Select an available custom subdomain or custom domain where supported, or obtain the assigned public address from your tunnel configuration. Follow current Localtonet instructions for any domain and DNS requirements.
- Record the exact external HTTPS origin, including the hostname. Confirm whether the address is available before starting the tunnel. Do not expose an unsecured instance simply to discover it.
- Apply that address using the public-URL configuration documented for your selected Synaplan release, then complete the production startup sequence.
- Finish administrator setup locally, verify the exact local target, and start the tunnel for controlled testing.
- Test redirects, sign-in, generated links, and each intended integration through the final address before sharing it.
The supplied current Synaplan production documentation instructs administrators to set the public URL in the deployment configuration, but does not identify its exact variable name or a complete URL-change restart procedure. We therefore cannot responsibly provide a guessed environment key or claim that a simple restart applies the change. Before durable public use, inspect deploy/selfhost.env.example, deploy/README.md, and docs/INSTALLATION.md for your selected release and establish the required setting and redeployment procedure. Until that is resolved, treat the installation as local preparation, not a completed production remote-access setup.
If the address becomes available only after an activation step, keep the real Synaplan service unavailable through that route until its configuration and authentication are ready. If you already deployed with another URL, stop public access, back up the deployment, and use the release's configuration-change procedure. Merely editing a file does not guarantee that running containers receive new environment values.
Custom-domain DNS instructions and address-retention guarantees are not established here. Check our HTTP tunnel documentation and current dashboard before depending on either. Any later hostname change should trigger another review of callbacks, widgets, generated links, and client configuration.
Secure accounts and application access
For evaluation, replace the public demonstration password before considering even temporary exposure. For production, create the administrator through the bootstrap variables or complete the local first-run wizard. An unclaimed public setup wizard is not an acceptable remote-access test result.
Use unique passwords and individual accounts. Restrict administrator privileges to users who need system-wide configuration access. Connect an AI provider through Synaplan's intended configuration area, and keep provider keys out of URLs, tunnel targets, screenshots, source control, and support messages.
Pre-exposure checklist
- Confirm that no public demonstration credentials remain usable.
- Complete administrator creation and verify that unauthenticated visitors cannot claim the instance.
- Review users, roles, shared documents, assistants, tools, and knowledge access.
- Use non-sensitive data for a temporary development-stack demonstration.
- Do not publish databases, cache services, MailHog, phpMyAdmin, or compute ports.
- Review Docker host-port mappings as well as tunnel configuration.
- Confirm the production public URL and backup plan before ongoing use.
- Use access restrictions where available and appropriate to your environment.
Our HTTP tunnel provides a public HTTPS route to the selected endpoint. Synaplan remains responsible for user authentication, permissions, provider-key handling, and data access. Treat the public address as discoverable and use least privilege rather than relying on a hard-to-guess hostname.
Verify the exact local target from the client host
First open the documented local URL: http://localhost:5173 for the development quickstart, or http://127.0.0.1:8000 for the default production contract. Then test the exact numeric IP address and port you intend to enter in Localtonet, from the device running our client.
Do not assume that localhost and 127.0.0.1 are interchangeable. A hostname can resolve to IPv4 or IPv6 loopback, and a listener may not accept both. The quickstart documents localhost:5173; it does not prove that IPv4 loopback works on every installation.
For example, if considering IPv4 loopback for the development tunnel, explicitly open http://127.0.0.1:5173 on the client host. If curl is installed, these are optional diagnostic requests, not guaranteed target values:
# Development: test this candidate before using it.
curl -v http://127.0.0.1:5173/
# Production: test the documented default binding.
curl -v http://127.0.0.1:8000/
If the numeric request fails while localhost works, inspect hostname resolution and the actual listener or Docker port mapping. Use a supported numeric target that genuinely responds, or deliberately correct the binding and retest. Do not solve the problem by indiscriminately binding every service to all interfaces.
Use the correct Compose configuration
For development, run docker compose ps and docker compose logs from the repository root. For production, explicitly select the deployment files:
docker compose --env-file deploy/.env -f deploy/compose.yaml ps
docker compose --env-file deploy/.env -f deploy/compose.yaml logs
Using unqualified Compose commands in the repository root can inspect the development stack instead of production. Confirm that the intended containers exist and are not repeatedly restarting.
Perform application-level tests
- Sign in with the intended account and load the main interface.
- Sign out and sign in again using the new password.
- Submit a harmless prompt if a provider is configured.
- Test a small non-sensitive upload if file handling is in scope.
- Check a normal user's permissions separately from administrator access.
If our client runs on another computer, its loopback address points to that computer, not the Synaplan server. Use a deliberately reachable private address and test it from that device. Containers and virtual machines can also have separate loopback namespaces. Running both applications on the same physical machine is insufficient if their network environments cannot reach each other.
Configure the Localtonet HTTP tunnel
HTTP/s is the appropriate tunnel family for this web-interface workflow. Do not create separate raw-port tunnels for Synaplan's supporting containers. Follow our Localtonet HTTP tunnel documentation for current screen details; the supported connection lifecycle is below.
Install and run our client
Run the Localtonet client on the device that can reach the verified Synaplan endpoint. Prefer the application host when using its loopback binding.
Authenticate and select the device
Use the device-specific authentication token associated with that client. Keep it secret and never copy another device's token from an example.
Select an available relay
Choose a server or region currently available in your dashboard. Do not use a hardcoded relay code from an unrelated configuration.
Create the HTTP configuration
Enter the exact numeric IP and port verified from the client host. Select Random Sub Domain, Custom Sub Domain, or Custom Domain as supported by your account. For production, coordinate the chosen address with Synaplan's public-URL configuration before enabling access.
Start and test the tunnel
After completing local security checks, press Start and test the public HTTPS address. Creating a configuration alone does not start it. The selected device must remain connected.
Stop or delete access when finished
Stop the tunnel after a temporary evaluation. Delete unused configurations, and maintain monitoring and access reviews for deployments that remain available.
Verify the public path in a fresh session
Use a private browser window and, preferably, a device outside the Synaplan host's network. Expect the intended sign-in behavior, not an automatically authenticated administrator page or an unclaimed setup wizard. Sign in as a normal user and repeat the harmless application tests.
Check that redirects stay on the intended public hostname. Verify generated links, uploads, chat responses, and sign-out. A page that renders successfully does not prove that streaming responses, embedded widgets, webhooks, or third-party callbacks are configured correctly. Validate each feature you intend to use.
If you encounter unexpected access, redirect loops, or exposed setup functionality, stop the tunnel and correct the application configuration locally. Do not leave it available while experimenting with authentication or trust settings.
Routine operation, backups, and updates
Manage the two lifecycles independently
Synaplan can run locally while its tunnel is stopped. A tunnel cannot serve Synaplan if the containers are down, the client is disconnected, or the host is asleep. Stopping the tunnel removes that public route without deleting application data or stopping Docker.
To stop and remove development-stack containers, use:
docker compose down
For production, select the correct configuration explicitly:
docker compose --env-file deploy/.env -f deploy/compose.yaml down
Do not add volume-removal options or delete data directories unless you intend and understand the data loss. Use the documented startup workflow for your deployment when bringing it back.
Protect production data and secrets
The production contract stores persistent data beneath deploy/data/. This includes MariaDB, durable Redis data, Qdrant collections, uploaded and generated files, optional local models, backup artifacts, and generated secrets.
The documented backup lifecycle is:
deploy/scripts/pre-backup.sh
# Capture deploy/data with your backup system.
deploy/scripts/post-backup.sh
The pre-backup hook pauses writers, creates a single-transaction MariaDB dump, creates a snapshot for each Qdrant collection, and prepares a checksummed upload archive. Capture the data only after that preparation succeeds. The post-backup hook resumes operation; ensure it is handled even if your external backup job fails.
The comment in this example is not a backup command. You must supply a backup system that captures and protects deploy/data/. Include deploy/data/secrets.env in every backup: Synaplan documents that a database restored without the corresponding secrets cannot be opened again. Keep backups access-controlled and test recovery in an isolated environment.
The supplied production excerpt does not include a complete restore command sequence. Use the selected release's restore instructions rather than treating a raw directory copy into running containers as a verified recovery method. Record the deployed version and protect the configuration needed to reconstruct the instance.
Update deliberately
Back up before changing versions. Read release notes and migration instructions, choose a published immutable SYNAPLAN_VERSION, and use the release-specific update procedure. Do not assume that an arbitrary Git pull and container restart is a safe production upgrade.
After an update, repeat local verification, the smoke test where applicable, and public-path testing. Confirm that the intended URL, authentication, provider configuration, file access, and integrations still work. Separate application regressions from tunnel connectivity by testing locally first.
Troubleshoot one layer at a time
Docker cannot connect to its daemon
Start Docker Desktop or Docker Engine and confirm the current user has permission to use it. Resolve this host-level problem before investigating Synaplan or Localtonet.
The status page loads but startup never finishes
Inspect the correct Compose stack's status and logs. Look for failed image downloads, restart loops, storage errors, insufficient memory, or incomplete initialization. A responding frontend does not prove that its backend dependencies are ready.
The expected port is occupied
Identify the process using the port with your operating system's network tools. Decide deliberately which service should own it. If you change the host mapping, update local tests and the tunnel target together.
Localhost works but the numeric target fails
Check IPv4 and IPv6 resolution and actual listener bindings. Verify from the client device or its network namespace. Do not infer IPv4 reachability from a successful localhost request.
The local target works but the public URL does not
Confirm that our client is connected, the correct device token is selected, the tunnel is started, and its target matches the tested IP and port. A configuration that exists but has not been started cannot serve traffic.
Public login redirects to localhost or loops
Stop public access and review the production public-URL configuration and release-specific redeployment instructions. Retest in a fresh session after applying changes. Do not guess environment variables, disable security checks, or assume that restarting containers loads edited environment files.
Chat fails while the interface loads
Repeat the request locally. If it fails there too, inspect provider credentials, model selection, outbound provider connectivity, and application logs. A tunnel does not supply model credentials or fix provider failures.
The tunnel drops intermittently
Check host sleep, restarts, internet connectivity, and client process uptime. Verify that Synaplan remains healthy at the same time. The public route requires both a connected client and a running tunnel.
A user can see unintended data
Stop the tunnel immediately. Review users, roles, sharing, knowledge collections, assistants, and tool permissions. Rotate affected credentials where appropriate, then retest as a non-administrator before restoring remote access.
Frequently asked questions
Is changing the quickstart password enough for production?
No. The quickstart is a development stack with source builds, Vite, MailHog, and phpMyAdmin. Password replacement is necessary before temporary sharing, but durable public access should use the production deploy/ contract with appropriate security, backups, and operations.
Which IP address and port should I enter in Localtonet?
Use the numeric address and port that respond from the Localtonet client host. The quickstart documents localhost:5173, which does not guarantee 127.0.0.1:5173. Production defaults to 127.0.0.1:8000, but you should verify that target too.
How do I configure Synaplan's public URL?
Select or obtain the intended Localtonet address before finalizing production configuration. Synaplan's supplied production documentation requires a public URL but does not specify the exact setting name or URL-change redeployment sequence. Resolve those details in the selected release's deployment files before ongoing public use.
Does Localtonet require router port forwarding or a VPN?
No. Our client establishes an outbound connection to a relay, providing a public route without inbound router port forwarding or VPN setup. This HTTP tunnel is not a VPN and does not replace application authorization or organizational network policies.
Can our client run on another computer?
Yes, provided that computer can reach Synaplan's selected web endpoint. Its loopback address refers to itself, not the Synaplan server. Use a deliberately reachable private address and secure that local network path.
Does a working web page prove every integration works?
No. Widgets, callbacks, mobile clients, messaging channels, and other integrations can have separate URL and authentication requirements. Test each intended feature using the final public address.
What happens when I stop the tunnel?
The public route through that tunnel becomes unavailable. Synaplan can continue running locally, and Docker data is not deleted. Disconnecting the selected Localtonet client also makes that route unavailable.
Share a verified Synaplan endpoint with Localtonet
Use the production contract for ongoing access, resolve the public URL, secure administrator setup, and test the exact local target. Then create an HTTP tunnel for controlled remote access, or run a short, supervised evaluation and stop it afterward.
Get Started Free โ