Перейти к содержанию

Развёртывание на Ubuntu с доменом (БД на сервере)

Пошаговая инструкция: приложение в Docker, PostgreSQL уже установлен на этом же сервере, домен library.codnix.ru.


Минимальный деплой (максимум 3 шага)

Порты 9080 и 3001 наружу не открываются — приложение слушает только на 127.0.0.1:9080, доступ снаружи через Nginx на хосте (80/443). UFW менять не нужно.

  1. Клонировать проект и перейти в каталог

    sudo mkdir -p /opt && cd /opt
    sudo git clone <URL-репозитория> library_system
    cd library_system
    

  2. Создать в корне проекта файл .env с подключением к БД (БД уже есть, миграции не запускаются). Пример:

    DATABASE_URL=postgresql://library_user:ПАРОЛЬ@host.docker.internal:5432/library_utf8
    JWT_SECRET=...   # openssl rand -hex 32
    CSRF_SECRET=...  # openssl rand -hex 32
    VITE_API_URL=/api
    
    Пароль в URL кодируйте: @%40, #%23. Или запустите bash scripts/deploy.sh — скрипт создаст .env и подставит секреты; впишите свой DATABASE_URL.

  3. Запустить авторазвёртывание

    bash scripts/deploy.sh
    
    Скрипт поднимет контейнеры. Миграции по умолчанию не выполняются (БД уже готова). При необходимости: docker compose exec backend node migrations/migration-runner.js или RUN_MIGRATIONS=1 bash scripts/deploy.sh.

  4. HTTPS по домену — nginx и certbot уже есть. Один раз настроить виртуальный хост для library.codnix.ru:

    sudo bash scripts/setup-nginx-ssl.sh
    
    Скрипт получит сертификат (если ещё нет) и создаст конфиг Nginx с проксированием на 127.0.0.1:9080. Откройте: https://library.codnix.ru


1. Подготовка сервера (подробно)

1.1 Docker и Docker Compose

sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/osrelease && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER

Выйдите из SSH и зайдите снова (или выполните newgrp docker), чтобы группа docker применилась.

1.2 DNS и порты

  • В панели DNS добавьте A-запись: library.codnix.ru → IP вашего Ubuntu-сервера.
  • Откройте порты 80 и 443 (если используется фаервол):
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

2. Клонирование проекта

sudo mkdir -p /opt
cd /opt
sudo git clone <URL-вашего-репозитория> library_system
cd library_system

Если репозиторий приватный — настройте SSH-ключ или токен для git clone.


3. База данных на сервере

Убедитесь, что PostgreSQL запущен и доступен локально:

sudo systemctl status postgresql

Создайте БД и пользователя (если ещё не созданы):

sudo -u postgres psql -c "CREATE USER library_user WITH PASSWORD 'ваш_надёжный_пароль';"
sudo -u postgres psql -c "CREATE DATABASE library OWNER library_user;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE library TO library_user;"

Чтобы контейнер мог подключаться к PostgreSQL на хосте, сервер БД должен принимать подключения с Docker-сети. Проверьте:

  • В postgresql.conf: listen_addresses = 'localhost' или '*'.
  • В pg_hba.conf добавьте строку (подсеть Docker по умолчанию):
    host library library_user 172.17.0.0/16 scram-sha-256
    затем перезапустите PostgreSQL: sudo systemctl restart postgresql.

Пароль и имя БД/пользователя подставьте в шаг 4 в DATABASE_URL.


4. Файл окружения .env

В корне проекта (рядом с docker-compose.yml) создайте .env:

nano .env

Минимальный набор (подставьте свои значения):

# Подключение к PostgreSQL на этом же сервере (из контейнера — через host.docker.internal)
DATABASE_URL=postgresql://library_user:ваш_надёжный_пароль@host.docker.internal:5432/library

# Секреты (сгенерируйте: openssl rand -hex 32)
JWT_SECRET=ваш_jwt_секрет_минимум_32_символа_hex
CSRF_SECRET=ваш_csrf_секрет_минимум_32_символа_hex

# Фронт будет ходить на /api того же домена
VITE_API_URL=/api

Если PostgreSQL слушает только 127.0.0.1, проверьте в postgresql.conf, что есть строка listen_addresses = 'localhost' (или * при необходимости). С хоста подключаться будете как host.docker.internal:5432, что из контейнера указывает на этот же сервер.

Опционально (LDAP, Redis и т.д.) можно добавить позже по образцу server/env.example.


5. Первый запуск (HTTP, без SSL)

Запуск без профиля db (БД уже на хосте):

cd /opt/library_system
docker compose up -d --build

Первый запуск может занять несколько минут (сборка образов). Проверка:

docker compose ps
curl -s http://127.0.0.1:9080/health
curl -s http://127.0.0.1:9080/api/health

Миграции БД:

docker compose exec backend node migrations/migration-runner.js

Проверка в браузере по IP: http://IP-СЕРВЕРА:9080. Если всё ок — переходим к домену и HTTPS.


6. Домен library.codnix.ru и HTTPS

6.1 Внешний Nginx на хосте (рекомендуется)

Так порт 80/443 занимает один Nginx на сервере, он отдаёт сертификаты и проксирует на контейнер.

Установите Nginx и Certbot:

sudo apt install -y nginx certbot python3-certbot-nginx

Временно остановите контейнерный Nginx, чтобы порт 80 был свободен для выдачи сертификата:

cd /opt/library_system
docker compose stop nginx

Получите сертификат (замените email на свой):

sudo certbot certonly --standalone -d library.codnix.ru --email admin@codnix.ru --agree-tos --non-interactive

Создайте конфиг виртуального хоста для библиотеки:

sudo nano /etc/nginx/sites-available/library.codnix.ru

Содержимое:

server {
    listen 80;
    listen [::]:80;
    server_name library.codnix.ru www.library.codnix.ru;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name library.codnix.ru www.library.codnix.ru;

    ssl_certificate /etc/letsencrypt/live/library.codnix.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/library.codnix.ru/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    client_max_body_size 10M;
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    location / {
        proxy_pass http://127.0.0.1:9080;
        proxy_http_version 1.1;
        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;
        proxy_cache_bypass $http_upgrade;
    }
}

Включите сайт и перезагрузите Nginx:

sudo ln -sf /etc/nginx/sites-available/library.codnix.ru /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Снова запустите контейнерный Nginx (он слушает только 9080 на localhost):

cd /opt/library_system
docker compose start nginx

Проверка: в браузере откройте https://library.codnix.ru. Запросы идут так: браузер → Nginx (хост, 443) → 127.0.0.1:9080 (контейнеры frontend/backend).

6.2 Вариант без внешнего Nginx (SSL в контейнере)

Если не хотите ставить Nginx на хост:

  1. Остановите контейнеры: docker compose down.
  2. Получите сертификат certbot (как выше), затем снова запустите контейнеры.
  3. Запуск с SSL в контейнере: docker compose -f docker-compose.yml -f docker-compose.ssl.yml up -d (конфиг nginx.prod.conf, том /etc/letsencrypt — см. docker-compose.ssl.yml).

При этом порты 80 и 443 должны быть свободны на сервере (не заняты системным Nginx).


7. Обновление сертификата (cron)

При использовании Certbot на хосте:

sudo crontab -e

Добавьте строку (путь к проекту при необходимости измените):

0 3 * * * certbot renew -q && systemctl reload nginx

8. Полезные команды

Действие Команда
Логи backend docker compose logs -f backend
Перезапуск docker compose restart
Остановить всё docker compose down
Запустить с пересборкой docker compose up -d --build
Миграции docker compose exec backend node migrations/migration-runner.js

9. Первый вход и админ

После миграций создайте первого администратора (если в проекте есть скрипт или эндпоинт первичной настройки), например:

docker compose exec backend node scripts/setup-admin.js

Либо через API/интерфейс — см. README проекта.


Краткая последовательность

  1. Установить Docker и Docker Compose.
  2. DNS: A-запись library.codnix.ru → IP сервера.
  3. Создать БД и пользователя в PostgreSQL на сервере.
  4. Клонировать проект в /opt/library_system.
  5. Создать .env с DATABASE_URL=...@host.docker.internal:5432/library, JWT_SECRET, CSRF_SECRET, VITE_API_URL=/api.
  6. Запустить: docker compose up -d --build.
  7. Выполнить миграции.
  8. Получить сертификат Certbot, настроить Nginx на хосте на 80/443 с проксированием на 127.0.0.1:9080.
  9. Открыть https://library.codnix.ru и создать админа при необходимости.