From 3d3c9390b0bd406a10d84323946b04a3a1f1798f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:00:47 +0000 Subject: [PATCH 1/6] Initial plan From 185a582c36aed4a08534311430e67774014d3504 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:25:36 +0000 Subject: [PATCH 2/6] Add Docker support and GitHub Actions workflow for container registry - Create Dockerfiles for backend (NestJS) and frontend (React/Vite) - Add .dockerignore files to optimize builds - Create GitHub Actions workflow to build and push images to GHCR - Add comprehensive Docker deployment documentation - Handle circular dependency issues in package.json during builds Co-authored-by: CodingF0X <79570460+CodingF0X@users.noreply.github.com> --- .github/workflows/docker-build-push.yml | 112 +++++++++++++ DOCKER.md | 213 ++++++++++++++++++++++++ backend/.dockerignore | 48 ++++++ backend/Dockerfile | 47 ++++++ frontend/.dockerignore | 42 +++++ frontend/Dockerfile | 47 ++++++ 6 files changed, 509 insertions(+) create mode 100644 .github/workflows/docker-build-push.yml create mode 100644 DOCKER.md create mode 100644 backend/.dockerignore create mode 100644 backend/Dockerfile create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml new file mode 100644 index 0000000..98844da --- /dev/null +++ b/.github/workflows/docker-build-push.yml @@ -0,0 +1,112 @@ +name: Build and Push Docker Images + +on: + push: + branches: + - main + - develop + tags: + - 'v*.*.*' + pull_request: + branches: + - main + - develop + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME_BACKEND: ${{ github.repository }}/backend + IMAGE_NAME_FRONTEND: ${{ github.repository }}/frontend + +jobs: + build-and-push-backend: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata for Docker (backend) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,prefix={{branch}}- + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Backend Docker image + uses: docker/build-push-action@v5 + with: + context: ./backend + file: ./backend/Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64,linux/arm64 + + build-and-push-frontend: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata for Docker (frontend) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,prefix={{branch}}- + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Frontend Docker image + uses: docker/build-push-action@v5 + with: + context: ./frontend + file: ./frontend/Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64,linux/arm64 diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..b534fbc --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,213 @@ +# Docker Deployment Guide + +This guide explains how to build and deploy the Chat App using Docker and the automated GitHub Actions workflow. + +## Overview + +The Chat App consists of two main components: +- **Backend**: NestJS application (port 3000) +- **Frontend**: React application served by nginx (port 80) + +Each component has its own Dockerfile for building optimized production images. + +## GitHub Actions Workflow + +The repository includes an automated workflow (`.github/workflows/docker-build-push.yml`) that: + +1. **Builds Docker images** for both backend and frontend +2. **Pushes images** to GitHub Container Registry (ghcr.io) +3. **Tags images** appropriately based on the trigger: + - `latest` tag for the default branch (main) + - Branch name tags for branch pushes + - Semantic version tags for version tags (v*.*.*) + - PR tags for pull requests + - SHA-based tags for all builds + +### Triggering the Workflow + +The workflow automatically runs on: +- Push to `main` or `develop` branches +- Creation of version tags (e.g., `v1.0.0`) +- Pull requests to `main` or `develop` +- Manual trigger via GitHub Actions UI + +### Accessing Built Images + +After the workflow completes, images are available at: +- Backend: `ghcr.io/codingf0x/chat-app/backend:latest` +- Frontend: `ghcr.io/codingf0x/chat-app/frontend:latest` + +To pull and run the images: + +```bash +# Pull images +docker pull ghcr.io/codingf0x/chat-app/backend:latest +docker pull ghcr.io/codingf0x/chat-app/frontend:latest + +# Run backend +docker run -p 3000:3000 \ + -e MONGODB_URI=mongodb://your-mongo-uri \ + -e JWT_SECRET=your-secret \ + ghcr.io/codingf0x/chat-app/backend:latest + +# Run frontend +docker run -p 80:80 ghcr.io/codingf0x/chat-app/frontend:latest +``` + +## Local Docker Build + +### Building Images Locally + +To build the Docker images locally: + +```bash +# Build backend image +cd backend +docker build -t chat-app-backend . + +# Build frontend image +cd frontend +docker build -t chat-app-frontend . +``` + +### Running Locally with Docker + +```bash +# Run backend +docker run -d \ + --name chat-backend \ + -p 3000:3000 \ + -e MONGODB_URI=mongodb://localhost:27017/chatapp \ + -e JWT_SECRET=your-secret-key \ + -e AWS_ACCESS_KEY_ID=your-aws-key \ + -e AWS_SECRET_ACCESS_KEY=your-aws-secret \ + -e S3_BUCKET_NAME=your-bucket \ + chat-app-backend + +# Run frontend +docker run -d \ + --name chat-frontend \ + -p 80:80 \ + chat-app-frontend +``` + +## Docker Compose (Optional) + +You can create a `docker-compose.yml` file for easier local development: + +```yaml +version: '3.8' + +services: + backend: + build: ./backend + ports: + - "3000:3000" + environment: + - MONGODB_URI=mongodb://mongo:27017/chatapp + - JWT_SECRET=dev-secret-key + - STAGE=prod + depends_on: + - mongo + + frontend: + build: ./frontend + ports: + - "80:80" + depends_on: + - backend + + mongo: + image: mongo:latest + ports: + - "27017:27017" + volumes: + - mongo-data:/data/db + +volumes: + mongo-data: +``` + +Then run: +```bash +docker-compose up -d +``` + +## Image Features + +### Backend Image +- **Base**: node:20-slim (optimized for size) +- **Multi-stage build**: Separate build and production stages +- **Security**: Runs as non-root user (nestjs:nodejs) +- **Health check**: Built-in health check endpoint +- **Port**: 3000 + +### Frontend Image +- **Base Builder**: node:20-slim +- **Base Production**: nginx:alpine (minimal size) +- **Multi-stage build**: Build with Node, serve with nginx +- **SPA Support**: Configured for React Router +- **Health check**: nginx health check +- **Port**: 80 + +## Environment Variables + +### Backend Required Variables: +- `MONGODB_URI`: MongoDB connection string +- `JWT_SECRET`: Secret for JWT token generation +- `AWS_ACCESS_KEY_ID`: AWS credentials for S3 +- `AWS_SECRET_ACCESS_KEY`: AWS credentials for S3 +- `S3_BUCKET_NAME`: S3 bucket for file uploads +- `STAGE`: Environment stage (dev/prod) + +### Frontend Configuration: +The frontend build includes the API endpoint configuration. Update the environment variables before building if needed. + +## Troubleshooting + +### Build Issues +- **Circular dependency**: The Dockerfiles automatically remove the circular `"backend": "file:"` and `"frontend": "file:"` dependencies from package.json +- **Network timeouts**: Use `--legacy-peer-deps` flag (already included in Dockerfiles) +- **Missing packages**: The build uses `npm install` without lock file to avoid corruption issues + +### Runtime Issues +- **Backend won't start**: Check environment variables, especially `MONGODB_URI` +- **Frontend 404 errors**: nginx is configured for SPA routing, check browser console for API errors +- **Connection refused**: Ensure backend is accessible at the configured API endpoint + +## Production Deployment + +For production deployment: + +1. **Use version tags** instead of `latest`: + ```bash + docker pull ghcr.io/codingf0x/chat-app/backend:v1.0.0 + ``` + +2. **Set proper environment variables** using secrets management + +3. **Use orchestration** (Kubernetes, Docker Swarm, or ECS) for: + - Auto-scaling + - Load balancing + - Health checks + - Rolling updates + +4. **Monitor logs**: + ```bash + docker logs -f chat-backend + docker logs -f chat-frontend + ``` + +## GitHub Container Registry Authentication + +To push/pull from GHCR locally: + +```bash +# Login to GHCR +echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin + +# Pull private images +docker pull ghcr.io/codingf0x/chat-app/backend:latest +``` + +The GitHub Actions workflow uses `GITHUB_TOKEN` automatically, no manual configuration needed. diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..31f77c2 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,48 @@ +# Dependencies +node_modules +npm-debug.log +package-lock.json + +# Testing +coverage +.nyc_output +*.spec.ts +test + +# Build outputs +dist + +# Environment files +.env +.env.local +.env.*.local +.env.stage.prod + +# IDE +.idea +.vscode +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore +.gitattributes + +# Documentation +README.md +*.md + +# Logs +logs +*.log + +# Misc +.prettierrc +.eslintrc.js +module-deps.png diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..52f6be6 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,47 @@ +# Build stage +FROM node:20-slim AS builder + +WORKDIR /app + +# Install all dependencies by only copying package.json (not package-lock.json) +# This avoids the circular dependency issue in package-lock.json +COPY package.json ./ +RUN npm pkg delete dependencies.backend 2>/dev/null || true && \ + npm install --legacy-peer-deps + +# Copy source code +COPY . . + +# Build the application +RUN npm run build + +# Production stage +FROM node:20-slim + +WORKDIR /app + +# Create a non-root user +RUN groupadd -g 1001 nodejs && \ + useradd -r -u 1001 -g nodejs nestjs + +# Install only production dependencies +COPY package.json ./ +RUN npm pkg delete dependencies.backend 2>/dev/null || true && \ + npm install --omit=dev --legacy-peer-deps + +# Copy built application from builder stage +COPY --from=builder --chown=nestjs:nodejs /app/dist ./dist + +# Switch to non-root user +USER nestjs + +# Expose the application port +EXPOSE 3000 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \ + CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" || exit 1 + +# Start the application +CMD ["node", "dist/main"] + diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..8b42c4a --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,42 @@ +# Dependencies +node_modules +npm-debug.log +package-lock.json + +# Build outputs +dist + +# Environment files +.env +.env.local +.env.*.local + +# IDE +.idea +.vscode +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore +.gitattributes + +# Documentation +README.md +*.md + +# Logs +logs +*.log + +# Misc +.prettierrc +eslint.config.js +codegen.ts +vite.config.ts diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..08d05a2 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,47 @@ +# Build stage +FROM node:20-slim AS builder + +WORKDIR /app + +# Install dependencies by only copying package.json (not package-lock.json) +# This avoids the circular dependency issue in package-lock.json +COPY package.json ./ +RUN npm pkg delete dependencies.frontend 2>/dev/null || true && \ + npm install --legacy-peer-deps + +# Copy source code +COPY . . + +# Build the application +RUN npm run build + +# Production stage +FROM nginx:alpine + +# Copy custom nginx config if needed +COPY --from=builder /app/dist /usr/share/nginx/html + +# Create nginx config for SPA +RUN echo 'server { \n\ + listen 80; \n\ + location / { \n\ + root /usr/share/nginx/html; \n\ + index index.html index.htm; \n\ + try_files $uri $uri/ /index.html; \n\ + } \n\ + error_page 500 502 503 504 /50x.html; \n\ + location = /50x.html { \n\ + root /usr/share/nginx/html; \n\ + } \n\ +}' > /etc/nginx/conf.d/default.conf + +# Expose port +EXPOSE 80 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=10s \ + CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"] + From 7c085bf1d10583b5f486e18f5080e72e7e62c98f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:26:30 +0000 Subject: [PATCH 3/6] Add docker-compose.yml and environment configuration - Add docker-compose.yml for easy local development - Add .env.example template for environment variables - Update DOCKER.md with docker-compose usage instructions - Configure health checks for all services - Add MongoDB service with persistent volumes Co-authored-by: CodingF0X <79570460+CodingF0X@users.noreply.github.com> --- .env.example | 18 +++++++++++ DOCKER.md | 68 +++++++++++++++++++----------------------- docker-compose.yml | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 37 deletions(-) create mode 100644 .env.example create mode 100644 docker-compose.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..fd04bd9 --- /dev/null +++ b/.env.example @@ -0,0 +1,18 @@ +# MongoDB Configuration +MONGODB_URI=mongodb://mongo:27017/chatapp + +# JWT Configuration +JWT_SECRET=change-this-to-a-secure-random-string +JWT_EXPIRATION=3600 + +# Cookie Configuration +COOKIE_EXPIRATION=3600000 + +# AWS S3 Configuration (for file uploads) +AWS_ACCESS_KEY_ID=your-aws-access-key-id +AWS_SECRET_ACCESS_KEY=your-aws-secret-access-key +S3_BUCKET_NAME=your-s3-bucket-name +AWS_REGION=us-east-1 + +# Application Stage +STAGE=prod diff --git a/DOCKER.md b/DOCKER.md index b534fbc..e8c43e8 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -91,48 +91,42 @@ docker run -d \ chat-app-frontend ``` -## Docker Compose (Optional) - -You can create a `docker-compose.yml` file for easier local development: - -```yaml -version: '3.8' - -services: - backend: - build: ./backend - ports: - - "3000:3000" - environment: - - MONGODB_URI=mongodb://mongo:27017/chatapp - - JWT_SECRET=dev-secret-key - - STAGE=prod - depends_on: - - mongo - - frontend: - build: ./frontend - ports: - - "80:80" - depends_on: - - backend - - mongo: - image: mongo:latest - ports: - - "27017:27017" - volumes: - - mongo-data:/data/db - -volumes: - mongo-data: -``` +## Docker Compose + +For easier local development and testing, use the included `docker-compose.yml`: -Then run: ```bash +# Copy environment variables template +cp .env.example .env + +# Edit .env with your configuration +nano .env # or use your preferred editor + +# Start all services (backend, frontend, and MongoDB) docker-compose up -d + +# View logs +docker-compose logs -f + +# Stop all services +docker-compose down + +# Stop and remove volumes (WARNING: This deletes database data) +docker-compose down -v ``` +The docker-compose setup includes: +- **MongoDB**: Database service with persistent volume +- **Backend**: NestJS application connected to MongoDB +- **Frontend**: React application served by nginx +- **Health checks**: All services have health checks configured +- **Automatic restart**: Services restart on failure + +Access the application: +- Frontend: http://localhost +- Backend API: http://localhost:3000 +- MongoDB: localhost:27017 + ## Image Features ### Backend Image diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f56c2b2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,74 @@ +version: '3.8' + +services: + # MongoDB Database + mongo: + image: mongo:latest + container_name: chat-mongo + restart: unless-stopped + ports: + - "27017:27017" + volumes: + - mongo-data:/data/db + environment: + - MONGO_INITDB_DATABASE=chatapp + healthcheck: + test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/chatapp --quiet + interval: 10s + timeout: 5s + retries: 5 + + # Backend Service + backend: + build: + context: ./backend + dockerfile: Dockerfile + container_name: chat-backend + restart: unless-stopped + ports: + - "3000:3000" + environment: + - MONGODB_URI=mongodb://mongo:27017/chatapp + - JWT_SECRET=dev-secret-key-change-in-production + - STAGE=prod + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-your-aws-key} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-your-aws-secret} + - S3_BUCKET_NAME=${S3_BUCKET_NAME:-your-bucket} + - JWT_EXPIRATION=3600 + - COOKIE_EXPIRATION=3600000 + depends_on: + mongo: + condition: service_healthy + healthcheck: + test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 40s + + # Frontend Service + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + container_name: chat-frontend + restart: unless-stopped + ports: + - "80:80" + depends_on: + backend: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 10s + +volumes: + mongo-data: + driver: local + +networks: + default: + name: chat-network From 83d8b44055a01c8d8de59ffa73707a5fcb6ce6b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:27:29 +0000 Subject: [PATCH 4/6] Add QUICKSTART guide and update main README - Add QUICKSTART.md with step-by-step Docker setup instructions - Update README.md with Docker deployment section - Add references to Docker documentation - Document container registry usage Co-authored-by: CodingF0X <79570460+CodingF0X@users.noreply.github.com> --- QUICKSTART.md | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 34 +++++++++++ 2 files changed, 195 insertions(+) create mode 100644 QUICKSTART.md diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 0000000..050bd74 --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,161 @@ +# Quick Start Guide - Docker Deployment + +This guide will help you quickly set up and run the Chat App using Docker. + +## Prerequisites + +- Docker installed (version 20.10 or higher) +- Docker Compose installed (version 2.0 or higher) +- Git (to clone the repository) + +## Quick Start (Local Development) + +1. **Clone the repository:** + ```bash + git clone https://github.com/CodingF0X/Chat-app.git + cd Chat-app + ``` + +2. **Configure environment variables:** + ```bash + cp .env.example .env + # Edit .env with your actual AWS credentials and secrets + nano .env + ``` + +3. **Start all services:** + ```bash + docker-compose up -d + ``` + +4. **Access the application:** + - Frontend: http://localhost + - Backend API: http://localhost:3000 + - MongoDB: localhost:27017 + +5. **View logs:** + ```bash + # All services + docker-compose logs -f + + # Specific service + docker-compose logs -f backend + docker-compose logs -f frontend + ``` + +6. **Stop services:** + ```bash + docker-compose down + ``` + +## Quick Start (Using Pre-built Images from GitHub Container Registry) + +If the Docker images have been built and published via GitHub Actions: + +1. **Pull the images:** + ```bash + docker pull ghcr.io/codingf0x/chat-app/backend:latest + docker pull ghcr.io/codingf0x/chat-app/frontend:latest + ``` + +2. **Run MongoDB:** + ```bash + docker run -d \ + --name chat-mongo \ + -p 27017:27017 \ + -v mongo-data:/data/db \ + mongo:latest + ``` + +3. **Run Backend:** + ```bash + docker run -d \ + --name chat-backend \ + -p 3000:3000 \ + -e MONGODB_URI=mongodb://host.docker.internal:27017/chatapp \ + -e JWT_SECRET=your-secret-key \ + -e AWS_ACCESS_KEY_ID=your-aws-key \ + -e AWS_SECRET_ACCESS_KEY=your-aws-secret \ + -e S3_BUCKET_NAME=your-bucket \ + ghcr.io/codingf0x/chat-app/backend:latest + ``` + +4. **Run Frontend:** + ```bash + docker run -d \ + --name chat-frontend \ + -p 80:80 \ + ghcr.io/codingf0x/chat-app/frontend:latest + ``` + +## GitHub Actions - Automated Builds + +The repository includes a GitHub Actions workflow that automatically: + +1. Builds Docker images when you push to `main` or `develop` branches +2. Pushes images to GitHub Container Registry (GHCR) +3. Tags images appropriately + +### How to trigger a build: + +- **Push to main/develop:** Images are built and pushed automatically +- **Create a version tag:** `git tag v1.0.0 && git push origin v1.0.0` +- **Manual trigger:** Go to Actions tab in GitHub → Select workflow → Run workflow + +### Access built images: + +Images are available at: +- `ghcr.io/codingf0x/chat-app/backend:latest` +- `ghcr.io/codingf0x/chat-app/frontend:latest` + +## Troubleshooting + +### Services won't start +```bash +# Check service status +docker-compose ps + +# View logs for errors +docker-compose logs +``` + +### Database connection issues +```bash +# Ensure MongoDB is running +docker-compose ps mongo + +# Check MongoDB logs +docker-compose logs mongo +``` + +### Port already in use +```bash +# Find what's using the port +sudo lsof -i :3000 # For backend +sudo lsof -i :80 # For frontend + +# Or change ports in docker-compose.yml +``` + +### Reset everything +```bash +# Stop and remove all containers, networks, and volumes +docker-compose down -v + +# Start fresh +docker-compose up -d +``` + +## Next Steps + +- Read [DOCKER.md](./DOCKER.md) for detailed documentation +- Configure AWS S3 for file uploads +- Set up proper JWT secrets for production +- Consider using Kubernetes for production deployment + +## Support + +For issues or questions: +- Create an issue on GitHub +- Check existing documentation in DOCKER.md +- Review Docker logs for error messages diff --git a/README.md b/README.md index a135c1e..af3ea13 100644 --- a/README.md +++ b/README.md @@ -210,3 +210,37 @@ npm run test:e2e # run end-to-end tests npm run dev # start Vite development server npm run build # production build npm run codegen # generate GraphQL types/hooks +``` + +--- + +## Docker Deployment + +The application supports Docker containerization with automated builds via GitHub Actions. + +### Quick Start with Docker + +```bash +# Using Docker Compose (recommended for local development) +docker-compose up -d + +# Or pull pre-built images from GitHub Container Registry +docker pull ghcr.io/codingf0x/chat-app/backend:latest +docker pull ghcr.io/codingf0x/chat-app/frontend:latest +``` + +### Documentation + +- **[QUICKSTART.md](./QUICKSTART.md)** - Quick setup guide for Docker +- **[DOCKER.md](./DOCKER.md)** - Comprehensive Docker deployment documentation + +### Container Registry + +Docker images are automatically built and pushed to GitHub Container Registry (GHCR) via GitHub Actions when: +- Code is pushed to `main` or `develop` branches +- Version tags are created (e.g., `v1.0.0`) +- Manually triggered via GitHub Actions UI + +**Available Images:** +- Backend: `ghcr.io/codingf0x/chat-app/backend:latest` +- Frontend: `ghcr.io/codingf0x/chat-app/frontend:latest` From aecf3754de8223390026d0572e32e79f0e2f33e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:29:23 +0000 Subject: [PATCH 5/6] Address code review feedback - Fix frontend/.dockerignore to include vite.config.ts (required for build) - Update docker-compose.yml to use environment variable for JWT_SECRET - Add Linux-specific MongoDB connection instructions in QUICKSTART.md - Add comment clarifying wget availability in nginx:alpine Co-authored-by: CodingF0X <79570460+CodingF0X@users.noreply.github.com> --- QUICKSTART.md | 12 ++++++++++++ docker-compose.yml | 2 +- frontend/.dockerignore | 1 - frontend/Dockerfile | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/QUICKSTART.md b/QUICKSTART.md index 050bd74..928f104 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -79,6 +79,18 @@ If the Docker images have been built and published via GitHub Actions: -e S3_BUCKET_NAME=your-bucket \ ghcr.io/codingf0x/chat-app/backend:latest ``` + + **Note for Linux users:** Replace `host.docker.internal` with `172.17.0.1` (Docker bridge IP) or use `--network host` mode. + + ```bash + # Alternative for Linux + docker run -d \ + --name chat-backend \ + -p 3000:3000 \ + -e MONGODB_URI=mongodb://172.17.0.1:27017/chatapp \ + -e JWT_SECRET=your-secret-key \ + ghcr.io/codingf0x/chat-app/backend:latest + ``` 4. **Run Frontend:** ```bash diff --git a/docker-compose.yml b/docker-compose.yml index f56c2b2..fd6e832 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: - "3000:3000" environment: - MONGODB_URI=mongodb://mongo:27017/chatapp - - JWT_SECRET=dev-secret-key-change-in-production + - JWT_SECRET=${JWT_SECRET:-please-change-this-secret-in-production} - STAGE=prod - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-your-aws-key} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-your-aws-secret} diff --git a/frontend/.dockerignore b/frontend/.dockerignore index 8b42c4a..f9c0a77 100644 --- a/frontend/.dockerignore +++ b/frontend/.dockerignore @@ -39,4 +39,3 @@ logs .prettierrc eslint.config.js codegen.ts -vite.config.ts diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 08d05a2..57b27d1 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -38,7 +38,7 @@ RUN echo 'server { \n\ # Expose port EXPOSE 80 -# Health check +# Health check using wget (installed in nginx:alpine) HEALTHCHECK --interval=30s --timeout=3s --start-period=10s \ CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1 From ef264e0473f365bb51efdbd2d6b7b9db2ee10ef2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:31:33 +0000 Subject: [PATCH 6/6] Optimize workflow and improve security - Make multi-platform builds conditional (only on version tags) for faster CI - Remove default JWT_SECRET from docker-compose.yml for better security - Update DOCKER.md to emphasize JWT_SECRET requirement - Add command to generate secure JWT_SECRET Co-authored-by: CodingF0X <79570460+CodingF0X@users.noreply.github.com> --- .github/workflows/docker-build-push.yml | 6 ++++-- DOCKER.md | 5 ++++- docker-compose.yml | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 98844da..25af346 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -63,7 +63,8 @@ jobs: labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - platforms: linux/amd64,linux/arm64 + # Build for multiple platforms only on version tags for faster CI + platforms: ${{ startsWith(github.ref, 'refs/tags/v') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} build-and-push-frontend: runs-on: ubuntu-latest @@ -109,4 +110,5 @@ jobs: labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - platforms: linux/amd64,linux/arm64 + # Build for multiple platforms only on version tags for faster CI + platforms: ${{ startsWith(github.ref, 'refs/tags/v') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} diff --git a/DOCKER.md b/DOCKER.md index e8c43e8..523195c 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -99,9 +99,12 @@ For easier local development and testing, use the included `docker-compose.yml`: # Copy environment variables template cp .env.example .env -# Edit .env with your configuration +# Edit .env with your configuration (REQUIRED: Set JWT_SECRET) nano .env # or use your preferred editor +# IMPORTANT: You MUST set JWT_SECRET in .env before starting +# Generate a secure secret: openssl rand -base64 32 + # Start all services (backend, frontend, and MongoDB) docker-compose up -d diff --git a/docker-compose.yml b/docker-compose.yml index fd6e832..9d62ae7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: - "3000:3000" environment: - MONGODB_URI=mongodb://mongo:27017/chatapp - - JWT_SECRET=${JWT_SECRET:-please-change-this-secret-in-production} + - JWT_SECRET=${JWT_SECRET} - STAGE=prod - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-your-aws-key} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-your-aws-secret}