Skip to content

Commit 20e50e8

Browse files
author
Muhamad Sazwan Bin Ismail
authored
Create Docker image GitHub
# 🐳 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! 🚀
1 parent aa17a0e commit 20e50e8

File tree

1 file changed

+893
-0
lines changed

1 file changed

+893
-0
lines changed

0 commit comments

Comments
 (0)