Run a persistent Telegram media bridge, install its Stremio addon, and add controlled remote access
PencariMovie Server is a self-hosted Telegram MTProto media bridge for Stremio, Nuvio, Eclipse Music, and web clients. This guide deploys the current Docker image with persistent storage, completes Telegram authorization, validates the Stremio manifest, and tests playback and seeking. It then adds a Localtonet HTTP tunnel without inbound router port forwarding or a public IP address. The deployment begins directly with Docker Compose so that setup data is not accidentally split between a temporary named volume and a different production storage directory.
📋 What's in this guide
How PencariMovie fits into the streaming path

PencariMovie Server is a self-hosted utility and protocol bridge. It uses MadelineProto to connect an authorized Telegram account to Telegram's MTProto API, then converts authorized Telegram file references into HTTP streams that compatible media clients can consume. The project documents HTTP range-request support, including HTTP 206 Partial Content responses, so a compatible player can seek without first downloading the complete file.
PencariMovie does not replace Stremio. It supplies a Stremio-compatible addon manifest and the HTTP endpoints referenced by that manifest. Successful playback therefore depends on several separate layers: the container must be running, PencariMovie must have a valid Telegram session, the client must be able to retrieve the manifest, and the generated stream endpoints must remain reachable.
The current upstream Docker example uses ghcr.io/aiskendi/pencarimovie-server:latest. The application listens on container port 8088, and persistent state belongs under /app/storage. At the time of this review, GitHub marks v2.8.0 as the latest release. Because the Compose example follows the moving latest image tag, check the repository's current release information before each update rather than assuming that the image still contains the same version described here.
/app/storage.
/manifest.json. The address before that path must be reachable from the device performing the installation and playback.
/eclipse/manifest.json path. It should not be substituted for the standard Stremio and Nuvio manifest.
SERVER_PASSWORD protects documented public dashboard access, while SERVER_TOKEN appears in protected public addon paths.
Running the bridge on your own hardware does not grant permission to access, copy, or distribute media. Use PencariMovie only with accounts and files you are authorized to use, and comply with Telegram's terms and applicable laws.
Prerequisites and deployment decisions
This tutorial uses Docker Compose on a computer, server, NAS, or VPS. Upstream also publishes native Windows, Linux, macOS, Android, and Termux installation paths, but those paths have different startup and storage behavior and are outside this Docker-specific workflow.
Install Docker and Compose
On Windows and macOS, use a supported Docker Desktop installation. On a Linux server, follow the Docker Engine installation instructions for the host distribution. Docker documents the Compose plugin separately in its Compose installation guide.
Confirm both components before creating the project:
docker version
docker compose version
Your account must be allowed to communicate with the Docker daemon and create images, containers, networks, bind mounts, and published ports. Docker access is privileged on the host, so do not grant it to an untrusted account merely to run this tutorial.
Check host architecture and image compatibility
PencariMovie describes Docker support for operating systems, NAS devices, and VPS deployments, but the supplied upstream evidence does not publish a definitive architecture matrix for every container release. Before choosing unusual ARM hardware or a NAS architecture, inspect the current package information and release assets in the repository. Do not assume that every tag supports every processor architecture merely because Docker itself runs on the host.
You can also ask Docker to inspect the current image manifest before deployment:
docker buildx imagetools inspect ghcr.io/aiskendi/pencarimovie-server:latest
If that Docker subcommand is unavailable, use the package details and current release information in the PencariMovie repository instead. Select an image platform that actually matches the host.
Prepare Telegram authorization
PencariMovie uses Telegram MTProto through an authorized Telegram account. Have the following ready before opening the setup flow:
- A Telegram account that you are authorized to use with the server.
- Access to the Telegram application that receives the account's login code.
- The account's two-step verification password if Telegram two-step verification is enabled.
- The Telegram application API ID and API hash from Telegram's application configuration page if the current PencariMovie setup requests them.
- A private browser session on a trusted device. Do not complete Telegram authorization through a public or untrusted PencariMovie address.
Telegram's API hash, login code, two-step verification password, and resulting session are credentials. Do not put them in the Compose file, screenshots, issue reports, or shell history. PencariMovie's optional BOT_TOKEN is a separate Bot API credential. Upstream documents automatic guest bot provisioning when that variable is omitted, so a custom bot token is not required for this basic deployment.
Choose the network scope before publishing a port
Docker port publication and PencariMovie authentication solve different problems. A mapping such as 8088:8088 normally publishes the port on the host's available interfaces. A host firewall can further limit which devices reach it. PencariMovie then decides how to handle requests that arrive, while a Localtonet tunnel creates an additional public route.
Upstream explicitly describes LAN dashboard access as password-free. For that reason, SERVER_PASSWORD must not be treated as the only control protecting a LAN deployment. If Localtonet runs on the same Docker host and no other LAN device needs direct access, bind the Docker port to loopback. If a television, phone, or separate Stremio computer must connect directly, use the LAN variant and control access with the host firewall and network segmentation.
| Layer | What it controls | What it does not replace |
|---|---|---|
| Docker port mapping | Which host address and port forward traffic into container port 8088. | It does not authenticate dashboard users. |
| Host firewall | Which source networks or devices may contact the published host port. | It does not validate Telegram or PencariMovie credentials. |
| PencariMovie authentication | Public dashboard password behavior and tokenized remote addon paths. | It does not make broad LAN publication unnecessary. |
| Localtonet tunnel | Creates a public route to the configured local target while the tunnel runs. | It does not replace the application's password, token, or authorization model. |
Prepare persistent storage permissions
This guide uses one bind-mounted storage directory from the beginning. That avoids the original quick-test problem where setup is completed in the pencarimovie-data named volume and the later Compose service silently starts with an empty ./storage directory.
Create the project directory and storage location using an account that can manage the deployment:
mkdir -p pencarimovie/storage
cd pencarimovie
touch compose.yaml .env
Docker must be able to write to ./storage. Ownership behavior varies by Docker platform, NAS, host filesystem, and container release, so this guide does not prescribe a universal numeric user ID or world-writable permission. If startup logs report a permission failure, assign the directory to the user expected by the current image or use an administrator-approved ACL. Do not solve the problem with unrestricted permissions unless the host's security policy explicitly permits that risk.
Deploy PencariMovie directly with Docker Compose
The upstream quick command uses a named Docker volume, while its Compose example uses ./storage:/app/storage. Both are valid, but they are different storage locations. This tutorial starts directly with Compose and keeps all application setup in the bind-mounted directory.
Option A: loopback-only publication for same-host Localtonet
Use this configuration when PencariMovie and the Localtonet client run on the same machine and no separate LAN client needs to connect directly:
services:
pencarimovie:
image: ghcr.io/aiskendi/pencarimovie-server:latest
container_name: pencarimovie-server
restart: unless-stopped
ports:
- "127.0.0.1:${PORT:-8088}:8088"
env_file:
- .env
volumes:
- ./storage:/app/storage
Binding the host side to 127.0.0.1 prevents ordinary LAN clients from connecting directly to the published port. The Localtonet client on the same host can target 127.0.0.1:8088.
Option B: LAN publication for direct client access
Use the upstream-style port mapping only when a separate Stremio, television, phone, or computer must contact the Docker host directly:
services:
pencarimovie:
image: ghcr.io/aiskendi/pencarimovie-server:latest
container_name: pencarimovie-server
restart: unless-stopped
ports:
- "${PORT:-8088}:8088"
env_file:
- .env
volumes:
- ./storage:/app/storage
Docker explains the implications of host port mappings in its port-publishing documentation. Because upstream states that LAN access is password-free, limit this variant to trusted networks, apply appropriate firewall rules, and do not expose host port 8088 directly through a router.
Create the environment file
Put the following variables in .env. Replace both credential placeholders before starting:
PORT=8088
SERVER_PASSWORD=REPLACE_WITH_A_STRONG_UNIQUE_PASSWORD
SERVER_TOKEN=REPLACE_WITH_A_RANDOM_32_CHARACTER_TOKEN
DEBUG=0
Upstream documents 123456 as the default password. Do not use that default for a public deployment. It also documents SERVER_TOKEN as a 32-character static token for protected remote addon URLs. If OpenSSL is available, this command produces 16 random bytes represented as 32 hexadecimal characters:
openssl rand -hex 16
Copy the result into SERVER_TOKEN without publishing it. Choose a separate strong password for SERVER_PASSWORD. Restrict access to the completed environment file according to the host's security model and keep it out of source control.
The replacement strings are not usable secrets. Set the real values before the first start so that the persisted application state and any later public route are created with the intended security configuration.
Start the deployment
Validate the Compose file
Run the Compose configuration parser from the directory containing compose.yaml and .env. Review the result privately because resolved output can include sensitive environment values.
Pull and start PencariMovie
Pull the current image and create the container using the selected port scope and the persistent ./storage directory.
Check state and startup logs
Confirm that the service remains running. Investigate storage permissions, invalid variables, image compatibility, or port conflicts before continuing.
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 pencarimovie
The project documents several optional variables. Leave them unset unless there is a specific need:
| Variable | Documented default | Purpose |
|---|---|---|
PORT |
8088 |
Selects the host-facing port in the Compose mapping. |
SERVER_PASSWORD |
123456 |
Protects dashboard access in documented public VPS and tunnel scenarios. Replace the default. |
SERVER_TOKEN |
Auto-generated | Provides the 32-character token used in protected public addon URLs. |
TUNNEL_TOKEN |
Empty | Configures the project's optional Cloudflare named tunnel integration. It is unrelated to Localtonet. |
BOT_TOKEN |
Auto-provision | Overrides automatic guest bot provisioning with a custom Telegram Bot API token. |
LAN_IP |
Auto-detected | Overrides the detected LAN IPv4 address for multi-device Wi-Fi manifests. |
FRANKENPHP_NUM_THREADS |
8 |
Sets the initial FrankenPHP worker-thread count. |
FRANKENPHP_MAX_THREADS |
16 |
Sets the documented thread-scaling ceiling. |
FD_DOWNLOAD_PARALLEL_CHUNKS |
4 |
Controls parallel chunk downloads for each active stream. |
DEBUG |
0 |
Enables verbose stream and MadelineProto logging in storage/debug.log when set to 1 or true. |
Upstream also documents optional Redis, MySQL, and PostgreSQL session-storage configurations. They are not required for this single-container tutorial. Do not copy placeholder database credentials into a live deployment.
Complete Telegram authorization in PencariMovie
Open http://127.0.0.1:8088 on the Docker host. If you intentionally selected the LAN configuration, you may instead use http://<LAN-IP>:8088 from a trusted device. Complete this setup before starting a public tunnel.
PencariMovie labels this part of its documentation as App Setup. The current release can evolve independently of this article, so visual placement may change, but the authorization sequence and credential boundaries remain important.
Open the local dashboard and begin App Setup
Use a private local address and begin the Telegram application or account setup offered by the installed release. Verify that the page is your own PencariMovie instance before entering any Telegram information.
Provide Telegram API application credentials when requested
Enter the API ID and API hash obtained from Telegram's application configuration page if the setup requests them. These values identify your Telegram API application. They are not the PencariMovie server token, a Localtonet device token, or a Telegram bot token.
Authorize the Telegram account
Supply the account phone number in the format requested by Telegram, then enter the login code delivered through Telegram. If the account has two-step verification enabled, enter its two-step verification password only into the trusted local setup flow.
Confirm that the Telegram session persists
A completed setup should stop requesting initial authorization and allow the server to produce its addon manifest and serve authorized media references. Restart the container once and confirm that it does not ask for a new login, which demonstrates that the session is being retained in ./storage.
Review Telegram account sessions
Check the active sessions shown by Telegram and confirm that the new session is expected. If setup occurred on an untrusted page or an unexpected session appears, revoke it from Telegram and remove the affected PencariMovie storage before trying again.
Complete initial Telegram authorization over loopback or a trusted private network. Login codes and two-step verification passwords are short-lived credentials, while the resulting session remains valuable after setup. Protect the entire storage directory and every backup containing it.
The strongest completion check is functional rather than visual: the container remains running, the dashboard no longer requests initial authorization, /manifest.json returns a valid addon manifest, authorized content is available, and the session survives a container restart.
Verify the dashboard, manifest, and stream locally
Test each layer locally before introducing Stremio or a public tunnel. A tunnel cannot repair a container, permission, Telegram session, or manifest problem.
Confirm the service remains running
docker compose ps
docker compose logs --tail=100 pencarimovie
The container should remain in a running state instead of repeatedly restarting. Check the logs for storage permission errors, invalid environment values, unsupported image architecture, port conflicts, or Telegram authorization failures.
Retrieve the dashboard locally
curl -i http://127.0.0.1:8088/
If you changed PORT, replace 8088 with the selected host port. The expected result is an HTTP response from PencariMovie, not a connection refusal, unrelated web application, or Docker gateway error.
Retrieve and inspect the Stremio manifest
curl -fsS http://127.0.0.1:8088/manifest.json
The response should be a JSON object rather than HTML or a proxy error. Under Stremio's addon manifest model, inspect the response for an addon identifier, name, version, supported resource declarations, supported content types, and catalog declarations when the addon supplies catalogs. The precise values belong to the installed PencariMovie release, so do not replace them with values from a different addon.
If Python is installed, this command verifies that the response is syntactically valid JSON without publishing it:
curl -fsS http://127.0.0.1:8088/manifest.json | python -m json.tool
A successful JSON parse is necessary but not sufficient. Confirm that the object describes PencariMovie and contains usable Stremio resource and type declarations. An empty JSON object, login page, or error object is not a successful addon manifest.
Test direct LAN access only when required
If you selected the LAN Compose mapping, test from a separate trusted device:
http://<LAN-IP>:8088/
http://<LAN-IP>:8088/manifest.json
Replace <LAN-IP> with the Docker host's real private address. Do not use 127.0.0.1 from another device because loopback always points back to the device making the request.
If PencariMovie generates the wrong LAN address on a multi-interface host, add the documented override to .env:
LAN_IP=192.168.1.100
Replace the example with the Docker host's actual LAN IPv4 address, then recreate the service and retrieve a fresh manifest:
docker compose up -d
curl -fsS http://127.0.0.1:8088/manifest.json
Restart and confirm persistence
docker compose restart pencarimovie
docker compose ps
curl -fsS http://127.0.0.1:8088/manifest.json
Confirm that the dashboard remains configured and Telegram authorization is still active. If setup disappears after this restart, stop and correct the ./storage:/app/storage mount or its permissions before proceeding.
Test playback and seeking
Once an authorized media item is available, start playback in a compatible client and seek to a later position. Follow logs while reproducing the request:
docker compose logs --follow pencarimovie
If you have a temporary stream URL from your own session, a byte-range request can test the documented range behavior:
curl -i -H "Range: bytes=0-1023" "YOUR_TEMPORARY_STREAM_URL"
A range-aware stream can return 206 Partial Content with a content range. Do not share the real URL because it may contain temporary authorization or identify private media.
Install the PencariMovie addon in Stremio
Stremio installs an addon from its complete manifest URL. The correct hostname and transport depend on where the client runs. Review the official Stremio addon guidance together with the PencariMovie repository when client behavior changes.
| Installation context | Manifest pattern | Important limitation |
|---|---|---|
| Stremio Desktop on the Docker host | http://127.0.0.1:8088/manifest.json |
Works only when the desktop application and Docker host are the same machine. |
| Desktop client on the same trusted LAN | http://<LAN-IP>:8088/manifest.json |
Requires LAN port publication, firewall permission, and client support for the HTTP manifest. |
| Stremio Web | Prefer the protected public HTTPS manifest | A web page loaded over HTTPS can reject insecure HTTP addon or stream resources because of browser mixed-content policy. |
| Television or mobile client | Use a manifest already installed to the same Stremio account, or a reachable supported URL | Manual URL entry and local HTTP support vary by platform and application version. |
| Remote client | https://<PUBLIC-HOST>/<SERVER_TOKEN>/manifest.json |
Use only after the Localtonet route and token protection have been verified externally. |
Install through a client that accepts addon URLs
Verify the exact manifest URL first
Open the URL from the same device and network context as Stremio. It must return the PencariMovie JSON manifest rather than a dashboard page, connection error, or authentication prompt.
Open Stremio's Addons area
Use Stremio Desktop or another current client that provides addon installation from a URL. Open Addons and use the manifest URL entry or search field provided by that client.
Paste the complete manifest URL
Paste the full URL ending in /manifest.json. For remote access, include the private PencariMovie server token in the path exactly as generated by your deployment.
Review and install the detected addon
Confirm that Stremio displays PencariMovie's addon metadata, then approve installation. Do not continue if the displayed addon identity or manifest origin is unexpected.
Confirm account synchronization where needed
If the television or mobile client does not expose manual URL installation, sign in to the same Stremio account and verify whether the addon installed on Desktop or Web appears there. Platform capabilities can differ, so absence on a client is not proof that the server failed.
Test catalog, playback, and seeking
Confirm that the addon appears, its expected catalog or resources load, an authorized item starts playing, and seeking works. These checks validate more than manifest retrieval alone.
Desktop, Web, television, and mobile clients can differ in manual addon installation, mixed-content enforcement, local-network permissions, account synchronization, and support for insecure HTTP resources. Test the intended client. If the client requires HTTPS or cannot reach the LAN address, use the protected Localtonet HTTPS route rather than weakening browser or device security settings.
Expose the verified service through Localtonet
With Localtonet, our client establishes an outbound connection to a relay server and gives the tunnel a public URL. This avoids inbound router port forwarding, firewall changes for a public inbound port, VPN setup, and the requirement for a public IP address. The public route exists only while the selected Localtonet client is connected and the tunnel is running.
Use an HTTP tunnel because the PencariMovie dashboard, manifest, and stream routes are HTTP endpoints. HTTP and File Server process types can provide a random subdomain, a custom subdomain where supported, or a custom domain. Available relay servers, hostname options, and plan capabilities must be taken from the current dashboard rather than assumed from this tutorial.
Install and run the Localtonet client
Run our client on the Docker host or another trusted device that can reach PencariMovie. Verify the local target from that same device before creating the tunnel.
Authenticate the correct device
Select the device-specific Localtonet auth token associated with the client that will operate the tunnel. Do not put that token in PencariMovie's .env, manifest URL, or TUNNEL_TOKEN variable.
Select an available relay server
Choose a currently available server or region from the dashboard. Do not copy an old server code from another tutorial because availability can change.
Create the HTTP tunnel
If Localtonet runs on the Docker host, target 127.0.0.1 and port 8088, or the host port selected through PORT. If it runs elsewhere, use an address that device can reach and confirm that the LAN Compose variant and firewall permit only the required connection.
Start the tunnel explicitly
Creating a tunnel does not make it active. Press Start and confirm that both the selected client and the tunnel show as connected.
Verify it from an external network
Use mobile data or another network, not the server's LAN. Verify dashboard authentication, tokenized manifest behavior, playback, and seeking before installing the addon on additional devices.
See our HTTP tunnel documentation for the current dashboard workflow. Exact labels, server choices, hostname options, and availability can vary by current product configuration.
Use the protected public manifest path
If the assigned public base address is represented as https://<PUBLIC-HOST>, PencariMovie's documented protected remote addon pattern is:
https://<PUBLIC-HOST>/<SERVER_TOKEN>/manifest.json
Replace both placeholders locally. The completed URL is a credential-bearing URL because it includes SERVER_TOKEN. Do not publish it, include it in a screenshot, or paste it into a public support request.
Test protected and unprotected public routes
From an external network, perform these checks in order:
- Open the public dashboard base URL and confirm that it requires the configured
SERVER_PASSWORD. - Request
https://<PUBLIC-HOST>/manifest.jsonwithout the token. It must not provide an unexpectedly usable unprotected remote addon. - Request
https://<PUBLIC-HOST>/<SERVER_TOKEN>/manifest.jsonand confirm that it returns the expected JSON manifest. - Install that tokenized URL in the intended remote Stremio client.
- Start authorized playback and test seeking.
If the unprotected public route exposes a usable manifest or the dashboard does not enforce the expected password behavior, stop the tunnel immediately. Check that the intended environment reached the current container and verify behavior against the current PencariMovie release before restoring public access.
Anyone who learns the hostname can send requests to it. Keep the dashboard password strong, use the tokenized remote path, protect the manifest URL, and stop the tunnel whenever remote access is unnecessary. An unlisted URL is not an access-control system.
Back up, restore, update, and roll back safely
Routine status and logs
docker compose ps
docker compose logs --tail=100 pencarimovie
docker compose logs --follow pencarimovie
Keep DEBUG=0 during normal operation. If debugging is temporarily enabled, upstream documents verbose output in storage/debug.log. Treat that log as sensitive because it may contain account, request, path, or media details.
Create an application-consistent backup
The complete bind-mounted storage directory can contain Telegram session state and other sensitive application data. Stop the service before taking a simple filesystem archive so files are not changing during the copy:
docker compose stop
tar -czf pencarimovie-storage-backup.tar.gz storage
docker compose start
Protect the archive at least as carefully as the Telegram account session and server credentials. The Compose file can be backed up separately. Back up .env only to an encrypted secret-management or backup system approved for credentials.
Validate restoration in a separate test directory
A backup is not proven until it has been restored and tested. On an isolated test host or during a controlled maintenance window, create a separate project directory, extract the archive so that the restored files again appear under ./storage, provide an appropriate protected environment file, and start the same image version used to create the backup.
mkdir -p pencarimovie-restore-test
cd pencarimovie-restore-test
tar -xzf ../pencarimovie-storage-backup.tar.gz
Copy the Compose definition through a secure administrative process, select an unused host port, and keep the restored test bound to loopback. Confirm that the container starts, the dashboard remains configured, Telegram authorization persists, the manifest is valid, and authorized playback works. Stop and remove the test deployment after validation. Do not run the original and restored Telegram session concurrently longer than necessary.
Record the current image before updating
The moving latest tag can point to a different image after a pull. Record and preserve the current image locally before updating:
docker image inspect --format '{{.Id}}' ghcr.io/aiskendi/pencarimovie-server:latest
docker tag ghcr.io/aiskendi/pencarimovie-server:latest local/pencarimovie-server:pre-update
Create and validate a storage backup, review the current PencariMovie releases, and then update:
docker compose pull
docker compose up -d
docker compose logs --tail=100 pencarimovie
Repeat dashboard, manifest, playback, seeking, container-restart, and Localtonet tunnel checks. Do not consider the update successful merely because the container reports that it is running.
Roll back the image and data together when necessary
If the new image fails before changing persistent data, temporarily change the Compose image value to:
local/pencarimovie-server:pre-update
Then recreate the service:
docker compose up -d
docker compose logs --tail=100 pencarimovie
If the update migrated or modified persistent state incompatibly, restoring only the old container may not be sufficient. Stop the service, preserve the failed post-update storage for diagnosis, restore the validated pre-update storage archive, and then start the preserved image. The supplied evidence does not guarantee backward compatibility for storage across every release, so container rollback and data rollback should be planned as one recovery operation.
Verify behavior after restarts
Restart both layers independently:
- Restart PencariMovie and confirm the dashboard, Telegram session, manifest, playback, and seeking.
- Stop the Localtonet tunnel and confirm that public access ends while local access remains available.
- Start the tunnel again and confirm that the tokenized public manifest returns.
- Restart the Localtonet client and verify that the tunnel reconnects according to its configured lifecycle.
Stopping the tunnel does not stop PencariMovie. Stopping PencariMovie does not delete the tunnel configuration, but the public route will have no working local target. During maintenance, stop the tunnel first and restore it only after local verification passes.
Troubleshooting by layer

| Symptom | Likely layer | What to check |
|---|---|---|
| Container exits or restarts repeatedly | Docker or application startup | Inspect Compose logs for invalid variables, unsupported architecture, storage permissions, or startup errors. |
| Port 8088 is already allocated | Host port publication | Identify the existing listener or choose another PORT. Keep the container target at port 8088. |
| Setup disappears after restart | Persistent storage | Confirm that ./storage is mounted at /app/storage and remains writable. |
| Telegram repeatedly requests authorization | Telegram session persistence | Check the storage mount and logs. Confirm that the host is not deleting or replacing the storage directory. |
| Dashboard works on the host but not the LAN | Network scope | A loopback-only mapping intentionally blocks LAN access. If LAN access is required, use the LAN variant and apply suitable firewall restrictions. |
| Manifest contains the wrong LAN address | Address detection | Set LAN_IP to the correct host IPv4 address, recreate the service, and retrieve a fresh manifest. |
| Stremio rejects a local HTTP URL | Client compatibility | Check platform support, mixed-content policy, local-network permission, and whether manual URL installation is available. Use protected HTTPS where required. |
| Addon installs but no content appears | Telegram setup or addon resources | Confirm authorization completed, inspect the manifest declarations, and follow application logs while refreshing the addon. |
| Playback starts but seeking fails | Stream range handling | Test a private temporary stream URL with a Range request and check for an HTTP 206 response. |
| Public URL does not respond | Localtonet lifecycle or target | Confirm the selected client is connected, the tunnel was explicitly started, and the configured local address works from that client device. |
| Unprotected public manifest is usable | Application security | Stop the tunnel, confirm the active environment and current release behavior, and do not resume exposure until token protection is effective. |
| Public route fails after a restart | Container or tunnel continuity | Check PencariMovie, the Localtonet client, and the tunnel independently. All three must be available. |
Test in a strict sequence
Test the same resource through progressively wider network scopes:
http://127.0.0.1:8088/manifest.jsonon the Docker host.http://<LAN-IP>:8088/manifest.jsononly if LAN publication is enabled.- The protected Localtonet HTTPS manifest from an external network.
- The installed addon inside the intended Stremio client.
- Actual authorized playback and seeking.
A failure at the first stage belongs to Docker or PencariMovie. A failure only on the LAN belongs to port binding, firewall, routing, or client isolation. A failure only through the public URL belongs to the Localtonet client, tunnel state, local target, public path, or application behavior for remote requests.
Apply environment changes correctly
Editing .env does not change the environment of an existing container. Reconcile the service after changing a variable:
docker compose up -d
docker compose logs --tail=100 pencarimovie
Never print the complete resolved environment in a public terminal capture. It contains the dashboard password and server token.
Do not run competing tunnel systems unintentionally
PencariMovie's TUNNEL_TOKEN configures its optional Cloudflare connector. It is not a Localtonet auth token. Leave it unset for this workflow unless you deliberately intend to operate that separate access method. Multiple connectors can create several public routes and make it difficult to determine whether the service is actually private.
Frequently asked questions
What port does PencariMovie use?
The documented default is port 8088. The container listens on 8088, while PORT selects the host-facing port in the supplied Compose configuration.
Why does this guide not begin with docker run?
The upstream docker run command stores state in a named volume, while the Compose example uses ./storage. Starting directly with Compose avoids completing Telegram setup in one storage location and then launching an apparently unconfigured service from another.
Should Docker publish PencariMovie to the LAN?
Only when another LAN device needs direct access. If Localtonet and PencariMovie run on the same host, bind the Docker port to 127.0.0.1. Upstream describes LAN access as password-free, so broad LAN publication should be controlled through Docker binding, firewall rules, and network design.
What is the PencariMovie Stremio manifest URL?
On the Docker host it is normally http://127.0.0.1:8088/manifest.json. A trusted LAN client uses the Docker host's LAN address. A remote client should use the protected HTTPS pattern https://<PUBLIC-HOST>/<SERVER_TOKEN>/manifest.json.
Will a LAN HTTP manifest work on every Stremio client?
No universal behavior should be assumed. Desktop, Web, television, and mobile clients can differ in manual URL installation, local-network access, mixed-content rules, and account synchronization. Test the intended client and use a protected HTTPS manifest when the platform requires it.
Is SERVER_TOKEN the same as a Localtonet auth token?
No. SERVER_TOKEN belongs to PencariMovie and appears in its protected remote addon path. A Localtonet auth token identifies the device running the tunnel. Keep both private and never interchange them.
Do I still need SERVER_PASSWORD when using Localtonet?
Yes. A tunnel provides reachability, not replacement application authentication. Set a strong unique password and verify dashboard authentication from an external network before installing the public addon URL.
Does Localtonet require router port forwarding?
No. Our client establishes an outbound connection to a Localtonet relay server, so this HTTP tunnel does not require inbound router port forwarding or a public IP address.
Will the public URL work while the Localtonet client is offline?
No. The public route is available only while the selected Localtonet client is connected and the tunnel is running. PencariMovie can continue working locally while the tunnel is offline.
Connect your verified PencariMovie server with Localtonet
Complete Telegram authorization, validate the manifest, and test Stremio playback locally first. Then create a Localtonet HTTP tunnel for protected HTTPS access without opening an inbound router port.
Get Started Free →