Best Practices¶
A deployment checklist, ordered by how much it matters.
Essential¶
1. Turn authentication on before exposing anything¶
This is the one that bites
A fresh instance has no account and no login. Anyone who reaches the port has full access — every download, every cookie jar, your Lalal.ai minutes.
Then create the admin account under Settings → Security.
2. Generate a real secret key¶
Never reuse a key across instances, never commit it, never bake it into an image.
The key is effectively permanent
The password salt and pepper are derived from it. Rotating it invalidates the stored password and every session and anti-bot token. Decide once, store it durably.
3. Terminate TLS¶
Put a reverse proxy in front and set:
Without FETCHLY_BEHIND_HTTPS=1 the session cookie is not marked Secure. Without a correct FORWARDED_ALLOW_IPS every client shares one rate-limit bucket. See Reverse Proxy.
4. Protect the data volume¶
It holds live platform sessions, your Lalal.ai key, and the admin password hash. Back it up encrypted.
Strongly recommended¶
5. Do not put it on the public internet¶
fetchly is a single-user tool. The safest deployment is on a private network or behind a VPN. If it must be reachable from outside, at minimum:
- Authentication on
- TLS with a valid certificate
- Restrictive proxy access rules (IP allow-list, or an auth layer in front)
6. Keep WORKERS at 1¶
Not a performance knob. More than one process means duplicate jobs and missing live updates. Scale with Settings → General → Runtime limits → Download workers instead.
7. Set a retention period¶
Unlimited retention means downloaded media accumulates until the disk fills. It also means a share link handed out a year ago still works.
8. Cap share links¶
Unlimited links are bearer tokens with no expiry. A modest use count limits the damage when one is forwarded further than you intended.
9. Set the public hostname¶
Otherwise share links may carry an internal hostname and leak your topology while not working for the recipient.
Recommended¶
10. Harden the container further¶
no-new-privileges:true already ships in docker/docker-compose.yml; you only need to add the read-only root filesystem yourself:
security_opt:
- no-new-privileges:true # already in the shipped compose file
read_only: true
tmpfs:
- /tmp
read_only needs the /tmp tmpfs — ffmpeg and the cookie importer write there.
11. Bound the logs¶
12. Keep it updated¶
Settings → System shows the running version against the latest release, plus the component versions of yt-dlp, ffmpeg, and friends. yt-dlp in particular breaks when platforms change; a stale image shows up as downloads that used to work and no longer do.
13. Test your backups¶
A backup you have never restored is a hypothesis.
Cookie hygiene¶
- Import a session only for platforms you actually need gated content from
- Prefer a secondary account over your primary one where the platform allows it
- Signing out in the browser you copied from invalidates the imported jar too
- Remove a platform's jar when you stop needing it
- Never share a snapshot of the data volume — it contains working sessions
Anti-checklist¶
Things that look like hardening and are not:
| Idea | Why it does not help |
|---|---|
FORWARDED_ALLOW_IPS=* "to make the proxy work" | Disables client-IP integrity; every rate limit becomes bypassable |
| Raising the share-redeem rate limit | That limit is what makes 48-bit tokens safe |
| Running more Gunicorn workers "for safety" | Breaks job processing and live updates |
| Relying on an unguessable port | Port scans are cheap; this is not access control |
| Turning off the Lalal.ai duration guard to "save a step" | Sends oversized jobs at your own cost |
Verifying a deployment¶
# App answers
curl -fsS https://fetchly.example.com/health
# Authentication is on: an unauthenticated API call is refused
curl -si https://fetchly.example.com/api/jobs | head -1
# The session cookie carries Secure and HttpOnly
curl -sI https://fetchly.example.com/login | grep -i set-cookie
# The port is not reachable around the proxy
curl -m 3 http://<host>:8000/health # should fail