feat: build a debug-shell and distroless container

This commit is contained in:
Aarnav Tale
2025-06-24 10:56:43 -04:00
parent 5a254b746b
commit eed12d348e
5 changed files with 73 additions and 9 deletions
+16 -4
View File
@@ -21,6 +21,14 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.ref == 'next') }}
name: Docker Pre-release
runs-on: ubuntu-latest
strategy:
matrix:
include:
- target: final
tag: 'next'
- target: debug-shell
tag: 'next-shell'
steps:
- name: Check out the repo
uses: actions/checkout@v4
@@ -31,7 +39,7 @@ jobs:
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=next
type=raw,value=${{ matrix.tag }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@@ -46,22 +54,26 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
- name: Build and publish ghcr.io/${{ github.repository }}:${{ matrix.tag }}
uses: docker/build-push-action@v6
id: push
with:
context: .
file: ./Dockerfile
target: ${{ matrix.target }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64, linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Attestation Provenance
build-args: |
IMAGE_TAG=ghcr.io/${{ github.repository }}:${{ matrix.tag }}
- name: Attestation Provenance for ghcr.io/${{ github.repository }}:${{ matrix.tag }}
uses: actions/attest-build-provenance@v2
id: attest
with:
subject-name: ghcr.io/${{ github.repository }}
subject-name: ghcr.io/${{ github.repository }}:${{ matrix.tag }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
+1
View File
@@ -1,3 +1,4 @@
# REMEMBER TO UPDATE mise.toml TOO
pnpm 10.4.0
node 22.16
go 1.24.4
+23 -5
View File
@@ -1,5 +1,5 @@
FROM --platform=$BUILDPLATFORM jdxcode/mise:latest AS mise-context
COPY mise.toml .
COPY mise.toml .tool-versions ./
RUN mise install
FROM --platform=$BUILDPLATFORM mise-context AS go-build
@@ -13,11 +13,13 @@ COPY internal/ ./internal/
ARG TARGETOS
ARG TARGETARCH
ARG IMAGE_TAG
RUN mkdir -p /build/app/ && \
GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 \
mise run wasm ::: agent
GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 IMAGE_TAG=$IMAGE_TAG \
mise run wasm ::: agent ::: fake-shell
RUN chmod +x /build/build/hp_agent
RUN chmod +x /build/build/sh
FROM --platform=$BUILDPLATFORM mise-context AS js-build
WORKDIR /build
@@ -32,7 +34,23 @@ COPY --from=go-build /build/app/wasm_exec.js /build/app/wasm_exec.js
RUN pnpm run build
RUN mkdir -p /var/lib/headplane/agent
FROM gcr.io/distroless/nodejs22-debian12:nonroot
FROM gcr.io/distroless/nodejs22-debian12:nonroot AS final
COPY --from=js-build --chown=nonroot:nonroot /build/build/ /app/build/
COPY --from=js-build --chown=nonroot:nonroot /build/drizzle /app/drizzle/
COPY --from=js-build --chown=nonroot:nonroot /var/lib/headplane /var/lib/headplane
COPY --from=js-build --chown=nonroot:nonroot /build/node_modules/ /app/node_modules/
COPY --from=go-build --chown=nonroot:nonroot /build/build/hp_agent /usr/libexec/headplane/agent
# Fake shell to inform the user that they should use the debug image
COPY --from=go-build --chown=nonroot:nonroot /build/build/sh /bin/sh
COPY --from=go-build --chown=nonroot:nonroot /build/build/sh /bin/bash
WORKDIR /app
CMD [ "/app/build/server/index.js" ]
FROM node:22-alpine AS debug-shell
RUN apk add --no-cache bash curl git
COPY --from=js-build --chown=nonroot:nonroot /build/build/ /app/build/
COPY --from=js-build --chown=nonroot:nonroot /build/drizzle /app/drizzle/
COPY --from=js-build --chown=nonroot:nonroot /var/lib/headplane /var/lib/headplane
@@ -40,4 +58,4 @@ COPY --from=js-build --chown=nonroot:nonroot /build/node_modules/ /app/node_modu
COPY --from=go-build --chown=nonroot:nonroot /build/build/hp_agent /usr/libexec/headplane/agent
WORKDIR /app
CMD [ "/app/build/server/index.js" ]
CMD [ "node", "/app/build/server/index.js" ]
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
)
var imageTag string
func main() {
if imageTag == "" {
os.Exit(1)
}
fmt.Fprintln(os.Stderr, "Headplane containers do not contain a shell by default.")
fmt.Fprintln(os.Stderr, "If you need a non-production container with a shell and root access use:")
fmt.Fprintf(os.Stderr, "\n%s-shell\n\n", imageTag)
os.Exit(127)
}
+14
View File
@@ -1,3 +1,9 @@
[tools]
# REMEMBER TO UPDATE .tool-versions TOO
go = "1.24.4"
pnpm = "10.4.0"
node = "22.16"
[tasks.copy-wasm-shim]
alias = ["gojs"]
description = "Copies Go's wasm_exec.js to the public directory"
@@ -18,6 +24,14 @@ alias = ["agent"]
description = "Builds the Go agent for HostInfo"
run = "go build -o build/hp_agent ./cmd/hp_agent"
[tasks.build-fake-shell]
alias = ["fake-shell"]
description = "Builds the fake shell for Distroless docker images"
run = [
'test -n "$IMAGE_TAG" || (echo "IMAGE_TAG is not set" && exit 1)',
'go build -ldflags="-s -w -X main.imageTag=$IMAGE_TAG" -o build/sh ./cmd/fake_sh'
]
[tasks.generate-caddy-certs]
alias = ["mkcert"]
dir = "{{cwd}}/test/caddy/certs"