Interfaz Web
Rol de la interfaz web
La interfaz web es el plano de control visual de BunkerWeb. Administra servicios, ajustes globales, bloqueos, plugins, trabajos, caché, registros y actualizaciones sin usar la CLI. Es una app Flask servida por Gunicorn y normalmente se coloca detrás de un reverse proxy BunkerWeb.
Manténla detrás de BunkerWeb
La UI puede cambiar configuración, ejecutar trabajos y desplegar fragmentos personalizados. Ubícala en una red de confianza, enrútala mediante BunkerWeb y protégela con credenciales fuertes y 2FA.
Datos rápidos
- Escucha por defecto:
0.0.0.0:7000en contenedores,127.0.0.1:7000en paquetes (cambia conUI_LISTEN_ADDR/UI_LISTEN_PORT) - Consciente de reverse proxy: respeta
X-Forwarded-*viaUI_FORWARDED_ALLOW_IPS; ajustaPROXY_NUMBERSsi varios proxies agregan cabeceras - Auth: cuenta admin local (política de contraseña aplicada), roles opcionales, 2FA TOTP con
TOTP_ENCRYPTION_KEYS - Sesiones: firmadas con
FLASK_SECRET, vida útil por defecto 12 h, fijadas a IP y User-Agent;ALWAYS_REMEMBERcontrola cookies persistentes - Logs:
/var/log/bunkerweb/ui.log(+ access log si se captura), UID/GID 101 dentro del contenedor - Salud:
GET /healthcheckopcional siENABLE_HEALTHCHECK=yes - Dependencias: comparte la base de datos de BunkerWeb y habla con la API para recargar, bloquear o consultar instancias
Checklist de seguridad
- Ejecuta la UI detrás de BunkerWeb en una red interna; usa un
REVERSE_PROXY_URLdifícil de adivinar y limita IPs de origen. - Establece
ADMIN_USERNAME/ADMIN_PASSWORDfuertes; usaOVERRIDE_ADMIN_CREDS=yessolo cuando quieras forzar un reseteo. - Habilita TOTP en las cuentas admin y guarda los códigos de recuperación. Las claves de cifrado se generan en el primer arranque, así que
TOTP_ENCRYPTION_KEYSsolo importa si no puedes persistir el volumen de la UI. - Usa TLS (terminado en BunkerWeb o
UI_SSL_ENABLED=yescon rutas de cert/clave); fijaUI_FORWARDED_ALLOW_IPSa proxies de confianza. - Persiste secretos: en contenedores monta un volumen en
/data(/var/lib/bunkerwebes un enlace simbólico a/data/liben las imágenes) para conservarFLASK_SECRET, las llaves Biscuit y las claves de cifrado TOTP. Sin ese volumen, recrear el contenedor de la UI borra todas las inscripciones 2FA. - Mantén
CHECK_PRIVATE_IP=yes(por defecto) para ligar sesiones a la IP; dejaALWAYS_REMEMBER=nosalvo que requieras cookies largas. - Asegura que
/var/log/bunkerwebsea legible por UID/GID 101 (o el UID mapeado en rootless) para que la UI pueda leer logs.
Puesta en marcha
La UI requiere scheduler/API de BunkerWeb/redis/base de datos accesibles.
Usa las imágenes publicadas y el layout del guía rápida para levantar el stack, luego completa el asistente en el navegador.
docker compose -f https://raw.githubusercontent.com/bunkerity/bunkerweb/v1.6.15~rc3-rc1/misc/integrations/docker-compose.yml up -d
Visita el hostname del scheduler (ej. https://www.example.com/changeme) y ejecuta el asistente /setup para configurar la UI, el scheduler y la instancia.
Omite el asistente precargando credenciales y red; ejemplo Compose con sidecar syslog:
x-service-env: &service-env
DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db"
LOG_TYPES: "stderr syslog"
LOG_SYSLOG_ADDRESS: "udp://bw-syslog:514"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.6.15-rc3
ports:
- "80:8080/tcp"
- "443:8443/tcp"
- "443:8443/udp"
environment:
API_WHITELIST_IP: "127.0.0.0/24 10.20.30.0/24"
restart: "unless-stopped"
networks: [bw-universe, bw-services]
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.6.15-rc3
environment:
<<: *service-env
BUNKERWEB_INSTANCES: "bunkerweb"
SERVER_NAME: "www.example.com"
MULTISITE: "yes"
API_WHITELIST_IP: "127.0.0.0/24 10.20.30.0/24"
ACCESS_LOG_1: "syslog:server=bw-syslog:514,tag=bunkerweb_access"
ERROR_LOG_1: "syslog:server=bw-syslog:514,tag=bunkerweb"
DISABLE_DEFAULT_SERVER: "yes"
www.example.com_USE_TEMPLATE: "ui"
www.example.com_USE_REVERSE_PROXY: "yes"
www.example.com_REVERSE_PROXY_URL: "/changeme"
www.example.com_REVERSE_PROXY_HOST: "http://bw-ui:7000"
volumes:
- bw-storage:/data
restart: "unless-stopped"
networks: [bw-universe, bw-db]
bw-ui:
image: bunkerity/bunkerweb-ui:1.6.15-rc3
environment:
<<: *service-env
ADMIN_USERNAME: "admin"
ADMIN_PASSWORD: "Str0ng&P@ss!"
# TOTP_ENCRYPTION_KEYS: "changeme" # Opcional: se genera en el volumen bw-ui-data si no se define; una clave tiene 43 caracteres
UI_FORWARDED_ALLOW_IPS: "10.20.30.0/24"
volumes:
- bw-logs:/var/log/bunkerweb
- bw-ui-data:/data # Se usa para conservar los secretos de la interfaz web (secreto Flask, claves de cifrado TOTP, claves Biscuit)
restart: "unless-stopped"
networks: [bw-universe, bw-db]
bw-db:
image: mariadb:11
command: --max-allowed-packet=67108864
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: "db"
MYSQL_USER: "bunkerweb"
MYSQL_PASSWORD: "changeme"
volumes:
- bw-data:/var/lib/mysql
restart: "unless-stopped"
networks: [bw-db]
bw-syslog:
image: balabit/syslog-ng:4.10.2
volumes:
- bw-logs:/var/log/bunkerweb
- ./syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf
restart: "unless-stopped"
networks: [bw-universe]
volumes:
bw-data:
bw-storage:
bw-logs:
bw-lib:
bw-ui-data:
networks:
bw-universe:
ipam:
config: [{ subnet: 10.20.30.0/24 }]
bw-services:
bw-db:
Añade bunkerweb-autoconf y aplica labels al contenedor de la UI en vez de BUNKERWEB_INSTANCES. El scheduler sigue haciendo reverse proxy a la UI mediante la plantilla ui y un REVERSE_PROXY_URL secreto.
El paquete instala el servicio systemd bunkerweb-ui. Se activa automáticamente con easy-install (el asistente también se inicia por defecto). Para ajustar o reconfigurar, edita /etc/bunkerweb/ui.env y luego:
sudo systemctl enable --now bunkerweb-ui
sudo systemctl restart bunkerweb-ui # después de cambios
Publícalo detrás de BunkerWeb (plantilla ui, REVERSE_PROXY_URL=/changeme, upstream http://127.0.0.1:7000). Monta /var/lib/bunkerweb y /var/log/bunkerweb para persistir secretos y logs.
Específicos Linux vs Docker
- Enlaces por defecto: imágenes Docker escuchan en
0.0.0.0:7000; paquetes Linux en127.0.0.1:7000. Cambia conUI_LISTEN_ADDR/UI_LISTEN_PORT. - Cabeceras de proxy:
UI_FORWARDED_ALLOW_IPSpor defecto127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16;UI_PROXY_ALLOW_IPStoma por defecto el valor deFORWARDED_ALLOW_IPS. En Linux ajústalos a las IP de tu proxy para endurecer. - Secretos y estado:
/var/lib/bunkerwebguardaFLASK_SECRET, las llaves Biscuit y las claves de cifrado TOTP. En contenedores esa ruta es un enlace simbólico a/data/lib, así que monta un volumen en/data; en Linux el directorio lo gestiona el paquete. - Logs:
/var/log/bunkerwebdebe ser legible por UID/GID 101 (o el UID mapeado en rootless). Los paquetes crean la ruta; los contenedores necesitan un volumen con permisos adecuados. - Asistente: easy-install en Linux arranca la UI y el asistente automáticamente; en Docker se accede al asistente vía la URL reverse-proxificada salvo que preselecciones variables de entorno.
Autenticación y sesiones
- Cuenta admin: créala con el asistente o con
ADMIN_USERNAME/ADMIN_PASSWORD. La contraseña debe incluir minúsculas, mayúsculas, dígito y carácter especial.OVERRIDE_ADMIN_CREDS=yesfuerza la resiembra aunque ya exista. - Límite de longitud de contraseña: bcrypt solo usa los primeros 72 bytes de un secreto, por lo que las contraseñas se limitan a 72 bytes en todos los lugares donde se configuran (asistente de configuración, página de perfil,
ADMIN_PASSWORD/API_PASSWORD). Un valor más largo se rechaza con un error o registro explicativo en lugar de truncarse silenciosamente. Ten en cuenta que los caracteres no ASCII (acentos, emoji) consumen varios bytes cada uno; una frase de contraseña de "72 caracteres" formada por esos caracteres puede superar el límite. Los valores bcrypt pre-hasheados están exentos (el hash ya codifica el límite). - Roles:
admin,writeryreaderse crean automáticamente; las cuentas viven en la base de datos. - Secretos:
FLASK_SECRETse guarda en/var/lib/bunkerweb/.flask_secret; las llaves Biscuit al lado, opcionalmente víaBISCUIT_PUBLIC_KEY/BISCUIT_PRIVATE_KEY. -
2FA: los secretos TOTP se guardan en la base de datos, cifrados con claves que viven en
/var/lib/bunkerweb/.totp_encryption_keys.json. La UI las genera en el primer arranque, así que no hace falta nada mientras ese fichero se conserve. DefineTOTP_ENCRYPTION_KEYS(separadas por espacios o mapa JSON) para aportar las tuyas; entonces cada clave debe tener exactamente 43 caracteres, cualquier otro valor se descarta con un avisoInvalid TOTP secret for keyy se sustituye por una clave aleatoria. Genera una llave:python3 -c "from passlib import totp; print(totp.generate_secret())"Los códigos de recuperación se muestran una sola vez; si pierdes las llaves de cifrado, se eliminan los secretos TOTP almacenados. - Sesiones: duración de inactividad por defecto 12 h (
SESSION_LIFETIME_HOURS), refrescada en cada petición. Se aplica un límite absoluto víaSESSION_ABSOLUTE_HOURS(por defecto168= 7 días) — superado ese tiempo, los usuarios son desconectados aunque sigan activos. Rotación opcional del identificador de sesión (SESSION_ROLLING_HOURS, por defecto0= deshabilitada) regenera el ID de sesión en ese intervalo. Sesiones fijadas a IP y User-Agent;CHECK_PRIVATE_IP=norelaja el control de IP solo en rangos privados.ALWAYS_REMEMBER=yesfuerza cookies persistentes. - Almacenamiento de sesiones: las sesiones viven en Redis cuandoUSE_REDIS=yes, y si no en una caché local bajo/var/lib/bunkerweb. Un Redis que deja de responder, o que rechaza las escrituras porque alcanzómaxmemory, ya no rompe la interfaz: las sesiones afectadas pasan a esa caché local, que se lee antes que Redis para que un cambio o un borrado que nunca llegó a Redis no quede oculto tras la copia antigua que Redis aún conserva, y se reconcilian con Redis en cuanto responde de nuevo. Un cierre de sesión o una rotación del ID de sesión durante la caída tampoco se deshace con la recuperación. Cada revocación se registra en ambos almacenes para seguir aplicándose en cualquier caso. Un desalojo no está cubierto, porque Redis informa éxito y simplemente deja de tener la clave, así que dimensionamaxmemorypara las claves que conservas. Cuando Redis rechaza una actualización, esa sesión pasa al almacenamiento local y se elimina de inmediato la copia que Redis aún tenía, de modo que el cambio no quede oculto tras la versión anterior y un flujo de varios pasos como el 2FA no se quede en bucle sobre su estado previo. Esa caché local es por host, lo que importa si ejecutas varias réplicas de la interfaz: las demás réplicas dejan de ver una sesión que se ha movido a la caché local de una réplica hasta que esa réplica la reconcilia con Redis, una revocación emitida mientras Redis no estaba disponible solo la aplica la réplica que la emitió, y una réplica que ya sirve una sesión desde su propia caché local puede seguir haciéndolo hastaSESSION_LIFETIME_HOURSdespués de que otra réplica borre esa sesión a través de Redis.UI_USE_REDIS=nodesconecta solo la interfaz de Redis, a diferencia delUSE_REDISglobal, que además deja de compartir baneos e informes entre instancias. - AjustaPROXY_NUMBERSsi varios proxies añadenX-Forwarded-*.
La 2FA desaparece al recrear el contenedor
Los secretos TOTP se guardan cifrados en la base de datos, y las claves que los descifran viven en disco, no en la base. En cada arranque la UI toma la primera fuente disponible: /var/lib/bunkerweb/.totp_encryption_keys.json y luego TOTP_ENCRYPTION_KEYS (alias TOTP_SECRETS). Si ninguna es utilizable genera un juego aleatorio nuevo: los secretos almacenados ya no se pueden descifrar, la inscripción del admin se elimina de la base y cada usuario debe volver a inscribirse.
Reiniciar un contenedor no rompe nada. Lo que pierde las claves es perder el sistema de archivos del contenedor: docker compose down seguido de up, una recreación tras cambiar la imagen o el entorno, docker rm, o un pod nuevo. Basta con montar un volumen persistente en /data en el contenedor bw-ui, y todos los ejemplos de esta página lo hacen: las claves se generan en el primer arranque y se conservan en /data/lib, lo que deja TOTP_ENCRYPTION_KEYS como opcional.
Define la variable tú mismo solo si ese volumen no se puede persistir, o para controlar la rotación. Si lo haces, cuidado con la longitud: un marcador como changeme no es una clave válida — las claves tienen 43 caracteres, como las que produce generate_secret() de passlib. Un valor inválido se descarta y se sustituye por una clave aleatoria y, a diferencia de una variable sin definir, también impide que se reinicie la inscripción del admin, por lo que la 2FA queda inutilizable hasta borrarla manualmente. La rotación es posible con un mapa JSON: mantén las claves antiguas junto a la nueva y las inscripciones existentes siguen siendo válidas.
Contraseña de administrador pre-hasheada
ADMIN_PASSWORD acepta un hash bcrypt ($2a$/$2b$/$2y$) y lo almacena tal cual, manteniendo el texto plano fuera de tus archivos de entorno y secretos. Se omite la política de fortaleza (tú eres responsable de la contraseña de origen), pero se rechaza un factor de coste inferior a 10; 10–11 registra una advertencia (se recomienda 12+). Solo en creación por entorno y OVERRIDE_ADMIN_CREDS: el asistente y el perfil siguen requiriendo texto plano.
Genera un hash:
python3 -c "import bcrypt; print(bcrypt.hashpw(b'Str0ng&P@ss!', bcrypt.gensalt(rounds=13)).decode())"
Un hash incorrecto te bloquea
Usa un hash solo si conoces su texto plano. Un hash válido pero incorrecto en la primera creación no se puede revertir y un reinicio no lo arregla. Recupera con un ADMIN_PASSWORD distinto y OVERRIDE_ADMIN_CREDS=yes.
Fuentes de configuración y prioridad
- Variables de entorno (incl.
environment:de Docker/Compose) - Secrets en
/run/secrets/<VAR>(Docker) - Archivo env
/etc/bunkerweb/ui.env(paquetes Linux) - Valores por defecto integrados
Borradores en el editor RAW
El editor RAW de un servicio o de la configuración global puede conservar un ajuste como borrador: el valor se guarda pero no se aplica, y el valor efectivo sigue siendo el heredado (global) o el predeterminado. Coloque el cursor al inicio de una línea KEY=value y pulse # para alternar el estado de borrador, o Retroceso en una línea en borrador para activarla, y luego guarde. Las líneas en borrador se resaltan y conservan su valor entre guardados, de modo que un cambio puede prepararse y activarse más tarde con un solo guardado. Un ajuste que no es editable desde la UI (gestionado por autoconf, o un valor predeterminado de plugin que no puede sobrescribirse) no puede cambiar de estado de borrador.
Referencia de configuración
Tiempo de ejecución y zona horaria
| Ajuste | Descripción | Valores aceptados | Predeterminado |
|---|---|---|---|
TZ |
Zona horaria para logs de la UI y acciones programadas | Nombre TZ (ej. UTC, Europe/Madrid) |
sin definir (normalmente UTC en contenedor) |
Listener y TLS
| Ajuste | Descripción | Valores aceptados | Predeterminado |
|---|---|---|---|
UI_LISTEN_ADDR |
Dirección de escucha de la UI | IP o hostname | 0.0.0.0 (Docker) / 127.0.0.1 (paquete) |
UI_LISTEN_PORT |
Puerto de escucha de la UI | Entero | 7000 |
LISTEN_ADDR, LISTEN_PORT |
Alternativas si faltan vars de UI | IP/hostname, entero | 0.0.0.0, 7000 |
UI_SSL_ENABLED |
Habilitar TLS en el contenedor UI | yes o no |
no |
UI_SSL_CERTFILE, UI_SSL_KEYFILE |
Rutas de cert/clave PEM con TLS | Rutas de archivo | sin definir |
UI_SSL_CA_CERTS |
CA/cadena opcional | Ruta de archivo | sin definir |
UI_FORWARDED_ALLOW_IPS |
Proxies de confianza para X-Forwarded-* |
IPs/CIDRs separados por espacio/coma | 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 |
UI_PROXY_ALLOW_IPS |
Proxies de confianza para protocolo PROXY | IPs/CIDRs separados por espacio/coma | FORWARDED_ALLOW_IPS |
Auth, sesiones y cookies
| Ajuste | Descripción | Valores aceptados | Predeterminado |
|---|---|---|---|
ADMIN_USERNAME, ADMIN_PASSWORD |
Inicializar cuenta admin (política de contraseña; ADMIN_PASSWORD también acepta un hash bcrypt, almacenado tal cual) |
Cadenas / hash bcrypt | sin definir |
OVERRIDE_ADMIN_CREDS |
Forzar actualización de credenciales admin desde env | yes o no |
no |
FLASK_SECRET |
Secreto de firma de sesión (persistido en /var/lib/bunkerweb/.flask_secret) |
Cadena hex/base64/opaca | generado automáticamente |
TOTP_ENCRYPTION_KEYS (TOTP_SECRETS) |
Claves para cifrar TOTP (espacio o JSON) | Cadenas / JSON | generadas si faltan |
BISCUIT_PUBLIC_KEY, BISCUIT_PRIVATE_KEY |
Claves Biscuit (hex) para tokens de UI | Cadenas hex | autogeneradas y guardadas |
SESSION_LIFETIME_HOURS |
Duración de inactividad de sesión (TTL deslizante, refrescada por petición) | Número (horas) | 12 |
SESSION_ABSOLUTE_HOURS |
Límite absoluto de sesión independiente de la actividad | Número (horas) | 168 |
SESSION_ROLLING_HOURS |
Intervalo de rotación del ID de sesión (0 deshabilita la rotación) |
Número (horas) | 0 |
ALWAYS_REMEMBER |
Activar siempre “remember me” | yes o no |
no |
CHECK_PRIVATE_IP |
Ligar sesión a IP (relaja en redes privadas con no) |
yes o no |
yes |
PROXY_NUMBERS |
Saltos de proxy confiables para X-Forwarded-* |
Entero | 1 |
UI_USE_REDIS |
Desconecta la interfaz web de Redis sin tocar el USE_REDIS global |
yes o no |
yes |
Logging
| Ajuste | Descripción | Valores aceptados | Predeterminado |
|---|---|---|---|
LOG_LEVEL, CUSTOM_LOG_LEVEL |
Nivel base / override | debug, info, warning, error, critical |
info |
LOG_TYPES |
Destinos | stderr/file/syslog separados por espacio |
stderr |
LOG_FILE_PATH |
Ruta para logs a archivo (file o CAPTURE_OUTPUT=yes) |
Ruta de archivo | /var/log/bunkerweb/ui.log si file/capture |
CAPTURE_OUTPUT |
Enviar stdout/stderr de Gunicorn a handlers | yes o no |
no |
LOG_SYSLOG_ADDRESS |
Destino syslog (udp://host:514, tcp://host:514, socket) |
Host:puerto / URL / socket | sin definir |
LOG_SYSLOG_TAG |
Tag/ident syslog | Cadena | bw-ui |
Runtime misceláneo
| Ajuste | Descripción | Valores aceptados | Predeterminado |
|---|---|---|---|
MAX_WORKERS, MAX_THREADS |
Workers/hilos de Gunicorn | Entero | cpu_count()-1 (mín 1), workers*2 |
MAX_REQUESTS |
Solicitudes antes de reciclar el worker Gunicorn (previene exceso de memoria) | Entero | 1000 |
ENABLE_HEALTHCHECK |
Exponer GET /healthcheck |
yes o no |
no |
FORWARDED_ALLOW_IPS |
Alias para lista de proxies | IPs/CIDRs | 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 |
PROXY_ALLOW_IPS |
Alias para lista de PROXY | IPs/CIDRs | FORWARDED_ALLOW_IPS |
DISABLE_CONFIGURATION_TESTING |
Saltar reloads de prueba al aplicar config | yes o no |
no |
IGNORE_REGEX_CHECK |
Omitir validación regex de ajustes | yes o no |
no |
MAX_CONTENT_LENGTH |
Tamaño máximo de subida (Flask MAX_CONTENT_LENGTH) |
Tamaño con unidad (50M, 1G, 52428800) |
50MB |
Acceso a logs
La UI lee logs de NGINX/servicios desde /var/log/bunkerweb. Alimenta ese directorio con un demonio syslog o un volumen:
- El UID/GID del contenedor es 101. En el host hazlos legibles:
chown root:101 bw-logs && chmod 770 bw-logs(ajusta para rootless). - Envía access/error logs de BunkerWeb vía
ACCESS_LOG/ERROR_LOGal sidecar syslog; logs de componentes conLOG_TYPES=syslog.
Ejemplo de syslog-ng.conf para escribir logs por programa:
@version: 4.10
source s_net { udp(ip("0.0.0.0")); };
template t_imp { template("$MSG\n"); template_escape(no); };
destination d_dyna_file {
file("/var/log/bunkerweb/${PROGRAM}.log"
template(t_imp) owner("101") group("101")
dir_owner("root") dir_group("101")
perm(0440) dir_perm(0770) create_dirs(yes));
};
log { source(s_net); destination(d_dyna_file); };
Capacidades
- Panel para solicitudes, bloqueos, caché y jobs; reinicio/recarga de instancias.
- Crear/actualizar/eliminar servicios y ajustes globales con validación contra esquemas de plugins.
- Subir y gestionar configs personalizadas (NGINX/ModSecurity) y plugins (externos o PRO).
- Ver logs, buscar reportes e inspeccionar artefactos de caché.
- Gestionar usuarios de UI, roles, sesiones y TOTP con códigos de recuperación.
- Actualizar a BunkerWeb PRO y ver estado de licencia en la página dedicada.
Actualizar a PRO
Prueba gratis de BunkerWeb PRO
Inicia una prueba gratuita de 30 días de BunkerWeb PRO desde el Panel de BunkerWeb.
Pega tu clave PRO en la página PRO de la UI (o precarga PRO_LICENSE_KEY para el asistente). Las actualizaciones se descargan en segundo plano por el scheduler; revisa en la UI la caducidad y los límites de servicios tras aplicarlas.
Traducciones (i18n)
La interfaz web está disponible en varios idiomas gracias a las contribuciones de la comunidad. Las traducciones se almacenan en archivos JSON por idioma (por ejemplo en.json, fr.json, …). Para cada idioma se documenta claramente si la traducción fue realizada de forma manual o generada mediante IA, así como su estado de revisión.
Idiomas disponibles y colaboradores
| Idioma | Locale | Creado por | Revisado por |
|---|---|---|---|
| Árabe | ar |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Bengalí | bn |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Bretón | br |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Alemán | de |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Inglés | en |
Manual (@TheophileDiot) | Manual (@TheophileDiot) |
| Español | es |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Francés | fr |
Manual (@TheophileDiot) | Manual (@TheophileDiot) |
| Hindi | hi |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Italiano | it |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Coreano | ko |
Manual (@rayshoo) | Manual (@rayshoo) |
| Polaco | pl |
Manual (@tomkolp) vía Weblate | Manual (@tomkolp) |
| Portugués | pt |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Ruso | ru |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Turco | tr |
Manual (@wiseweb-works) | Manual (@wiseweb-works) |
| Chino (Tradicional) | tw |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Urdu | ur |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
| Chino (Simplificado) | zh |
IA (Google:Gemini-2.5-pro) | IA (Google:Gemini-3-pro) |
💡 Algunas traducciones pueden ser parciales. Se recomienda encarecidamente una revisión manual, especialmente para los elementos críticos de la interfaz.
Cómo contribuir
Las contribuciones de traducción siguen el flujo estándar de contribuciones de BunkerWeb:
- Crear o actualizar el archivo de traducción
- Copia
src/ui/app/static/locales/en.jsony renómbralo con el código de tu idioma (por ejemplode.json). -
Traduce solo los valores; las claves no deben modificarse.
-
Registrar el idioma
-
Añade o actualiza la entrada del idioma en
src/ui/app/lang_config.py(código del locale, nombre visible, bandera, nombre en inglés). Este archivo es la fuente única de verdad para los idiomas compatibles. -
Actualizar la documentación y la procedencia
src/ui/app/static/locales/README.md→ añade el nuevo idioma a la tabla de procedencia (creado por / revisado por).README.md→ actualiza la documentación general del proyecto para reflejar el nuevo idioma compatible.docs/web-ui.md→ actualiza la documentación de la interfaz web (esta sección de Traducciones).-
docs/*/web-ui.md→ actualiza las versiones traducidas de la documentación de la interfaz web con la misma sección de Traducciones. -
Abrir un pull request
- Indica claramente si la traducción se realizó de forma manual o con una herramienta de IA.
- Para cambios importantes (nuevo idioma o actualizaciones grandes), se recomienda abrir primero un issue para su discusión.
Al contribuir con traducciones, ayudas a que BunkerWeb sea accesible para una audiencia internacional más amplia.