chore: remove SMTP relay, clean up tools role after Outline/n8n migration to main

- Remove smtp-relay (postfix) container — Outline now on main, uses Resend directly
- Remove UFW port 1025 rule (SMTP relay no longer needed)
- Remove postfix-relay from image pull list
- Clean up tools role: remove Outline/n8n/env.j2, simplify tasks/main.yml
- tools docker-compose now empty (pending monitoring migration)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jack 2026-03-27 03:10:56 +07:00
parent 489791403c
commit 36be9fb33d
6 changed files with 10 additions and 242 deletions

View file

@ -25,20 +25,24 @@
- "{{ promtail_image }}" - "{{ promtail_image }}"
- "{{ crowdsec_image }}" - "{{ crowdsec_image }}"
- "{{ uptime_kuma_image }}" - "{{ uptime_kuma_image }}"
- "tecnativa/postfix-relay" - "{{ outline_image }}"
- "{{ outline_db_image }}"
- "{{ outline_redis_image }}"
- "{{ n8n_image }}"
register: pull_result register: pull_result
changed_when: "'Status: Downloaded newer image' in pull_result.stdout" changed_when: "'Status: Downloaded newer image' in pull_result.stdout"
retries: 5 retries: 5
delay: 30 delay: 30
until: pull_result.rc == 0 until: pull_result.rc == 0
- name: Allow SMTP relay port from tools server - name: Remove legacy SMTP relay UFW rule (port 1025)
community.general.ufw: community.general.ufw:
rule: allow rule: allow
port: "1025" port: "1025"
proto: tcp proto: tcp
src: "{{ ip_tools }}" src: "{{ ip_tools }}"
comment: "SMTP relay for tools-server Outline" delete: true
failed_when: false
- name: Deploy Docker Compose stack - name: Deploy Docker Compose stack
community.docker.docker_compose_v2: community.docker.docker_compose_v2:

View file

@ -580,30 +580,6 @@ services:
timeout: 5s timeout: 5s
retries: 3 retries: 3
# ── SMTP Relay ─────────────────────────────────────────────────────────────
# Forwards mail from tools-server (85.193.83.9) to Resend SMTP.
# tools-server has outbound SMTP blocked by the VPS provider.
# Listens on 85.193.83.9:1025 (UFW allows only from ip_tools).
smtp-relay:
image: tecnativa/postfix-relay
container_name: smtp-relay
restart: unless-stopped
ports:
- "{{ ip_tools }}:1025:25"
networks:
- proxy
environment:
- MAILNAME={{ domain_base }}
- MAIL_RELAY_HOST=smtp.resend.com
- MAIL_RELAY_PORT=587
- MAIL_RELAY_USER=resend
- MAIL_RELAY_PASS={{ resend_api_key }}
- MAIL_RELAY_MYHOSTNAME=mail.{{ domain_base }}
logging:
driver: json-file
options:
max-size: "5m"
max-file: "2"
# ── Outline wiki ──────────────────────────────────────────────────────────── # ── Outline wiki ────────────────────────────────────────────────────────────
outline: outline:

View file

@ -1,7 +1,2 @@
--- ---
tools_root: /opt/tools tools_root: /opt/tools
outline_image: "outlinewiki/outline:0.80.2"
outline_db_image: "postgres:15-alpine"
outline_redis_image: "redis:7-alpine"
n8n_image: "n8nio/n8n:1.89.2" # https://hub.docker.com/r/n8nio/n8n/tags
outline_mcp_image: "git.{{ domain_base }}/jack/outline-mcp:latest"

View file

@ -7,7 +7,6 @@
group: "{{ deploy_group }}" group: "{{ deploy_group }}"
mode: "0750" mode: "0750"
# ── Deploy configs and start stack ────────────────────────────────────────────
- name: Deploy docker-compose.yml - name: Deploy docker-compose.yml
ansible.builtin.template: ansible.builtin.template:
src: docker-compose.yml.j2 src: docker-compose.yml.j2
@ -16,27 +15,8 @@
group: "{{ deploy_group }}" group: "{{ deploy_group }}"
mode: "0640" mode: "0640"
- name: Deploy .env
ansible.builtin.template:
src: env.j2
dest: "{{ tools_root }}/.env"
owner: "{{ deploy_user }}"
group: "{{ deploy_group }}"
mode: "0600"
- name: Pull images
community.docker.docker_image:
name: "{{ item }}"
source: pull
loop:
- "{{ outline_image }}"
- "{{ outline_db_image }}"
- "{{ outline_redis_image }}"
- "{{ n8n_image }}"
- name: Start tools stack - name: Start tools stack
community.docker.docker_compose_v2: community.docker.docker_compose_v2:
project_src: "{{ tools_root }}" project_src: "{{ tools_root }}"
state: present state: present
pull: missing
remove_orphans: true remove_orphans: true

View file

@ -1,150 +1,10 @@
# Tools stack — generated by Ansible # Tools stack — generated by Ansible
# Do not edit manually; re-run ansible-playbook playbooks/tools.yml # Do not edit manually; re-run ansible-playbook playbooks/tools.yml
# All app services (Outline, n8n) have been migrated to main server.
# Monitoring stack (Grafana, Prometheus, Loki, Alertmanager) will be added here.
networks: networks:
# front — non-internal: needed for Docker port binding to work (expose ports to host)
# Docker does not create DNAT rules for containers only on internal networks
front: front:
driver: bridge driver: bridge
outline-internal:
driver: bridge
internal: true
n8n-internal:
driver: bridge
internal: true
volumes: services: {}
outline_db_data:
outline_redis_data:
n8n_data:
services:
# ── Outline wiki ────────────────────────────────────────────────────────────
outline:
image: {{ outline_image }}
container_name: outline
restart: unless-stopped
env_file: .env
networks:
- outline-internal
- front # needed for host port binding
ports:
# Exposed only to main Traefik (access controlled by UFW)
- "{{ ip_tools }}:3000:3000"
depends_on:
outline-db:
condition: service_healthy
outline-redis:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/_health"]
interval: 30s
timeout: 5s
retries: 3
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
outline-db:
image: {{ outline_db_image }}
container_name: outline-db
restart: unless-stopped
environment:
POSTGRES_DB: outline
POSTGRES_USER: outline
POSTGRES_PASSWORD: ${OUTLINE_DB_PASSWORD}
networks:
- outline-internal
volumes:
- outline_db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U outline"]
interval: 10s
timeout: 5s
retries: 5
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
outline-redis:
image: {{ outline_redis_image }}
container_name: outline-redis
restart: unless-stopped
networks:
- outline-internal
volumes:
- outline_redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# ── Outline MCP server ───────────────────────────────────────────────────────
# MCP server exposing Outline wiki to Claude/AI clients (port 8765, internal only)
outline-mcp:
image: {{ outline_mcp_image }}
container_name: outline-mcp
restart: unless-stopped
networks:
- front # needed for host port binding
ports:
- "127.0.0.1:8765:8765"
environment:
- OUTLINE_URL=https://{{ domain_wiki }}
- OUTLINE_API_KEY={{ outline_mcp_api_key }}
- PORT=8765
- HOST=0.0.0.0
- LOG_LEVEL=INFO
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# ── n8n workflow automation ──────────────────────────────────────────────────
n8n:
image: {{ n8n_image }}
container_name: n8n
restart: unless-stopped
networks:
- n8n-internal
- front # needed for host port binding
ports:
# Exposed only to main Traefik (access controlled by UFW)
- "{{ ip_tools }}:5678:5678"
volumes:
- n8n_data:/home/node/.n8n
environment:
- N8N_HOST={{ domain_n8n }}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://{{ domain_n8n }}/
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_USER_MANAGEMENT_JWT_SECRET=${N8N_JWT_SECRET}
- GENERIC_TIMEZONE=Europe/Moscow
- TZ=Europe/Moscow
- N8N_METRICS=false
- N8N_LOG_LEVEL=warn
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=336
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:5678/healthz"]
interval: 30s
timeout: 5s
retries: 3
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

View file

@ -1,47 +0,0 @@
# Outline env — generated by Ansible
NODE_ENV=production
SECRET_KEY={{ outline_secret_key }}
UTILS_SECRET={{ outline_utils_secret }}
# Database
DATABASE_URL=postgres://outline:{{ outline_db_password }}@outline-db:5432/outline
PGSSLMODE=disable
# Redis
REDIS_URL=redis://outline-redis:6379
# App URL
URL=https://{{ domain_wiki }}
PORT=3000
# S3 file storage (Timeweb Object Storage)
AWS_ACCESS_KEY_ID={{ s3_access_key }}
AWS_SECRET_ACCESS_KEY={{ s3_secret_key }}
AWS_REGION=ru-1
AWS_S3_UPLOAD_BUCKET_NAME=visual-outline
AWS_S3_UPLOAD_BUCKET_URL=https://s3.timeweb.cloud
AWS_S3_FORCE_PATH_STYLE=true
AWS_S3_ACL=private
FILE_STORAGE=s3
# Auth
AUTH_PROVIDERS=email
# SMTP via relay on main server (tools-server has outbound SMTP blocked)
SMTP_HOST={{ ip_main }}
SMTP_PORT=1025
SMTP_FROM_EMAIL=noreply@{{ domain_base }}
SMTP_FROM_NAME=Visual Wiki
SMTP_SECURE=false
# Outline DB password (used in docker-compose)
OUTLINE_DB_PASSWORD={{ outline_db_password }}
# Optional
DEFAULT_LANGUAGE=en_US
RATE_LIMITER_ENABLED=true
ENABLE_UPDATES=false
# n8n secrets
N8N_ENCRYPTION_KEY={{ n8n_encryption_key }}
N8N_JWT_SECRET={{ n8n_jwt_secret }}