Files
TelegramTwitterMediaBot/.env.example
T
YoursFunny c420c95165 fix(docker): refuse a root or non-numeric LOCAL_USER_ID
LOCAL_USER_ID=0 passed every check and reached `setpriv --reuid=0`: the bot would run root while looking properly configured, and useradd -o accepted the duplicate uid without complaint. A non-numeric value failed later inside useradd behind `|| true`, which hid the real cause. The entrypoint now rejects both up front with a message naming the variable, and the id/uid expansions are quoted so a value with spaces cannot word-split into extra useradd arguments (audit SEC-007).

Verified by sourcing the entrypoint under a faked `id`: uid 0, 'abc' and '12 3' each exit 1 with the refusal line, while a non-root caller passes straight through to exec. AGENTS and .env.example state the constraint.
2026-09-24 15:12:22 +08:00

84 lines
4.0 KiB
Bash

# Copy to `.env` (gitignored) and fill in:
#
# cp .env.example .env
#
# `docker compose` reads it for the `${VAR}` substitutions in
# docker-compose.yml, and `cargo run` reads it through dotenv. Every variable is
# described in README.md ("环境变量说明" / "Environment variables") — this file
# only shows the shape, with the defaults the code would use anyway.
# --- required -------------------------------------------------------------
# Token from @BotFather. Without it the bot exits at startup.
TELOXIDE_TOKEN=
# --- sites (all optional) -------------------------------------------------
# Pixiv: refresh token. Unset = pixiv links answer "support is disabled".
PIXIV_REFRESH_TOKEN=
# Twitter/X: the `auth_token` cookie of a logged-in session, used only for
# NSFW tweets that the public syndication endpoint withholds.
TWITTER_AUTH_TOKEN=
# bilibili: the whole cookie string; only needed when the egress IP stays
# risk-controlled (device cookies are fetched automatically).
BILIBILI_COOKIE=
# --- bot behaviour --------------------------------------------------------
# Admin chat IDs, comma-separated: start/stop notices, admin-only commands.
BOT_ADMIN=
# Log level. Leave the line commented out for the default
# (`info,hyper_util=warn,reqwest=warn`); do not set it to an empty value.
# RUST_LOG=info,xmedia_bot=debug,x_media=debug
# Edit-before-forward record TTL (seconds).
EDIT_MESSAGE_TTL_SECONDS=86400
# Link-result cache TTL (seconds).
LINK_CACHE_TTL_SECONDS=604800
# Wrap a post's text in a collapsible blockquote from this many characters on;
# 0 disables the wrap.
CAPTION_QUOTE_TEXT_CHARS=200
# State directory (local runs only — the container uses /app/data).
DATA_DIR=data
# --- network --------------------------------------------------------------
# HTTP proxy for the Bot API and site fetches. Two traps: teloxide panics on a
# *blank* value, so comment the line out rather than leaving it empty; and
# inside a container the proxy must be reachable from there (use
# host.docker.internal, not 127.0.0.1 — that is the container itself).
# docker-compose.yml does not pass this variable unless you add it to the bot
# service's `environment:` block.
# TELOXIDE_PROXY=http://127.0.0.1:10808
# --- webhook deployment (docker-compose.yml) ------------------------------
# false = long polling (no public URL needed). true = webhook behind the
# bundled nginx-proxy — and then WEBHOOK_LISTEN/PORT/URL are required.
# The compose healthcheck probes the listener only when this is true.
WEBHOOK=false
# WEBHOOK_LISTEN=0.0.0.0
# WEBHOOK_PORT=8443
# WEBHOOK_URL=https://your.domain/
# Validation token Telegram echoes back as X-Telegram-Bot-Api-Secret-Token.
# Required when WEBHOOK=true: the bot refuses to start without one (use a
# random value of 16+ chars — without it the listener accepts any request).
# WEBHOOK_SECRET_TOKEN=
# Self-signed certificate path, used only for Telegram-side validation (TLS is
# terminated by the reverse proxy); unneeded with acme-companion. Not passed by
# docker-compose.yml — add the line there if this deployment needs it.
# WEBHOOK_CERT=/app/cert/cert.pem
# --- reverse proxy (docker-compose.yml) -----------------------------------
# Public domain or IP that nginx-proxy routes for; empty = do not route.
VIRTUAL_HOST=
# Port inside the bot container nginx-proxy forwards to.
VIRTUAL_PORT=8443
# Certificate notification address for acme-companion.
DEFAULT_EMAIL=
# UID the container runs as; it must be able to write ./data on the host.
# The entrypoint's default (and the README's) is 9001 — keep them equal so
# the file owner on the host matches what you expect. Must be a non-zero
# numeric uid: the entrypoint refuses 0 (the bot would keep root through the
# privilege drop) and anything non-numeric.
LOCAL_USER_ID=9001
# Uncomment (here and the matching line in docker-compose.yml) to have
# acme-companion issue the certificate for VIRTUAL_HOST.
# ACME_HOST=
# Send requests with an unknown Host to this vhost (needed for plain-IP access).
# DEFAULT_HOST=