Skip to content

Github docs#43317

Open
Sazwanismail wants to merge 6 commits intogithub:mainfrom
Sazwanismail:main
Open

Github docs#43317
Sazwanismail wants to merge 6 commits intogithub:mainfrom
Sazwanismail:main

Conversation

@Sazwanismail
Copy link

@Sazwanismail Sazwanismail commented Mar 11, 2026

Why:

Closes:

What's being changed (if available, include any code snippets, screenshots, or gifs):

Check off the following:

  • A subject matter expert (SME) has reviewed the technical accuracy of the content in this PR. In most cases, the author can be the SME. Open source contributions may require an SME review from GitHub staff.
  • The changes in this PR meet the docs fundamentals that are required for all content.
  • All CI checks are passing and the changes look good in the review environment.
68747470733a2f2f616c76656e2e746563682f77702d636f6e74656e742f75706c6f6164732f323032302f31302f696d6167652d32392e706e67

Muhamad Sazwan Bin Ismail added 3 commits March 12, 2026 00:49
# 🐳 Docker Image GitHub Actions Workflow – Complete Guide

You want to create a GitHub Actions workflow to build and push a Docker image automatically whenever you push code or create a release. This is a crucial part of modern CI/CD pipelines, especially for projects involving microservices, AI models, or deployable applications.

Below I'll provide you with a **production‑ready template** for `.github/workflows/docker-image.yml`, explain each part, and show you how to customize it for your needs (e.g., pushing to Docker Hub, GitHub Container Registry, or both).

---

## 📁 File Location

Place this file in your repository at:

```
.github/workflows/docker-image.yml
```

---

## 🚀 Full Workflow Example

```yaml
name: Build and Push Docker Image

on:
  push:
    branches: [ "main", "develop" ]
    tags: [ "v*.*.*" ]
  pull_request:
    branches: [ "main" ]
  release:
    types: [ published ]

env:
  REGISTRY: docker.io                  # change to ghcr.io for GitHub Container Registry
  IMAGE_NAME: ${{ github.repository }}  # e.g., username/repo

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write      # needed for GHCR

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      # If you want to push to GitHub Container Registry instead (or in addition)
      # - name: Log in to GHCR
      #   uses: docker/login-action@v3
      #   with:
      #     registry: ghcr.io
      #     username: ${{ github.actor }}
      #     password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,format=long
            type=raw,value=latest,enable={{is_default_branch}}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          platforms: linux/amd64,linux/arm64   # optional: multi‑arch
```

---

## 🔍 Step‑by‑Step Explanation

### 1. **Triggers (`on`)**
The workflow runs on:
- `push` to `main` or `develop` branches.
- `push` of tags matching `v*.*.*` (e.g., `v1.2.3`).
- `pull_request` to `main` (builds only, does **not** push).
- `release` published (ideal for final tagging).

Adjust the branches and patterns to match your workflow.

### 2. **Environment Variables**
- `REGISTRY`: set to `docker.io` for Docker Hub, or `ghcr.io` for GitHub Container Registry.
- `IMAGE_NAME`: uses `github.repository` (e.g., `yourusername/yourrepo`). You can hardcode a custom name if needed.

### 3. **Permissions**
- `packages: write` is required if you push to GHCR. For Docker Hub you don’t need it, but it’s harmless to keep.

### 4. **Checkout**
Fetches your code so the Docker build can use it.

### 5. **Set up Docker Buildx**
Enables advanced features like multi‑platform builds and better caching.

### 6. **Login to Registry**
- **Docker Hub**: uses secrets `DOCKER_USERNAME` and `DOCKER_PASSWORD`.  
  (Create these in your repository **Settings → Secrets and variables → Actions**.)
- **GHCR**: uses the built‑in `GITHUB_TOKEN` – no extra secrets needed. Uncomment the second login block if you want to push there as well.

### 7. **Metadata Extraction**
The `docker/metadata-action` generates Docker tags and labels based on the git reference.  
Common tag types:
- `type=ref,event=branch` → e.g., `main`, `develop`
- `type=ref,event=pr` → `pr-123`
- `type=semver,pattern={{version}}` → for tags: `v1.2.3`, `v1.2`, `v1`
- `type=sha,format=long` → full commit hash
- `type=raw,value=latest,enable={{is_default_branch}}` → adds `latest` only on the default branch

You can customise the tag list as you like.

### 8. **Build and Push**
- `push: true` only when the event is **not** a pull request (to avoid pushing PR images).
- `tags` and `labels` come from the metadata step.
- **Caching** (`cache-from` / `cache-to` with `type=gha`) uses GitHub Actions cache to speed up subsequent builds.
- `platforms`: optional, enables multi‑architecture images (e.g., both Intel and ARM). Requires QEMU setup (see below).

---

## 🧪 Adding Multi‑Platform Builds

If you need images for different CPU architectures (e.g., `linux/arm64` for Raspberry Pi), include these steps before `buildx`:

```yaml
- name: Set up QEMU
  uses: docker/setup-qemu-action@v3
```

Then in the build step, add:
```yaml
platforms: linux/amd64,linux/arm64,linux/arm/v7
```

---

## 🔒 Security Scanning

Integrate vulnerability scanning to ensure your images are safe:

```yaml
- name: Scan image with Trivy
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
    format: 'sarif'
    output: 'trivy-results.sarif'

- name: Upload Trivy results to GitHub Security tab
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: 'trivy-results.sarif'
```

Add this **after** the build step.

---

## 🧪 Running Tests Before Building

You can add a separate job for testing, or include test steps in the same job:

```yaml
- name: Run unit tests
  run: |
    docker build --target test -t test-image .
    docker run --rm test-image npm test
```

(Assumes your Dockerfile has a `test` stage.)

---

## 📦 Using the GitHub Container Registry (GHCR)

If you prefer GHCR over Docker Hub:
- Set `REGISTRY: ghcr.io`
- Use the GHCR login step (already shown, commented out).
- Your image will be available at `ghcr.io/yourusername/yourrepo:tag`.

---

## 🔐 Required Secrets

| Secret Name | Description |
|-------------|-------------|
| `DOCKER_USERNAME` | Your Docker Hub username |
| `DOCKER_PASSWORD` | Docker Hub password or access token (recommended) |

If you use two‑factor authentication on Docker Hub, create an **access token** (Account Settings → Security → New Access Token) and use that as the password.

For GHCR, no secrets are needed – `GITHUB_TOKEN` is automatically provided.

---

## 🧠 Customizing for Your Project

### **Context Path**
If your Dockerfile is not in the repository root, change `context` to the correct folder, e.g.:
```yaml
context: ./my-service
```

### **Dockerfile Name**
If your Dockerfile has a different name, add:
```yaml
file: ./my-service/Dockerfile.custom
```

### **Tagging Overrides**
Add custom tags using `type=raw`:
```yaml
tags: |
  type=raw,value=production,enable=${{ github.ref == 'refs/heads/production' }}
```

---

## ✅ Example Workflow in Action

1. You push a commit to `main`.
2. GitHub Actions triggers the workflow.
3. It builds the Docker image with tags: `main`, `latest`, and the commit SHA.
4. The image is pushed to Docker Hub.
5. (Optional) Trivy scans it and uploads results.

When you create a release (or push a tag `v1.2.3`), it also builds and pushes `v1.2.3`, `v1.2`, `v1`.

---

## 📚 Next Steps

1. **Copy the template** into your repository.
2. **Add secrets** if using Docker Hub.
3. **Commit and push** to see the first run.
4. **Check the Actions tab** in your GitHub repo to monitor progress.

You now have a fully automated Docker build pipeline. Combine it with your Firebase AI, ESP32, and WebRTC projects to deploy microservices effortlessly. Let me know if you need help adapting it to a specific part of your system! 🚀
@github-actions github-actions bot added the triage Do not begin working on this issue until triaged by the team label Mar 11, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

How to review these changes 👓

Thank you for your contribution. To review these changes, choose one of the following options:

A Hubber will need to deploy your changes internally to review.

Table of review links

Note: Please update the URL for your staging server or codespace.

This pull request contains code changes, so we will not generate a table of review links.

🤖 This comment is automatically generated.

Muhamad Sazwan Bin Ismail added 2 commits March 12, 2026 02:08
# 🛠️ Custom `dependabot.yml` for Node.js, Python, Docker, and GitHub Actions

Below is a tailored Dependabot configuration for a repository that uses **Node.js**, **Python**, **Docker**, and **GitHub Actions**. Adjust the `directory` paths to match your actual project layout.

## 📁 Assumed Project Structure

```
.
├── .github/
│   └── workflows/           # GitHub Actions workflows
├── frontend/                 # Node.js application (if separate)
│   ├── package.json
│   └── ...
├── backend/                  # Python application (if separate)
│   ├── requirements.txt
│   └── ...
├── Dockerfile                # If Dockerfile is in root
├── requirements.txt          # If Python deps are in root
├── package.json              # If Node.js deps are in root
└── ...
```

## 🔧 `dependabot.yml` Configuration

Create the file at `.github/dependabot.yml` with the following content:

```yaml
version: 2
updates:
  # 1. Node.js (npm) dependencies
  - package-ecosystem: "npm"
    # Adjust directory if your package.json is in a subfolder
    directory: "/"                     # root, or "/frontend", "/backend" etc.
    schedule:
      interval: "weekly"                # daily, weekly, monthly
      day: "monday"                     # optional
      time: "09:00"                      # UTC
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
      - "javascript"
    reviewers:
      - "your-github-username"           # optional: assign reviewers
    commit-message:
      prefix: "chore(deps)"
      prefix-development: "chore(deps-dev)"

  # 2. Python (pip) dependencies
  - package-ecosystem: "pip"
    directory: "/"                     # root, or "/backend"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
      - "python"
    reviewers:
      - "your-github-username"
    # For pip, you can also specify a requirements file pattern
    # requirements: "requirements.txt"  # if not in default location
    commit-message:
      prefix: "chore(deps-pip)"

  # 3. Docker
  - package-ecosystem: "docker"
    directory: "/"                     # location of Dockerfile
    schedule:
      interval: "monthly"               # base images change less often
    labels:
      - "dependencies"
      - "docker"
    commit-message:
      prefix: "chore(docker)"

  # 4. GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"                     # looks in .github/workflows
    schedule:
      interval: "weekly"
    labels:
      - "dependencies"
      - "github-actions"
    commit-message:
      prefix: "chore(actions)"
```

## 🔍 Explanation of Options

- **`package-ecosystem`**: Identifies the dependency manager.
- **`directory`**: The directory where the manifest files are located. For GitHub Actions, it's always `/` (the root) because it scans `.github/workflows`.
- **`schedule`**: How often Dependabot checks for updates. Choose `daily`, `weekly`, or `monthly`. You can also specify `day` and `time`.
- **`open-pull-requests-limit`**: Max number of open PRs Dependabot will create at once (prevents flooding).
- **`labels`**: Labels to add to PRs (useful for filtering and automation).
- **`reviewers` / `assignees`**: GitHub usernames or team names to auto-assign.
- **`commit-message`**: Customise the commit message prefix.

## 🧩 Customising for Your Project

- If your **Node.js** and **Python** dependencies are in the **root**, set both directories to `/`.
- If they are in separate subfolders (e.g., `frontend` and `backend`), change the `directory` accordingly:
  ```yaml
  - package-ecosystem: "npm"
    directory: "/frontend"
  - package-ecosystem: "pip"
    directory: "/backend"
  ```
- For **Docker**, if you have multiple Dockerfiles in different directories, you can add separate blocks for each.

## 🚀 Enabling Dependabot

1. Commit the `.github/dependabot.yml` file to your default branch.
2. Ensure **Dependabot alerts** and **Dependabot security updates** are enabled in your repository settings (Settings → Code security and analysis).
3. Dependabot will run within 24 hours and create PRs based on your schedule.

## ✅ Best Practices

- Start with `open-pull-requests-limit: 5` if you're new to Dependabot.
- Use **labels** to easily filter PRs in your CI (e.g., only run certain tests on dependency PRs).
- Combine with **GitHub Actions** to automatically run tests on Dependabot PRs (Dependabot PRs have `github.actor == 'dependabot[bot]'`).
- Consider using **`versioning-strategy`** for npm: `increase` updates both `package.json` and `package-lock.json`; `lockfile-only` only updates the lockfile.

Need adjustments for your specific folder layout? Let me know! 😊
# 🔄 Enhanced `dependabot.yml` with Advanced Features

You asked for "Again" – let's take Dependabot configuration to the next level! Below is an **advanced, production-ready** configuration for your Node.js, Python, Docker, and GitHub Actions stack. It includes grouping, ignore rules, custom labels, and settings to work seamlessly with your CI.

## 📁 Advanced `dependabot.yml`

```yaml
version: 2
updates:
  # -------------------- Node.js (npm) --------------------
  - package-ecosystem: "npm"
    directory: "/"                     # or "/frontend"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "09:00"
      timezone: "Asia/Kuala_Lumpur"
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
      - "javascript"
      - "automerge"                    # if you use auto-merge workflows
    reviewers:
      - "your-username"
    assignees:
      - "your-username"
    # Group all minor/patch updates together
    groups:
      minor-and-patch:
        applies-to: version-updates
        update-types:
          - "minor"
          - "patch"
        patterns:
          - "*"
    # Ignore major updates for certain packages
    ignore:
      - dependency-name: "react"
        versions: [ ">=18.x" ]
      - dependency-name: "express"
        versions: [ "5.x" ]
    versioning-strategy: increase       # updates package.json as well
    commit-message:
      prefix: "chore(deps)"
      prefix-development: "chore(deps-dev)"
      include: "scope"                  # includes dependency name

  # -------------------- Python (pip) --------------------
  - package-ecosystem: "pip"
    directory: "/"                     # or "/backend"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
      - "python"
    reviewers:
      - "your-username"
    groups:
      python-minor-patch:
        applies-to: version-updates
        update-types:
          - "minor"
          - "patch"
        patterns:
          - "*"
    ignore:
      - dependency-name: "django"
        versions: [ ">=4.0" ]
    # For pip, you can specify requirements files explicitly
    # requirements: "requirements.txt"
    commit-message:
      prefix: "chore(deps-pip)"

  # -------------------- Docker --------------------
  - package-ecosystem: "docker"
    directory: "/"                     # where Dockerfile lives
    schedule:
      interval: "monthly"               # base images change less often
    labels:
      - "dependencies"
      - "docker"
    commit-message:
      prefix: "chore(docker)"
    ignore:
      - dependency-name: "node"
        versions: [ ">=20" ]            # if you want to stick to older LTS

  # -------------------- GitHub Actions --------------------
  - package-ecosystem: "github-actions"
    directory: "/"                     # always root
    schedule:
      interval: "weekly"
    labels:
      - "dependencies"
      - "github-actions"
    commit-message:
      prefix: "chore(actions)"
```

## 🧠 Advanced Features Explained

### **1. Grouping Updates**
```yaml
groups:
  minor-and-patch:
    applies-to: version-updates
    update-types: ["minor", "patch"]
    patterns: ["*"]
```
- Groups all minor and patch updates into a **single pull request**. This reduces PR noise.
- You can create multiple groups (e.g., `major-updates`, `security-only`).

### **2. Ignoring Certain Versions**
```yaml
ignore:
  - dependency-name: "react"
    versions: [ ">=18.x" ]
```
- Prevents Dependabot from suggesting updates to React 18+ if you're not ready.

### **3. Timezone Support**
```yaml
timezone: "Asia/Kuala_Lumpur"
```
- Ensures the schedule runs at a sensible local time.

### **4. Commit Message Customisation**
```yaml
commit-message:
  prefix: "chore(deps)"
  include: "scope"
```
- Adds the dependency name to the commit message, e.g., `chore(deps): bump lodash from 4.17.20 to 4.17.21`.

### **5. Security Updates**
Dependabot also automatically opens PRs for **security vulnerabilities** – these are **not** controlled by `dependabot.yml`. They appear separately as "security" PRs with the label `security`. You can enable/disable them in repository settings.

## 🤖 Automating Dependabot PRs with GitHub Actions

You can automatically **approve and merge** Dependabot PRs that pass tests. Here's a simple workflow (`.github/workflows/auto-merge.yml`):

```yaml
name: Auto-merge Dependabot PRs

on: pull_request_target

permissions:
  pull-requests: write
  contents: write

jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: github.actor == 'dependabot[bot]'
    steps:
      - name: Fetch Dependabot metadata
        id: metadata
        uses: dependabot/fetch-metadata@v2
        with:
          github-token: "${{ secrets.GITHUB_TOKEN }}"
      - name: Approve PR
        run: gh pr review --approve "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Enable auto-merge
        if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor'
        run: gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

This workflow:
- Approves any Dependabot PR.
- Auto-merges if it's a patch or minor update (after CI passes).

## 🧪 Testing Dependabot Locally

You can't run Dependabot locally, but you can **manually trigger** a version update check using the GitHub CLI:

```bash
gh api -X POST /repos/{owner}/{repo}/dependabot/updates -f "package-ecosystem=npm" -f "directory=/" -f "schedule.interval=weekly"
```

This is useful for testing after changing `dependabot.yml`.

## 📌 Next Steps

1. **Copy the enhanced config** into `.github/dependabot.yml`.
2. **Adjust directories** and **ignore rules** to match your project.
3. **Commit and push** to your default branch.
4. **Monitor** the first run (within 24 hours) – check the **Insights → Dependency graph → Dependabot** tab.

Need further customisation? Let me know! 😊
@github-actions
Copy link
Contributor

👋 Hey there spelunker. It looks like you've modified some files that we can't accept as contributions:

  • .github/dependabot.yml

You'll need to revert all of the files you changed that match that list using GitHub Desktop or git checkout origin/main <file name>. Once you get those files reverted, we can continue with the review process. :octocat:

The complete list of files we can't accept are:

  • .devcontainer/**
  • .github/**
  • data/reusables/rai/**
  • Dockerfile*
  • src/**
  • package*.json
  • content/actions/how-tos/security-for-github-actions/security-hardening-your-deployments/**

We also can't accept contributions to files in the content directory with frontmatter type: rai or contentType: rai.

@github-actions
Copy link
Contributor

👋 Hey there spelunker. It looks like you've modified some files that we can't accept as contributions:

  • .github/dependabot.yml

You'll need to revert all of the files you changed that match that list using GitHub Desktop or git checkout origin/main <file name>. Once you get those files reverted, we can continue with the review process. :octocat:

The complete list of files we can't accept are:

  • .devcontainer/**
  • .github/**
  • data/reusables/rai/**
  • Dockerfile*
  • src/**
  • package*.json
  • content/actions/how-tos/security-for-github-actions/security-hardening-your-deployments/**

We also can't accept contributions to files in the content directory with frontmatter type: rai or contentType: rai.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage Do not begin working on this issue until triaged by the team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant