-
Notifications
You must be signed in to change notification settings - Fork 24
Configuration
This guide provides detailed information about configuring Acestream Ids Scraper.
- Application Settings
- Environment Variables
- Channel Status Checking
- Port Mapping
- Volumes
- ZeroNet Configuration
- Running Behind a Reverse Proxy
- Security Considerations
- Healthchecks
Scraper stores application settings in the database. Container environment variables set runtime defaults; saved engine and public-address settings take precedence. Source URLs belong in Scraper, XMLTV feeds in EPG → Sources. Scraper has no setup wizard and does not read config/config.json.
| Where | What to configure |
|---|---|
| Settings → Playback | Optional Acestream Engine URL, direct/Acexy routing and backend-facing Acexy URL. Save the engine URL and playback routing separately. |
| Settings → Automation | Dedicated checker selection, scraping interval (1–168 hours), EPG interval (1–168 hours), stream-check interval (1–10080 minutes). Saved intervals apply immediately. |
| Settings → Stream links | Named playlist formats and default, optional PID/AppID compatibility. Shared with Playlist → Manage link formats. |
| Settings → API access | The token this browser sends when the server has API_TOKEN configured. Stored locally in the browser. |
| Integrations → Public address | The HTTP(S) origin other devices use to reach the scraper, including its published port. |
| Integrations | Remote players, media servers and tuner limits/recovery. |
| Overview → Services | Runtime health, separate playback/checker controls and diagnostic downloads. |
The Settings tabs use /settings?tab=playback|automation|links|access.
-
ace_engine_url: optional playback engine endpoint. New scraper-only installs leave it empty; existing saved URLs are preserved. -
playback-routing: direct by default;{use_acexy, acexy_url}chooses Acexy for new web-player, tuner and remote-player sessions. Starting the Acexy service does not select this route. Health and signal probes remain direct to the selected engine. -
check-engine:{use_dedicated, url}selects an external checker. With dedicated checks off, checks use the playback URL; without either URL they are skipped. A bundled checker is container-managed and read-only here. A configured checker's failure never falls back to playback. -
base_url: default stream-link format. Named formats can be selected usingbase_url_id.{channel_id}is the AceStream hash;{tv_channel_id}is the TV-channel database ID. Use/tuner/channel/{tv_channel_id}.tsfor one stable station URL with fallback sources, or/tuner/stream/{channel_id}.tsfor one exact source.{pid}supplies a player/session ID where supported; a format without placeholders is a prefix. -
rescrape_interval: default 24 hours;epg_refresh_interval: default 6 hours;channel_status_interval: default 60 minutes.
See the illustrated walkthrough and playback routing guide for examples.
-
DATABASE_URL(default:sqlite:///./config/scraper.db) -
LEGACY_DATABASE_URL(default:sqlite:///./config/acestream.db) -
EPG_PROGRAM_RETENTION_HOURS(default:24) — EPG programs that ended more than this many hours ago are deleted by the hourlyepg_program_cleanupjob and skipped by the v1→v2 migration; negative keeps everything -
ZERONET_URL(default:http://host.docker.internal:43110in the checked-in compose example) -
IPFS_GATEWAY_URL(default: the embedded gatewayhttp://127.0.0.1:8081; point it at an external IPFS gateway whenENABLE_IPFS=false) -
CORS_ORIGINS(default:http://localhost:3000) -
FRONTEND_BUILD_PATH(default:frontend_build) -
ACE_ENGINE_URL(empty for new scraper-only installs;http://localhost:6878when bundled playback is enabled; saved Settings → Playback URLs take precedence) -
ACE_CHECK_ENGINE_URL(optional external checker default, editable in Settings → Automation; an unavailable dedicated checker never falls back to playback)
| Variable | Description | Default | Notes |
|---|---|---|---|
FLASK_PORT |
Port the web app (uvicorn) listens on | 8000 |
Name kept from v1 but still the real setting: entrypoint.sh passes it to uvicorn --port and healthcheck.sh probes http://localhost:${FLASK_PORT}/api/v1/health. Change it if port 8000 is in use |
FLASK_ENV |
Superseded (2026-08-28) — v1 Flask environment mode, not read by the v2 (FastAPI) runtime | – | For local debugging run uvicorn main:app --reload from backend/ instead |
API_TOKEN |
Require a token on API and playlist routes | unset (open) | Sent as Authorization: Bearer, X-Api-Token, or ?token= (for IPTV players); /api/v1/health stays public |
ALLOW_PRIVATE_SCRAPE_TARGETS |
Allow scrape/EPG URLs on private/LAN addresses | true |
Set false to block loopback/private/link-local targets; the cloud metadata endpoint is always blocked. It does not affect remote players, media servers or player discovery, which are LAN targets by design; the metadata/link-local block still applies to them |
ACESTREAM_STATUS_TIMEOUT |
Timeout (seconds) for the engine status probe | 10 |
A timed-out probe retries once with a doubled timeout |
EPG_PROGRAM_RETENTION_HOURS |
How long finished EPG programs are kept | 24 |
The hourly epg_program_cleanup job deletes programs that ended earlier than this, and a v1→v2 migration skips them (they are useless once aired — the EPG refresh keeps adding upcoming ones). 2 keeps only the last couple of hours; a negative value disables the purge. The XMLTV export's default days_back=1 needs at least 24
|
SUPERVISED_RESTART_DELAY_SECONDS |
Delay before restarting an exited engine or crashed sidecar | 5 |
AceStream retries indefinitely after any exit, including exit 0 (minimum delay 1 second). Overview → Services offers Stop to suspend recovery and Start/Restart to resume it. A container restart also resumes the enabled engine. Custom engine commands must run in the foreground |
SUPERVISED_FAST_EXIT_LIMIT |
Consecutive fast sidecar exits before giving up | 3 |
With SUPERVISED_FAST_EXIT_WINDOW (default 10s); a crash loop fails the container. Does not apply to AceStream, which keeps retrying |
External players and media servers (VLC, Kodi, Jellyfin, Plex) fetch streams over the network, so the app has to know which origin to advertise and which peers to trust:
| Variable | Description | Default | Notes |
|---|---|---|---|
PUBLIC_BASE_URL |
Origin (http://host:port) that Jellyfin/Plex/VLC use to reach this server |
(empty) | Empty derives it from each request. The same value is editable at runtime as the public_base_url setting, which wins over the variable |
FORWARDED_ALLOW_IPS |
Peers whose X-Forwarded-* headers the app trusts |
127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 |
Comma-separated addresses/CIDRs, or * to trust every peer. uvicorn's own handling is disabled (--no-proxy-headers) — the app does it |
TUNER_ALLOWED_NETWORKS |
Networks allowed to use the token-free /tuner/* routes |
127.0.0.0/8,10.0.0.0/8,100.64.0.0/10,172.16.0.0/12,192.168.0.0/16,::1/128,fc00::/7,fe80::/10 |
* disables the check. Media servers cannot send an API_TOKEN, so these routes are gated by address instead. Publish the web port as -p 0.0.0.0:8000:8000 (never the bare 8000:8000): an unaddressed mapping also listens on [::], and Docker then presents every IPv6 client to the app as the bridge gateway (172.17.0.1), which is inside this default list |
PLAYER_HLS_DIR |
Where the web player writes HLS segments | /tmp/acestream-player |
/dev/shm/acestream-player with a larger shm_size keeps them in RAM |
PLAYER_MAX_SESSIONS |
Maximum channels the web player prepares at once | 3 |
Each session costs one engine stream and one ffmpeg process |
PLAYER_START_TIMEOUT_SECONDS |
Seconds a web-player session may stay in "starting" before it is reported as stalled | 45 |
Raise it on slow links where streams take longer to buffer |
FFMPEG_BINARY_PATH |
ffmpeg used by the web player | (empty) | Empty falls back to ffmpeg on PATH; images that bundle ffmpeg set it to /opt/ffmpeg/bin/ffmpeg
|
MEDIA_SERVER_MIN_REFRESH_MINUTES |
Minimum minutes between automatic Jellyfin/Plex guide refreshes | 30 |
0 disables the debounce |
| Variable | Description | Default | Notes |
|---|---|---|---|
ENABLE_ACESTREAM_ENGINE |
Enable built-in Acestream Engine | false |
Set to true to run Acestream in the container |
ACESTREAM_HTTP_PORT |
Port for Acestream engine | 6878 |
Internal Acestream Engine HTTP port |
ACESTREAM_HTTP_HOST |
Host for Acestream engine | localhost |
Address to access Acestream Engine |
ACESTREAM_BIND_ALL |
Append --bind-all to the engine start command so any client address is accepted on a published 6878
|
true |
The engine otherwise admits only loopback/RFC1918 sources; false restores the engine's own filter |
ACE_ENGINE_URL |
Playback-engine default | Empty without bundled playback; http://localhost:6878 when enabled |
Saved Settings → Playback URL takes precedence |
ENABLE_ACESTREAM_CHECK_ENGINE |
Run a second bundled engine for checks | false |
Requires the playback engine enabled and an engine-containing image; do not also set ACE_CHECK_ENGINE_URL
|
ACE_CHECK_ENGINE_URL |
External dedicated checker default | Empty | May be overridden in Settings → Automation; configured checker failure never falls back |
| Variable | Description | Default | Notes |
|---|---|---|---|
ENABLE_ACEXY |
Enable Acexy proxy | false |
Set to true to enable enhanced Acestream proxy |
ACEXY_LISTEN_ADDR |
Address for Acexy to listen on | :8080 |
Format is [host]:port or just :port
|
ACEXY_HOST |
Hostname of Acestream Engine | localhost |
Hostname or IP where Acestream Engine runs |
ACEXY_PORT |
Port of Acestream Engine | 6878 |
Port where Acestream Engine is accessible |
ACEXY_NO_RESPONSE_TIMEOUT |
Timeout for Acestream responses | 15s |
Format: 15s, 1m, etc. |
ACEXY_BUFFER_SIZE |
Buffer size for data transfers | 5MiB |
Format: 5MiB, 10MiB, etc. |
The engine retrieves P2P media. Acexy is an optional HTTP proxy that shares streams and owns its engine sessions and cleanup. Direct app playback already assigns session IDs and coordinates its own source ownership; you do not need to add PIDs manually for the built-in browser player.
A unique PID alone does not prevent the native engine stopping another client of the same source. Use the app's coordinated relay or Acexy routing, and consider a separate checker for checks alongside playback. Direct external clients remain outside the app's registry. See Playback routing.
The amd64 and arm64 images bundle a ZeroNet node (zeronet-conservancy v0.7.10) that is off by default; 32-bit ARM images use an external service instead. In both cases the scraper reaches the node over HTTP via ZERONET_URL. The v1 in-container zeronet.conf mechanism is gone — the node is configured through these variables:
| Variable | Description | Default | Notes |
|---|---|---|---|
ENABLE_ZERONET |
Start the bundled ZeroNet node | false |
amd64 images only; fails with a clear error elsewhere |
ENABLE_TOR |
Run TOR for the bundled node | false |
Only takes effect with ENABLE_ZERONET=true; the node auto-detects TOR over the control port |
ZERONET_URL |
Address the scraper fetches zero:// sources through |
http://host.docker.internal:43110 in the checked-in compose example |
With ENABLE_ZERONET=true and no explicit value it targets the embedded UI port automatically |
ZERONET_DATA_DIR |
Bundled node's state directory | /data/zeronet |
Mount a volume there |
ZERONET_UI_PORT |
Bundled node's web UI port | 43110 |
|
ZERONET_FILESERVER_PORT |
Bundled node's fileserver/peer port | 26552 |
|
ZERONET_UI_HOST |
Extra Host headers the UI accepts | (none) | Space-separated hostnames; needed to browse the UI from another machine |
ZERONET_TRACKERS |
Bootstrap trackers for a fresh bundled node | Three public UDP trackers | Space-separated tracker URLs; override when the defaults are unavailable or unsuitable |
ZERONET_EXTRA_ARGS |
Extra zeronet-conservancy CLI flags | (none) | Passed through to the node verbatim |
TZ |
Timezone for the container | Europe/Madrid |
Use any valid TZ identifier |
The image bundles the Kubo IPFS daemon (amd64/arm64 — Kubo has no 32-bit ARM build) so ipfs:// and ipns:// sources can be scraped through its HTTP gateway:
| Variable | Description | Default | Notes |
|---|---|---|---|
ENABLE_IPFS |
Start the embedded Kubo daemon | false |
Opt-in; fails with a clear error on linux/arm/v7 images |
IPFS_GATEWAY_URL |
Gateway used to fetch ipfs:///ipns:// sources |
http://127.0.0.1:8081 |
Point at an external gateway to scrape IPFS without the embedded daemon |
IPFS_PATH |
IPFS repository location | /data/ipfs |
Mount a volume there when the daemon is enabled |
IPFS_SWARM_PORT |
Swarm (P2P) port | 4001 |
TCP and UDP (QUIC) |
IPFS_API_PORT |
RPC API / WebUI port | 5001 |
Unauthenticated; binds to the container loopback by default |
IPFS_API_HOST |
RPC API bind address | 127.0.0.1 |
Set 0.0.0.0 only if you need the WebUI, and publish it as 127.0.0.1:5001:5001
|
IPFS_GATEWAY_PORT |
HTTP gateway port | 8081 |
8080 is taken by Acexy in-container |
IPFS_PROFILE |
Kubo config profile applied at first init | (none) | e.g. lowpower for small devices, server for datacenter hosts |
Cloudflare WARP provides enhanced privacy and secure connection options:
| Variable | Description | Default | Notes |
|---|---|---|---|
ENABLE_WARP |
Start Cloudflare WARP | false |
Available on amd64/arm64; requires NET_ADMIN, SYS_ADMIN, and /dev/net/tun
|
WARP_ENABLE_NAT |
Connect WARP and enable NAT at startup | false |
Leave false to connect/disconnect from the WARP page instead |
WARP_LICENSE_KEY |
WARP license key | - | Optional: For WARP+ or Team accounts |
docker run -d \
-p 0.0.0.0:8000:8000 \
--cap-add NET_ADMIN \
--cap-add SYS_ADMIN \
--device /dev/net/tun:/dev/net/tun \
-e ENABLE_WARP=true \
-e WARP_ENABLE_NAT=true \
-v "${PWD}/config:/app/config" \
--name acestream-scraper \
pipepito/acestream-scraper:latestversion: '3.8'
services:
acestream-scraper:
image: pipepito/acestream-scraper:latest
container_name: acestream-scraper
cap_add:
- NET_ADMIN
- SYS_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- TZ=Europe/Madrid
- ENABLE_WARP=true
- WARP_ENABLE_NAT=true
ports:
- "0.0.0.0:8000:8000"
volumes:
- ./data/config:/app/config
restart: unless-stoppedUse Settings → Automation to select the checker and schedule. The default is one scan every 60 minutes. Manual checks and playback-triggered source refreshes use the same serialized priority queue: TV playback, individual manual checks, then scheduled/bulk work. A running probe finishes cleanup before another starts.
An online result requires increasing P2P downloads and a bounded media sample with identified audio/video packets. Peer counts and a catalogue's availability flag are insufficient. ID lookup is reported separately: found, explicitly not found, or unknown. Timeouts and engine errors must not be read as permanent ID absence. Saved results describe the last check, not continuous monitoring or browser codec compatibility.
Without any engine configured, checks are skipped and previous results remain. A configured dedicated checker that fails never sends checks to playback. This makes a second engine useful when you regularly watch and scan at the same time; it adds memory, cache and bandwidth use.
Unique PIDs alone do not isolate stopping the same source on native engine 3.2.11. The app protects streams owned by its web player and relay; clients connected directly to the engine are outside that registry. See checking and playback ownership.
Overview shows the persisted start time, result, next run and state of scheduled jobs. Runs interrupted by a restart are marked interrupted. Stream rows show the saved broadcast/lookup result and last-check information. Imports do not mark newly discovered streams online.
When using Docker, map these ports as needed:
| Port | Service | Notes |
|---|---|---|
| 8000 | Main web interface | Configurable via FLASK_PORT. Publish it as 0.0.0.0:8000:8000; a bare 8000:8000 also binds [::] and makes every IPv6 client look like the Docker bridge gateway, which defeats TUNER_ALLOWED_NETWORKS
|
| 8080 | Acexy web interface | Only if Acexy is enabled |
| 6878 | Acestream HTTP API | Configurable via ACESTREAM_HTTP_PORT
|
| 8621 | Acestream P2P port | For Acestream peer connections |
| 43110 | ZeroNet web interface | Only if ENABLE_ZERONET=true (or published by the optional zeronet sidecar) |
| 26552 | ZeroNet fileserver/peer port | Only if ENABLE_ZERONET=true; publishing it improves peer connectivity |
| 4001 | IPFS swarm port (TCP and UDP) | Only if ENABLE_IPFS=true; improves peer connectivity |
| 8081 | IPFS HTTP gateway | Only if ENABLE_IPFS=true and you want to browse IPFS through the node |
| 5001 | IPFS RPC API / WebUI | Unauthenticated — publish only as 127.0.0.1:5001:5001 if needed |
When using Docker, mount these volumes:
| Container Path | Purpose | Notes |
|---|---|---|
/app/config |
Configuration and data | Contains the database (scraper.db; a v1 acestream.db found here is migrated on first start — channels and settings before the dashboard comes up, EPG programs in the background afterwards; see Installation) |
/var/lib/acestream-check |
Dedicated checker state/cache | Use a separate host folder when the bundled checker is enabled |
/tmp/acestream-player |
Rolling browser-player HLS files | Recommended host mount, or configure RAM storage |
/root/.ACEStream/.acestream_cache |
Bundled amd64 playback cache | Recommended host mount; ARM uses its state folder |
/app/logs |
Scraper and per-service logs | Optional mount to retain diagnostics across container replacement; logs contain private operational data |
/var/lib/acestream |
AceStream engine state and cache | Only used when ENABLE_ACESTREAM_ENGINE=true (ARM Android engine) |
/data/ipfs |
IPFS repository (identity, config, blockstore) | Only required if ENABLE_IPFS=true
|
/data/zeronet |
Bundled ZeroNet node's state (sites, keys, content) | Only required if ENABLE_ZERONET=true
|
The v1 /app/ZeroNet/data path is gone — the bundled node keeps its state under /data/zeronet now (and the compose sidecar example keeps its own data in ./zeronet_data).
Example mount:
docker run -v "${PWD}/config:/app/config" -v "${PWD}/ipfs_data:/data/ipfs" -v "${PWD}/zeronet_app_data:/data/zeronet" ...The v1 zeronet.conf file is gone; in v2 you either enable the bundled node or point at an external one:
Bundled node (amd64 images):
- Set
ENABLE_ZERONET=true(and optionallyENABLE_TOR=true), mount/data/zeronet, and publish43110/26552if you want the UI or better peer connectivity. - Leave
ZERONET_URLunset — the scraper targets the embedded node automatically. - Tune the node with the
ZERONET_*variables above (ZERONET_UI_PORT,ZERONET_UI_HOST,ZERONET_EXTRA_ARGS, ...).
External service (any platform):
- Run a ZeroNet service somewhere the container can reach — the checked-in
docker-compose.ymlships an optional amd64 sidecar (docker compose --profile zeronet up -d), or use any existing ZeroNet install. - Point
ZERONET_URLat it (the compose default ishttp://host.docker.internal:43110). TOR and the node's own settings are configured on that external service.
Either way, add your ZeroNet sources in the Scraper page with the ZeroNet URL type (zero://... URLs are also auto-detected).
The application includes proper headers handling for running behind a reverse proxy:
- Automatic handling of SSL/TLS termination
- Correct handling of X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-For headers, honoured only when the proxy's own address is listed in
FORWARDED_ALLOW_IPS(default: loopback and private ranges) - Works with nginx, Apache, Traefik or other reverse proxies
- Set
PUBLIC_BASE_URLwhen the proxy rewritesHostor serves the app under a sub-path, so playlist and tuner links stay reachable
server {
listen 80;
server_name acestream.example.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}- Don't publish the AceStream engine API (
6878), the Acexy proxy (8080) or the IPFS RPC API (5001) beyond trusted networks — none of them authenticate callers - If you expose the web interface beyond your LAN, do it through a reverse proxy with TLS and authentication (see Reverse Proxy / HTTPS)
- Consider using a reverse proxy with SSL/TLS for secure access
- Be aware of copyright and legal considerations when sharing playlists
The container includes comprehensive health checks:
- Main application health check at
/api/v1/health(public, even with an API token) - Acexy health check (if enabled)
- Acestream Engine health check (if enabled)
- Automatic monitoring of internal services
- Graceful handling of service dependencies
The Docker container is configured with a health check that checks application readiness and the required enabled services; a checker outage does not fail whole-container health, and an intentional engine Stop is respected:
healthcheck:
test: ["CMD", "/usr/local/bin/healthcheck.sh"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60sYou can check the health status with: docker inspect --format='{{.State.Health.Status}}' acestream-scraper
v2.1 keeps legacy names working and shows deprecation warnings in startup logs and Overview → Storage. Nonempty canonical values take precedence when both names are set; otherwise the old values remain effective. Warnings contain variable names only.
Update these names in your Compose file, container settings or .env file when convenient:
-
SCRAPER_DB_URL->DATABASE_URL -
LEGACY_DB_URL->LEGACY_DATABASE_URL -
ZERONET_BASE_URL->ZERONET_URL -
CORS_ALLOW_ORIGINS->CORS_ORIGINS -
FRONTEND_STATIC_DIR->FRONTEND_BUILD_PATH -
ACESTREAM_ENGINE_URL->ACE_ENGINE_URL
ENABLE_LEGACY_ENV_ALIASES is no longer required and does not disable compatibility. See the v2.1 upgrade notes.
Acestream Ids Scraper
- Home
- First-run walkthrough
- Install and upgrade
- Docker and storage
- Storage report
- Docker command builder
Watch and manage
- Live TV and web player
- Channel management
- Stream statistics
- Extraction recipes
- VLC and Kodi
- Jellyfin and Plex
- Configuration
Get help
Contribute