Skip to content

Commit a869b8e

Browse files
committed
Add homelab CI/CD configuration - Use GHCR images instead of local builds
1 parent f8c6a06 commit a869b8e

3 files changed

Lines changed: 326 additions & 0 deletions

File tree

HOMELAB_DEPLOYMENT.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# 🏠 Homelab Deployment Guide - CI/CD Fix
2+
3+
## 🔍 Problem Identified
4+
5+
Your GitHub Actions workflow is successfully building and pushing images to GHCR, but your homelab server is still building images locally instead of pulling from GHCR. This means:
6+
7+
- ❌ Watchtower cannot detect new images (it only monitors registry images)
8+
- ❌ Changes pushed to GitHub won't appear on your server
9+
- ❌ You're not using the CI/CD pipeline you set up
10+
11+
## ✅ Solution
12+
13+
You need to update your homelab server to use the `docker-compose.homelab.yml` override file that pulls images from GHCR instead of building locally.
14+
15+
---
16+
17+
## 📋 Step-by-Step Fix
18+
19+
### Step 1: SSH into Your Homelab Server
20+
21+
```bash
22+
ssh -p 2222 -i ~/.ssh/id_ed25519 medevs@192.168.178.23
23+
```
24+
25+
### Step 2: Navigate to Your Project Directory
26+
27+
```bash
28+
cd ~/projects/local-smart-portfolio
29+
# OR wherever your portfolio project is located
30+
```
31+
32+
### Step 3: Pull the Latest Code (Including the New Override File)
33+
34+
```bash
35+
git pull origin main
36+
```
37+
38+
This will pull the new `docker-compose.homelab.yml` file.
39+
40+
### Step 4: Verify GHCR Authentication
41+
42+
Make sure your server is authenticated to pull from GHCR:
43+
44+
```bash
45+
# Check if you're logged in
46+
cat ~/.docker/config.json | grep ghcr.io
47+
48+
# If not logged in, authenticate:
49+
echo "YOUR_GHCR_TOKEN" | docker login ghcr.io -u medevs --password-stdin
50+
```
51+
52+
Replace `YOUR_GHCR_TOKEN` with your actual GitHub Personal Access Token (the same one used in GitHub Actions secrets).
53+
54+
### Step 5: Stop Current Containers
55+
56+
```bash
57+
docker compose down
58+
# OR if you're using the override:
59+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml down
60+
```
61+
62+
### Step 6: Pull Latest Images from GHCR
63+
64+
```bash
65+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml pull
66+
```
67+
68+
This will pull the latest images from GHCR.
69+
70+
### Step 7: Start Containers with Homelab Override
71+
72+
```bash
73+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml up -d
74+
```
75+
76+
### Step 8: Verify Containers Are Using GHCR Images
77+
78+
```bash
79+
# Check which images are being used
80+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml ps
81+
82+
# Inspect a container to see its image
83+
docker inspect portfolio-frontend | grep Image
84+
docker inspect portfolio-backend | grep Image
85+
```
86+
87+
You should see `ghcr.io/medevs/portfolio-frontend:latest` and `ghcr.io/medevs/portfolio-backend:latest`.
88+
89+
### Step 9: Verify Watchtower Is Running
90+
91+
```bash
92+
# Check if Watchtower is running
93+
docker ps | grep watchtower
94+
95+
# Check Watchtower logs
96+
docker logs watchtower --tail 50
97+
```
98+
99+
Watchtower should be monitoring your containers. If it's not running, start it:
100+
101+
```bash
102+
docker run -d \
103+
--name watchtower \
104+
-v /var/run/docker.sock:/var/run/docker.sock \
105+
containrrr/watchtower \
106+
--interval 30 \
107+
portfolio-frontend \
108+
portfolio-backend
109+
```
110+
111+
The container names at the end tell Watchtower which containers to monitor.
112+
113+
---
114+
115+
## 🔄 Testing the CI/CD Pipeline
116+
117+
After completing the above steps:
118+
119+
1. **Make a small change** to your code (e.g., update a text in `frontend/data/personal.ts`)
120+
2. **Commit and push** to GitHub:
121+
```bash
122+
git add .
123+
git commit -m "Test CI/CD deployment"
124+
git push origin main
125+
```
126+
3. **Wait for GitHub Actions** to complete (check Actions tab in GitHub)
127+
4. **Wait 30 seconds** for Watchtower to detect the new image
128+
5. **Check Watchtower logs**:
129+
```bash
130+
docker logs watchtower --tail 20
131+
```
132+
6. **Verify the change** appears on your deployed site
133+
134+
---
135+
136+
## 🐛 Troubleshooting
137+
138+
### Issue: "Error response from daemon: pull access denied"
139+
140+
**Solution**: Your server is not authenticated to GHCR. Run Step 4 again.
141+
142+
### Issue: Watchtower not updating containers
143+
144+
**Solution**:
145+
1. Make sure Watchtower is monitoring the correct container names
146+
2. Check that containers are using images from GHCR (not locally built)
147+
3. Verify Watchtower logs: `docker logs watchtower`
148+
149+
### Issue: Containers still using old images
150+
151+
**Solution**:
152+
```bash
153+
# Force pull and recreate
154+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml pull
155+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml up -d --force-recreate
156+
```
157+
158+
### Issue: Changes not appearing after update
159+
160+
**Solution**:
161+
1. Clear browser cache
162+
2. Check container logs: `docker logs portfolio-frontend --tail 50`
163+
3. Verify the new image was pulled: `docker images | grep portfolio`
164+
165+
---
166+
167+
## 📝 Quick Reference Commands
168+
169+
```bash
170+
# Start with homelab override
171+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml up -d
172+
173+
# Pull latest images
174+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml pull
175+
176+
# View running containers
177+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml ps
178+
179+
# View logs
180+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml logs -f
181+
182+
# Restart services
183+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml restart
184+
```
185+
186+
---
187+
188+
## ✅ Verification Checklist
189+
190+
- [ ] `docker-compose.homelab.yml` file exists in project directory
191+
- [ ] Server is authenticated to GHCR (`docker login ghcr.io`)
192+
- [ ] Containers are using GHCR images (check with `docker inspect`)
193+
- [ ] Watchtower is running and monitoring containers
194+
- [ ] GitHub Actions workflow completes successfully
195+
- [ ] Changes appear on deployed site after push
196+
197+
---
198+
199+
## 🎯 Expected Behavior After Fix
200+
201+
Once everything is configured correctly:
202+
203+
1. You push code to GitHub → GitHub Actions builds images → Images pushed to GHCR
204+
2. Watchtower detects new `:latest` image in GHCR (within 30 seconds)
205+
3. Watchtower pulls the new image and restarts the container
206+
4. Your changes appear on the deployed site automatically
207+
208+
No manual intervention needed! 🚀
209+

deploy-homelab.sh

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/bin/bash
2+
# =============================================================================
3+
# Homelab Deployment Script
4+
# =============================================================================
5+
# This script updates the portfolio containers using GHCR images
6+
# Run this on your homelab server after pushing changes to GitHub
7+
# =============================================================================
8+
9+
set -e # Exit on error
10+
11+
echo "🚀 Starting Homelab Deployment..."
12+
13+
# Colors for output
14+
GREEN='\033[0;32m'
15+
YELLOW='\033[1;33m'
16+
RED='\033[0;31m'
17+
NC='\033[0m' # No Color
18+
19+
# Check if we're in the right directory
20+
if [ ! -f "docker-compose.yml" ]; then
21+
echo -e "${RED}❌ Error: docker-compose.yml not found${NC}"
22+
echo "Please run this script from your project root directory"
23+
exit 1
24+
fi
25+
26+
# Check if homelab override exists
27+
if [ ! -f "docker-compose.homelab.yml" ]; then
28+
echo -e "${RED}❌ Error: docker-compose.homelab.yml not found${NC}"
29+
echo "Please ensure the homelab override file exists"
30+
exit 1
31+
fi
32+
33+
# Check GHCR authentication
34+
echo -e "${YELLOW}📋 Checking GHCR authentication...${NC}"
35+
if ! docker info | grep -q "ghcr.io"; then
36+
echo -e "${YELLOW}⚠️ Warning: GHCR authentication may not be set up${NC}"
37+
echo "If you get authentication errors, run:"
38+
echo " echo 'YOUR_TOKEN' | docker login ghcr.io -u medevs --password-stdin"
39+
fi
40+
41+
# Pull latest code (optional, uncomment if needed)
42+
# echo -e "${YELLOW}📥 Pulling latest code from Git...${NC}"
43+
# git pull origin main || echo "⚠️ Git pull failed, continuing anyway..."
44+
45+
# Pull latest images from GHCR
46+
echo -e "${YELLOW}📦 Pulling latest images from GHCR...${NC}"
47+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml pull
48+
49+
if [ $? -ne 0 ]; then
50+
echo -e "${RED}❌ Failed to pull images. Check GHCR authentication.${NC}"
51+
exit 1
52+
fi
53+
54+
# Stop existing containers
55+
echo -e "${YELLOW}🛑 Stopping existing containers...${NC}"
56+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml down
57+
58+
# Start containers with new images
59+
echo -e "${YELLOW}🚀 Starting containers with new images...${NC}"
60+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml up -d
61+
62+
if [ $? -ne 0 ]; then
63+
echo -e "${RED}❌ Failed to start containers${NC}"
64+
exit 1
65+
fi
66+
67+
# Wait a moment for containers to start
68+
sleep 5
69+
70+
# Show container status
71+
echo -e "${GREEN}✅ Deployment complete!${NC}"
72+
echo ""
73+
echo "📊 Container Status:"
74+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml ps
75+
76+
echo ""
77+
echo "📝 Recent logs (last 20 lines):"
78+
docker compose -f docker-compose.yml -f docker-compose.homelab.yml logs --tail=20
79+
80+
echo ""
81+
echo -e "${GREEN}✨ Your portfolio should now be updated!${NC}"
82+
echo "Access it at: https://portfolio.medevs.local"
83+

docker-compose.homelab.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# =============================================================================
2+
# Docker Compose - Homelab Override
3+
# =============================================================================
4+
# Use with: docker-compose -f docker-compose.yml -f docker-compose.homelab.yml up
5+
# This override configures the services to use GHCR images instead of building locally
6+
# =============================================================================
7+
8+
version: '3.8'
9+
10+
services:
11+
# ===========================================================================
12+
# Backend Service - Use GHCR Image
13+
# ===========================================================================
14+
backend:
15+
# Remove build section and use GHCR image instead
16+
image: ghcr.io/medevs/portfolio-backend:latest
17+
# Keep all other settings from base compose
18+
pull_policy: always # Always pull latest image
19+
20+
# ===========================================================================
21+
# Frontend Service - Use GHCR Image
22+
# ===========================================================================
23+
frontend:
24+
# Remove build section and use GHCR image instead
25+
image: ghcr.io/medevs/portfolio-frontend:latest
26+
# Override ports for homelab (as mentioned in Day 10)
27+
ports:
28+
- "3100:3000"
29+
# Override environment variables for homelab
30+
environment:
31+
- NEXT_PUBLIC_API_URL=http://portfolio-api.medevs.local
32+
- NEXT_PUBLIC_ADMIN_API_KEY=${ADMIN_API_KEY}
33+
pull_policy: always # Always pull latest image
34+

0 commit comments

Comments
 (0)