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:
parent
489791403c
commit
36be9fb33d
6 changed files with 10 additions and 242 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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"
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
|
||||||
|
|
|
||||||
|
|
@ -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 }}
|
|
||||||
Loading…
Reference in a new issue