Initial AI manga platform
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# Deploy
|
||||
|
||||
This directory is reserved for local dependencies, Docker, Nginx, PM2/systemd, backup, and release scripts.
|
||||
|
||||
Stage 01 does not start infrastructure automatically.
|
||||
|
||||
Planned services:
|
||||
|
||||
- backend-api
|
||||
- queue-worker
|
||||
- ffmpeg-worker
|
||||
- admin-web
|
||||
- user-web
|
||||
- mysql
|
||||
- redis
|
||||
- minio
|
||||
- nginx
|
||||
|
||||
## HTTPS / API transport
|
||||
|
||||
Production API traffic must be served over HTTPS, even though JSON request and response bodies also use an application-layer encrypted envelope. The recommended layout is:
|
||||
|
||||
- Nginx terminates TLS on `443`.
|
||||
- Frontend bundles call same-origin `/api` by default.
|
||||
- Nginx proxies `/api/` to `http://127.0.0.1:3000/api/`.
|
||||
- Nginx sets `X-Forwarded-Proto: https`.
|
||||
- Backend runs with `HTTPS_REQUIRED=true` and `TRUST_PROXY=true`.
|
||||
- Browser clients negotiate short-lived API crypto sessions through `GET /api/crypto/handshake`.
|
||||
|
||||
Example config:
|
||||
|
||||
```text
|
||||
deploy/nginx.https.example.conf
|
||||
```
|
||||
|
||||
Production environment example:
|
||||
|
||||
```bash
|
||||
NODE_ENV=production
|
||||
HTTPS_REQUIRED=true
|
||||
HTTPS_ALLOW_LOCAL_HTTP=false
|
||||
TRUST_PROXY=true
|
||||
CORS_ORIGINS=https://manga.example.com,https://admin.manga.example.com
|
||||
API_CRYPTO_ENABLED=auto
|
||||
API_CRYPTO_SESSION_TTL_SECONDS=900
|
||||
VITE_API_CRYPTO_ENABLED=auto
|
||||
VITE_API_BASE_URL=/api
|
||||
```
|
||||
|
||||
For local development, keep `HTTPS_REQUIRED=false` or leave `HTTPS_ALLOW_LOCAL_HTTP=true` so `http://127.0.0.1:3000/api` continues to work.
|
||||
API crypto is off by default through `security.api_crypto_enabled=false`; enable it from the admin settings page after production deployment.
|
||||
|
||||
Notes:
|
||||
|
||||
- The encrypted envelope covers JSON request bodies, JSON responses, error responses, encrypted novel upload payloads, and encrypted private asset download payloads.
|
||||
- HTTP method, path, host, and query string remain transport metadata. Do not place sensitive content in query parameters.
|
||||
- The API crypto session store is in memory. Use sticky sessions or move the session store to Redis before horizontal backend scaling.
|
||||
@@ -0,0 +1,33 @@
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
environment:
|
||||
MYSQL_DATABASE: ai_manga
|
||||
MYSQL_USER: ai_manga
|
||||
MYSQL_PASSWORD: ai_manga_password
|
||||
MYSQL_ROOT_PASSWORD: root_password
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- "6379:6379"
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: minioadmin
|
||||
MINIO_ROOT_PASSWORD: minioadmin
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- "9001:9001"
|
||||
volumes:
|
||||
- minio_data:/data
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
minio_data:
|
||||
@@ -0,0 +1,91 @@
|
||||
# Replace these placeholders before enabling:
|
||||
# - manga.example.com
|
||||
# - admin.manga.example.com
|
||||
# - /etc/letsencrypt/live/... certificate paths
|
||||
# - frontend dist paths if your release directory differs
|
||||
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name manga.example.com admin.manga.example.com;
|
||||
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name manga.example.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/manga.example.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/manga.example.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
|
||||
client_max_body_size 100m;
|
||||
|
||||
root /www/wwwroot/ai/user-app/dist;
|
||||
index index.html;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:3000/api/;
|
||||
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 https;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name admin.manga.example.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/admin.manga.example.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/admin.manga.example.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
|
||||
client_max_body_size 100m;
|
||||
|
||||
root /www/wwwroot/ai/admin/dist;
|
||||
index index.html;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:3000/api/;
|
||||
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 https;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user