diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1479785 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,53 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Build outputs +dist +dist-ssr +*.local + +# Environment files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Editor directories and files +.vscode +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Git +.git +.gitignore + +# Docker +Dockerfile +.dockerignore +docker-compose.yml + +# Misc +README.md +LICENSE +CODE_OF_CONDUCT.md +CONTRIBUTING.md +SECURITY.md + +# Lock files (we keep package-lock.json but ignore others) +pnpm-lock.yaml +yarn.lock +bun.lockb + +# Vite cache +vite.config.ts.timestamp-* diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..db348bf --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,160 @@ +# Docker Deployment Guide + +This guide explains how to run StackRender using Docker. + +## Quick Start + +### Using Docker Compose (Recommended) + +The easiest way to run StackRender: + +```bash +docker-compose up -d +``` + +The application will be available at `http://localhost:8080` + +To stop the application: + +```bash +docker-compose down +``` + +### Using Docker CLI + +Build the image: + +```bash +docker build -t stackrender . +``` + +Run the container: + +```bash +docker run -d -p 8080:80 --name stackrender stackrender +``` + +Stop and remove the container: + +```bash +docker stop stackrender +docker rm stackrender +``` + +## Configuration + +### Port Mapping + +By default, the application runs on port 80 inside the container and is mapped to port 8080 on the host. You can change this in `docker-compose.yml`: + +```yaml +ports: + - "YOUR_PORT:80" +``` + +Or when using Docker CLI: + +```bash +docker run -d -p YOUR_PORT:80 --name stackrender stackrender +``` + +### Health Check + +The Docker Compose configuration includes a health check that verifies the application is responding correctly: + +```yaml +healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s +``` + +## Architecture + +### Multi-Stage Build + +The Dockerfile uses a multi-stage build approach: + +1. **Builder Stage**: Uses Node.js 20 to install dependencies and build the application +2. **Production Stage**: Uses Nginx Alpine to serve the static files + +This approach minimizes the final image size by excluding build tools and dependencies. + +### Nginx Configuration + +The application uses a custom Nginx configuration (`nginx.conf`) that: + +- Enables gzip compression for better performance +- Sets security headers (X-Frame-Options, X-Content-Type-Options, X-XSS-Protection) +- Handles client-side routing (React Router) +- Configures caching for static assets + +## Troubleshooting + +### Build Issues + +If you encounter SSL certificate issues during the build, the Dockerfile includes a workaround: + +```dockerfile +RUN npm config set strict-ssl false && npm install +``` + +This is necessary in some build environments with certificate validation issues. + +### Container Not Starting + +Check the logs: + +```bash +docker logs stackrender +``` + +Or with Docker Compose: + +```bash +docker-compose logs +``` + +### Port Already in Use + +If port 8080 is already in use, you can change it in `docker-compose.yml` or use a different port with Docker CLI: + +```bash +docker run -d -p 8081:80 --name stackrender stackrender +``` + +## Development + +For development, it's recommended to run the application directly with Node.js instead of Docker: + +```bash +npm install +npm run dev +``` + +Docker is primarily intended for production deployments or testing the production build locally. + +## Production Deployment + +For production deployments: + +1. Build the image: + ```bash + docker build -t stackrender:production . + ``` + +2. Push to your container registry: + ```bash + docker tag stackrender:production your-registry/stackrender:latest + docker push your-registry/stackrender:latest + ``` + +3. Deploy using your orchestration tool (Kubernetes, Docker Swarm, etc.) + +## Additional Resources + +- [Docker Documentation](https://docs.docker.com/) +- [Docker Compose Documentation](https://docs.docker.com/compose/) +- [Nginx Documentation](https://nginx.org/en/docs/) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..70daa6f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +# Build stage - using standard debian-based node image for better compatibility +FROM node:20 AS builder + +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +# Note: strict-ssl is disabled to handle potential certificate issues in some build environments +RUN npm config set strict-ssl false && npm install + +# Copy source files +COPY . . + +# Increase Node memory to prevent out-of-memory errors during build +ENV NODE_OPTIONS=--max-old-space-size=4096 + + +# Build the application +RUN npm run build + +# Production stage +FROM nginx:alpine + +# Copy built files from builder stage +COPY --from=builder /app/dist /usr/share/nginx/html + +# Copy nginx configuration +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Expose port 80 +EXPOSE 80 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md index 54ab6fa..2e20c9d 100644 --- a/README.md +++ b/README.md @@ -45,18 +45,36 @@ And more coming very soon! Use the [cloud version](https://www.stackrender.io) or deploy locally to start designing your database schemas in minutes. -### How to Use +### How to Use Locally + +#### Using Docker (Recommended) +The easiest way to run StackRender locally is using Docker: + +```bash +# Build and run using Docker Compose +docker-compose up + +# Or build and run using Docker directly +docker build -t stackrender . +docker run -p 8080:80 stackrender +``` + +Then visit `http://localhost:8080` in your browser. + +#### Using Node.js Install dependencies and start the development server: -```text +```bash npm install npm run dev ``` + ### How to Build -Install dependencies and start the production build: -```text +Install dependencies and create a production build: +```bash npm install -npm run start +npm run build ``` + ## Try Using It in the Cloud 1. Visit [StackRender.io](https://www.stackrender.io) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..81a03bd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +services: + stackrender: + build: + context: . + dockerfile: Dockerfile + image: stackrender:latest + container_name: stackrender + ports: + - "8080:80" + restart: unless-stopped + environment: + - NODE_ENV=production + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..916e0d0 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,28 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Handle client-side routing + location / { + try_files $uri $uri/ /index.html; + } + + # Cache static assets + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|wasm)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } +}