fix: production deployment improvements and configuration fixes #1

Merged
let5see merged 2 commits from fix/production-deployment-improvements into main 2026-01-26 17:21:39 +08:00
16 changed files with 68 additions and 39 deletions

View File

@@ -1,17 +1,10 @@
{
email your-email@example.com
email let5sne@gmail.com
}
your-domain.com {
# Mobile client (default)
handle {
root * /srv/mobile
try_files {path} /index.html
file_server
}
# Screen client
handle /screen/* {
2026.cptp.let5see.xyz {
# Screen client (must be before mobile to match first)
handle /screen* {
root * /srv/screen
uri strip_prefix /screen
try_files {path} /index.html
@@ -28,6 +21,13 @@ your-domain.com {
reverse_proxy server:3000
}
# Mobile client (default, matches everything else)
handle {
root * /srv/mobile
try_files {path} /index.html
file_server
}
# Gzip compression
encode gzip
}

View File

@@ -2,9 +2,17 @@ FROM node:20-alpine AS builder
WORKDIR /app
RUN npm install -g pnpm
# Build arguments for environment variables
ARG VITE_SOCKET_URL
ARG VITE_API_URL
ARG VITE_MOBILE_URL
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
# Install pnpm and configure registry
RUN npm config set registry https://registry.npmmirror.com && \
npm install -g pnpm && \
pnpm config set registry https://registry.npmmirror.com
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json ./
COPY packages/shared ./packages/shared
COPY packages/client-screen ./packages/client-screen
COPY packages/client-mobile ./packages/client-mobile

View File

@@ -2,11 +2,13 @@ FROM node:20-alpine AS builder
WORKDIR /app
# Install pnpm
RUN npm install -g pnpm
# Install pnpm and configure registry
RUN npm config set registry https://registry.npmmirror.com && \
npm install -g pnpm && \
pnpm config set registry https://registry.npmmirror.com
# Copy workspace files
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json ./
COPY packages/shared ./packages/shared
COPY packages/client-screen ./packages/client-screen
COPY packages/client-mobile ./packages/client-mobile

View File

@@ -19,7 +19,8 @@ services:
environment:
- NODE_ENV=production
- PORT=3000
- REDIS_URL=redis://redis:6379
- REDIS_HOST=redis
- REDIS_PORT=6379
- CORS_ORIGINS=${CORS_ORIGINS:-*}
depends_on:
- redis
@@ -30,6 +31,10 @@ services:
build:
context: .
dockerfile: deploy/Dockerfile.caddy
args:
- VITE_SOCKET_URL=${VITE_SOCKET_URL:-}
- VITE_API_URL=${VITE_API_URL:-}
- VITE_MOBILE_URL=${VITE_MOBILE_URL:-}
container_name: gala-caddy
restart: unless-stopped
ports:

View File

@@ -66,7 +66,7 @@ const statusText = computed(() => {
}
.latency {
color: $color-text-muted;
color: #999;
font-size: $font-size-xs;
}

View File

@@ -162,7 +162,7 @@ function delay(ms: number): Promise<void> {
<Postmark
v-if="hasStamp && stampInfo"
:award-name="stampInfo.name"
:award-icon-key="stampedWith"
:award-icon-key="stampedWith!"
:user-name="connectionStore.userName || ''"
color="gold"
class="applied-stamp"

View File

@@ -289,7 +289,7 @@ async function handleEnter() {
.footer {
text-align: center;
padding: $spacing-md;
color: $color-text-muted;
color: #999;
font-size: $font-size-xs;
}
</style>

View File

@@ -263,7 +263,7 @@ async function handleSubmit() {
.footer {
text-align: center;
padding: 16px;
color: $color-text-muted;
color: #999;
font-size: 12px;
}
</style>

View File

@@ -173,7 +173,7 @@ onMounted(() => {
}
.logout-btn {
color: $color-text-muted;
color: #999;
cursor: pointer;
padding: 2px 6px;
border-radius: 4px;
@@ -181,7 +181,7 @@ onMounted(() => {
&:active {
background: rgba(255, 255, 255, 0.1);
color: $color-text-light;
color: #fff;
}
}

View File

@@ -1,2 +1,3 @@
VITE_SOCKET_URL=
VITE_API_URL=
VITE_MOBILE_URL=

View File

@@ -22,7 +22,7 @@ function generateToken(code: string): string {
export { ADMIN_TOKEN_KEY, ADMIN_ACCESS_CODE, generateToken };
const router = createRouter({
history: createWebHistory(),
history: createWebHistory('/screen/'),
routes: [
// ============================================
// Big Screen Display Routes (LED PC)

View File

@@ -19,9 +19,9 @@ let audioPlayer: HTMLAudioElement | null = null;
// Audio file paths - place audio files in public/audio/
const AUDIO_TRACKS: Record<string, string> = {
bgm: '/audio/bgm.mp3',
lottery: '/audio/lottery.mp3',
fanfare: '/audio/fanfare.mp3',
bgm: '/screen/audio/bgm.mp3',
lottery: '/screen/audio/lottery.mp3',
fanfare: '/screen/audio/fanfare.mp3',
};
export const useDisplayStore = defineStore('display', () => {

View File

@@ -25,7 +25,7 @@ const participantCount = ref(0);
let previousSubPhase: string | null = null;
// Prize configuration - 从服务器加载
const prizes = ref<Array<{ level: string; name: string; winnerCount: number; poolTag?: string }>>([]);
const prizes = ref<Array<{ level: string; name: string; winnerCount: number; poolTag?: string; round?: number }>>([]);
// 从 API 获取奖项配置
async function fetchPrizes() {

View File

@@ -10,8 +10,8 @@ const displayStore = useDisplayStore();
// QR Code Login (legacy - kept for direct access)
const showQRLogin = ref(false);
// Mobile URL for entry QR code
const mobileUrl = 'http://192.168.1.5:5174';
// Mobile URL for entry QR code - use environment variable or fallback to current origin
const mobileUrl = import.meta.env.VITE_MOBILE_URL || window.location.origin;
function handleLoginSuccess(data: { userId: string; userName: string; department: string; sessionToken: string }) {
console.log('Login success:', data);

View File

@@ -3,6 +3,7 @@ import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
export default defineConfig({
base: '/screen/',
plugins: [vue()],
resolve: {
alias: {

View File

@@ -2,11 +2,13 @@ FROM node:20-alpine AS builder
WORKDIR /app
# Install pnpm
RUN npm install -g pnpm
# Install pnpm and configure registry
RUN npm config set registry https://registry.npmmirror.com && \
npm install -g pnpm && \
pnpm config set registry https://registry.npmmirror.com
# Copy workspace files
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json ./
COPY packages/shared ./packages/shared
COPY packages/server ./packages/server
@@ -26,18 +28,28 @@ FROM node:20-alpine AS production
WORKDIR /app
RUN npm install -g pnpm
RUN npm config set registry https://registry.npmmirror.com && \
npm install -g pnpm && \
pnpm config set registry https://registry.npmmirror.com
# Copy package files
COPY --from=builder /app/pnpm-workspace.yaml ./
COPY --from=builder /app/package.json ./
COPY --from=builder /app/pnpm-lock.yaml ./
COPY --from=builder /app/packages/server/package.json ./packages/server/
COPY --from=builder /app/packages/shared ./packages/shared
# Install production dependencies only
RUN pnpm install --prod --frozen-lockfile
# Copy built files
COPY --from=builder /app/packages/server/dist ./dist
COPY --from=builder /app/packages/server/package.json ./
COPY --from=builder /app/packages/shared /app/packages/shared
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/packages/server/node_modules ./packages/server/node_modules
COPY --from=builder /app/packages/server/dist ./packages/server/dist
COPY --from=builder /app/packages/server/src/lua ./packages/server/lua
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000
WORKDIR /app/packages/server
CMD ["node", "dist/index.js"]