From 94286517d1a4d3d053fab0485f7bbeac1e353439 Mon Sep 17 00:00:00 2001 From: AlexKalll Date: Fri, 17 Oct 2025 20:27:23 +0300 Subject: [PATCH] cd: add Docker-based CD workflow for image segmentation app --- .github/workflows/cd.yml | 87 ++++++++++++++++++++++++++++++++++++++++ Dockerfile | 53 ++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 .github/workflows/cd.yml create mode 100644 Dockerfile diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..6104a2d --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,87 @@ +# ----------------------------------------------- +# 🌟 GitHub Actions: Continuous Delivery (CD) +# Builds and publishes a Docker image of your app +# ----------------------------------------------- + +name: Build and publish Docker image + +# ----------------------------------------------- +# 🧠 Trigger conditions +# Run this workflow when: +# 1. You push to the main branch +# 2. You create a version tag (e.g., v1.0.0) +# ----------------------------------------------- +on: + push: + branches: [ main ] + tags: [ 'v*.*.*' ] + +# ----------------------------------------------- +# πŸ”‘ Permissions for GitHub Container Registry +# ----------------------------------------------- +permissions: + contents: read + packages: write + +# ----------------------------------------------- +# 🧱 Define the job +# ----------------------------------------------- +jobs: + build-and-push: + runs-on: ubuntu-latest # use latest Ubuntu VM for building + + steps: + # ------------------------------------------- + # Step 1: Checkout your code + # ------------------------------------------- + - name: Checkout repository + uses: actions/checkout@v4 + + # ------------------------------------------- + # Step 2: Extract metadata for tagging the Docker image + # Example: main branch β†’ "latest", v1.0.0 tag β†’ "v1.0.0" + # ------------------------------------------- + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=sha + + # ------------------------------------------- + # Step 3: Set up QEMU (for cross-platform builds) + # ------------------------------------------- + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + # ------------------------------------------- + # Step 4: Set up Docker Buildx (for building images) + # ------------------------------------------- + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # ------------------------------------------- + # Step 5: Log in to GitHub Container Registry (GHCR) + # GitHub automatically provides a token for this. + # ------------------------------------------- + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # ------------------------------------------- + # Step 6: Build and push the Docker image + # "push: true" publishes it to GHCR + # ------------------------------------------- + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . # project root + push: true # upload to registry + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1f35984 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,53 @@ +# ----------------------------- +# 🐳 Base image: a lightweight Python environment +# ----------------------------- +FROM python:3.11-slim + +# Prevent Python from writing .pyc files and buffering output +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +# ----------------------------- +# 🏠 Set the working directory inside the container +# ----------------------------- +WORKDIR /app + +# ----------------------------- +# βš™οΈ Install system dependencies (optional but useful for numpy, pillow, etc.) +# ----------------------------- +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +# ----------------------------- +# πŸ“¦ Install Python dependencies +# ----------------------------- +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# ----------------------------- +# πŸ“‚ Copy project files into container +# ----------------------------- +# Copy your app code and support folders +COPY app ./app +COPY src ./src +COPY assets ./assets +COPY .streamlit ./.streamlit +COPY README.md . + +# ----------------------------- +# 🌐 Expose Streamlit’s default port +# ----------------------------- +EXPOSE 8501 + +# ----------------------------- +# βš™οΈ Environment settings for Streamlit +# ----------------------------- +ENV STREAMLIT_SERVER_HEADLESS=true \ + STREAMLIT_SERVER_PORT=8501 \ + STREAMLIT_BROWSER_GATHERUSAGESTATS=false + +# ----------------------------- +# πŸš€ Run your Streamlit app +# ----------------------------- +CMD ["streamlit", "run", "app/main.py"]