# مدیریت Base Image

این مستند راهنمای کامل برای مدیریت و استفاده از base image در پروژه Peikarband است.

## نمای کلی

**Base Image چیست؟**

Base image یک Docker image از پیش ساخته شده است که شامل تمام ابزارهای مورد نیاز برای build اپلیکیشن است:
- Python 3.11
- Node.js 20
- Bun (برای Reflex frontend)
- Build tools (gcc, g++, make)
- Git و curl

**چرا Base Image؟**

✅ **سرعت Build:** 8-10 دقیقه → 2-3 دقیقه  
✅ **قابلیت اطمینان:** بدون نیاز به دانلود مکرر npm/bun  
✅ **Consistency:** همه builds از همان environment استفاده می‌کنند  
✅ **Network Resilience:** مشکلات network کمتر  

## ساختار فایل‌ها

```
.
├── docker/
│   ├── Dockerfile            # استفاده از base image
│   └── Dockerfile.base       # تعریف base image
├── .woodpecker.yml          # Build اپلیکیشن (از base استفاده می‌کند)
└── .woodpecker-base.yml     # Build base image (manual/on-change)
```

## Base Image Tags

```
hub.peikarband.ir/peikarband/base:latest              # آخرین version
hub.peikarband.ir/peikarband/base:python3.11-node20   # Version specific
hub.peikarband.ir/peikarband/base:python3.11-node20-a1b2c3d4  # With commit SHA
```

## چگونه Base Image را Build کنیم؟

### روش 1: Manual Trigger در Woodpecker (پیشنهادی)

1. رفتن به Woodpecker UI
2. انتخاب repository: `peikarband/landing`
3. کلیک روی "Pipelines"
4. کلیک روی "New Pipeline"
5. انتخاب pipeline: `.woodpecker-base.yml`
6. کلیک روی "Start"

### روش 2: Push تغییرات Dockerfile.base

هر بار که `docker/Dockerfile.base` تغییر کند، pipeline به‌طور خودکار trigger می‌شود:

```bash
# تغییر Dockerfile.base
vim docker/Dockerfile.base

# Commit و push
git add docker/Dockerfile.base
git commit -m "chore: update base image to Node.js 21"
git push origin main

# Pipeline به‌طور خودکار اجرا می‌شود
```

### روش 3: Local Build (برای تست)

```bash
# Build locally
docker build -f docker/Dockerfile.base \
  -t hub.peikarband.ir/peikarband/base:latest \
  --build-arg PYTHON_VERSION=3.11 \
  --build-arg NODE_VERSION=20 \
  .

# Test locally
docker run --rm hub.peikarband.ir/peikarband/base:latest \
  bash -c "python --version && node --version && bun --version"

# Push to registry
docker login hub.peikarband.ir
docker push hub.peikarband.ir/peikarband/base:latest
docker push hub.peikarband.ir/peikarband/base:python3.11-node20
```

## چگونه Application از Base Image استفاده می‌کند؟

Pipeline اصلی (`.woodpecker.yml`) به‌طور خودکار از base image استفاده می‌کند:

### مرحله 1: Check Base Image

```yaml
check-base-image:
  # بررسی می‌کند که base image در registry موجود است
  # اگر نباشد، error می‌دهد و راهنمایی می‌کند
```

### مرحله 2: Build Application

```yaml
build-image:
  build_args:
    - BASE_IMAGE=hub.peikarband.ir/peikarband/base:latest
  push: false  # فقط build، بدون push
```

### مرحله 3: Push Application

```yaml
push-image:
  tags:
    - latest
    - ${CI_COMMIT_SHA:0:8}
    - ${CI_COMMIT_BRANCH}
  push: true  # حالا push می‌کنیم
```

### مرحله 4: Verify

```yaml
verify-push:
  # تایید می‌کند که image با موفقیت push شده
```

## چه زمانی باید Base Image را Rebuild کنیم؟

### Rebuild ضروری است:

1. **تغییر Python version:**
   ```bash
   # در Dockerfile.base
   ARG PYTHON_VERSION=3.12  # تغییر از 3.11
   ```

2. **تغییر Node.js version:**
   ```bash
   # در Dockerfile.base
   ARG NODE_VERSION=21  # تغییر از 20
   ```

3. **اضافه کردن system dependencies:**
   ```dockerfile
   RUN apt-get install -y \
       gcc g++ make \
       postgresql-dev  # جدید
   ```

4. **تغییر bun installation:**
   ```dockerfile
   # اگر روش نصب bun تغییر کند
   ```

### Rebuild اختیاری است:

1. **تغییرات جزئی در Dockerfile اصلی**
2. **تغییر کد اپلیکیشن**
3. **تغییر Helm charts**

## مدیریت Versions

### Strategy ما:

```
latest              → همیشه آخرین version
python3.11-node20   → Version مشخص (stable)
python3.11-node20-a1b2c3d4  → با commit SHA (rollback)
```

### مثال: Update به Python 3.12

```bash
# 1. تغییر Dockerfile.base
vim docker/Dockerfile.base
# ARG PYTHON_VERSION=3.12

# 2. Commit
git add docker/Dockerfile.base
git commit -m "chore: upgrade base image to Python 3.12"
git push origin main

# 3. Wait for .woodpecker-base.yml to complete

# 4. تغییر تگ در application Dockerfile (اختیاری)
vim docker/Dockerfile
# ARG BASE_IMAGE=hub.peikarband.ir/peikarband/base:python3.12-node20

# 5. Test application build
git add docker/Dockerfile
git commit -m "chore: use Python 3.12 base image"
git push origin main
```

## Troubleshooting

### خطا: "Base image not found"

**علت:** Base image هنوز build نشده یا در registry موجود نیست

**راه‌حل:**

```bash
# 1. بررسی کنید که base image در registry موجود است
curl -u "admin:password" \
  https://hub.peikarband.ir/v2/peikarband/base/tags/list

# 2. اگر موجود نیست، pipeline base را اجرا کنید
# Manual trigger در Woodpecker UI → .woodpecker-base.yml

# 3. یا local build:
docker build -f docker/Dockerfile.base -t hub.peikarband.ir/peikarband/base:latest .
docker push hub.peikarband.ir/peikarband/base:latest
```

### خطا: "Failed to pull base image"

**علت:** Registry authentication مشکل دارد

**راه‌حل:**

```bash
# 1. بررسی credentials در Woodpecker secrets
# Repository → Settings → Secrets → HARBOR_USERNAME, HARBOR_PASSWORD

# 2. Test login locally
docker login hub.peikarband.ir
Username: admin
Password: [your-password]

# 3. Test pull
docker pull hub.peikarband.ir/peikarband/base:latest
```

### Base Image خیلی بزرگ است

**بررسی اندازه:**

```bash
# Check image size
docker images hub.peikarband.ir/peikarband/base
```

**Optimization:**

```dockerfile
# در Dockerfile.base

# 1. حذف apt cache
RUN apt-get update && apt-get install -y ... \
    && rm -rf /var/lib/apt/lists/*  # این خط مهم است

# 2. حذف npm cache
RUN npm cache clean --force

# 3. استفاده از slim image
FROM python:3.11-slim  # نه python:3.11
```

### Build Time هنوز کند است

**بررسی:**

```bash
# 1. آیا واقعاً از base image استفاده می‌شود؟
docker history hub.peikarband.ir/peikarband/landing:latest | grep base

# 2. آیا cache درست کار می‌کند؟
# در .woodpecker.yml:
cache_from: type=registry,ref=...
```

**بهبود:**

```yaml
# در .woodpecker.yml
build-image:
  settings:
    # Pull base image first for caching
    pull: true
    cache_from: 
      - type=registry,ref=hub.peikarband.ir/peikarband/base:latest
      - type=registry,ref=hub.peikarband.ir/peikarband/landing:buildcache
```

## Best Practices

### 1. Version Pinning

❌ **بد:**
```dockerfile
FROM hub.peikarband.ir/peikarband/base:latest
```

✅ **خوب (برای production):**
```dockerfile
FROM hub.peikarband.ir/peikarband/base:python3.11-node20
```

### 2. Testing Base Changes

قبل از اینکه base image جدید را در production استفاده کنید:

```bash
# 1. Build base با tag test
docker build -f docker/Dockerfile.base \
  -t hub.peikarband.ir/peikarband/base:test .

# 2. Test application با این base
docker build --build-arg BASE_IMAGE=hub.peikarband.ir/peikarband/base:test \
  -f docker/Dockerfile .

# 3. اگر موفق بود، tag را به latest تغییر دهید
docker tag hub.peikarband.ir/peikarband/base:test \
  hub.peikarband.ir/peikarband/base:latest
docker push hub.peikarband.ir/peikarband/base:latest
```

### 3. Documentation

هر بار که base image را تغییر می‌دهید، در CHANGELOG.md یادداشت کنید:

```markdown
## [Base Image] 2024-12-30

### Changed
- Upgraded Python from 3.11 to 3.12
- Updated Node.js from 20 to 21
- Added postgresql-dev for database support

### Impact
- All future builds will use new base
- Rebuild takes ~10 minutes
- Application builds will be ~30% faster
```

### 4. Cleanup Old Images

```bash
# List all base images
curl -u "admin:password" \
  https://hub.peikarband.ir/v2/peikarband/base/tags/list | jq

# حذف تگ‌های قدیمی (از Harbor UI)
# Repository → peikarband/base → Tags → Select → Delete
```

## Monitoring

### چگونه بفهمیم base image استفاده می‌شود؟

```bash
# 1. از Docker history
docker history hub.peikarband.ir/peikarband/landing:latest

# 2. از image labels
docker inspect hub.peikarband.ir/peikarband/landing:latest | \
  jq '.[0].Config.Labels'

# 3. از build logs در Woodpecker
# Stage "check-base-image" باید "✓ Base image found" نمایش دهد
```

### Metrics مفید:

```bash
# Build time comparison
# Before base image: 8-10 min
# After base image:  2-3 min
# Improvement: 60-70%

# Network usage
# Before: ~500 MB download per build (npm, bun, etc.)
# After: ~50 MB (only base image pull if not cached)
# Improvement: 90%
```

## FAQ

**Q: چند وقت یکبار باید base را rebuild کنیم؟**  
A: فقط وقتی که dependencies (Python, Node.js, bun) تغییر می‌کنند. معمولاً هر 2-3 ماه یکبار.

**Q: آیا می‌توانیم چند base image داشته باشیم؟**  
A: بله! مثلاً:
- `base:python3.11-node20` → برای پروژه‌های قدیمی
- `base:python3.12-node21` → برای پروژه‌های جدید

**Q: اگر base image corrupt شود چه کنیم؟**  
A: Application Dockerfile می‌تواند به `python:3.11-slim` fallback کند:
```dockerfile
ARG BASE_IMAGE=hub.peikarband.ir/peikarband/base:latest
FROM ${BASE_IMAGE:-python:3.11-slim} AS builder
```

**Q: چگونه base را به پروژه‌های دیگر منتقل کنیم؟**  
A: Base image در registry مرکزی است، تمام پروژه‌ها می‌توانند از آن استفاده کنند:
```dockerfile
# در هر پروژه دیگر
FROM hub.peikarband.ir/peikarband/base:latest
```

## مراجع

- [Multi-stage Docker Builds](https://docs.docker.com/build/building/multi-stage/)
- [Docker Build Cache](https://docs.docker.com/build/cache/)
- [Harbor Registry Management](https://goharbor.io/docs/latest/)
- [Woodpecker CI Documentation](https://woodpecker-ci.org/docs/)

