feat: make backend Docker-ready and web Vercel-ready
- Switch @bytelyst/* deps from link: to private Gitea registry (^0.x) - Add .npmrc pointing to gitea.bytelyst.com private npm registry - Rewrite backend/Dockerfile: monorepo root context, pnpm workspace, correct EXPOSE 4018, CMD node dist/backend/src/bootstrap.js - Move vercel.json to repo root with pnpm filter build commands - Remove web/Dockerfile and web/nginx.conf (web is Vercel-only) - Remove web service from docker-compose.yml (backend Docker only) - Document GITEA_NPM_TOKEN requirement in .env.example - Fix start script path: dist/backend/src/bootstrap.js (rootDir: "..") PREREQUISITE: Set GITEA_NPM_TOKEN and run pnpm install to regenerate pnpm-lock.yaml before first Docker build. Vercel settings: Root Directory = repo root, add GITEA_NPM_TOKEN env var. Docker build: GITEA_NPM_TOKEN=<token> docker compose build Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a256571480
commit
5e07ac040d
@ -1,3 +1,7 @@
|
|||||||
|
# Private npm registry for @bytelyst/* packages (Gitea)
|
||||||
|
# Required for: pnpm install (dev + CI), Docker builds, Vercel builds
|
||||||
|
GITEA_NPM_TOKEN=
|
||||||
|
|
||||||
# Shared product identity
|
# Shared product identity
|
||||||
PRODUCT_ID=invttrdg
|
PRODUCT_ID=invttrdg
|
||||||
PRODUCT_DISPLAY_NAME=ByteLyst Trading
|
PRODUCT_DISPLAY_NAME=ByteLyst Trading
|
||||||
|
|||||||
2
.npmrc
Normal file
2
.npmrc
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@bytelyst:registry=https://gitea.bytelyst.com/api/packages/ByteLyst/npm/
|
||||||
|
//gitea.bytelyst.com/api/packages/ByteLyst/npm/:_authToken=${GITEA_NPM_TOKEN}
|
||||||
@ -1,35 +1,54 @@
|
|||||||
# --- Stage 1: Build ---
|
# Build context: learning_ai_invt_trdg/ (monorepo root)
|
||||||
FROM node:18-alpine AS builder
|
# docker-compose passes GITEA_NPM_TOKEN as a build arg for the private @bytelyst registry
|
||||||
|
#
|
||||||
WORKDIR /app
|
# --- Stage 1: Build ---
|
||||||
|
FROM node:18-alpine AS builder
|
||||||
# Install build dependencies
|
|
||||||
COPY package*.json ./
|
RUN corepack enable && corepack prepare pnpm@10.6.5 --activate
|
||||||
RUN npm ci
|
|
||||||
|
WORKDIR /app
|
||||||
# Copy source and compile
|
|
||||||
COPY . .
|
ARG GITEA_NPM_TOKEN
|
||||||
RUN npm run build
|
ENV GITEA_NPM_TOKEN=${GITEA_NPM_TOKEN}
|
||||||
|
|
||||||
# --- Stage 2: Production ---
|
# Copy workspace root files first (layer cache)
|
||||||
FROM node:18-alpine
|
# NOTE: After switching @bytelyst/* deps from link: to registry, run:
|
||||||
|
# GITEA_NPM_TOKEN=<token> pnpm install
|
||||||
WORKDIR /app
|
# to regenerate pnpm-lock.yaml, then restore --frozen-lockfile here.
|
||||||
|
COPY .npmrc pnpm-workspace.yaml pnpm-lock.yaml* ./
|
||||||
# Copy only production dependencies
|
COPY package.json ./package.json
|
||||||
COPY package*.json ./
|
COPY backend/package.json ./backend/package.json
|
||||||
RUN npm ci --omit=dev
|
|
||||||
|
# Install backend deps only
|
||||||
# Copy compiled files from builder
|
RUN pnpm install --filter @bytelyst/trading-backend
|
||||||
COPY --from=builder /app/dist ./dist
|
|
||||||
|
# Copy source (backend + shared types used by tsconfig rootDir "..")
|
||||||
# Ensure the node user owns the app directory
|
COPY backend/ ./backend/
|
||||||
RUN chown -R node:node /app
|
COPY shared/ ./shared/
|
||||||
|
WORKDIR /app/backend
|
||||||
# Expose the API port for the dashboard
|
RUN pnpm run build
|
||||||
EXPOSE 5000
|
|
||||||
|
# --- Stage 2: Production ---
|
||||||
# Use non-root user for security
|
FROM node:18-alpine
|
||||||
USER node
|
|
||||||
|
RUN corepack enable && corepack prepare pnpm@10.6.5 --activate
|
||||||
CMD ["node", "dist/index.js"]
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ARG GITEA_NPM_TOKEN
|
||||||
|
ENV GITEA_NPM_TOKEN=${GITEA_NPM_TOKEN}
|
||||||
|
|
||||||
|
COPY .npmrc pnpm-workspace.yaml pnpm-lock.yaml* ./
|
||||||
|
COPY package.json ./package.json
|
||||||
|
COPY backend/package.json ./backend/package.json
|
||||||
|
|
||||||
|
RUN pnpm install --filter @bytelyst/trading-backend --prod
|
||||||
|
|
||||||
|
COPY --from=builder /app/backend/dist ./backend/dist
|
||||||
|
|
||||||
|
RUN chown -R node:node /app
|
||||||
|
USER node
|
||||||
|
|
||||||
|
WORKDIR /app/backend
|
||||||
|
EXPOSE 4018
|
||||||
|
CMD ["node", "dist/backend/src/bootstrap.js"]
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
"dev": "node --import tsx src/bootstrap.ts",
|
"dev": "node --import tsx src/bootstrap.ts",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"start": "node dist/bootstrap.js",
|
"start": "node dist/backend/src/bootstrap.js",
|
||||||
"check:schema-contract": "node --import tsx verifySchemaContract.ts",
|
"check:schema-contract": "node --import tsx verifySchemaContract.ts",
|
||||||
"check:rls-policies": "node --import tsx verifyRlsPolicies.ts",
|
"check:rls-policies": "node --import tsx verifyRlsPolicies.ts",
|
||||||
"check:secret-hygiene": "node --import tsx verifySecretHygiene.ts",
|
"check:secret-hygiene": "node --import tsx verifySecretHygiene.ts",
|
||||||
@ -53,10 +53,10 @@
|
|||||||
"@azure/cosmos": "^4.3.0",
|
"@azure/cosmos": "^4.3.0",
|
||||||
"@azure/identity": "^4.10.0",
|
"@azure/identity": "^4.10.0",
|
||||||
"@azure/keyvault-secrets": "^4.9.0",
|
"@azure/keyvault-secrets": "^4.9.0",
|
||||||
"@bytelyst/auth": "link:../../../learning_ai/learning_ai_common_plat/packages/auth",
|
"@bytelyst/auth": "^0.1.0",
|
||||||
"@bytelyst/config": "link:../../../learning_ai/learning_ai_common_plat/packages/config",
|
"@bytelyst/config": "^0.1.0",
|
||||||
"@bytelyst/cosmos": "link:../../../learning_ai/learning_ai_common_plat/packages/cosmos",
|
"@bytelyst/cosmos": "^0.1.0",
|
||||||
"@bytelyst/llm": "link:../../../learning_ai/learning_ai_common_plat/packages/llm",
|
"@bytelyst/llm": "^0.1.0",
|
||||||
"@alpacahq/alpaca-trade-api": "^3.1.3",
|
"@alpacahq/alpaca-trade-api": "^3.1.3",
|
||||||
"@supabase/supabase-js": "^2.90.1",
|
"@supabase/supabase-js": "^2.90.1",
|
||||||
"@types/cors": "^2.8.19",
|
"@types/cors": "^2.8.19",
|
||||||
|
|||||||
@ -3,19 +3,11 @@ version: '3.9'
|
|||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
build:
|
build:
|
||||||
context: ./backend
|
context: .
|
||||||
|
dockerfile: backend/Dockerfile
|
||||||
|
args:
|
||||||
|
GITEA_NPM_TOKEN: ${GITEA_NPM_TOKEN}
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
ports:
|
ports:
|
||||||
- '4018:4018'
|
- '4018:4018'
|
||||||
|
|
||||||
web:
|
|
||||||
build:
|
|
||||||
context: ./web
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
ports:
|
|
||||||
- '3048:3048'
|
|
||||||
depends_on:
|
|
||||||
- backend
|
|
||||||
|
|
||||||
|
|||||||
@ -13,10 +13,10 @@
|
|||||||
"verify": "./scripts/verify.sh"
|
"verify": "./scripts/verify.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bytelyst/kill-switch-client": "link:../../learning_ai/learning_ai_common_plat/packages/kill-switch-client",
|
"@bytelyst/kill-switch-client": "^0.1.0",
|
||||||
"@bytelyst/react-auth": "link:../../learning_ai/learning_ai_common_plat/packages/react-auth",
|
"@bytelyst/react-auth": "^0.1.1",
|
||||||
"@bytelyst/react-native-platform-sdk": "link:../../learning_ai/learning_ai_common_plat/packages/react-native-platform-sdk",
|
"@bytelyst/react-native-platform-sdk": "^1.0.0",
|
||||||
"@bytelyst/telemetry-client": "link:../../learning_ai/learning_ai_common_plat/packages/telemetry-client"
|
"@bytelyst/telemetry-client": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
|
|||||||
11
vercel.json
Normal file
11
vercel.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"installCommand": "pnpm install --filter @bytelyst/trading-web",
|
||||||
|
"buildCommand": "pnpm --filter @bytelyst/trading-web run build",
|
||||||
|
"outputDirectory": "web/dist",
|
||||||
|
"rewrites": [
|
||||||
|
{
|
||||||
|
"source": "/(.*)",
|
||||||
|
"destination": "/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# --- Stage 1: Build ---
|
|
||||||
FROM node:18-alpine AS builder
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Install build dependencies
|
|
||||||
COPY package*.json ./
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# Copy source and build
|
|
||||||
# Copy source and build
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Build-time environment variables
|
|
||||||
ARG VITE_SUPABASE_URL
|
|
||||||
ARG VITE_SUPABASE_ANON_KEY
|
|
||||||
ARG VITE_API_URL
|
|
||||||
|
|
||||||
ENV VITE_SUPABASE_URL=$VITE_SUPABASE_URL
|
|
||||||
ENV VITE_SUPABASE_ANON_KEY=$VITE_SUPABASE_ANON_KEY
|
|
||||||
ENV VITE_API_URL=$VITE_API_URL
|
|
||||||
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# --- Stage 2: Serve ---
|
|
||||||
FROM nginx:stable-alpine
|
|
||||||
|
|
||||||
# Copy static assets from builder
|
|
||||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
|
||||||
|
|
||||||
# Expose port 80
|
|
||||||
EXPOSE 80
|
|
||||||
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
|
||||||
@ -18,9 +18,9 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bytelyst/kill-switch-client": "link:../../../learning_ai/learning_ai_common_plat/packages/kill-switch-client",
|
"@bytelyst/kill-switch-client": "^0.1.0",
|
||||||
"@bytelyst/react-auth": "link:../../../learning_ai/learning_ai_common_plat/packages/react-auth",
|
"@bytelyst/react-auth": "^0.1.1",
|
||||||
"@bytelyst/telemetry-client": "link:../../../learning_ai/learning_ai_common_plat/packages/telemetry-client",
|
"@bytelyst/telemetry-client": "^0.1.0",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"rewrites": [
|
|
||||||
{
|
|
||||||
"source": "/(.*)",
|
|
||||||
"destination": "/index.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user