266 lines
6.1 KiB
Markdown
266 lines
6.1 KiB
Markdown
# 🔄 Rebuild Guide - When You Need to Rebuild the Image
|
|
|
|
## Why Rebuild?
|
|
|
|
SvelteKit's `PUBLIC_*` environment variables are **baked into the JavaScript** at build time. You need to rebuild when:
|
|
|
|
1. ✅ Changing `PUBLIC_API_URL`
|
|
2. ✅ Changing `PUBLIC_URL`
|
|
3. ✅ Changing `PUBLIC_UMAMI_ID`
|
|
4. ✅ Changing any `LETTERSPACE_*` variables
|
|
5. ❌ NOT needed for Directus env vars (those are runtime)
|
|
|
|
## Quick Rebuild Process
|
|
|
|
### 1. Update Frontend Environment Variables
|
|
|
|
Edit the frontend `.env` file:
|
|
|
|
```bash
|
|
nano packages/frontend/.env
|
|
```
|
|
|
|
Set your production values:
|
|
```bash
|
|
PUBLIC_API_URL=https://sexy.pivoine.art/api
|
|
PUBLIC_URL=https://sexy.pivoine.art
|
|
PUBLIC_UMAMI_ID=your-umami-id
|
|
LETTERSPACE_API_URL=https://api.letterspace.com/v1
|
|
LETTERSPACE_API_KEY=your-key
|
|
LETTERSPACE_LIST_ID=your-list-id
|
|
```
|
|
|
|
### 2. Rebuild the Image
|
|
|
|
```bash
|
|
# From the project root
|
|
docker build -t ghcr.io/valknarxxx/sexy:latest -t sexy.pivoine.art:latest .
|
|
```
|
|
|
|
**Expected Time:** 30-45 minutes (first build), 10-15 minutes (cached rebuild)
|
|
|
|
### 3. Restart Services
|
|
|
|
```bash
|
|
# If using docker-compose
|
|
cd /home/valknar/Projects/docker-compose/sexy
|
|
docker compose down
|
|
docker compose up -d
|
|
|
|
# Or directly
|
|
docker stop sexy_frontend
|
|
docker rm sexy_frontend
|
|
docker compose up -d frontend
|
|
```
|
|
|
|
## Monitoring the Build
|
|
|
|
### Check Build Progress
|
|
|
|
```bash
|
|
# Watch build output
|
|
docker build -t ghcr.io/valknarxxx/sexy:latest .
|
|
|
|
# Build stages:
|
|
# 1. Base (~30s) - Node.js setup
|
|
# 2. Builder (~25-40min) - Rust + WASM + packages
|
|
# - Rust installation: ~2-3 min
|
|
# - wasm-bindgen-cli: ~10-15 min
|
|
# - WASM build: ~5-10 min
|
|
# - Package builds: ~5-10 min
|
|
# 3. Runner (~2min) - Final image assembly
|
|
```
|
|
|
|
### Verify Environment Variables in Built Image
|
|
|
|
```bash
|
|
# Check what PUBLIC_API_URL is baked in
|
|
docker run --rm ghcr.io/valknarxxx/sexy:latest sh -c \
|
|
"grep -r 'PUBLIC_API_URL' /home/node/app/packages/frontend/build/ | head -3"
|
|
|
|
# Should show: https://sexy.pivoine.art/api
|
|
```
|
|
|
|
## Push to GitHub Container Registry
|
|
|
|
After successful build:
|
|
|
|
```bash
|
|
# Login to GHCR (first time only)
|
|
echo $GITHUB_TOKEN | docker login ghcr.io -u valknarxxx --password-stdin
|
|
|
|
# Push the image
|
|
docker push ghcr.io/valknarxxx/sexy:latest
|
|
```
|
|
|
|
## Alternative: Build Arguments (Future Enhancement)
|
|
|
|
To avoid rebuilding for every env change, consider adding build arguments:
|
|
|
|
```dockerfile
|
|
# In Dockerfile, before building frontend:
|
|
ARG PUBLIC_API_URL=https://sexy.pivoine.art/api
|
|
ARG PUBLIC_URL=https://sexy.pivoine.art
|
|
ARG PUBLIC_UMAMI_ID=
|
|
|
|
# Create .env.production dynamically
|
|
RUN echo "PUBLIC_API_URL=${PUBLIC_API_URL}" > packages/frontend/.env.production && \
|
|
echo "PUBLIC_URL=${PUBLIC_URL}" >> packages/frontend/.env.production && \
|
|
echo "PUBLIC_UMAMI_ID=${PUBLIC_UMAMI_ID}" >> packages/frontend/.env.production
|
|
```
|
|
|
|
Then build with:
|
|
```bash
|
|
docker build \
|
|
--build-arg PUBLIC_API_URL=https://sexy.pivoine.art/api \
|
|
--build-arg PUBLIC_URL=https://sexy.pivoine.art \
|
|
-t ghcr.io/valknarxxx/sexy:latest .
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Build Fails at Rust Installation
|
|
|
|
```bash
|
|
# Check network connectivity
|
|
ping -c 3 sh.rustup.rs
|
|
|
|
# Build with verbose output
|
|
docker build --progress=plain -t ghcr.io/valknarxxx/sexy:latest .
|
|
```
|
|
|
|
### Build Fails at WASM
|
|
|
|
```bash
|
|
# Check if wasm-bindgen-cli matches package.json version
|
|
docker run --rm rust:latest cargo install wasm-bindgen-cli --version 0.2.103
|
|
```
|
|
|
|
### Frontend Still Shows Wrong URL
|
|
|
|
```bash
|
|
# Verify .env file is correct
|
|
cat packages/frontend/.env
|
|
|
|
# Check if old image is cached
|
|
docker images | grep sexy
|
|
docker rmi ghcr.io/valknarxxx/sexy:old-tag
|
|
|
|
# Force rebuild without cache
|
|
docker build --no-cache -t ghcr.io/valknarxxx/sexy:latest .
|
|
```
|
|
|
|
### Container Starts But Can't Connect to API
|
|
|
|
1. Check Traefik routing:
|
|
```bash
|
|
docker logs traefik | grep sexy
|
|
```
|
|
|
|
2. Check if Directus is accessible:
|
|
```bash
|
|
curl -I https://sexy.pivoine.art/api/server/health
|
|
```
|
|
|
|
3. Check frontend logs:
|
|
```bash
|
|
docker logs sexy_frontend
|
|
```
|
|
|
|
## Development vs Production
|
|
|
|
### Development (Local)
|
|
- Use `pnpm dev` for hot reload
|
|
- No rebuild needed for code changes
|
|
- Env vars from `.env` or shell
|
|
|
|
### Production (Docker)
|
|
- Rebuild required for PUBLIC_* changes
|
|
- Changes baked into JavaScript
|
|
- Env vars from `packages/frontend/.env`
|
|
|
|
## Optimization Tips
|
|
|
|
### Speed Up Rebuilds
|
|
|
|
1. **Use BuildKit cache:**
|
|
```bash
|
|
export DOCKER_BUILDKIT=1
|
|
docker build --build-arg BUILDKIT_INLINE_CACHE=1 -t ghcr.io/valknarxxx/sexy:latest .
|
|
```
|
|
|
|
2. **Multi-stage caching:**
|
|
- Dockerfile already optimized with multi-stage build
|
|
- Dependencies cached separately from code
|
|
|
|
3. **Parallel builds:**
|
|
```bash
|
|
# Build with more CPU cores
|
|
docker build --cpus 4 -t ghcr.io/valknarxxx/sexy:latest .
|
|
```
|
|
|
|
### Reduce Image Size
|
|
|
|
Current optimizations:
|
|
- ✅ Multi-stage build
|
|
- ✅ Production dependencies only
|
|
- ✅ Minimal base image
|
|
- ✅ No dev tools in final image
|
|
|
|
Expected sizes:
|
|
- Base: ~100MB
|
|
- Builder: ~2-3GB (not shipped)
|
|
- Runner: ~300-500MB (final)
|
|
|
|
## Automation
|
|
|
|
### GitHub Actions (Already Set Up)
|
|
|
|
The `.github/workflows/docker-build-push.yml` automatically:
|
|
1. Builds on push to main
|
|
2. Creates version tags
|
|
3. Pushes to GHCR
|
|
4. Caches layers for faster builds
|
|
|
|
**Trigger a rebuild:**
|
|
```bash
|
|
git tag v1.0.1
|
|
git push origin v1.0.1
|
|
```
|
|
|
|
### Local Build Script
|
|
|
|
Use the provided `build.sh`:
|
|
```bash
|
|
./build.sh -t v1.0.0 -p
|
|
```
|
|
|
|
## When NOT to Rebuild
|
|
|
|
You DON'T need to rebuild for:
|
|
- ❌ Directus configuration changes
|
|
- ❌ Database credentials
|
|
- ❌ Redis settings
|
|
- ❌ SMTP settings
|
|
- ❌ Session cookie settings
|
|
- ❌ Traefik labels
|
|
|
|
These are runtime environment variables and can be changed in docker-compose.
|
|
|
|
## Summary
|
|
|
|
| Change | Rebuild Needed | How to Apply |
|
|
|--------|----------------|--------------|
|
|
| `PUBLIC_API_URL` | ✅ Yes | Rebuild image |
|
|
| `PUBLIC_URL` | ✅ Yes | Rebuild image |
|
|
| `PUBLIC_UMAMI_ID` | ✅ Yes | Rebuild image |
|
|
| `LETTERSPACE_*` | ✅ Yes | Rebuild image |
|
|
| `SEXY_DIRECTUS_*` | ❌ No | Restart container |
|
|
| `DB_*` | ❌ No | Restart container |
|
|
| `EMAIL_*` | ❌ No | Restart container |
|
|
| Traefik labels | ❌ No | Restart container |
|
|
|
|
---
|
|
|
|
**Remember:** The key difference is **build-time** (compiled into JS) vs **runtime** (read from environment).
|