Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Related to issue #83: Added support for container image #105

Closed
wants to merge 12 commits into from
44 changes: 44 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Create and publish Docker image

on:
push:
branches: ['main']
Comment on lines +3 to +5

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to have a way to test building (but not releasing) the container for commits, so people know nothing breaks on the container side whenever they propose a change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll need to investigate on that part


env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
uses: docker/build-push-action
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this, I'm a bit opinionated, but four versions should be released if, say, we're releasing version 3.7.4 (as an example, we don't have that version but let's assume we do):

  • latest, as in overriding the latest tag
  • v3
  • v3.7
  • and finally v3.7.4

This is because this repo tries to follow Semver, so people that need the guarantee that no major breaking change appear in a minor change can confidently pull the newer version of the image. If I ever do, that's on me, not on the people maintaining these apps deployed to environments.

I do something similar here: https://github.com/patrickdappollonio/http-server/pkgs/container/docker-http-server although with no minor version, just major and patch, and this has proven to work in corporate environments where that stability can be called out during usage.

labels: ${{ steps.meta.outputs.labels }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.history
28 changes: 28 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Go builder image
FROM golang:1.22 as builder

ENV GOPATH=/usr/local/go/bin

WORKDIR /go

COPY . .

RUN CGO_ENABLED=0 go build -ldflags "-s" -a -installsuffix cgo .

## Base image for production usage
FROM alpine:3.14 as production

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be the somewhat biggest showstopper. musl gets less use overall than libc, and ash (the shell in alpine) is somewhat different than bash: https://www.geeksforgeeks.org/difference-between-ash-and-bash/

I would be tempted to use bash: https://hub.docker.com/_/bash or even busybox (although that'll get you sh rather than bash, so I'm hesitant).

Without this project gathering metrics on its own and based purely on experience reports I've received over the years, as well as looking at the usage of kubectl-slice here in Github I would be tempted to say bash, the image, might be a better fit.

Another thing IMHO I would do here would be to have the image include kubectl even if its usage cannot be easily achieved with kubeconfigs that use a tool to authenticate. Same with krew (the plugin manager) but this IMHO has lesser priority, we could see how well the Docker image plays in the wild and do this paragraph after.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What use case do you find that necessary to do?
IMHO I only needed this to run in CI - instead of running the go code out-of-the-box.
So I would keep it clean, and not put kubeconfig + krew inside.


COPY --from=builder /go/kubectl-slice /usr/bin/kubectl-slice

WORKDIR /workdir

## add user k8s to run the slice tool
RUN set -eux; \
addgroup -g 1000 k8s; \
adduser -u 1000 -G k8s -s /bin/sh -h /home/k8s -D k8s

RUN chown -R k8s:k8s /workdir

USER k8s

CMD ["/bin/sh", "-c"]
43 changes: 43 additions & 0 deletions docs/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Running in docker

Run the Docker image from `gchr.io/patrickdappollonio/kubectl-slice`

## Usage
The container is build to execute both interactive and inline.

### Interactive shell

Example, this will start the container in the `/workdir` directory.
```sh
docker run --rm -it \
gchr.io/patrickdappollonio/kubectl-slice /bin/sh
```

### Inline

**Example 1:**
This will split the `ingress-namespace.yaml` file in the directory `${PWD}/slice/testdata`.

```sh
docker run --rm -v \
"${PWD}/slice/testdata":/workdir gchr.io/patrickdappollonio/kubectl-slice \
kubectl-slice -f ingress-namespace.yaml -o ./
```

**Example 2:**
To display the `kubectl-slice` help.

```sh
docker run --rm -v \
"${PWD}/slice/testdata":/workdir gchr.io/patrickdappollonio/kubectl-slice \
kubectl-slice -h
```

**Example 3:**
Statements to `kubectl-slice` can be wrapped in `""` if the commandline escapes unintentionally.

```sh
docker run --rm -v \
"${PWD}/slice/testdata":/workdir gchr.io/patrickdappollonio/kubectl-slice \
kubectl-slice "-h"
```