#4 - CI pipeline & Dockerfile hardening: env var rename, extended logging, POSIX shell, privilege drop (#5)
This PR closes #4 by renaming the GitHub Actions variable from GITHUB_REF_NAME to GIT_REF_NAME, fixing secrets and artifact destination paths, and adding detailed logging of environment variables and build actions for easier troubleshooting. It also updates the Dockerfile to run installation steps as root but switches to a non-root user for runtime, and replaces the shell with a strictly POSIX-compliant variant to improve portability and security. Reviewed-on: #5 Co-authored-by: Guillaume B.B. Van Hemmen <GuillaumeHemmen@noreply.git.van-hemmen.com> Co-committed-by: Guillaume B.B. Van Hemmen <GuillaumeHemmen@noreply.git.van-hemmen.com>
This commit is contained in:
parent
9395bf30a3
commit
a719e4dfbc
3 changed files with 58 additions and 50 deletions
|
@ -34,11 +34,14 @@ LABEL \
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Copy artefacts & make the wrapper executable
|
# Copy artefacts & make the wrapper executable
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
COPY build.sh /usr/local/bin/build.sh
|
COPY --chmod=0755 build.sh /bin/build.sh
|
||||||
COPY LICENSE /LICENSE
|
COPY LICENSE /LICENSE
|
||||||
RUN chmod +x /usr/local/bin/build.sh
|
RUN chmod +x /bin/build.sh
|
||||||
|
|
||||||
|
# Drop root privileges (UID 1000 exists in the base image)
|
||||||
|
USER 0
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Runtime entrypoint
|
# Runtime entrypoint
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
ENTRYPOINT ["/usr/local/bin/build.sh"]
|
ENTRYPOINT ["/bin/build.sh"]
|
||||||
|
|
14
README.md
14
README.md
|
@ -47,15 +47,15 @@ jobs:
|
||||||
env:
|
env:
|
||||||
# --- mandatory --------------------------------------------------------
|
# --- mandatory --------------------------------------------------------
|
||||||
KANIKO_CONTEXT: git://git.van-hemmen.com/actions/kaniko.git
|
KANIKO_CONTEXT: git://git.van-hemmen.com/actions/kaniko.git
|
||||||
GITHUB_REF_NAME: ${{ github.ref_name }}
|
GIT_REF_NAME: ${{ github.ref_name }}
|
||||||
GIT_USERNAME: ${{ secrets.GIT_USERNAME }}
|
GIT_USERNAME: ${{ secrets.docker_username }}
|
||||||
GIT_PASSWORD: ${{ secrets.GIT_PASSWORD }}
|
GIT_PASSWORD: ${{ secrets.access_token }}
|
||||||
|
|
||||||
# --- optional (only needed when you plan to push) ---------------------
|
# --- optional (only needed when you plan to push) ---------------------
|
||||||
REGISTRY_HOST: ghcr.io
|
REGISTRY_HOST: ghcr.io
|
||||||
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
REGISTRY_USER: ${{ secrets.docker_username }}
|
||||||
REGISTRY_PASS: ${{ secrets.REGISTRY_PASS }}
|
REGISTRY_PASS: ${{ secrets.access_token }}
|
||||||
KANIKO_DESTINATION: ghcr.io/myorg/myapp:${{ github.sha }}
|
KANIKO_DESTINATION: git.van-hemmen.com/myorg/myapp:${GITHUB_SHA}
|
||||||
|
|
||||||
# --- fine-tuning ------------------------------------------------------
|
# --- fine-tuning ------------------------------------------------------
|
||||||
KANIKO_DOCKERFILE: ./Dockerfile
|
KANIKO_DOCKERFILE: ./Dockerfile
|
||||||
|
@ -68,7 +68,7 @@ jobs:
|
||||||
| Variable | Required | Purpose | Example value |
|
| Variable | Required | Purpose | Example value |
|
||||||
|----------|----------|---------|----------------------------------------------------------------|
|
|----------|----------|---------|----------------------------------------------------------------|
|
||||||
| `KANIKO_CONTEXT` | **Yes** | Build context (`git://`). | `git://git.van-hemmen.com/actions/kaniko.git` |
|
| `KANIKO_CONTEXT` | **Yes** | Build context (`git://`). | `git://git.van-hemmen.com/actions/kaniko.git` |
|
||||||
| `GITHUB_REF_NAME` | **Yes** | Branch or tag that is being built. | `${{ github.ref_name }}` |
|
| `GIT_REF_NAME` | **Yes** | Branch or tag that is being built. | `${{ github.ref_name }}` |
|
||||||
| `GIT_USERNAME` | **Yes** | Username with access to `KANIKO_CONTEXT` when it is private. | `${{ secrets.GIT_USERNAME }}` |
|
| `GIT_USERNAME` | **Yes** | Username with access to `KANIKO_CONTEXT` when it is private. | `${{ secrets.GIT_USERNAME }}` |
|
||||||
| `GIT_PASSWORD` | **Yes** | Token/password paired with `GIT_USERNAME`. | `${{ secrets.GIT_PASSWORD }}` |
|
| `GIT_PASSWORD` | **Yes** | Token/password paired with `GIT_USERNAME`. | `${{ secrets.GIT_PASSWORD }}` |
|
||||||
| `REGISTRY_HOST` | No (default `git.van-hemmen.com`) | Target registry hostname. | `ghcr.io` |
|
| `REGISTRY_HOST` | No (default `git.van-hemmen.com`) | Target registry hostname. | `ghcr.io` |
|
||||||
|
|
85
build.sh
85
build.sh
|
@ -1,28 +1,17 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/sh
|
||||||
set -euo pipefail
|
# BusyBox/dash-friendly: no “pipefail”, no “[[ … ]]”, no “+=”
|
||||||
|
|
||||||
|
set -eu # BusyBox ash does not support “pipefail”
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Mandatory variables – abort if not provided
|
# Mandatory variables – abort if not provided
|
||||||
###############################################################################
|
###############################################################################
|
||||||
if [[ -z "${KANIKO_CONTEXT:-}" ]]; then
|
for var in KANIKO_CONTEXT GIT_REF_NAME GIT_USERNAME GIT_PASSWORD; do
|
||||||
echo "Error: KANIKO_CONTEXT environment variable is required but not set." >&2
|
eval [ -z \"\${$var:-}\" ] && {
|
||||||
exit 1
|
echo "Error: $var environment variable is required but not set." >&2
|
||||||
fi
|
exit 1
|
||||||
|
}
|
||||||
if [[ -z "${GITHUB_REF_NAME:-}" ]]; then
|
done
|
||||||
echo "Error: GITHUB_REF_NAME environment variable is required but not set." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "${GIT_USERNAME:-}" ]]; then
|
|
||||||
echo "Error: GIT_USERNAME environment variable is required but not set." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "${GIT_PASSWORD:-}" ]]; then
|
|
||||||
echo "Error: GIT_PASSWORD environment variable is required but not set." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Optional / defaulted variables
|
# Optional / defaulted variables
|
||||||
|
@ -39,7 +28,7 @@ KANIKO_DOCKERFILE="${KANIKO_DOCKERFILE:-./Dockerfile}"
|
||||||
# Handle registry authentication (only if credentials are present)
|
# Handle registry authentication (only if credentials are present)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
AUTH_ENABLED=false
|
AUTH_ENABLED=false
|
||||||
if [[ -n "${REGISTRY_USER}" && -n "${REGISTRY_PASS}" ]]; then
|
if [ -n "${REGISTRY_USER}" ] && [ -n "${REGISTRY_PASS}" ]; then
|
||||||
echo "Registry credentials supplied – configuring authentication for ${REGISTRY_HOST}"
|
echo "Registry credentials supplied – configuring authentication for ${REGISTRY_HOST}"
|
||||||
mkdir -p /kaniko/.docker
|
mkdir -p /kaniko/.docker
|
||||||
cat > /kaniko/.docker/config.json <<EOF
|
cat > /kaniko/.docker/config.json <<EOF
|
||||||
|
@ -62,35 +51,51 @@ fi
|
||||||
###############################################################################
|
###############################################################################
|
||||||
DEST_FLAGS=""
|
DEST_FLAGS=""
|
||||||
|
|
||||||
# Push is only possible if we have BOTH credentials and at least one destination
|
if $AUTH_ENABLED && [ -n "${KANIKO_DESTINATION## }" ]; then
|
||||||
if $AUTH_ENABLED && [[ -n "${KANIKO_DESTINATION// }" ]]; then
|
|
||||||
echo "Building list of --destination flags"
|
echo "Building list of --destination flags"
|
||||||
OLD_IFS="$IFS"; IFS=','
|
old_ifs="$IFS"; IFS=','
|
||||||
|
|
||||||
for raw in $KANIKO_DESTINATION; do
|
for raw in $KANIKO_DESTINATION; do
|
||||||
raw="$(echo "$raw" | xargs)" # trim whitespace
|
raw=$(echo "$raw" | xargs) # trim
|
||||||
expanded="$(eval echo "$raw")" # expand variables
|
expanded=$(eval echo "$raw") # env-var expansion if any
|
||||||
[[ -n "$expanded" ]] && DEST_FLAGS+=" --destination=${expanded}"
|
[ -n "$expanded" ] && DEST_FLAGS="$DEST_FLAGS --destination=$expanded"
|
||||||
done
|
done
|
||||||
|
IFS="$old_ifs"
|
||||||
IFS="$OLD_IFS"
|
|
||||||
echo "Image(s) will be pushed to the registry."
|
echo "Image(s) will be pushed to the registry."
|
||||||
else
|
else
|
||||||
DEST_FLAGS="--no-push"
|
DEST_FLAGS="--no-push"
|
||||||
if ! $AUTH_ENABLED; then
|
$AUTH_ENABLED || echo "Registry credentials are missing – image(s) will not be pushed."
|
||||||
echo "Image(s) will NOT be pushed because registry credentials are missing."
|
[ -n "${KANIKO_DESTINATION## }" ] || echo "KANIKO_DESTINATION not provided – using --no-push."
|
||||||
elif [[ -z "${KANIKO_DESTINATION// }" ]]; then
|
|
||||||
echo "KANIKO_DESTINATION not provided – image(s) will be built with --no-push."
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Kaniko will be called with: ${DEST_FLAGS}"
|
echo "Kaniko will be called with:${DEST_FLAGS}"
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# resume what will be done
|
||||||
|
###############################################################################
|
||||||
|
echo "Environment Variables:"
|
||||||
|
echo "KANIKO_CONTEXT=${KANIKO_CONTEXT}"
|
||||||
|
echo "GIT_REF_NAME=${GIT_REF_NAME}"
|
||||||
|
echo "GIT_USERNAME=${GIT_USERNAME}"
|
||||||
|
echo "GIT_PASSWORD=$(echo "${GIT_PASSWORD}" | sed 's/\(^..\).*\(..$\)/\1...\2/')"
|
||||||
|
echo "REGISTRY_HOST=${REGISTRY_HOST}"
|
||||||
|
echo "REGISTRY_USER=${REGISTRY_USER}"
|
||||||
|
[ -n "${REGISTRY_PASS}" ] && echo "REGISTRY_PASS=$(echo "${REGISTRY_PASS}" | sed 's/\(^..\).*\(..$\)/\1...\2/')"
|
||||||
|
echo "KANIKO_DESTINATION=${KANIKO_DESTINATION}"
|
||||||
|
echo "KANIKO_VERBOSITY=${KANIKO_VERBOSITY}"
|
||||||
|
echo "KANIKO_DOCKERFILE=${KANIKO_DOCKERFILE}"
|
||||||
|
echo ""
|
||||||
|
if [ "${DEST_FLAGS}" = "--no-push" ]; then
|
||||||
|
echo "Action: Build only (no push)"
|
||||||
|
else
|
||||||
|
echo "Action: Build and push"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Invoke Kaniko
|
# Invoke Kaniko
|
||||||
###############################################################################
|
###############################################################################
|
||||||
/kaniko/executor \
|
exec /kaniko/executor \
|
||||||
--verbosity="${KANIKO_VERBOSITY}" \
|
--verbosity="${KANIKO_VERBOSITY}" \
|
||||||
--context="${KANIKO_CONTEXT}#${GITHUB_REF_NAME}" \
|
--context="${KANIKO_CONTEXT}#${GIT_REF_NAME}" \
|
||||||
--dockerfile="${KANIKO_DOCKERFILE}" \
|
--dockerfile="${KANIKO_DOCKERFILE}" \
|
||||||
${DEST_FLAGS}
|
$DEST_FLAGS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue