MAATRIX / Блог / File Browser в Docker Compose: готовый файл

File Browser в Docker Compose: готовый файл

MAATRIX

Нужен веб-интерфейс для файлов на сервере — быстро, без изучения документации с нуля. File Browser отлично для этого подходит: один контейнер, один YAML-файл, и через пару минут в браузере открывается загрузка, редактор и шаринг ссылками. Ниже — рабочий docker-compose.yml с разбором каждой строки, варианты публикации через Traefik и Nginx, и грабли, на которые чаще всего наступают именно в связке с Compose (а не с самим File Browser).

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Готовый docker-compose.yml

Вот минимальный рабочий стек — скопируйте, поправьте пути и пароли под себя:

# docker-compose.yml
services:
  filebrowser:
    image: filebrowser/filebrowser:s6
    container_name: filebrowser
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ./srv:/srv
      - ./database/filebrowser.db:/database/filebrowser.db
      - ./config/settings.json:/config/settings.json
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Moscow
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost/health"]
      interval: 30s
      timeout: 5s
      retries: 3

Перед первым запуском создайте пустые файлы для монтирования — иначе Docker на их месте создаст директории, и контейнер откажется стартовать:

mkdir -p srv database config
touch database/filebrowser.db config/settings.json
docker compose up -d

Порт публикуется только на 127.0.0.1 — File Browser хранит пароли и раздаёт файлы, поэтому наружу без TLS его выставлять не стоит. Как добавить HTTPS через Traefik или Nginx — в разделе про публикацию ниже. Если нужен более развёрнутый разбор самой установки (не только compose-файл, а весь процесс от нуля), у нас есть отдельная статья как установить и настроить File Browser на VPS — здесь фокус именно на конфигурации compose-стека.

Что означает каждая настройка

Разберём файл построчно, потому что половина проблем с File Browser в Docker — это непонимание, что делает конкретная строка.

  • image: filebrowser/filebrowser:s6 — тег s6 собран на базе s6-overlay и умеет переключать пользователя внутри контейнера по PUID/PGID. Без него (тег :latest) процесс работает от root, и файлы, созданные через веб-интерфейс, будут принадлежать root на хосте — неудобно, если с этими файлами потом работают другие процессы под обычным пользователем.
  • ./srv:/srv — папка, которую File Browser показывает в интерфейсе. Можно смонтировать вместо неё любую другую директорию хоста, например /home/user/shared:/srv, если файлы уже лежат в конкретном месте.
  • filebrowser.db — SQLite-база с пользователями, правами и настройками. Именно её теряют чаще всего, поэтому бэкапу посвящён отдельный раздел ниже.
  • settings.json — файл конфигурации приложения (порт, база, ветка авторизации через прокси-заголовки и т.д.). Пустой файл при первом запуске — это нормально, File Browser заполнит его дефолтными значениями.
  • PUID / PGID — узнать актуальные значения для текущего пользователя хоста можно командой id -u и id -g. Если владелец файлов в srv после загрузки через веб-интерфейс не совпадает с ожидаемым — проверьте ls -la srv, почти всегда причина именно в неверном PUID/PGID.
  • healthcheck — не обязателен, но полезен, если вы используете docker compose ps для мониторинга или связку с Watchtower/Portainer, которые ориентируются на статус healthy/unhealthy контейнера.

Учтите: image: filebrowser/filebrowser:s6 без версии подтянет актуальный s6-тег при docker compose pull. Для продакшена лучше зафиксировать конкретную версию (например, filebrowser/filebrowser:v2.31.2-s6) — так апдейт не прилетит незаметно между pull и up -d, а будет осознанным действием.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Публикация с HTTPS: Traefik и Nginx

Прямой доступ к File Browser по HTTP — плохая идея: логин и пароль администратора уйдут открытым текстом при первом же входе. Два рабочих варианта в связке с Compose.

Traefik — если у вас уже поднят Traefik как reverse proxy для остальных контейнеров, добавление File Browser сводится к лейблам прямо в сервисе:

services:
  filebrowser:
    image: filebrowser/filebrowser:s6
    container_name: filebrowser
    restart: unless-stopped
    volumes:
      - ./srv:/srv
      - ./database/filebrowser.db:/database/filebrowser.db
      - ./config/settings.json:/config/settings.json
    environment:
      - PUID=1000
      - PGID=1000
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.filebrowser.rule=Host(`files.example.com`)"
      - "traefik.http.routers.filebrowser.entrypoints=websecure"
      - "traefik.http.routers.filebrowser.tls.certresolver=letsencrypt"
      - "traefik.http.services.filebrowser.loadbalancer.server.port=80"

networks:
  proxy:
    external: true

Здесь секция ports в сервисе не нужна вовсе — Traefik обращается к контейнеру напрямую через внутреннюю docker-сеть proxy. Если Traefik ещё не настроен, порядок разворачивания и объяснение лейблов — в статье Traefik как reverse proxy для Docker; там же разбирается, чем этот подход отличается от Nginx Proxy Manager, если выбираете между ними — сравнение есть в статье Traefik или Nginx Proxy Manager — что выбрать для сервера.

Nginx — если прокси уже Nginx, публикуем контейнер на 127.0.0.1:8080 (как в базовом compose-файле выше) и добавляем виртуальный хост:

server {
    listen 80;
    server_name files.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;

        client_max_body_size 4G;
        proxy_read_timeout 600s;
    }
}

client_max_body_size важно увеличить сразу — с дефолтным лимитом Nginx в 1 МБ любая загрузка файла крупнее упадёт с ошибкой 413, и разбираться с этим постфактум неприятнее, чем прописать заранее. Дальше — стандартно: ln -s в sites-enabled, nginx -t, certbot --nginx -d files.example.com.

Права доступа: PUID, PGID и общие тома

Специфика именно Compose-развёртывания в том, что права на файлы регулируются на стыке трёх мест: владельца директории на хосте, PUID/PGID в окружении контейнера и того, что видит сам File Browser внутри. Рассинхрон между ними — самая частая причина «файл загрузился, но я не могу его открыть через SFTP другим пользователем».

Проверка перед первым продакшн-запуском:

id -u
id -g
ls -la /opt/filebrowser

Если директория srv создана от root (например, вы делали mkdir через sudo), а PUID=1000 указывает на обычного пользователя — контейнер может не иметь прав на запись. Правьте владельца заранее, а не после первого failed upload:

sudo chown -R 1000:1000 /opt/filebrowser/srv

Если File Browser должен видеть несколько независимых директорий с разными правами для разных клиентов — не пытайтесь городить это через один общий /srv и права внутри приложения. Практичнее смонтировать нужные поддиректории отдельными volume-строками и развести пользователей File Browser по Scope в веб-интерфейсе (Settings → Users → Scope), это надёжнее, чем полагаться только на файловые права Linux внутри контейнера.

Резервное копирование тома в Compose-стеке

В Compose-развёртывании бэкапить нужно не образ (он воспроизводится из docker-compose.yml за секунды), а состояние — том с базой filebrowser.db и, отдельно, содержимое srv, если оно не бэкапится другим способом.

#!/bin/bash
set -e
DEST=/opt/backups/filebrowser
DATE=$(date +%Y-%m-%d)
STACK=/opt/filebrowser

mkdir -p "$DEST"
docker compose -f "$STACK/docker-compose.yml" stop filebrowser
tar -czf "$DEST/filebrowser-state-$DATE.tar.gz" -C "$STACK" database config
docker compose -f "$STACK/docker-compose.yml" start filebrowser

find "$DEST" -name "filebrowser-state-*.tar.gz" -mtime +14 -delete

Останавливать контейнер перед копированием SQLite-базы — не перестраховка: если снять снимок файла во время активной записи, можно получить повреждённую базу, которая откажется открываться при восстановлении. Секундный простой сервиса раз в сутки почти всегда допустим, но если это критично — переносите бэкап на ночное окно с наименьшей нагрузкой.

Сами файлы из srv, если их объём заметный, разумнее бэкапить инкрементально, а не гонять весь архив каждый раз — например, через BorgBackup, который делает дедупликацию и не пересылает по сети уже сохранённые блоки. Добавьте скрипт в cron:

crontab -e
# 0 3 * * * /opt/filebrowser/backup.sh >> /var/log/filebrowser-backup.log 2>&1

Частые ошибки при запуске

Контейнер не стартует, docker compose up -d молча завершается. Почти всегда причина в том, что filebrowser.db или settings.json смонтированы как директории вместо файлов — Docker создаёт их автоматически, если файл не существует на хосте до up. Проверьте: file database/filebrowser.db должен показать SQLite, а не directory. Если попали в эту ситуацию — удалите созданные каталоги и пересоздайте пустыми файлами через touch перед новым запуском.

Пароль администратора неизвестен. Сгенерированный пароль печатается в лог контейнера только при самом первом старте. Если момент упущен, проще сбросить пароль напрямую:

docker compose exec filebrowser filebrowser users update admin --password 'НовыйПароль123!'

После docker compose pull контейнер перестал запускаться. Обычно это следствие незафиксированной версии образа — новая мажорная версия s6-тега может менять формат settings.json или схему базы. Правило простое: перед pull на проде — бэкап database и config (см. раздел выше), а версию образа держите зафиксированной явно, а не на плавающем теге.

Healthcheck постоянно unhealthy, хотя интерфейс открывается в браузере. Проверьте, что путь /health в тесте совпадает с тем, что реально отдаёт версия образа — в части релизов endpoint здоровья менялся. Временно замените test на простой wget --spider http://localhost/ — этого достаточно, чтобы убедиться, что процесс жив, не завязываясь на конкретный API-путь.

Файлы, загруженные через интерфейс, не видны в SFTP-клиенте под другим пользователем. Это про PUID/PGID из раздела выше — если правильно выставить владельца при создании директории и совпадающие ID в compose-файле, проблема исчезает сама.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Обязателен ли тег :s6 у образа?

Нет, но без него контейнер работает от root и PUID/PGID не действуют — для многопользовательского сервера с монтированием чужих директорий это неудобно и потенциально небезопасно.

Можно ли обойтись без Traefik и Nginx, просто открыть порт наружу?

Технически да, но без HTTPS логин и пароль администратора при первом входе уйдут в открытом виде — для продакшена так делать не стоит даже временно.

Что будет, если удалить том с filebrowser.db?

Все пользователи, права и настройки Scope будут потеряны, придётся настраивать заново. Сами файлы в srv при этом не пострадают — они лежат в отдельном томе.

Как обновить File Browser без даунтайма?

Строго без даунтайма — не получится: docker compose pull && docker compose up -d пересоздаёт контейнер, и на несколько секунд сервис недоступен. Для одного инстанса это обычно некритично, для высокой доступности нужен уже другой уровень архитектуры (несколько реплик за балансировщиком), что для File Browser избыточно.

Нужен ли Redis или отдельная база данных, как у Nextcloud?

Нет, File Browser самодостаточен — вся конфигурация в одном SQLite-файле, никаких дополнительных сервисов в compose-стеке не требуется.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →