Ваш обычный компьютер
- Подходит для
- Коротко попробовать Cotton перед выбором постоянного места.
- Главный плюс
- Не нужно покупать железо или арендовать VPS.
- Что будет сложнее
- Cotton выключится вместе с компьютером или при переходе в сон.
Разберитесь, чем домашний сервер, NAS и VPS отличаются, зачем нужны Docker и reverse proxy, а затем пройдите один полный сценарий на Ubuntu VPS с постоянной базой PostgreSQL и автоматическим HTTPS.
Эта инструкция не предполагает, что вы уже администрировали сервер. Сначала разберём все термины и связи, затем пройдём один конкретный путь: VPS с Ubuntu 24.04, Docker Compose и автоматический HTTPS через Caddy.
Это необязательно стойка в дата-центре. Cotton может жить на компьютере дома или на арендованной виртуальной машине. Важно, где физически лежат файлы, как компьютер выходит в интернет и кто отвечает за его работу.
Браузер не подключается напрямую к базе или папке с файлами. DNS находит сервер, Caddy принимает защищённое соединение, а Cotton решает, какие данные прочитать или записать.
При обновлении Docker обычно заменяет контейнер. Это безопасно только потому, что настоящее состояние хранится за пределами заменяемых контейнеров.
Без Docker пришлось бы вручную ставить правильную версию .NET, инструменты PostgreSQL, программы для превью, пользователей, права и обновления. Docker упаковывает приложение, а Compose записывает, как все сервисы запускаются вместе.
Готовая упаковка приложения. В bvdcode/cotton уже есть Cotton и необходимые ему системные инструменты.
Запущенный экземпляр образа. Его можно остановить или заменить, но он не должен быть единственным местом хранения данных.
Один YAML-файл, который поднимает PostgreSQL, Cotton и Caddy в общей приватной сети.
Хранилище вне заменяемого контейнера. Там постоянно живут база, чанки файлов и сертификаты.
Cotton слушает порт 8080 внутри Docker. Reverse proxy занимает публичные порты 80 и 443, получает TLS-сертификат и передаёт каждый HTTPS-запрос в Cotton. То, что часто называют SSL, сегодня работает как TLS; HTTPS — это обычный веб-трафик, защищённый TLS. Пользователь видит только обычный адрес https://.
Самый короткий первый запуск: один домен в Caddyfile, после чего сертификат получается и продлевается автоматически.
Удобен, когда один Docker-хост уже раздаёт много сервисов через labels и общие middleware. Для первого Cotton добавляет лишние понятия.
Команды ниже рассчитаны на Ubuntu Server 24.04 LTS на VPS. Это не единственный правильный способ, но это понятная база, которую новичок может воспроизвести.
Чистый сервер и пользователь с правом запускать sudo. Размер диска выбирайте с учётом объёма будущих файлов.
Например, cloud.example.com. До запуска Caddy вы направите его на IP-адрес сервера.
Провайдер выдаёт IP сервера и пароль или SSH-ключ. SSH — это удалённый терминал для выполнения команд ниже.
22 нужен для управления по SSH, 80 и 443 — для сертификата и сайта. Порт PostgreSQL 5432 открывать в интернет не надо.
Сначала создайте VPS. Затем откройте управление DNS там, где обслуживается ваш домен. Команды в терминале не могут выполнить эти два действия, зависящие от ваших аккаунтов.
Выберите Ubuntu 24.04 LTS, добавьте SSH-ключ или получите временный пароль и скопируйте публичный IPv4. Регион и размер диска должны подходить вашим пользователям и объёму файлов.
Создайте A-запись, например cloud.example.com, со значением публичного IPv4 сервера. Обновление DNS может занять время. Пока имя не ведёт на этот VPS, Caddy не сможет получить HTTPS-сертификат.
Откройте Terminal в macOS/Linux или Windows Terminal в Windows и выполните ssh <пользователь>@<ip-сервера>. Подтверждайте fingerprint только если IP совпадает с только что созданным сервером.
В терминале появилась строка ввода удалённого Ubuntu-сервера. Начиная отсюда все команды выполняются на нём, а не на вашем личном компьютере.
PostgreSQL хранит базу в именованном volume postgres_data. Cotton хранит зашифрованные чанки и sentinel ключа в /data/cotton. Только Caddy доступен из интернета, а его сертификаты лежат в постоянных volumes.
name: cotton
services:
postgres:
image: postgres:18
restart: unless-stopped
environment:
POSTGRES_DB: cotton
POSTGRES_USER: cotton
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
volumes:
- postgres_data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U cotton -d cotton"]
interval: 5s
timeout: 5s
retries: 20
cotton:
image: bvdcode/cotton:latest
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
expose:
- "8080"
volumes:
- /data/cotton:/app/files
environment:
COTTON_PG_HOST: postgres
COTTON_PG_PORT: "5432"
COTTON_PG_DATABASE: cotton
COTTON_PG_USERNAME: cotton
COTTON_PG_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
security_opt:
- no-new-privileges:true
caddy:
image: caddy:2
restart: unless-stopped
depends_on:
- cotton
ports:
- "80:80"
- "443:443"
- "443:443/udp"
environment:
COTTON_DOMAIN: ${COTTON_DOMAIN:?Set COTTON_DOMAIN in .env}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
volumes:
postgres_data:
caddy_data:
caddy_config:Caddy читает домен из .env, получает доверенный TLS-сертификат, автоматически продлевает его и передаёт трафик контейнеру Cotton в приватной сети Docker.
{$COTTON_DOMAIN} {
reverse_proxy cotton:8080
}Команда подготовки сама генерирует пароль базы прямо в защищённый файл. Вы меняете только пример домена. В рекомендуемом режиме мастер-ключ Cotton намеренно не хранится в .env.
POSTGRES_PASSWORD=<создаётся автоматически> COTTON_DOMAIN=cloud.example.com
Эти команды ставят Docker Engine и Compose из репозиториев Ubuntu, запускают Docker сейчас и включают его после перезагрузки.
sudo apt update sudo apt install -y docker.io docker-compose-v2 curl nano openssl ufw sudo systemctl enable --now docker sudo docker --version sudo docker compose version
Команды создают /opt/cotton для конфигурации и /data/cotton для файлов, скачивают два показанных выше файла, записывают случайный пароль базы прямо в .env и открывают домен для редактирования.
sudo install -d -m 0750 /opt/cotton /data/cotton cd /opt/cotton sudo curl -fsSLo compose.yml https://cottoncloud.dev/install/docker-compose.yml sudo curl -fsSLo Caddyfile https://cottoncloud.dev/install/Caddyfile DB_PASSWORD="$(openssl rand -hex 24)" printf 'POSTGRES_PASSWORD=%s\nCOTTON_DOMAIN=cloud.example.com\n' "$DB_PASSWORD" | sudo tee .env >/dev/null sudo chmod 600 .env sudo nano .env
Сначала оставляем разрешённым SSH, чтобы не отрезать себе доступ. Если у VPS-провайдера есть отдельный облачный firewall, там тоже разрешите TCP 80 и 443.
sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw --force enable
Compose сначала проверяет файл, затем скачивает образы, запускает три сервиса и показывает их состояние.
cd /opt/cotton sudo docker compose config --quiet sudo docker compose pull sudo docker compose up -d sudo docker compose ps
Новый Cotton запускается заблокированным, потому что мастер-ключ намеренно не хранится в Docker. В логе сервера появляется короткоживущий токен для первой разблокировки.
sudo docker compose logs cotton | grep -i "bootstrap token"
Откройте https://cloud.example.com/unlock со своим настоящим доменом. Страница разблокировки появляется раньше обычного приложения, потому что без мастер-ключа Cotton не может читать зашифрованное состояние.
Нажмите «Сгенерировать», скопируйте 32-символьный ключ в менеджер паролей или офлайн-запись, введите bootstrap-токен и разблокируйте Cotton. Потеря ключа может сделать зашифрованные данные невосстановимыми.
После запуска форма входа сообщит, что пользователей пока нет. Указанные email и пароль создадут первого администратора. Используйте уникальный пароль.
Для этого базового сценария выберите локальное хранилище файлов. Ответьте на вопросы об использовании, приватности, email и часовом поясе: интерфейс объясняет варианты, а большинство решений можно изменить позже.
В качестве public base URL укажите тот же https:// домен, который будут открывать пользователи. От него зависят ссылки, passkeys, восстановление пароля и OIDC callback.
В настройке trusted proxy запустите проверку наблюдаемого proxy и сохраните предложенную границу Docker bridge. Не разрешайте подмену заголовков с любого адреса в интернете.
Открывшаяся логин-страница — ещё не финиш.
Включите passkeys или TOTP для администратора до того, как инстанс станет доступен извне.
Админ-проверка подсветит публичную регистрацию, отсутствие 2FA, writable rootfs, проброс Docker socket и не только.
Перезапустите стек, снова разблокируйте Cotton и убедитесь, что администратор и тестовый файл остались на месте, прежде чем загружать важные данные.
Проверьте, как вы тянете новый образ и перезапускаетесь без потери базы и хранилища чанков.
Установке можно доверять, только если вы умеете её обновить и вынести данные для восстановления за пределы сервера. Копия на том же VPS не защищает от потери этого VPS.
Сначала прочитайте примечания к релизу Cotton. Команды скачивают актуальные образы и пересоздают сервисы, сохраняя именованные volumes и /data/cotton.
cd /opt/cotton sudo docker compose pull sudo docker compose up -d sudo docker compose ps
Команда пишет датированный дамп базы в /var/backups/cotton. Скопируйте этот дамп, /data/cotton, мастер-ключ и /opt/cotton в отдельное хранилище как единый комплект восстановления.
sudo install -d -m 0700 /var/backups/cotton sudo sh -c 'docker compose -f /opt/cotton/compose.yml exec -T postgres pg_dump -U cotton -d cotton -Fc > /var/backups/cotton/postgres-$(date +%F).dump'
Не удаляйте volumes и не создавайте новый мастер-ключ ради исчезновения ошибки. Начинайте с первого неработающего звена на схеме выше.
Проверьте, что A-запись содержит публичный IPv4 вашего VPS. Пока DNS не обновился, Caddy не сможет получить публичный сертификат.
Сначала проверьте firewall провайдера, затем sudo ufw status и sudo docker compose ps. Порты 80 и 443 должны доходить до Caddy.
Cotton ещё не готов. Откройте sudo docker compose logs --tail=200 cotton и исправьте первую ошибку запуска — часто это пароль базы или права на хранилище.
Это ожидаемо в рекомендуемом режиме разблокировки через браузер. Используйте тот же сохранённый мастер-ключ. Никогда не создавайте новый ключ для существующих зашифрованных данных.
Не нужно быть Docker-специалистом, но надо понимать три вещи: контейнер запускает приложение, volumes и папки хранят данные после перезапуска, а удаление не того volume может удалить настоящую базу или файлы.
Да. Домашний сервер, mini PC или NAS-подобная машина подходят, если они постоянно работают, имеют достаточно диска и входят в нормальную схему бэкапов. Для доступа из интернета всё равно нужны HTTPS и reverse proxy.
Для локального теста не обязательно. Для публичного инстанса домен и HTTPS нужны, чтобы у браузера, мобильного приложения и десктопных клиентов был один стабильный безопасный адрес.
PostgreSQL — это база данных. Cotton хранит там пользователей, дерево папок, записи о файлах, шары, настройки и служебное состояние. Сами большие байты файлов хранятся отдельно как чанки.
Cotton хранит содержимое файлов как чанки в выбранном backend: в постоянной папке на сервере или в S3-совместимом хранилище. Поэтому важно бэкапить и базу, и хранилище чанков.
Оба работают как reverse proxy: завершают HTTPS и передают запросы Cotton. Caddy проще для первой установки. Traefik удобен, если существующий Docker-хост уже маршрутизирует много сервисов через labels и общие middleware.
Да. Здесь есть один воспроизводимый путь для VPS с Ubuntu 24.04, скачиваемые Compose- и Caddy-файлы, настройка DNS и firewall, первый запуск в браузере, обновление, команда бэкапа PostgreSQL и диагностика частых проблем.