diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..3562bd5 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,88 @@ +name: Build and Publish Docker Image + +on: + push: + branches: [ main, master ] + tags: [ 'v*.*.*' ] + pull_request: + branches: [ main, master ] + workflow_dispatch: + +env: + # Use docker.io for Docker Hub, ghcr.io for GitHub Container Registry + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Build frontend before Docker build + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install frontend dependencies + working-directory: ./frontend + run: npm ci + + - name: Build frontend + working-directory: ./frontend + run: npm run build + + # Setup Docker buildx for multi-platform builds + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # Login to GitHub Container Registry + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata for Docker + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=raw,value=latest,enable={{is_default_branch}} + + # Build and push Docker image + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v5 + with: + context: . + 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 + + # Output image digest + - name: Output image details + run: | + echo "Image pushed to:" + echo "${{ steps.meta.outputs.tags }}" diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 5f81454..a161282 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -36,7 +36,7 @@ That's it! 🎉 ## What This Does The Docker Compose file: -- ✅ Pulls pre-built image from Docker Hub (`aiulian25/soundwave:latest`) +- ✅ Pulls pre-built image from GitHub Container Registry (`ghcr.io/aiulian25/soundwave:latest`) - ✅ Starts ElasticSearch for search functionality - ✅ Starts Redis for task queue - ✅ Automatically runs migrations @@ -44,6 +44,8 @@ The Docker Compose file: **No npm, no build, no compilation needed!** +> **Note**: If the image pull fails (image not published yet), see the "Building Locally" section below. + --- ## Directory Structure @@ -117,17 +119,38 @@ docker compose up -d --- -## For Developers +## Building Locally + +If the pre-built image is not available (not published yet or want latest code): + +**Prerequisites**: Node.js 18+ and npm -If you want to build from source: ```bash +# Clone repository git clone https://github.com/aiulian25/soundwave.git cd soundwave -cd frontend && npm install && npm run build && cd .. + +# Build frontend +cd frontend +npm install +npm run build +cd .. + +# Build Docker image and start docker compose build docker compose up -d ``` +Alternatively, uncomment the `build:` section in docker-compose.yml and it will build automatically: +```yaml +# In docker-compose.yml, uncomment: +build: + context: . + dockerfile: Dockerfile +``` + +Then run: `docker compose up -d --build` + --- ## System Requirements diff --git a/SETUP_INSTRUCTIONS.md b/SETUP_INSTRUCTIONS.md new file mode 100644 index 0000000..44f9261 --- /dev/null +++ b/SETUP_INSTRUCTIONS.md @@ -0,0 +1,114 @@ +# 🚀 Quick Setup - Publishing Docker Image + +## The Problem +The docker-compose.yml was trying to pull `aiulian25/soundwave:latest` from Docker Hub, but this image was never published. New machines couldn't install SoundWave. + +## The Solution +I've set up automated publishing to GitHub Container Registry (free and integrated with GitHub). + +## 📋 Steps to Enable (One-Time Setup) + +### 1. Push This Code to GitHub + +```bash +git add . +git commit -m "Add GitHub Actions workflow for Docker image publishing" +git push origin main +``` + +### 2. Enable GitHub Actions Permissions + +1. Go to your repository on GitHub +2. Click **Settings** → **Actions** → **General** +3. Scroll to "Workflow permissions" +4. Select **"Read and write permissions"** +5. Check **"Allow GitHub Actions to create and approve pull requests"** +6. Click **Save** + +### 3. Trigger First Build + +The workflow will automatically run when you push. To manually trigger: + +1. Go to **Actions** tab on GitHub +2. Click **"Build and Publish Docker Image"** +3. Click **"Run workflow"** → **"Run workflow"** + +Wait 5-10 minutes for the build to complete. + +### 4. Make the Image Public (Optional but Recommended) + +By default, the image is private (only you can pull it). + +1. Go to your GitHub profile +2. Click **"Packages"** tab +3. Click on **"soundwave"** package +4. Click **"Package settings"** (right side) +5. Scroll to "Danger Zone" +6. Click **"Change visibility"** → **"Public"** +7. Confirm + +Now anyone can pull the image! + +## ✅ Verification + +After the workflow completes, verify it worked: + +```bash +# Pull the published image +docker pull ghcr.io/aiulian25/soundwave:latest + +# Check it works +docker run --rm ghcr.io/aiulian25/soundwave:latest python --version +``` + +## 🎯 Now Users Can Install With: + +```bash +# Download docker-compose.yml +wget https://raw.githubusercontent.com/aiulian25/soundwave/main/docker-compose.yml + +# Start (it will pull the pre-built image automatically) +docker compose up -d +``` + +## 🔄 Future Updates + +Every time you push to main/master: +1. GitHub Actions automatically builds new image +2. Publishes to ghcr.io/aiulian25/soundwave:latest +3. Users can update with: `docker compose pull && docker compose up -d` + +## 🛠️ Alternative: Build Locally + +If you don't want to wait for GitHub Actions or the image isn't published yet, users can still build locally: + +```bash +# Clone repo +git clone https://github.com/aiulian25/soundwave.git +cd soundwave + +# Build frontend +cd frontend && npm install && npm run build && cd .. + +# Build and start +docker compose up -d --build +``` + +## 📝 What I Changed + +1. ✅ Created `.github/workflows/docker-publish.yml` - Automated CI/CD +2. ✅ Updated `docker-compose.yml` - Changed image from `aiulian25/soundwave` to `ghcr.io/aiulian25/soundwave` +3. ✅ Created `docs/DOCKER_IMAGE_FIX.md` - Detailed troubleshooting guide +4. ✅ Updated `DEPLOYMENT.md` - Fixed deployment instructions + +## 🎉 Summary + +**Before**: Image didn't exist → Pull failed → Installation broken + +**After**: +- GitHub Actions builds image on every push +- Published to GitHub Container Registry +- Users can pull and run immediately +- Fallback to local build if needed + +Your next git push will trigger the first build! 🚀 diff --git a/docker-compose.yml b/docker-compose.yml index 47ce8b1..9667de8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,12 @@ services: soundwave: container_name: soundwave - image: aiulian25/soundwave:latest + # Option 1: Pull from GitHub Container Registry (recommended for users) + #image: ghcr.io/aiulian25/soundwave:latest + # Option 2: Build locally (uncomment if pulling fails or for development) + build: + context: . + dockerfile: Dockerfile ports: - "8889:8888" volumes: diff --git a/docs/DOCKER_IMAGE_FIX.md b/docs/DOCKER_IMAGE_FIX.md new file mode 100644 index 0000000..57e0818 --- /dev/null +++ b/docs/DOCKER_IMAGE_FIX.md @@ -0,0 +1,152 @@ +# 🐛 Docker Image Pull Issue - Fixed + +## Problem Identified + +The deployment was failing on new machines because: + +1. ❌ **No image published** - The Docker image `aiulian25/soundwave:latest` was never pushed to Docker Hub +2. ❌ **No CI/CD pipeline** - No automated builds to GitHub Container Registry +3. ❌ **No fallback option** - Users couldn't build locally if pull failed + +## Solutions Implemented + +### 1. GitHub Actions Workflow (Automated) + +Created [`.github/workflows/docker-publish.yml`](.github/workflows/docker-publish.yml): +- ✅ Automatically builds Docker image on push to main/master +- ✅ Publishes to GitHub Container Registry (ghcr.io) +- ✅ Supports multi-platform (amd64, arm64) +- ✅ Creates versioned tags for releases +- ✅ Uses GitHub Actions cache for faster builds + +### 2. Updated docker-compose.yml + +Changed image source from Docker Hub to GitHub Container Registry: +```yaml +image: ghcr.io/aiulian25/soundwave:latest +``` + +Added commented build option as fallback: +```yaml +# build: +# context: . +# dockerfile: Dockerfile +``` + +## 🚀 How to Use + +### For End Users (After First Push) + +**Option 1: Pull Pre-built Image** (Recommended) +```bash +# Clone repository +git clone https://github.com/aiulian25/soundwave.git +cd soundwave + +# Start services (will pull from ghcr.io) +docker compose up -d +``` + +**Option 2: Build Locally** (If pull fails or for development) +```bash +# Clone repository +git clone https://github.com/aiulian25/soundwave.git +cd soundwave + +# Build frontend first +cd frontend +npm install +npm run build +cd .. + +# Build and start with Docker +docker compose up -d --build +``` + +### For Repository Owner (First Time Setup) + +1. **Push to GitHub** - Push this repository to GitHub +2. **Enable Package Publishing**: + - Go to repository Settings → Actions → General + - Under "Workflow permissions", select "Read and write permissions" + - Check "Allow GitHub Actions to create and approve pull requests" +3. **Trigger First Build**: + - Push to main branch, or + - Go to Actions → "Build and Publish Docker Image" → Run workflow + +The image will be published to: `ghcr.io/yourusername/soundwave:latest` + +### Making the Image Public + +By default, GitHub Container Registry images are private. To make it public: + +1. Go to your GitHub profile → Packages +2. Click on `soundwave` package +3. Click "Package settings" +4. Scroll to "Danger Zone" +5. Click "Change visibility" → "Public" + +## 📝 Deployment Files Updated + +1. ✅ [`.github/workflows/docker-publish.yml`](.github/workflows/docker-publish.yml) - CI/CD pipeline +2. ✅ [`docker-compose.yml`](docker-compose.yml) - Updated image reference +3. ✅ This troubleshooting guide + +## 🔄 Updating the Image + +After pushing code changes: +1. GitHub Actions automatically builds new image +2. Users pull latest with: `docker compose pull && docker compose up -d` + +## 🛠️ Alternative: Docker Hub + +If you prefer Docker Hub over GitHub Container Registry: + +1. **Login to Docker Hub**: + ```bash + docker login + ``` + +2. **Build and push**: + ```bash + cd frontend && npm install && npm run build && cd .. + docker build -t aiulian25/soundwave:latest . + docker push aiulian25/soundwave:latest + ``` + +3. **Update docker-compose.yml**: + ```yaml + image: aiulian25/soundwave:latest + ``` + +4. **Add to GitHub Secrets** (for automation): + - Repository Settings → Secrets → Actions + - Add `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN` + - Update workflow to use Docker Hub + +## 📋 Quick Reference + +**Current Image Location**: `ghcr.io/aiulian25/soundwave:latest` +**Build Context**: Root directory (includes frontend/dist) +**Platforms Supported**: linux/amd64, linux/arm64 +**Auto-build**: On push to main/master branch + +## ✅ Verification + +After setup, verify the image is available: + +```bash +# Check if image exists (after first GitHub Actions run) +docker pull ghcr.io/aiulian25/soundwave:latest + +# Or check GitHub Packages +# Visit: https://github.com/yourusername?tab=packages +``` + +## 🎯 Benefits + +1. **Zero-config for users** - Just `docker compose up -d` +2. **Automatic updates** - CI/CD builds on every push +3. **Multi-platform** - Works on Intel and ARM (Apple Silicon, Raspberry Pi) +4. **Version tags** - Can pin to specific versions +5. **Fallback option** - Can build locally if needed