diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d1013f3..2488ec7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,12 @@ jobs: uses: astral-sh/setup-uv@v10.0.1 with: cache-suffix: ${{ matrix.python-version }} + - name: Install shell tools + run: sudo apt-get update && sudo apt-get install --yes shellcheck shfmt + - name: Check template shell scripts + run: | + shellcheck template/docker/*.sh + test -z "$(shfmt --list template/docker/*.sh)" - uses: actions/setup-node@v7 with: node-version: latest diff --git a/template/.github/workflows/ci.yml b/template/.github/workflows/ci.yml index 6561a12..e737730 100644 --- a/template/.github/workflows/ci.yml +++ b/template/.github/workflows/ci.yml @@ -15,10 +15,17 @@ jobs: - uses: actions/checkout@v7 - name: Install uv uses: astral-sh/setup-uv@v10.0.1 + - name: Install shell tools + run: sudo apt-get update && sudo apt-get install --yes shellcheck shfmt - name: Sync dependencies run: uv sync --locked + - name: Check shell scripts + run: | + shellcheck docker/*.sh + test -z "$(shfmt --list docker/*.sh)" + - name: Format run: uv run --frozen ruff format . --check --diff diff --git a/template/docker/build.sh b/template/docker/build.sh index ef05da9..07cfcac 100755 --- a/template/docker/build.sh +++ b/template/docker/build.sh @@ -1,14 +1,15 @@ -#!/bin/bash +#!/usr/bin/env bash -cd $(dirname $0) -cd ../ +set -euo pipefail + +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." BUILDER_IMAGE="ubuntu:24.04" RUNNER_IMAGE="ubuntu:24.04" -IMAGE_NAME=$(basename $(pwd) | tr '[:upper:]' '[:lower:]') +IMAGE_NAME="$(basename -- "$PWD" | tr '[:upper:]' '[:lower:]')" -docker build \ - --build-arg BUILDER_IMAGE=${BUILDER_IMAGE} \ - --build-arg RUNNER_IMAGE=${RUNNER_IMAGE} \ - -t "${IMAGE_NAME}:latest" \ - -f docker/Dockerfile . +exec docker build \ + --build-arg "BUILDER_IMAGE=${BUILDER_IMAGE}" \ + --build-arg "RUNNER_IMAGE=${RUNNER_IMAGE}" \ + -t "${IMAGE_NAME}:latest" \ + -f docker/Dockerfile . diff --git a/template/docker/entrypoint.sh b/template/docker/entrypoint.sh index 51db1fe..9c078c5 100644 --- a/template/docker/entrypoint.sh +++ b/template/docker/entrypoint.sh @@ -1,16 +1,18 @@ -#!/bin/bash +#!/usr/bin/env bash -USER_ID=${USER_ID:-1000} -GROUP_ID=${GROUP_ID:-1000} -USER_NAME=${USER_NAME:-user} -GROUP_NAME=${GROUP_NAME:-group} +set -euo pipefail -userdel -r ubuntu > /dev/null 2>&1 # For Ubuntu 24.04 image -groupadd -g ${GROUP_ID} ${GROUP_NAME} > /dev/null 2>&1 -useradd -u ${USER_ID} -g ${GROUP_NAME} -G sudo -o -m ${USER_NAME} > /dev/null 2>&1 +USER_ID="${USER_ID:-1000}" +GROUP_ID="${GROUP_ID:-1000}" +USER_NAME="${USER_NAME:-user}" +GROUP_NAME="${GROUP_NAME:-group}" + +userdel -r ubuntu >/dev/null 2>&1 || true # For Ubuntu 24.04 image +groupadd -g "${GROUP_ID}" "${GROUP_NAME}" >/dev/null 2>&1 || true +useradd -u "${USER_ID}" -g "${GROUP_NAME}" -G sudo -o -m "${USER_NAME}" >/dev/null 2>&1 || true if [[ $# -eq 0 ]]; then - exec /usr/sbin/gosu ${USER_NAME} bash + exec /usr/sbin/gosu "${USER_NAME}" bash else - /usr/sbin/gosu ${USER_NAME} "$@" + exec /usr/sbin/gosu "${USER_NAME}" "$@" fi diff --git a/template/docker/run.sh b/template/docker/run.sh index 32507b1..bea0a37 100755 --- a/template/docker/run.sh +++ b/template/docker/run.sh @@ -1,41 +1,59 @@ -#!/bin/bash +#!/usr/bin/env bash -cd $(dirname $0) -cd ../ +set -euo pipefail -IMAGE_NAME=$(basename $(pwd) | tr '[:upper:]' '[:lower:]') -USER_ID=`id -u` -GROUP_ID=`id -g` -GROUP_NAME=`id -gn` -USER_NAME=$USER +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." -GPU_OPTION="" -if docker system info | grep -qE '^\s*Runtimes: .*nvidia.*'; then - # Use GPU - GPU_OPTION="--gpus all" +IMAGE_NAME="$(basename -- "$PWD" | tr '[:upper:]' '[:lower:]')" +USER_ID="$(id -u)" +GROUP_ID="$(id -g)" +GROUP_NAME="$(id -gn)" +USER_NAME="${USER:-}" + +DOCKER_OPTIONS=() +if docker system info | grep -E '^[[:space:]]*Runtimes: .*nvidia.*' >/dev/null; then + # Use GPU + DOCKER_OPTIONS+=(--gpus all) fi # Check if TTY is available (not in CI environment) -TTY_OPTION="" if [ -t 0 ] && [ -t 1 ]; then - TTY_OPTION="-it" + DOCKER_OPTIONS+=(-it) +fi + +DOCKER_OPTIONS+=( + --rm + --shm-size=32g + --net + host + --env + "DISPLAY=${DISPLAY:-}" + --env + "USER_NAME=${USER_NAME}" + --env + "USER_ID=${USER_ID}" + --env + "GROUP_NAME=${GROUP_NAME}" + --env + "GROUP_ID=${GROUP_ID}" + --workdir + /app + -v + "${HOME:-}/.Xauthority:/home/${USER_NAME}/.Xauthority:rw" + -v + /tmp/.X11-unix:/tmp/.X11-unix:rw + -v + "${PWD}:/app" + --name + "${IMAGE_NAME}-$(date '+%s')" +) + +COMMAND=("$@") +if (($# == 0)); then + COMMAND=(bash) fi -docker run \ - $TTY_OPTION \ - $GPU_OPTION \ - --rm \ - --shm-size=32g \ - --net host \ - --env DISPLAY=$DISPLAY \ - --env USER_NAME=$USER_NAME \ - --env USER_ID=$USER_ID \ - --env GROUP_NAME=$GROUP_NAME \ - --env GROUP_ID=$GROUP_ID \ - --workdir /app \ - -v $HOME/.Xauthority:/home/$USER_NAME/.Xauthority:rw \ - -v /tmp/.X11-unix:/tmp/.X11-unix:rw \ - -v ${PWD}:/app \ - --name "${IMAGE_NAME}-$(date '+%s')" \ - "${IMAGE_NAME}:latest" \ - ${@:-bash} +exec docker run \ + "${DOCKER_OPTIONS[@]}" \ + "${IMAGE_NAME}:latest" \ + "${COMMAND[@]}"