Add neurapress docker deployment role
This commit is contained in:
parent
4dc54f6644
commit
1d7263767d
11
playbooks/deploy_neurapress_docker.yaml
Normal file
11
playbooks/deploy_neurapress_docker.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
- name: setup neurapress
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
neurapress_domain: "{{ domain }}"
|
||||||
|
neurapress_workspace: /opt/neurapress
|
||||||
|
neurapress_image: neurapress:prod
|
||||||
|
neurapress_certbot_email: manbuzhe2009@qq.com
|
||||||
|
roles:
|
||||||
|
- vhosts/docker/
|
||||||
|
- docker/neurapress/
|
||||||
7
playbooks/roles/docker/neurapress/defaults/main.yml
Normal file
7
playbooks/roles/docker/neurapress/defaults/main.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
# Default deployment directory for Neurapress Docker stack
|
||||||
|
neurapress_deploy_dir: /opt/neurapress
|
||||||
|
neurapress_workspace: "{{ neurapress_deploy_dir }}"
|
||||||
|
neurapress_domain: write.svc.plus
|
||||||
|
neurapress_image: neurapress:prod
|
||||||
|
neurapress_certbot_email: manbuzhe2009@qq.com
|
||||||
51
playbooks/roles/docker/neurapress/files/nginx/nginx.conf
Normal file
51
playbooks/roles/docker/neurapress/files/nginx/nginx.conf
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
# Logs → container stdout / stderr
|
||||||
|
error_log /dev/stderr warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
# Access log → stdout
|
||||||
|
log_format main
|
||||||
|
'$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent '
|
||||||
|
'"$http_referer" "$http_user_agent"';
|
||||||
|
|
||||||
|
access_log /dev/stdout main;
|
||||||
|
|
||||||
|
# Core performance (safe defaults)
|
||||||
|
sendfile on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
# TLS session cache (in-memory only)
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
|
||||||
|
# Gzip (lightweight)
|
||||||
|
gzip on;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_min_length 256;
|
||||||
|
gzip_types
|
||||||
|
text/plain
|
||||||
|
text/css
|
||||||
|
application/json
|
||||||
|
application/javascript
|
||||||
|
application/xml
|
||||||
|
image/svg+xml;
|
||||||
|
|
||||||
|
# Allow uploads (Markdown / images)
|
||||||
|
client_max_body_size 50m;
|
||||||
|
|
||||||
|
# Load virtual hosts
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
||||||
6
playbooks/roles/docker/neurapress/files/run.sh
Normal file
6
playbooks/roles/docker/neurapress/files/run.sh
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Helper script to start the Neurapress docker compose stack
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
docker compose -f docker-compose.yaml up -d
|
||||||
69
playbooks/roles/docker/neurapress/tasks/main.yml
Normal file
69
playbooks/roles/docker/neurapress/tasks/main.yml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure Neurapress directories exist
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
loop:
|
||||||
|
- "{{ neurapress_workspace }}"
|
||||||
|
- "{{ neurapress_workspace }}/certbot"
|
||||||
|
- "{{ neurapress_workspace }}/certbot/conf"
|
||||||
|
- "{{ neurapress_workspace }}/certbot/www"
|
||||||
|
- "{{ neurapress_workspace }}/nginx"
|
||||||
|
- "{{ neurapress_workspace }}/nginx/conf.d"
|
||||||
|
|
||||||
|
- name: Ensure Neurapress workspace ownership
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ neurapress_workspace }}"
|
||||||
|
state: directory
|
||||||
|
recurse: true
|
||||||
|
owner: "1000"
|
||||||
|
group: "1000"
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Template Neurapress configuration files
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ neurapress_workspace }}/{{ item.dest }}"
|
||||||
|
mode: "{{ item.mode | default('0644') }}"
|
||||||
|
loop:
|
||||||
|
- { src: 'docker-compose.yaml', dest: 'docker-compose.yaml' }
|
||||||
|
- { src: 'nginx/conf.d/default.conf', dest: 'nginx/conf.d/default.conf' }
|
||||||
|
- { src: 'nginx/conf.d/bootstrap-nginx.conf', dest: 'nginx/conf.d/bootstrap-nginx.conf' }
|
||||||
|
|
||||||
|
- name: Copy Neurapress static files
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ neurapress_workspace }}/{{ item.dest }}"
|
||||||
|
mode: "{{ item.mode | default('0644') }}"
|
||||||
|
loop:
|
||||||
|
- { src: 'run.sh', dest: 'run.sh', mode: '0755' }
|
||||||
|
- { src: 'nginx/nginx.conf', dest: 'nginx/nginx.conf' }
|
||||||
|
|
||||||
|
- name: Bootstrap NGINX (80-only for ACME)
|
||||||
|
become: true
|
||||||
|
command: docker compose --profile bootstrap -f {{ neurapress_workspace }}/docker-compose.yaml up -d bootstrap-nginx
|
||||||
|
args:
|
||||||
|
chdir: "{{ neurapress_workspace }}"
|
||||||
|
|
||||||
|
- name: Run certbot initial ACME challenge
|
||||||
|
become: true
|
||||||
|
command: docker compose --profile bootstrap -f {{ neurapress_workspace }}/docker-compose.yaml run --rm certbot
|
||||||
|
args:
|
||||||
|
chdir: "{{ neurapress_workspace }}"
|
||||||
|
|
||||||
|
- name: Destroy Bootstrap NGINX (80-only for ACME)
|
||||||
|
become: true
|
||||||
|
command: docker compose --profile bootstrap -f {{ neurapress_workspace }}/docker-compose.yaml down bootstrap-nginx
|
||||||
|
args:
|
||||||
|
chdir: "{{ neurapress_workspace }}"
|
||||||
|
|
||||||
|
- name: Bring up Neurapress stack
|
||||||
|
become: true
|
||||||
|
command: docker compose -f {{ neurapress_workspace }}/docker-compose.yaml up -d
|
||||||
|
args:
|
||||||
|
chdir: "{{ neurapress_workspace }}"
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: "{{ neurapress_image }}"
|
||||||
|
command: pnpm start
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:mainline-alpine
|
||||||
|
container_name: neurapress-nginx
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- "{{ neurapress_workspace }}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
|
||||||
|
- "{{ neurapress_workspace }}/nginx/conf.d:/etc/nginx/conf.d:ro"
|
||||||
|
- "{{ neurapress_workspace }}/certbot/conf:/etc/letsencrypt"
|
||||||
|
- "{{ neurapress_workspace }}/certbot/www:/var/www/certbot"
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
|
||||||
|
bootstrap-nginx:
|
||||||
|
profiles: ["bootstrap"]
|
||||||
|
image: nginx:mainline-alpine
|
||||||
|
container_name: bootstrap-nginx
|
||||||
|
volumes:
|
||||||
|
- "{{ neurapress_workspace }}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
|
||||||
|
- "{{ neurapress_workspace }}/nginx/conf.d/bootstrap-nginx.conf:/etc/nginx/conf.d/default.conf:ro"
|
||||||
|
- "{{ neurapress_workspace }}/certbot/conf:/etc/letsencrypt"
|
||||||
|
- "{{ neurapress_workspace }}/certbot/www:/var/www/certbot"
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "-qO-", "http://{{ neurapress_domain }}"]
|
||||||
|
interval: 3s
|
||||||
|
timeout: 2s
|
||||||
|
retries: 10
|
||||||
|
start_period: 3s
|
||||||
|
|
||||||
|
certbot:
|
||||||
|
profiles: ["bootstrap"]
|
||||||
|
image: certbot/certbot
|
||||||
|
container_name: certbot
|
||||||
|
command: >
|
||||||
|
certonly --webroot
|
||||||
|
--webroot-path=/var/www/certbot
|
||||||
|
--email {{ neurapress_certbot_email }}
|
||||||
|
--agree-tos
|
||||||
|
--no-eff-email
|
||||||
|
--keep-until-expiring
|
||||||
|
--non-interactive
|
||||||
|
-d {{ neurapress_domain }}
|
||||||
|
volumes:
|
||||||
|
- "{{ neurapress_workspace }}/certbot/conf:/etc/letsencrypt"
|
||||||
|
- "{{ neurapress_workspace }}/certbot/www:/var/www/certbot"
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app:
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ neurapress_domain }};
|
||||||
|
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 不 redirect!不要 https!
|
||||||
|
# certbot 需要纯 http 验证
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
# ----------------------------------------------------
|
||||||
|
# 80 - ACME Challenge + Redirect to HTTPS
|
||||||
|
# ----------------------------------------------------
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ neurapress_domain }};
|
||||||
|
|
||||||
|
# Certbot HTTP-01 challenge
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
# All HTTP → HTTPS
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------------
|
||||||
|
# 443 - TLS Termination for Neurapress
|
||||||
|
# ----------------------------------------------------
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name {{ neurapress_domain }};
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ neurapress_domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ neurapress_domain }}/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
# Next.js / Neurapress
|
||||||
|
location / {
|
||||||
|
proxy_pass http://app:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
# WebSocket / HMR support
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# Standard headers
|
||||||
|
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 https;
|
||||||
|
|
||||||
|
proxy_read_timeout 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user