build: add container and deployment configuration

This commit is contained in:
DiheChen committed 2026-10-30 01:34:19 +08:00
1 parent 50039353ad
commit c41b1d350a
26 files changed
+1238

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
FROM --platform=$BUILDPLATFORM node:24-alpine AS build
ARG VERSION=dev
WORKDIR /src
COPY web/package.json web/package-lock.json ./
RUN npm ci
COPY web/ .
RUN npm run build \
&& find dist -type f \( -name '*.html' -o -name '*.js' -o -name '*.css' -o -name '*.svg' -o -name '*.json' -o -name '*.webmanifest' \) -exec gzip -9 -k {} + \
&& sed "s|@VERSION@|${VERSION}|" nginx/default.conf > /tmp/default.conf
FROM nginxinc/nginx-unprivileged:1.30-alpine
ENV NGINX_ENTRYPOINT_QUIET_LOGS=1
COPY web/nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=build /tmp/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /src/dist /usr/share/nginx/html
COPY web/nginx/templates /etc/nginx/alisten-templates
COPY LICENSE /usr/share/doc/alisten/
EXPOSE 8080 9090
HEALTHCHECK --start-period=30s --start-interval=1s --interval=10s --timeout=3s --retries=3 \
CMD wget -q -O /dev/null http://127.0.0.1:9090/healthz || exit 1
+59
View File
@@ -0,0 +1,59 @@
map $status $log_level {
~^5 ERROR;
default INFO;
}
log_format json escape=json
'{"time":"$time_iso8601","level":"$log_level","msg":"HTTP 请求",'
'"service":"alisten","component":"web","version":"@VERSION@",'
'"method":"$request_method","path":"$uri","status":$status,'
'"bytes":$body_bytes_sent,"duration_seconds":$request_time}';
server {
listen 8080;
root /usr/share/nginx/html;
server_tokens off;
access_log /dev/stdout json;
gzip_static on;
gzip on;
gzip_vary on;
gzip_types text/css text/javascript application/javascript application/json application/manifest+json image/svg+xml;
include /tmp/alisten.d/*.conf;
location ~ ^/(?:admin|settings|history)?$ {
add_header Cache-Control "no-cache";
try_files /index.html =404;
}
location ~ ^/r/[^/]+(?:/(?:queue|chat|search|playlists/[^/]+/[^/]+))?$ {
add_header Cache-Control "no-cache";
try_files /index.html =404;
}
location ~ ^/.+/$ {
return 404;
}
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
location / {
add_header Cache-Control "no-cache";
try_files $uri =404;
}
}
server {
listen 9090;
access_log off;
location = /healthz {
default_type text/plain;
return 200 "ok\n";
}
location / {
return 404;
}
}
+28
View File
@@ -0,0 +1,28 @@
worker_processes 1;
error_log /dev/stderr warn;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
client_body_temp_path /tmp/client_temp;
proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;
include /etc/nginx/mime.types;
types {
application/manifest+json webmanifest;
}
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
@@ -0,0 +1,36 @@
# 主机名放在变量中,nginx 才会在每个请求时解析:serve 有两个副本且重启后地址会变,启动时上游也不必已经存在。
resolver 127.0.0.11 valid=5s;
set $serve serve:8080;
set $rustfs rustfs:9000;
proxy_http_version 1.1;
absolute_redirect off;
# default.conf 中有匹配以 / 结尾的路径的正则 location,只有带 ^~ 的前缀 location 才能优先于它。
location ^~ /api/ {
# 不小于 serve 的请求体上限,请求体就不会写入临时文件,也就不会因此输出纯文本的 warn 日志。
client_body_buffer_size 64k;
proxy_pass http://$serve;
}
location ^~ /media/ {
proxy_pass http://$serve;
}
# 空闲连接由 serve 断开,这里的超时只作兜底。
location = /ws {
proxy_pass http://$serve;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 1h;
proxy_send_timeout 1h;
}
# 只转发 link/ 下的读取请求:RustFS 的其他接口也在同一端口上。对象来自用户提交的链接且与页面同源,依靠这两个响应头阻止其中的脚本运行。
# 用 return 而不用 limit_except:拒绝时不写纯文本的错误日志。关闭缓冲:缓冲时超出内存缓冲区的响应会写入 /tmp 的 tmpfs。
location ^~ /storage/${STORAGE_BUCKET_NAME}/link/ {
if ($request_method !~ ^(GET|HEAD)$) {
return 405;
}
rewrite ^/storage(/.*)$ $1 break;
proxy_pass http://$rustfs;
proxy_buffering off;
add_header Content-Security-Policy "sandbox; default-src 'none'" always;
add_header X-Content-Type-Options nosniff always;
}