Docker
This commit is contained in:
27
Dockerfile
Normal file
27
Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
||||
# Multi-stage Dockerfile for wsmud
|
||||
FROM node:18-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
# copy package and lock first for faster rebuilds
|
||||
COPY package.json package-lock.json* ./
|
||||
RUN npm ci --omit=dev || npm i --no-audit
|
||||
|
||||
# copy full source and build frontend with vite
|
||||
COPY . .
|
||||
RUN npm run build || true
|
||||
|
||||
FROM node:18-alpine AS runtime
|
||||
WORKDIR /app
|
||||
|
||||
# create folder for logs and db
|
||||
RUN mkdir -p /app/log /app/data /app/www
|
||||
|
||||
# copy node_modules from build stage
|
||||
COPY --from=build /app/node_modules ./node_modules
|
||||
COPY --from=build /app/www ./www
|
||||
COPY --from=build /app .
|
||||
|
||||
ENV NODE_ENV=production
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["node", "web.js"]
|
||||
75
README_DEPLOY.md
Normal file
75
README_DEPLOY.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 部署说明(Docker / 本地 / 反向代理)
|
||||
|
||||
本文档说明如何在服务器上运行本项目(Node + Express + Vite 前端构建)。
|
||||
|
||||
环境变量(必需)
|
||||
- WEB_PORT: 前端/HTTP 服务端口(示例 80)
|
||||
- WS_PORT: 后端 WebSocket 端口(示例 4000)
|
||||
- MD5_PREFIX: 项目内部使用的 MD5 前缀
|
||||
- DESIV: DES IV(字符串)
|
||||
- SESSION_SECRET: express-session 的 secret
|
||||
|
||||
快速开始(Docker Compose)
|
||||
|
||||
1. 在项目根(带有 docker-compose.yml 的目录)创建或修改 `.env`,填入必需变量。示例:
|
||||
|
||||
```
|
||||
WEB_PORT=80
|
||||
WS_PORT=4000
|
||||
MD5_PREFIX=change_me
|
||||
DESIV=change_me
|
||||
SESSION_SECRET=change_me
|
||||
```
|
||||
|
||||
2. 构建并启动
|
||||
|
||||
```bash
|
||||
docker compose up --build -d
|
||||
```
|
||||
|
||||
3. 检查日志
|
||||
|
||||
```bash
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
本地开发
|
||||
|
||||
- 前端:在 `src/` 目录使用 Vite 开发服务器
|
||||
- npm run dev
|
||||
- 后端(静态 + API):
|
||||
- npm run web (启动 web.js)
|
||||
- npm run os (启动 main.js,后台游戏服务)
|
||||
|
||||
反向代理(使用 Nginx)
|
||||
|
||||
示例 Nginx 配置(简化)
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:80;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
持久化与备份
|
||||
|
||||
- SQLite 数据文件位于 `data/` 目录(`database.db`),请确保卷挂载或定期备份。
|
||||
- 日志目录在 `log/`。
|
||||
|
||||
K8s / CI/CD
|
||||
|
||||
- Dockerfile 为多阶段,已将前端构建产物输出到 `www/`。
|
||||
- 在 CI 中请先运行 `npm ci` 和 `npm run build`,然后构建镜像并推送到镜像仓库。
|
||||
|
||||
常见问题
|
||||
|
||||
- 端口冲突:确认 `WEB_PORT` 与宿主机端口映射一致
|
||||
- 权限问题:确保 `data/`、`log/` 可由容器写入(host 的 umask/owner)
|
||||
19
docker-compose.yml
Normal file
19
docker-compose.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
wsmud:
|
||||
build: .
|
||||
image: wsmud:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
- "4000:4000" # optional websocket port mapping if used
|
||||
environment:
|
||||
- WEB_PORT=80
|
||||
- WS_PORT=4000
|
||||
- MD5_PREFIX=change_me
|
||||
- DESIV=change_me
|
||||
- SESSION_SECRET=change_me
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./log:/app/log
|
||||
- ./www:/app/www
|
||||
restart: unless-stopped
|
||||
37
scripts/build_and_push.ps1
Normal file
37
scripts/build_and_push.ps1
Normal file
@@ -0,0 +1,37 @@
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Registry,
|
||||
[Parameter(Mandatory=$true)][string]$Owner,
|
||||
[Parameter(Mandatory=$true)][string]$Repo,
|
||||
[string]$Tag = 'latest',
|
||||
[string]$Username = $null,
|
||||
[string]$Token = $null
|
||||
)
|
||||
|
||||
if (-not $Registry -or -not $Owner -or -not $Repo) {
|
||||
Write-Error "Usage: .\scripts\build_and_push.ps1 -Registry <registry> -Owner <owner> -Repo <repo> [-Tag <tag>] [-Username <user>] [-Token <token>]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$localImage = "$Repo:$Tag"
|
||||
$remoteImage = "$Registry/$Owner/$Repo:$Tag"
|
||||
|
||||
Write-Host "Building image: $localImage"
|
||||
docker build -t $localImage .
|
||||
|
||||
Write-Host "Tagging image -> $remoteImage"
|
||||
docker tag $localImage $remoteImage
|
||||
|
||||
if ($Token) {
|
||||
Write-Host "Logging in to $Registry using token"
|
||||
$secureToken = ConvertTo-SecureString $Token -AsPlainText -Force
|
||||
$credential = New-Object System.Management.Automation.PSCredential($Username, $secureToken)
|
||||
$Token | docker login $Registry -u ${Username:-$Owner} --password-stdin
|
||||
} else {
|
||||
Write-Host "Logging in to $Registry interactively"
|
||||
docker login $Registry -u ${Username:-$Owner}
|
||||
}
|
||||
|
||||
Write-Host "Pushing $remoteImage"
|
||||
docker push $remoteImage
|
||||
|
||||
Write-Host "Push finished: $remoteImage"
|
||||
40
scripts/build_and_push.sh
Normal file
40
scripts/build_and_push.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# build_and_push.sh <registry> <owner> <repo> [tag] [username] [token]
|
||||
# Example:
|
||||
# ./scripts/build_and_push.sh git.templarz.com templarz wsmud latest tempalrz <TOKEN>
|
||||
|
||||
REGISTRY=${1:-}
|
||||
OWNER=${2:-}
|
||||
REPO=${3:-}
|
||||
TAG=${4:-latest}
|
||||
USERNAME=${5:-}
|
||||
TOKEN=${6:-}
|
||||
|
||||
if [ -z "$REGISTRY" ] || [ -z "$OWNER" ] || [ -z "$REPO" ]; then
|
||||
echo "Usage: $0 <registry> <owner> <repo> [tag] [username] [token]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LOCAL_IMAGE="${REPO}:${TAG}"
|
||||
REMOTE_IMAGE="${REGISTRY}/${OWNER}/${REPO}:${TAG}"
|
||||
|
||||
echo "Building image: $LOCAL_IMAGE"
|
||||
docker build -t "$LOCAL_IMAGE" .
|
||||
|
||||
echo "Tagging image -> $REMOTE_IMAGE"
|
||||
docker tag "$LOCAL_IMAGE" "$REMOTE_IMAGE"
|
||||
|
||||
if [ -n "$TOKEN" ]; then
|
||||
echo "Logging in to $REGISTRY using token (password-stdin)"
|
||||
echo "$TOKEN" | docker login "$REGISTRY" -u "${USERNAME:-$OWNER}" --password-stdin
|
||||
else
|
||||
echo "Logging in to $REGISTRY interactively (you will be prompted)"
|
||||
docker login "$REGISTRY" -u "${USERNAME:-$OWNER}"
|
||||
fi
|
||||
|
||||
echo "Pushing $REMOTE_IMAGE"
|
||||
docker push "$REMOTE_IMAGE"
|
||||
|
||||
echo "Push finished: $REMOTE_IMAGE"
|
||||
Reference in New Issue
Block a user