foundev.github.io

Busy Engineers Guide to Deploying on K8s Part 1 - Setting up Docker with GitHub Packages

Post Valid as of October 12, 2021.

Busy Engineer’s Guide to Deploying On K8s

While trying to take some coworkers through setting up Docker with GitHub Packages I ran some not obvious edges and my boss pointed out for new to Docker and new to Kubernetes people these could be totally derailing corners. I have to agree, so this series will take people front to back through setting up Kubernetes with the options most readily available to us.

Why GitHub Packages

Docker is easy right?! While it is easy to push to DockerHub it would require pushing to private repositories on private accounts and getting access to the company DockerHub account is not as easy as we would hope. I have seen similar in other companies so I do not think it is alone that way for us. Why not Google, EC2, etc? Same reasons as above. GitHub Packages has the advantage of, if you already have code in GitHub you can now start publishing to docker on company resources and really stay on those resources for as long as you need until the company DockerHub opens up for you. Honestly, I have had several projects canceled before I got access to the company DockerHub, so it ends up being a fatal blocker to our progress. Pragmatically, we can just use GitHub Packages and get on with our lives.

Why aren’t the docs good enough?

I had to go through a few hoops to get a package actually setup and showing in the repository in the GitHub UI. While this is all documented, again I knew where to look and had used GitHub Packages in an earlier iteration where the documents were honestly clearer to me. Also, the second part of this series will talk about using GitHub Packages with to Kubernetes. Again something rather basic for existing Kubernetes users, but that seems to be what the docs expect. This goes very quickly off the rails if you change one thing, and we live in a world where there are plenty of options for everything.

Getting started

I am going the easiest route, if you know how to do any of these things any other way, go for it

Mac and Linux

Optional make a repository and nodejs project

FROM node:16

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 3000
CMD [ "npm", "start" ]
name: GH Packages Push

on:
  push:
    # Publish `main` as Docker `latest` image.
    branches:
      - main
      - seed

    # Publish `v1.2.3` tags as releases.
    tags:
      - v*

  # Run tests for any PRs.
  pull_request:

env:
  IMAGE_NAME: app

jobs:
  # Push image to GitHub Packages.
  push:
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read

    steps:
      - uses: actions/checkout@v2

      - name: Build image
        run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}"

      - name: Log in to registry
        # This is where you will update the PAT to GITHUB_TOKEN
        run: echo "$" | docker login ghcr.io -u $ --password-stdin

      - name: Push image
        run: |
          IMAGE_ID=ghcr.io/$/$IMAGE_NAME

          # Change all uppercase to lowercase
          IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
          # Strip git ref prefix from version
          VERSION=$(echo "$" | sed -e 's,.*/\(.*\),\1,')
          # Strip "v" prefix from tag name
          [[ "$" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
          # Use Docker `latest` tag convention
          [ "$VERSION" == "main" ] && VERSION=latest
          echo IMAGE_ID=$IMAGE_ID
          echo VERSION=$VERSION
          docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
          docker push $IMAGE_ID:$VERSION

What did we do

Follow the next steps here