🤖 ci: optimize CI/CD with Docker cache and remove Buildx
This commit is contained in:
@@ -31,12 +31,14 @@ This approach is simpler, more reliable, and works consistently with self-signed
|
||||
|
||||
## Decision
|
||||
|
||||
**Replace Docker Buildx with traditional docker build + push** for the CI/CD pipeline.
|
||||
**Replace Docker Buildx with traditional docker build + push** for the CI/CD pipeline and implement a two-stage Docker build strategy.
|
||||
|
||||
### Implementation
|
||||
|
||||
#### 1. Build Cache Strategy
|
||||
|
||||
```yaml
|
||||
# New approach
|
||||
# Build cache using traditional docker build
|
||||
- name: Build and push Docker cache image
|
||||
if: steps.check_cache.outputs.cache_hit == 'false'
|
||||
run: |
|
||||
@@ -55,14 +57,121 @@ This approach is simpler, more reliable, and works consistently with self-signed
|
||||
echo "✅ Build cache image pushed successfully"
|
||||
```
|
||||
|
||||
#### 2. Production Build Strategy
|
||||
|
||||
```yaml
|
||||
# Production build using Dockerfile.prod
|
||||
- name: Build and push Docker image
|
||||
if: github.ref == 'refs/heads/main'
|
||||
run: |
|
||||
source VERSION
|
||||
IMAGE_VERSION="$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"
|
||||
|
||||
TAGS="$IMAGE_VERSION latest ${{ github.sha }}"
|
||||
echo "Building Docker image with tags: $TAGS"
|
||||
|
||||
# Use the production Dockerfile that leverages the build cache
|
||||
docker build -t dance-lessons-coach -f Dockerfile.prod .
|
||||
|
||||
for TAG in $TAGS; do
|
||||
IMAGE_NAME="${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:$TAG"
|
||||
echo "Tagging and pushing: $IMAGE_NAME"
|
||||
docker tag dance-lessons-coach "$IMAGE_NAME"
|
||||
docker push "$IMAGE_NAME"
|
||||
done
|
||||
```
|
||||
|
||||
#### 3. Dockerfile Structure
|
||||
|
||||
**Dockerfile.build** - Build environment with all dependencies:
|
||||
```dockerfile
|
||||
FROM golang:1.26.1-alpine AS builder
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache git bash curl make gcc musl-dev bc grep sed jq ca-certificates
|
||||
|
||||
# Install Go tools
|
||||
RUN go install github.com/swaggo/swag/cmd/swag@latest
|
||||
|
||||
# Copy and verify dependencies
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download && go mod verify
|
||||
|
||||
WORKDIR /workspace
|
||||
```
|
||||
|
||||
**Dockerfile.prod** - Minimal production image:
|
||||
```dockerfile
|
||||
# Use the build cache image as base
|
||||
FROM gitea.arcodange.lab/arcodange/dance-lessons-coach-build-cache:latest AS builder
|
||||
|
||||
# Final minimal image
|
||||
FROM alpine:3.18
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install minimal dependencies
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
|
||||
# Copy binary from builder
|
||||
COPY --from=builder /workspace/dance-lessons-coach /app/dance-lessons-coach
|
||||
|
||||
# Copy configuration
|
||||
COPY config.yaml /app/config.yaml
|
||||
|
||||
# Set permissions and entrypoint
|
||||
RUN chmod +x /app/dance-lessons-coach
|
||||
ENV TZ=UTC
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/app/dance-lessons-coach"]
|
||||
```
|
||||
|
||||
**Dockerfile** - Development Dockerfile (kept for local development):
|
||||
```dockerfile
|
||||
# Multi-stage build for development
|
||||
FROM golang:1.26.1-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . ./
|
||||
RUN go build -o /dance-lessons-coach ./cmd/server
|
||||
|
||||
FROM alpine:3.18
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
COPY --from=builder /dance-lessons-coach /app/dance-lessons-coach
|
||||
COPY config.yaml /app/config.yaml
|
||||
RUN chmod +x /app/dance-lessons-coach
|
||||
ENV TZ=UTC
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/app/dance-lessons-coach"]
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
### CI/CD Pipeline Benefits
|
||||
|
||||
1. **Simplicity**: Traditional approach is easier to understand and debug
|
||||
2. **Reliability**: Consistent behavior across different environments
|
||||
3. **Certificate Handling**: Works seamlessly with self-signed certificates
|
||||
4. **Performance**: Faster execution without Buildx overhead
|
||||
5. **Compatibility**: Better compatibility with GitHub Actions environment
|
||||
|
||||
### Two-Stage Build Benefits
|
||||
|
||||
1. **Separation of Concerns**: Clear separation between build environment and production runtime
|
||||
2. **Optimized Production Image**: Minimal Alpine-based image with only necessary dependencies
|
||||
3. **Reusable Build Cache**: Build environment can be reused across multiple CI runs
|
||||
4. **Faster CI Execution**: Pre-built build cache reduces CI execution time
|
||||
5. **Consistent Builds**: All builds use the same build environment
|
||||
|
||||
### Development vs Production Clarity
|
||||
|
||||
1. **Development Dockerfile**: Full build environment for local development
|
||||
2. **Production Dockerfile**: Minimal runtime environment for deployment
|
||||
3. **Build Cache Dockerfile**: Optimized build environment for CI/CD
|
||||
4. **Clear Documentation**: Each Dockerfile has a specific purpose
|
||||
|
||||
## Trade-offs
|
||||
|
||||
### What We Lose
|
||||
|
||||
Reference in New Issue
Block a user