chore(dev): update dev environment

This commit is contained in:
MingxuanGame
2025-08-24 13:49:09 +00:00
parent 7eea68aa9a
commit 86c6c291e4
11 changed files with 538 additions and 115 deletions

View File

@@ -6,11 +6,17 @@
"workspaceFolder": "/workspaces/osu_lazer_api",
"containerEnv": {
"MYSQL_DATABASE": "osu_api",
"MYSQL_USER": "osu_user",
"MYSQL_PASSWORD": "osu_password",
"MYSQL_USER": "osu_api",
"MYSQL_PASSWORD": "password",
"MYSQL_HOST": "mysql",
"MYSQL_PORT": "3306"
},
"runArgs": [
"--name",
"g0v0-devcontainer",
"--label",
"jetbrains-attach=true"
],
"customizations": {
"vscode": {
"extensions": [
@@ -21,7 +27,12 @@
"ms-vscode.vscode-json",
"redhat.vscode-yaml",
"ms-vscode.docker",
"rust-lang.rust-analyzer"
"rust-lang.rust-analyzer",
"ms-dotnettools.csdevkit",
"ms-dotnettools.csharp",
"ms-dotnettools.vscode-dotnet-runtime",
"ms-dotnettools.blazorwasm-companion",
"editorconfig.editorconfig"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
@@ -57,7 +68,24 @@
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true
}
},
"dotnet.defaultSolution": "/workspaces/osu_lazer_api/spectator-server/osu.Server.Spectator.sln",
"[csharp]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
},
"dotnet.completion.showCompletionItemsFromUnimportedNamespaces": true,
"dotnet.inlayHints.enableInlayHintsForParameters": true,
"dotnet.inlayHints.enableInlayHintsForLiteralParameters": true,
"dotnet.inlayHints.enableInlayHintsForIndexerParameters": true,
"dotnet.inlayHints.enableInlayHintsForObjectCreationParameters": true,
"dotnet.inlayHints.enableInlayHintsForOtherParameters": true,
"dotnet.inlayHints.enableInlayHintsForTypes": true,
"dotnet.inlayHints.enableInlayHintsForImplicitVariableTypes": true,
"dotnet.inlayHints.enableInlayHintsForLambdaParameterTypes": true,
"dotnet.inlayHints.enableInlayHintsForImplicitObjectCreation": true
}
}
},
@@ -66,13 +94,19 @@
"ghcr.io/devcontainers/features/rust:1": {
"version": "latest",
"profile": "default"
},
"ghcr.io/devcontainers/features/dotnet:2": {
"version": "8.0"
}
},
"forwardPorts": [
8000,
3306,
6379
6379,
8086,
80,
8080
],
"postCreateCommand": "uv sync --dev && uv pip install rosu-pp-py && uv run alembic upgrade head && uv run pre-commit install && cd packages/msgpack_lazer_api && cargo check",
"postCreateCommand": "uv sync --dev && uv pip install rosu-pp-py && uv run alembic upgrade head && uv run pre-commit install && cd packages/msgpack_lazer_api && cargo check && cd ../../spectator-server && dotnet restore",
"remoteUser": "vscode"
}
}

View File

@@ -1,56 +1,90 @@
version: '3.8'
services:
devcontainer:
image: mcr.microsoft.com/devcontainers/python:3.13
volumes:
- ../..:/workspaces:cached
- ~/.ssh:/home/vscode/.ssh:ro
command: sleep infinity
networks:
- devcontainer-network
depends_on:
- mysql
- redis
environment:
DATABASE_URL: mysql+aiomysql://osu_user:osu_password@mysql:3306/osu_api
REDIS_URL: redis://redis:6379/0
SECRET_KEY: dev-secret-key-change-in-production
OSU_CLIENT_ID: "5"
OSU_CLIENT_SECRET: "FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
mysql:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: osu_api
MYSQL_USER: osu_user
MYSQL_PASSWORD: osu_password
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ../mysql-init:/docker-entrypoint-initdb.d:cached
networks:
- devcontainer-network
command: --default-authentication-plugin=mysql_native_password
redis:
image: redis:7-alpine
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- devcontainer-network
command: redis-server --appendonly yes
networks:
devcontainer-network:
driver: bridge
volumes:
mysql-data:
redis-data:
version: '3.8'
services:
devcontainer:
image: mcr.microsoft.com/devcontainers/python:3.13
volumes:
- ../..:/workspaces:cached
- ~/.ssh:/home/vscode/.ssh:ro
command: sleep infinity
networks:
- devcontainer-network
depends_on:
- mysql
- redis
- nginx
environment:
# Python/FastAPI 环境变量
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: osu_api
MYSQL_USER: osu_api
MYSQL_PASSWORD: password
REDIS_URL: redis://redis:6379/0
OSU_CLIENT_ID: "5"
OSU_CLIENT_SECRET: "FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
# Spectator Server 环境变量
SAVE_REPLAYS: "0"
REPLAY_UPLOAD_THREADS: "1"
TRACK_BUILD_USER_COUNTS: "1"
SERVER_PORT: "8086"
REDIS_HOST: "redis"
DD_AGENT_HOST: "localhost"
SHARED_INTEROP_DOMAIN: "http://localhost:8000"
SHARED_INTEROP_SECRET: "dev-interop-secret"
SENTRY_DSN: "https://5840d8cb8d2b4d238369443bedef1d74@glitchtip.g0v0.top/4"
USE_LEGACY_RSA_AUTH: "0"
# .NET 环境变量
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
DOTNET_NOLOGO: "1"
mysql:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: osu_api
MYSQL_USER: osu_api
MYSQL_PASSWORD: password
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ../mysql-init:/docker-entrypoint-initdb.d:cached
networks:
- devcontainer-network
command: --default-authentication-plugin=mysql_native_password
redis:
image: redis:7-alpine
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- devcontainer-network
command: redis-server --appendonly yes
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- devcontainer-network
depends_on:
- mysql
- redis
networks:
devcontainer-network:
driver: bridge
volumes:
mysql-data:
redis-data:

78
.devcontainer/nginx.conf Normal file
View File

@@ -0,0 +1,78 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream app {
server devcontainer:8000;
}
upstream spectator {
server devcontainer:8086;
}
server {
listen 80;
server_name _;
client_max_body_size 50m;
# 屏蔽 /_lio/ 及其所有子路径的外部访问
location ~ ^/_lio/ {
return 403;
}
# Spectator Server SignalR Hub
location /signalr/ {
proxy_pass http://spectator/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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 $scheme;
proxy_set_header Authorization $http_authorization;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 60s;
proxy_cache_bypass $http_upgrade;
proxy_buffering off;
}
# Health check for spectator server
location /health {
proxy_pass http://spectator/health;
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 $scheme;
}
# FastAPI application
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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 $scheme;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 60s;
proxy_cache_bypass $http_upgrade;
proxy_buffering off;
}
}

View File

@@ -0,0 +1,42 @@
#!/bin/bash
# 开发环境启动脚本
# 同时启动 FastAPI 和 Spectator Server
set -e
if [ -f .env ]; then
echo "加载 .env 文件中的环境变量..."
set -a
source .env
set +a
else
echo ".env 文件未找到,跳过加载环境变量。"
fi
echo "🚀 启动开发环境..."
# 启动 FastAPI 服务器
echo "启动 FastAPI 服务器..."
cd /workspaces/osu_lazer_api
uv run uvicorn main:app --host 0.0.0.0 --port 8000 --reload &
FASTAPI_PID=$!
# 启动 Spectator Server
echo "启动 Spectator Server..."
cd /workspaces/osu_lazer_api/spectator-server
dotnet run --project osu.Server.Spectator --urls "http://0.0.0.0:8086" &
SPECTATOR_PID=$!
echo "✅ 服务已启动:"
echo " - FastAPI: http://localhost:8000"
echo " - Spectator Server: http://localhost:8086"
echo " - Nginx (统一入口): http://localhost:8080"
echo ""
echo "按 Ctrl+C 停止所有服务"
# 等待用户中断
trap 'echo "🛑 正在停止服务..."; kill $FASTAPI_PID $SPECTATOR_PID; exit 0' INT
# 保持脚本运行
wait