HAL 제어 평면(릴리스·서버·Agent·작업·모듈 배포·운영자 계정·긴급 복구·재해복구·공개 상태), Node Agent, 배포 스크립트·유닛·nginx 템플릿, 릴리스 도구, 포털 HAL 클라이언트 (§28·§29·§32~§34)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
403d0fb845
commit
6b5a014041
@@ -0,0 +1,31 @@
|
||||
# hal.ariweb.net — HAL(제어 평면). 운영자 콘솔 /ops 는 HAL 이 네트워크 관문(허용 CIDR 또는 접근권 쿠키)을 적용한다.
|
||||
# Agent 는 /agent/v1 로, 포털은 /portal/v1 로 서명된 요청을 보낸다. 큰 전송(/agent/v1/transfers)은 본문 제한을 넉넉히 둔다.
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{HAL_HOST}};
|
||||
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
|
||||
location / { return 301 https://$host$request_uri; }
|
||||
}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name {{HAL_HOST}};
|
||||
server_tokens off;
|
||||
client_max_body_size 0;
|
||||
ssl_certificate {{CERT_DIR}}/fullchain.pem;
|
||||
ssl_certificate_key {{CERT_DIR}}/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:{{PORT}};
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 120s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
# my.ariweb.net — 고객 포털
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{PORTAL_HOST}};
|
||||
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
|
||||
location / { return 301 https://$host$request_uri; }
|
||||
}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name {{PORTAL_HOST}};
|
||||
server_tokens off;
|
||||
client_max_body_size 200m;
|
||||
ssl_certificate {{CERT_DIR}}/fullchain.pem;
|
||||
ssl_certificate_key {{CERT_DIR}}/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:{{PORT}};
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# deploy/nginx/awstats.conf — /etc/nginx/conf.d/awstats.conf : Ariweb 관리형 사이트 접속 통계 로그 형식(§13.1).
|
||||
# Agent(site.usage)가 사이트별 로그(aw-<siteId>.access.log)를 읽어 요청 수·수신/송신 바이트·오류율·응답 시간을 집계한다. IP 는 기록하지 않는다(개인정보 최소화).
|
||||
log_format awstats '$time_iso8601|$host|$request_length|$bytes_sent|$status|$request_time|$uri';
|
||||
@@ -0,0 +1,7 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{OLD_NAMES}};
|
||||
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
|
||||
return 301 https://{{PRIMARY}}$request_uri;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
access_log {{LOG}} awstats;
|
||||
error_page 503 /__aw_maint;
|
||||
location = /__aw_maint { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{MAINT_HTML}}'; }
|
||||
if (-f {{SITE_DIR}}/.maintenance) { return 503; }
|
||||
if (-f {{SITE_DIR}}/.limited) { rewrite ^ /__aw_limited last; }
|
||||
location = /__aw_limited { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{LIMIT_HTML}}'; }
|
||||
location / { proxy_pass http://127.0.0.1:{{PORT}}; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 300s; }
|
||||
@@ -0,0 +1,11 @@
|
||||
root {{ROOT}};
|
||||
index index.html;
|
||||
access_log {{LOG}} awstats;
|
||||
error_page 503 /__aw_maint;
|
||||
location = /__aw_maint { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{MAINT_HTML}}'; }
|
||||
if (-f {{SITE_DIR}}/.maintenance) { return 503; }
|
||||
if (-f {{SITE_DIR}}/.limited) { rewrite ^ /__aw_limited last; }
|
||||
location = /__aw_limited { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{LIMIT_HTML}}'; }
|
||||
location ~ /\. { return 404; }
|
||||
location / { try_files $uri $uri/ /index.html =404; add_header Cache-Control "no-cache" always; }
|
||||
location /uploads/ { alias {{SITE_DIR}}/data/uploads/; }
|
||||
@@ -0,0 +1,12 @@
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name {{SERVER_NAMES}};
|
||||
server_tokens off;
|
||||
client_max_body_size 64m;
|
||||
ssl_certificate {{CERT_DIR}}/fullchain.pem;
|
||||
ssl_certificate_key {{CERT_DIR}}/privkey.pem;
|
||||
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
{{BODY}}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# Ariweb 관리형 사이트 vhost — Agent 가 만든다(site.deploy/domain.vhost). 손으로 고치지 마세요(다음 배포 때 덮어씁니다).
|
||||
# 사이트 {{SITE_ID}} · 도메인 {{DOMAIN_LIST}} · 생성 {{GENERATED_AT}}
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{SERVER_NAMES}};
|
||||
server_tokens off;
|
||||
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
|
||||
{{HTTP_BODY}}
|
||||
}
|
||||
{{HTTPS_SERVER}}
|
||||
Reference in New Issue
Block a user