Files
scriptshare-cursor/Dockerfile

128 lines
3.5 KiB
Docker

# Build stage
FROM node:18-alpine AS builder
# Install build dependencies for native modules (bcrypt, etc.)
RUN apk add --no-cache python3 make g++ libc6-compat
WORKDIR /app
# Copy package files first for better Docker layer caching
COPY package*.json ./
# Install dependencies with proper npm cache handling
RUN npm ci --only=production=false --silent
# Copy source code
COPY . .
# Set build-time environment variables
ARG VITE_APP_NAME="ScriptShare"
ARG VITE_APP_URL="https://scriptshare.example.com"
ARG VITE_ANALYTICS_ENABLED="false"
# Export as environment variables for Vite build
ENV VITE_APP_NAME=$VITE_APP_NAME
ENV VITE_APP_URL=$VITE_APP_URL
ENV VITE_ANALYTICS_ENABLED=$VITE_ANALYTICS_ENABLED
# Remove problematic server-side API files for frontend-only build
RUN rm -rf src/lib/api || true
RUN rm -rf src/lib/db || true
# Create mock API layer for frontend demo
RUN mkdir -p src/lib/api src/lib/db
RUN echo "export const db = {}; export * from './mock';" > src/lib/db/index.ts
RUN echo "export const users = {}; export const scripts = {};" > src/lib/db/schema.ts
RUN echo "export * from './mock';" > src/lib/api/index.ts
# Create mock API files
RUN cat > src/lib/api/auth.ts << 'EOF'
export const authApi = {
login: async () => ({ token: 'demo', user: { id: '1', username: 'demo' } }),
register: async () => ({ token: 'demo', user: { id: '1', username: 'demo' } }),
};
EOF
RUN cat > src/lib/api/scripts.ts << 'EOF'
export const scriptsApi = {
getScripts: async () => ({ scripts: [], total: 0 }),
getScript: async () => null,
createScript: async () => ({}),
updateScript: async () => ({}),
deleteScript: async () => ({}),
moderateScript: async () => ({}),
};
EOF
RUN cat > src/lib/api/ratings.ts << 'EOF'
export const ratingsApi = {
submitRating: async () => ({}),
getUserRating: async () => null,
getScriptRatingStats: async () => ({ averageRating: 0, totalRatings: 0 }),
};
EOF
RUN cat > src/lib/api/analytics.ts << 'EOF'
export const analyticsApi = {
trackEvent: async () => ({}),
getAnalytics: async () => ({ views: [], downloads: [] }),
};
EOF
RUN cat > src/lib/api/collections.ts << 'EOF'
export const collectionsApi = {
getCollections: async () => [],
createCollection: async () => ({}),
updateCollection: async () => ({}),
deleteCollection: async () => ({}),
};
EOF
RUN cat > src/lib/api/users.ts << 'EOF'
export const usersApi = {
getUser: async () => null,
updateUser: async () => ({}),
updateUserPermissions: async () => ({}),
};
EOF
# Build the application (frontend only with mocks)
RUN npm run build
# Verify build output exists
RUN ls -la /app/dist
# Production stage
FROM nginx:alpine
# Install curl for health checks
RUN apk add --no-cache curl
# Copy built files from builder stage
COPY --from=builder /app/dist /usr/share/nginx/html
# Copy nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf
# Create nginx pid directory
RUN mkdir -p /var/run/nginx
# Set proper permissions
RUN chown -R nginx:nginx /usr/share/nginx/html
RUN chown -R nginx:nginx /var/cache/nginx
RUN chown -R nginx:nginx /var/log/nginx
RUN chown -R nginx:nginx /var/run/nginx
# Switch to non-root user for security
USER nginx
# Expose port 80
EXPOSE 80
# Add healthcheck
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost/health || exit 1
# Start nginx
CMD ["nginx", "-g", "daemon off;"]