feat: Caddy reverse proxy, SSL и инструкция для Ubuntu
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -40,20 +40,27 @@ cp .env.example .env
|
||||
# Сгенерируйте секрет сессии:
|
||||
sed -i "s/change-me-to-a-long-random-string/$(openssl rand -hex 32)/" .env
|
||||
|
||||
# 5. Установка и первый запуск
|
||||
# 5. Установка приложения
|
||||
npm install --omit=dev
|
||||
|
||||
# 6. Caddy (HTTPS + прокси) — см. раздел ниже; для проверки без домена:
|
||||
npm start
|
||||
```
|
||||
|
||||
Сайт будет доступен на **http://IP_СЕРВЕРА:3000**.
|
||||
Без Caddy сайт на **http://IP:3000**. С Caddy и доменом — **https://ваш-домен**.
|
||||
|
||||
Порт можно изменить в `.env`:
|
||||
В `.env` для production задайте (уже есть в `.env.example`):
|
||||
|
||||
```env
|
||||
PORT=3000
|
||||
HOST=127.0.0.1
|
||||
NODE_ENV=production
|
||||
TRUST_PROXY=1
|
||||
SESSION_SECRET=ваш-длинный-секрет
|
||||
```
|
||||
|
||||
`HOST=127.0.0.1` — Node слушает только localhost; снаружи доступ через Caddy.
|
||||
|
||||
При первом запуске создаются `data/shop.db`, `data/sessions.db` и демо-товары.
|
||||
|
||||
---
|
||||
@@ -72,7 +79,7 @@ After=network.target
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/opt/shop
|
||||
Environment=NODE_ENV=production
|
||||
EnvironmentFile=/opt/shop/.env
|
||||
ExecStart=/usr/bin/node src/server.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
@@ -94,32 +101,87 @@ systemctl status shop
|
||||
|
||||
---
|
||||
|
||||
## Nginx (опционально, порт 80/443)
|
||||
## Caddy — SSL и reverse proxy (рекомендуется)
|
||||
|
||||
[Caddy](https://caddyserver.com/) автоматически выпускает и продлевает сертификаты Let's Encrypt.
|
||||
|
||||
**Перед установкой:**
|
||||
|
||||
1. Домен указывает на IP сервера (A-запись).
|
||||
2. Открыты порты **80** и **443** в файрволе.
|
||||
3. Служба `shop` запущена и слушает `127.0.0.1:3000`.
|
||||
|
||||
### Установка Caddy на Ubuntu
|
||||
|
||||
```bash
|
||||
apt install -y nginx
|
||||
|
||||
cat > /etc/nginx/sites-available/shop << 'EOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name shop.example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
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;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
ln -sf /etc/nginx/sites-available/shop /etc/nginx/sites-enabled/
|
||||
nginx -t && systemctl reload nginx
|
||||
apt install -y debian-keyring debian-archive-keyring apt-transport-https
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
|
||||
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
|
||||
| tee /etc/apt/sources.list.d/caddy-stable.list
|
||||
apt update
|
||||
apt install -y caddy
|
||||
```
|
||||
|
||||
Замените `shop.example.com` на ваш домен. HTTPS: `apt install certbot python3-certbot-nginx && certbot --nginx`.
|
||||
### Конфигурация
|
||||
|
||||
В репозитории лежит пример: `caddy/Caddyfile.example`.
|
||||
|
||||
```bash
|
||||
# Замените shop.example.com и email на свои
|
||||
cp /opt/shop/caddy/Caddyfile.example /etc/caddy/Caddyfile
|
||||
nano /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
Пример `/etc/caddy/Caddyfile`:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
email admin@example.com
|
||||
}
|
||||
|
||||
shop.example.com {
|
||||
encode gzip zstd
|
||||
reverse_proxy 127.0.0.1:3000
|
||||
}
|
||||
```
|
||||
|
||||
Проверка и перезапуск:
|
||||
|
||||
```bash
|
||||
caddy validate --config /etc/caddy/Caddyfile
|
||||
systemctl enable caddy
|
||||
systemctl reload caddy
|
||||
systemctl status caddy
|
||||
```
|
||||
|
||||
Сайт: **https://shop.example.com**
|
||||
|
||||
Логи Caddy: `journalctl -u caddy -f`
|
||||
|
||||
### Файрвол (ufw)
|
||||
|
||||
```bash
|
||||
ufw allow 22/tcp
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
ufw enable
|
||||
```
|
||||
|
||||
Порт **3000** наружу не открывайте — к приложению ходят только через Caddy.
|
||||
|
||||
### Порядок запуска после перезагрузки
|
||||
|
||||
1. `shop` (Node.js на `127.0.0.1:3000`)
|
||||
2. `caddy` (прокси + HTTPS)
|
||||
|
||||
### Типичные проблемы
|
||||
|
||||
| Симптом | Решение |
|
||||
|--------|---------|
|
||||
| 502 Bad Gateway | `systemctl status shop`, проверьте `curl http://127.0.0.1:3000` |
|
||||
| Нет сертификата | DNS, порты 80/443, верный домен в `Caddyfile` |
|
||||
| Редирект-цикл / нет cookies | В `.env`: `TRUST_PROXY=1`, `NODE_ENV=production` |
|
||||
|
||||
---
|
||||
|
||||
@@ -131,6 +193,7 @@ systemctl stop shop
|
||||
git pull
|
||||
npm install --omit=dev
|
||||
systemctl start shop
|
||||
# Caddy перезагружать не нужно, если Caddyfile не менялся
|
||||
```
|
||||
|
||||
---
|
||||
@@ -150,6 +213,9 @@ npm run dev
|
||||
| Переменная | Описание | По умолчанию |
|
||||
|------------------|---------------------------|----------------|
|
||||
| `PORT` | Порт HTTP-сервера | `3000` |
|
||||
| `HOST` | Адрес привязки | `0.0.0.0` (dev), `127.0.0.1` (prod) |
|
||||
| `NODE_ENV` | Режим (`production` — secure cookies) | — |
|
||||
| `TRUST_PROXY` | Доверять заголовкам Caddy (`1`) | — |
|
||||
| `SESSION_SECRET` | Секрет для сессий | dev-значение |
|
||||
|
||||
## Скрипты npm
|
||||
@@ -176,13 +242,15 @@ cp -a data/shop.db data/shop.db.bak
|
||||
## Структура проекта
|
||||
|
||||
```
|
||||
caddy/
|
||||
Caddyfile.example — пример reverse proxy + SSL
|
||||
src/
|
||||
server.js — точка входа
|
||||
db.js — схема SQLite
|
||||
seed.js — демо-данные
|
||||
routes/ — маршруты
|
||||
views/ — шаблоны EJS
|
||||
public/css/ — стили
|
||||
server.js — точка входа
|
||||
db.js — схема SQLite
|
||||
seed.js — демо-данные
|
||||
routes/ — маршруты
|
||||
views/ — шаблоны EJS
|
||||
public/css/ — стили
|
||||
```
|
||||
|
||||
## Репозиторий
|
||||
|
||||
Reference in New Issue
Block a user