init
This commit is contained in:
10
.env.example
Normal file
10
.env.example
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# PostgreSQL для n8n (не коммитить .env в репозиторий)
|
||||||
|
POSTGRES_USER=n8n
|
||||||
|
POSTGRES_PASSWORD=<сгенерировать_надёжный_пароль>
|
||||||
|
POSTGRES_DB=n8n
|
||||||
|
|
||||||
|
# Внешний прокси: только домены из proxy/squid.conf идут через него
|
||||||
|
EXTERNAL_PROXY_HOST=proxy.example.com
|
||||||
|
EXTERNAL_PROXY_PORT=3128
|
||||||
|
EXTERNAL_PROXY_USER=
|
||||||
|
EXTERNAL_PROXY_PASS=
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.env
|
||||||
54
README.md
Normal file
54
README.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# n8n на n8n.clientright.ru
|
||||||
|
|
||||||
|
Развёртывание n8n в Docker с PostgreSQL, SSL (Let's Encrypt) и выборочным прокси для части доменов (OpenAI, Anthropic и др.).
|
||||||
|
|
||||||
|
## Состав
|
||||||
|
|
||||||
|
- **n8n** (n8nio/n8n:2.7.5) — за Nginx по HTTPS
|
||||||
|
- **PostgreSQL 16** — хранилище n8n
|
||||||
|
- **Squid** — локальный прокси: часть доменов идёт через внешний прокси, остальное — напрямую
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- Docker и Docker Compose
|
||||||
|
- Nginx как reverse proxy с SSL для `n8n.clientright.ru`
|
||||||
|
- Файл `.env` (см. ниже)
|
||||||
|
|
||||||
|
## Быстрый старт
|
||||||
|
|
||||||
|
1. Скопировать `.env.example` в `.env` и заполнить значения (пароли, внешний прокси при необходимости).
|
||||||
|
2. Запуск:
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
3. Открыть https://n8n.clientright.ru и создать первого пользователя.
|
||||||
|
|
||||||
|
## Переменные окружения (.env)
|
||||||
|
|
||||||
|
Файл `.env` не коммитится в репозиторий. Пример структуры — в `.env.example`.
|
||||||
|
|
||||||
|
- **POSTGRES_*** — пользователь, пароль и БД для PostgreSQL.
|
||||||
|
- **EXTERNAL_PROXY_*** — внешний HTTP-прокси (host, port, при необходимости user/pass). Через него идут только домены из `proxy/squid.conf` (по умолчанию openai.com, anthropic.com, googleapis.com).
|
||||||
|
- Остальной трафик n8n выходит в интернет напрямую.
|
||||||
|
|
||||||
|
## Прокси
|
||||||
|
|
||||||
|
- n8n использует только локальный Squid (`http://proxy:3128`).
|
||||||
|
- В `proxy/squid.conf` заданы домены (acl `to_parent_proxy`), которые маршрутизируются во внешний прокси; для них включён `never_direct allow to_parent_proxy`.
|
||||||
|
- Добавить домен: дописать в `proxy/squid.conf` строку вида `acl to_parent_proxy dstdomain .example.com`, пересобрать и перезапустить proxy:
|
||||||
|
`docker compose build proxy && docker compose up -d proxy`.
|
||||||
|
|
||||||
|
## Обновление n8n
|
||||||
|
|
||||||
|
Изменить тег образа в `docker-compose.yml` (например, `n8nio/n8n:2.7.6`), затем:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose pull n8n
|
||||||
|
docker compose up -d n8n
|
||||||
|
```
|
||||||
|
|
||||||
|
## Файлы
|
||||||
|
|
||||||
|
- `docker-compose.yml` — сервисы n8n, postgres, proxy
|
||||||
|
- `proxy/` — образ и конфиг Squid (Dockerfile, squid.conf, entrypoint.sh)
|
||||||
|
- `n8n.clientright.ru.conf` — пример конфига Nginx (реальный конфиг на сервере в `/etc/nginx/conf.d/`)
|
||||||
59
docker-compose.yml
Normal file
59
docker-compose.yml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
services:
|
||||||
|
proxy:
|
||||||
|
build: ./proxy
|
||||||
|
restart: always
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
EXTERNAL_PROXY_HOST: ${EXTERNAL_PROXY_HOST:-}
|
||||||
|
EXTERNAL_PROXY_PORT: ${EXTERNAL_PROXY_PORT:-}
|
||||||
|
EXTERNAL_PROXY_USER: ${EXTERNAL_PROXY_USER:-}
|
||||||
|
EXTERNAL_PROXY_PASS: ${EXTERNAL_PROXY_PASS:-}
|
||||||
|
# Порт только внутри Docker-сети, наружу не светим
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
restart: always
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB}
|
||||||
|
volumes:
|
||||||
|
- n8n_postgres_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER:-n8n} -d ${POSTGRES_DB:-n8n}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
n8n:
|
||||||
|
image: n8nio/n8n:2.7.5
|
||||||
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
proxy:
|
||||||
|
condition: service_started
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_TYPE: postgresdb
|
||||||
|
DB_POSTGRESDB_HOST: postgres
|
||||||
|
DB_POSTGRESDB_PORT: 5432
|
||||||
|
DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
|
||||||
|
DB_POSTGRESDB_USER: ${POSTGRES_USER}
|
||||||
|
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
N8N_PROTOCOL: https
|
||||||
|
N8N_HOST: n8n.clientright.ru
|
||||||
|
WEBHOOK_URL: https://n8n.clientright.ru/
|
||||||
|
# Весь трафик n8n — через локальный Squid; выборочно домены идут во внешний прокси
|
||||||
|
HTTP_PROXY: http://proxy:3128
|
||||||
|
HTTPS_PROXY: http://proxy:3128
|
||||||
|
NO_PROXY: postgres,127.0.0.1,localhost,n8n.clientright.ru
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:5678:5678"
|
||||||
|
volumes:
|
||||||
|
- n8n_data:/home/node/.n8n
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
n8n_postgres_data:
|
||||||
|
n8n_data:
|
||||||
38
n8n.clientright.ru.conf
Normal file
38
n8n.clientright.ru.conf
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# n8n.clientright.ru
|
||||||
|
server {
|
||||||
|
listen 147.45.146.17:80;
|
||||||
|
server_name n8n.clientright.ru;
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/fastuser/data/www/n8n.clientright.ru;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 147.45.146.17:443 ssl http2;
|
||||||
|
server_name n8n.clientright.ru;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/n8n.clientright.ru/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/n8n.clientright.ru/privkey.pem;
|
||||||
|
ssl_trusted_certificate /etc/letsencrypt/live/n8n.clientright.ru/chain.pem;
|
||||||
|
|
||||||
|
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:5678;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
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_read_timeout 300;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
proxy/Dockerfile
Normal file
9
proxy/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM alpine:3.19
|
||||||
|
RUN apk add --no-cache squid \
|
||||||
|
&& mkdir -p /var/log/squid /var/cache/squid /var/run/squid \
|
||||||
|
&& chown -R squid:squid /var/log/squid /var/cache/squid /var/run/squid
|
||||||
|
COPY squid.conf /etc/squid/squid.conf
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
RUN chmod +x /entrypoint.sh
|
||||||
|
EXPOSE 3128
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
15
proxy/entrypoint.sh
Normal file
15
proxy/entrypoint.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
mkdir -p /etc/squid/conf.d
|
||||||
|
# Родительский прокси: host и port из .env (генерируем одну строку конфига)
|
||||||
|
if [ -n "$EXTERNAL_PROXY_HOST" ] && [ -n "$EXTERNAL_PROXY_PORT" ]; then
|
||||||
|
_auth=""
|
||||||
|
if [ -n "$EXTERNAL_PROXY_USER" ] && [ -n "$EXTERNAL_PROXY_PASS" ]; then
|
||||||
|
_auth=" login=${EXTERNAL_PROXY_USER}:${EXTERNAL_PROXY_PASS}"
|
||||||
|
fi
|
||||||
|
echo "cache_peer ${EXTERNAL_PROXY_HOST} parent ${EXTERNAL_PROXY_PORT} 0 no-query default name=parent${_auth}" > /etc/squid/conf.d/parent.conf
|
||||||
|
else
|
||||||
|
echo "# Внешний прокси не задан (EXTERNAL_PROXY_HOST/PORT). Заполни .env и перезапусти." > /etc/squid/conf.d/parent.conf
|
||||||
|
echo "cache_peer no-proxy.invalid parent 1 0 no-query default name=parent" >> /etc/squid/conf.d/parent.conf
|
||||||
|
fi
|
||||||
|
exec squid -f /etc/squid/squid.conf -N
|
||||||
39
proxy/squid.conf
Normal file
39
proxy/squid.conf
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Локальный прокси для n8n: часть доменов — через внешний прокси, остальное — напрямую
|
||||||
|
# Внешний прокси задаётся в .env: EXTERNAL_PROXY_HOST, EXTERNAL_PROXY_PORT
|
||||||
|
# Домены для внешнего прокси — список ниже (acl to_parent_proxy)
|
||||||
|
|
||||||
|
http_port 3128
|
||||||
|
|
||||||
|
# Доступ только из Docker-сети (n8n)
|
||||||
|
acl localnet src 10.0.0.0/8
|
||||||
|
acl localnet src 172.16.0.0/12
|
||||||
|
acl localnet src 192.168.0.0/16
|
||||||
|
|
||||||
|
acl SSL_ports port 443
|
||||||
|
acl Safe_ports port 80 443
|
||||||
|
acl CONNECT method CONNECT
|
||||||
|
|
||||||
|
# Подключаем сгенерированный конфиг с cache_peer (host/port из env)
|
||||||
|
include /etc/squid/conf.d/parent.conf
|
||||||
|
|
||||||
|
# Домены, которые идут через внешний прокси (остальные — напрямую)
|
||||||
|
acl to_parent_proxy dstdomain .openai.com
|
||||||
|
acl to_parent_proxy dstdomain .anthropic.com
|
||||||
|
acl to_parent_proxy dstdomain .googleapis.com
|
||||||
|
# Добавь при необходимости: .azure.com, .aws.amazon.com и т.д.
|
||||||
|
|
||||||
|
# Родительский прокси только для этих доменов
|
||||||
|
cache_peer_access parent allow to_parent_proxy
|
||||||
|
cache_peer_access parent deny all
|
||||||
|
|
||||||
|
# Важно: CONNECT (HTTPS) по умолчанию Squid может слать напрямую, а не в parent.
|
||||||
|
# Запрещаем прямой доступ для этих доменов — только через parent.
|
||||||
|
never_direct allow to_parent_proxy
|
||||||
|
|
||||||
|
# Таймауты при работе через родительский прокси (увеличить при медленном прокси)
|
||||||
|
connect_timeout 30 seconds
|
||||||
|
read_timeout 60 seconds
|
||||||
|
|
||||||
|
# Разрешаем запросы из нашей сети
|
||||||
|
http_access allow localnet
|
||||||
|
http_access deny all
|
||||||
Reference in New Issue
Block a user