From 86652da94b1e844b08bbf7e4eb397dc3499a17a5 Mon Sep 17 00:00:00 2001 From: "SN\\plastic" Date: Fri, 3 Oct 2025 15:27:51 +0200 Subject: [PATCH 1/7] feat: add Docker containerization support - Add Dockerfile for SenseNet client application - Add docker-compose.dev.yml for development with hot reload - Add docker-compose.prod.yml for production deployment - Add .dockerignore for optimized builds - Add .env.example for environment configuration Usage: - Development: docker-compose -f docker-compose.dev.yml up -d - Production: docker-compose -f docker-compose.prod.yml up -d --- .dockerignore | 42 +++++++++++++++++++++++++++++++++++++++++ .env.example | 31 ++++++++++++++++++++++++++++++ Dockerfile | 24 +++++++++++++++++++++++ docker-compose.dev.yml | 22 +++++++++++++++++++++ docker-compose.prod.yml | 14 ++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 Dockerfile create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.prod.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..dacef15da --- /dev/null +++ b/.dockerignore @@ -0,0 +1,42 @@ +# Node modules (will be installed in container) +node_modules +*/node_modules +**/node_modules + +# Build outputs +dist +build +coverage +*.tsbuildinfo + +# Development files +.git +.github +.vscode +*.log +# Note: We need yarn.lock and package-lock.json for dependency resolution +# *.lock + +# Docker +*.dockerignore +Dockerfile* +docker-compose* +.docker + +# Docker volumes +docker_data/ +docker_volumes/ + +# Development +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Cypress +cypress/videos +cypress/screenshots + +# Misc +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..b4ef6d10b --- /dev/null +++ b/.env.example @@ -0,0 +1,31 @@ +# Environment Variables for Docker Compose +# Copy this file to .env and modify as needed + +# Authentication Type (SNAuth or IdentityServer) +AUTH_TYPE=SNAuth + +# Node Environment +NODE_ENV=production + +# Ports +SENSENET_CLIENT_PORT=8080 +SENSENET_DEV_PORT=3000 + +# Development Settings (for hot reload) +CHOKIDAR_USEPOLLING=true +WATCHPACK_POLLING=true + +# Database Settings (if using database service) +# DB_PASSWORD=YourPassword123! +# DB_NAME=SenseNet +# DB_USER=sa + +# Redis Settings (if using redis service) +# REDIS_PASSWORD= + +# Traefik Settings (if using traefik service) +# TRAEFIK_DOMAIN=sensenet.local + +# Backend API URL (if connecting to external backend) +# REACT_APP_SERVICE_URL=https://dev.demo.sensenet.com +# REACT_APP_IDENTITY_SERVER_URL=https://is.demo.sensenet.com \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..83bb18a13 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +# Development Dockerfile for SenseNet client with hot reload +FROM node:20-alpine + +# Set working directory +WORKDIR /app + +# Copy everything (dockerignore excludes unwanted files) +COPY . . + +# Install dependencies +RUN yarn install + +# Build packages (required for the app to work) +RUN yarn build + +# Expose port +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8080/ || exit 1 + +# Default command (overridden in docker-compose for hot reload) +CMD ["yarn", "snapp", "start"] diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 000000000..4c2a74a77 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,22 @@ +version: "3.8" + +services: + sensenet-dev: + build: + context: . + dockerfile: Dockerfile + container_name: sensenet-dev + ports: + - "8080:8080" + environment: + - NODE_ENV=development + - AUTH_TYPE=SNAuth + - CHOKIDAR_USEPOLLING=true + - WATCHPACK_POLLING=true + volumes: + - .:/app + - /app/node_modules + - /app/packages/*/node_modules + - /app/apps/*/node_modules + command: yarn snapp start + restart: unless-stopped diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 000000000..781e6904c --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,14 @@ +version: "3.8" + +services: + sensenet-app: + build: + context: . + dockerfile: Dockerfile + container_name: sensenet-app + ports: + - "8080:8080" + environment: + - NODE_ENV=production + - AUTH_TYPE=SNAuth + restart: unless-stopped From 8736972aa36ed9854ebba56671a210eaed46e30c Mon Sep 17 00:00:00 2001 From: "SN\\plastic" Date: Fri, 3 Oct 2025 16:23:50 +0200 Subject: [PATCH 2/7] feat: add Docker CI/CD workflow - Add GitHub Actions workflow for Docker image builds - Builds and pushes to DockerHub with smart tagging - Triggers on pushes to docker-containerization branch - Triggers on PRs to develop, main, and sn-auth-package-extraimprovements - Safely skips build if no Dockerfile exists - Uses branch-based and SHA-based tags for versioning --- .github/workflows/docker-image.yml | 62 ++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 000000000..48fe95281 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,62 @@ +name: Docker Image CI + +on: + push: + branches: + - "feature/docker-containerization" # Only containerization branch for now + pull_request: + branches: + - "develop" + - "main" + - "feature/sn-auth-package-extraimprovements" # Current dev branch with latest sn-auth + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Check if Dockerfile exists + id: check_dockerfile + run: | + if [ -f "Dockerfile" ]; then + echo "dockerfile_exists=true" >> $GITHUB_OUTPUT + else + echo "dockerfile_exists=false" >> $GITHUB_OUTPUT + echo "⚠️ No Dockerfile found, skipping Docker build" + fi + + - name: Set up Docker metadata + if: steps.check_dockerfile.outputs.dockerfile_exists == 'true' + id: meta + uses: docker/metadata-action@v5 + with: + images: sensenetcsp/sn-client + tags: | + # Branch name + type=ref,event=branch + # Latest tag for main branch + type=raw,value=latest,enable={{is_default_branch}} + # PR number for pull requests + type=ref,event=pr + # Short SHA + type=sha,prefix={{branch}}- + + - name: Login to DockerHub + if: steps.check_dockerfile.outputs.dockerfile_exists == 'true' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push Docker image + if: steps.check_dockerfile.outputs.dockerfile_exists == 'true' + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From f05b42b2c8ab043c67b3b5da96eef46f26a9ba7d Mon Sep 17 00:00:00 2001 From: "SN\\plastic" Date: Fri, 3 Oct 2025 16:26:28 +0200 Subject: [PATCH 3/7] fix: Docker workflow tag format issue - Fix invalid tag format causing build failure - Use proper suffix/prefix for SHA tags - Ensure Docker tag compliance --- .github/workflows/docker-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 48fe95281..27afdf822 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -35,14 +35,14 @@ jobs: with: images: sensenetcsp/sn-client tags: | - # Branch name - type=ref,event=branch + # Branch name (replace slashes with hyphens) + type=ref,event=branch,suffix=-{{sha}} # Latest tag for main branch type=raw,value=latest,enable={{is_default_branch}} # PR number for pull requests type=ref,event=pr - # Short SHA - type=sha,prefix={{branch}}- + # Short SHA for current commit + type=sha,prefix=sha- - name: Login to DockerHub if: steps.check_dockerfile.outputs.dockerfile_exists == 'true' From 02802c14365f0e74055531ed8d960cad37103beb Mon Sep 17 00:00:00 2001 From: "SN\\plastic" Date: Fri, 3 Oct 2025 16:30:05 +0200 Subject: [PATCH 4/7] fix: prevent duplicate workflow runs - Skip draft PRs to avoid duplicate builds - Only trigger PR builds when PR is ready for review - Maintain push-based builds for active development --- .github/workflows/docker-image.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 27afdf822..1506df21c 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -5,6 +5,7 @@ on: branches: - "feature/docker-containerization" # Only containerization branch for now pull_request: + types: [opened, synchronize, reopened, ready_for_review] # Skip draft PRs branches: - "develop" - "main" @@ -13,6 +14,8 @@ on: jobs: build: runs-on: ubuntu-latest + # Skip draft PRs + if: github.event.pull_request.draft == false || github.event_name == 'push' steps: - name: Check out the repo From 12723ab984c9b4b0f1e98485032732d90710e5df Mon Sep 17 00:00:00 2001 From: "SN\\plastic" Date: Fri, 3 Oct 2025 16:31:39 +0200 Subject: [PATCH 5/7] remove space --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 1506df21c..1249e08b4 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -5,7 +5,7 @@ on: branches: - "feature/docker-containerization" # Only containerization branch for now pull_request: - types: [opened, synchronize, reopened, ready_for_review] # Skip draft PRs + types: [opened, synchronize, reopened, ready_for_review] # Skip draft PRs branches: - "develop" - "main" From 93f91529bb4781b30cfb36b5ecb31ad8b6bf7adb Mon Sep 17 00:00:00 2001 From: "SN\\plastic" Date: Fri, 3 Oct 2025 16:40:58 +0200 Subject: [PATCH 6/7] refactor: remove SHA-only Docker tags - Remove standalone SHA tags to prevent DockerHub clutter - Keep clean branch names and branch+SHA tags for useful scenarios - Maintain manageable tag strategy for long-term development --- .github/workflows/docker-image.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 1249e08b4..11acc91fe 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -38,14 +38,14 @@ jobs: with: images: sensenetcsp/sn-client tags: | - # Branch name (replace slashes with hyphens) + # Clean branch name (e.g., feature-docker-containerization) + type=ref,event=branch + # Branch name with SHA (e.g., feature-docker-containerization-abc1234) type=ref,event=branch,suffix=-{{sha}} # Latest tag for main branch type=raw,value=latest,enable={{is_default_branch}} # PR number for pull requests type=ref,event=pr - # Short SHA for current commit - type=sha,prefix=sha- - name: Login to DockerHub if: steps.check_dockerfile.outputs.dockerfile_exists == 'true' From ea3da19ead4e7b01d9917e30ebafe7eb0e2841c4 Mon Sep 17 00:00:00 2001 From: "SN\\plastic" Date: Fri, 3 Oct 2025 17:01:53 +0200 Subject: [PATCH 7/7] docs: update Docker documentation to reflect simplified setup - Removed multi-stage Dockerfile complexity - Updated documentation to match single Dockerfile approach - Both dev and prod modes use 'yarn snapp start' - Development uses volume mounts for hot reload - Production uses built-in code without volumes - Simplified and cleaner Docker setup --- DOCKER.md | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 DOCKER.md diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 000000000..059048134 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,129 @@ +# Docker Setup for SenseNet Client + +This guide explains how to run the SenseNet client application using Docker. + +## 🚀 Quick Start + +### Development (with hot reload) +```bash +docker-compose -f docker-compose.dev.yml up -d +``` +- **URL**: http://localhost:8080 +- **Hot reload**: ✅ File changes are instantly reflected +- **Use case**: Active development + +### Production +```bash +docker-compose -f docker-compose.prod.yml up -d +``` +- **URL**: http://localhost:8080 +- **Hot reload**: ❌ Static built files +- **Use case**: Testing production builds, deployment + +## 📁 Files Overview + +| File | Purpose | +|------|---------| +| `Dockerfile` | Single Docker image for both dev and prod | +| `docker-compose.dev.yml` | Development setup with volume mounts | +| `docker-compose.prod.yml` | Production setup without volume mounts | +| `.dockerignore` | Excludes unnecessary files from build context | + +## 🔧 How It Works + +### Development Mode +- **Volume mounting**: Your local code is mounted into the container +- **File watching**: Changes trigger automatic rebuilds +- **Command**: `yarn snapp start` (webpack dev server with hot reload) + +### Production Mode +- **Built files**: Uses pre-built static files inside the container +- **No volumes**: Container is self-contained +- **Command**: `yarn snapp start` (same command, but runs webpack dev server on built files) + +## 🛠️ Common Commands + +```bash +# Start development +docker-compose -f docker-compose.dev.yml up -d + +# Stop development +docker-compose -f docker-compose.dev.yml down + +# Rebuild and start (after dependency changes) +docker-compose -f docker-compose.dev.yml up --build -d + +# View logs +docker-compose -f docker-compose.dev.yml logs -f + +# Start production +docker-compose -f docker-compose.prod.yml up -d +``` + +## 🐳 Docker Images + +Automatic builds are available on DockerHub: + +```bash +# Latest development build +docker pull sensenetcsp/sn-client:feature-docker-containerization + +# Specific commit +docker pull sensenetcsp/sn-client:feature-docker-containerization-abc1234 + +# Production (when merged to main) +docker pull sensenetcsp/sn-client:latest +``` + +## ⚙️ Configuration + +### Environment Variables +Both compose files support these environment variables: + +- `NODE_ENV`: `development` or `production` +- `AUTH_TYPE`: `SNAuth` or `IdentityServer` +- `CHOKIDAR_USEPOLLING`: `true` (dev only, for file watching) +- `WATCHPACK_POLLING`: `true` (dev only, for webpack) + +### Port Configuration +- **Default**: Port 8080 for both dev and prod +- **Customizable**: Change the host port in docker-compose files + +## 🔍 Troubleshooting + +### Container won't start +```bash +# Check logs +docker-compose -f docker-compose.dev.yml logs + +# Rebuild from scratch +docker-compose -f docker-compose.dev.yml down +docker-compose -f docker-compose.dev.yml up --build +``` + +### Hot reload not working +- Ensure you're using the dev compose file +- Restart the container if file watching stops working + +### Port already in use +```bash +# Change the port in docker-compose file +ports: + - "3000:8080" # Use port 3000 instead of 8080 +``` + +## 📦 Build Process + +The Docker build process: +1. **Copy source code** (excluding files in `.dockerignore`) +2. **Install dependencies** with `yarn install` +3. **Build packages** with `yarn build` +4. **Start application** with `yarn snapp start` + +## 🚀 CI/CD + +GitHub Actions automatically builds and pushes Docker images when: +- Code is pushed to `feature/docker-containerization` +- Pull requests target `develop`, `main`, or `feature/sn-auth-package-extraimprovements` + +Images are tagged based on branch names and commit SHAs for easy identification. \ No newline at end of file