Generated by Spark: Is there a simpler way for the docker image to serve up the app? Its really glitchy when deploying to caprover

This commit is contained in:
2026-01-17 17:00:11 +00:00
committed by GitHub
parent 640c861ac2
commit 855257f392
4 changed files with 87 additions and 24 deletions

77
DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,77 @@
# Deployment Guide
## Simplified Docker Setup
The application now uses a simplified single-stage Docker build with Vite's preview server instead of nginx. This eliminates the complexity and glitches associated with the multi-stage nginx deployment.
## Benefits
- **Simpler**: Single-stage build, no nginx configuration needed
- **Smaller**: Alpine-based image (~100MB smaller)
- **More reliable**: Vite preview server handles routing correctly by default
- **Faster builds**: No multi-stage copying overhead
- **Better for SPA**: Vite preview understands React Router automatically
## CapRover Deployment
### Quick Deploy
1. Build and push your image:
```bash
docker build -t your-registry/codeforge:latest .
docker push your-registry/codeforge:latest
```
2. In CapRover, create a new app and deploy using the image
3. CapRover will automatically map port 80
### Environment Variables
The app respects the `PORT` environment variable, which CapRover sets automatically:
- Default: `80`
- CapRover will override this as needed
### Build Notes
- The Dockerfile uses `npm ci --omit=dev` to install only production dependencies after the build
- Console logs are stripped in production via terser
- Assets are served with proper routing via Vite's preview server
## Local Testing
Test the production build locally:
```bash
# Build the app
npm run build
# Preview (simulates production)
npm run preview
# Or with custom port
PORT=3000 npm run preview
```
## Why This Works Better
The previous nginx setup had these issues:
1. Required maintaining separate nginx configuration
2. Multi-stage build complexity
3. Asset path resolution issues with React Router
4. Health check endpoint needs custom nginx config
The Vite preview server:
1. Built-in SPA routing support
2. Handles all asset paths correctly
3. Production-ready and officially supported
4. Simpler configuration via vite.config.ts
## Troubleshooting
If you still experience issues:
1. **Check the base path**: Ensure `base: './'` in vite.config.ts
2. **Verify port**: CapRover should set PORT env var automatically
3. **Check logs**: Use CapRover's log viewer to see startup issues
4. **Test locally**: Run `npm run build && npm run preview` to verify the build

View File

@@ -1,39 +1,20 @@
FROM node:lts-trixie AS builder
FROM node:lts-alpine
WORKDIR /app
# Upgrade npm to the latest version
RUN npm install -g npm@latest
# Copy workspace configuration and all package files
COPY package*.json ./
# Copy spark-tools package (the actual @github/spark implementation)
COPY packages/spark-tools ./packages/spark-tools
# Copy spark wrapper package
COPY packages/spark ./packages/spark
# Install dependencies with npm ci for consistent, reproducible builds
# Include optional dependencies to ensure platform-specific binaries are installed
RUN npm ci --include=optional
RUN npm ci --include=optional --omit=dev
# Copy remaining application files
COPY . .
# Build the application
RUN npm run build
FROM nginx:alpine AS runtime
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/health || exit 1
ENV PORT=80
CMD ["nginx", "-g", "daemon off;"]
CMD ["npm", "run", "preview"]

View File

@@ -11,7 +11,7 @@
"lint": "eslint . --fix",
"lint:check": "eslint .",
"optimize": "vite optimize",
"preview": "vite preview",
"preview": "vite preview --host 0.0.0.0 --port ${PORT:-80}",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed",

View File

@@ -28,6 +28,11 @@ export default defineConfig({
port: 5000,
strictPort: false,
},
preview: {
host: '0.0.0.0',
port: Number(process.env.PORT) || 80,
strictPort: false,
},
build: {
outDir: 'dist',
emptyOutDir: true,