Skip to content

Instantly share code, notes, and snippets.

@faytranevozter
Last active December 30, 2025 06:31
Show Gist options
  • Select an option

  • Save faytranevozter/7c17cf936c0a0cf659507e5722191d54 to your computer and use it in GitHub Desktop.

Select an option

Save faytranevozter/7c17cf936c0a0cf659507e5722191d54 to your computer and use it in GitHub Desktop.
Build docker from repository
#!/bin/bash
set -euo pipefail
# Include color configuration (optional)
source ~/.fay/colors 2>/dev/null || true
function _docker_snippet_help() {
printf "${BBlue}╔══════════════════════════════════════════════════════════╗${Color_Off}\n"
printf "${BBlue}β•‘ ${BYellow}Docker Build & Push Helper v1.1${BBlue} β•‘${Color_Off}\n"
printf "${BBlue}β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•${Color_Off}\n"
echo
printf "${BGreen}Usage:${Color_Off}\n"
printf " build_docker ${BYellow}[-b|g|t|r|h]${Color_Off} ${UWhite}[reponame[:tag]]${Color_Off}\n"
echo
printf "${BGreen}Options:${Color_Off}\n"
printf " ${BYellow}-b${Color_Off} Use current git branch as image tag\n"
printf " ${BYellow}-g${Color_Off} Use current git tag as image tag (e.g. v1.0.0)\n"
printf " ${BYellow}-t${Color_Off} Specify custom image tag (e.g. -t v1.0.0)\n"
printf " ${BYellow}-r${Color_Off} Replace existing image if already exists\n"
printf " ${BYellow}-f${Color_Off} Specify custom Dockerfile (default: Dockerfile)\n"
printf " ${BYellow}-p${Color_Off} Specify build platform (default: linux/amd64)\n"
printf " ${BYellow}-a${Color_Off} Load build args from file (e.g. -a .build-args)\n"
printf " ${BYellow}-n${Color_Off} Skip push step (no confirmation or push)\n"
printf " ${BYellow}-h${Color_Off} Show this help message\n"
echo
printf "${BGreen}Examples:${Color_Off}\n"
printf " ${BWhite}# Build with default folder name as image name and commit SHA as tag${Color_Off}\n"
printf " build_docker\n"
echo
printf " ${BWhite}# Use current git tag as image tag${Color_Off}\n"
printf " build_docker -g\n"
echo
printf " ${BWhite}# Specify image name${Color_Off}\n"
printf " build_docker ${UWhite}web-app${Color_Off}\n"
echo
printf " ${BWhite}# Specify image name and tag directly${Color_Off}\n"
printf " build_docker ${UWhite}web-app:latest${Color_Off}\n"
echo
printf " ${BWhite}# Use branch as tag${Color_Off}\n"
printf " build_docker -b\n"
echo
printf " ${BWhite}# Use custom tag explicitly${Color_Off}\n"
printf " build_docker -t v1.2.3\n"
echo
printf " ${BWhite}# Push to custom registry prefix${Color_Off}\n"
printf " build_docker ${UWhite}ghcr.io/my-org/${Color_Off}\n"
echo
printf " ${BWhite}# Add build args${Color_Off}\n"
printf " build_docker -a .build-args ${UWhite}web-app:latest${Color_Off}\n"
echo
printf "${BGreen}Notes:${Color_Off}\n"
printf " πŸ”Ή Use only ${BYellow}-b${Color_Off}, ${BYellow}-g${Color_Off}, OR ${BYellow}-t${Color_Off}, not multiple together.\n"
printf " πŸ”Ή Build args file format: one KEY=VALUE per line, '#' for comments.\n"
echo
}
# Join array elements with a delimiter
function join_by {
local IFS="$1" # Use the first argument as the delimiter
shift # Remove the first argument
echo "$*" # Use "$*" to expand with the new IFS
}
# Default variables
USE_BRANCH=0
USE_GIT_TAG=0
REPLACE_IMAGE=0
USE_SPECIFIC_TAG=0
TAGNAME=""
DOCKERFILE_PATH="Dockerfile"
BUILD_PLATFORM="linux/amd64"
REPO_ARG=""
BUILD_ARGS_FILE=""
NO_PUSH=0
# Parse options
while getopts ":hbgrt:f:p:a:n" opt; do
case ${opt} in
a)
BUILD_ARGS_FILE="$OPTARG"
;;
h)
_docker_snippet_help
exit 0
;;
b)
USE_BRANCH=1
;;
g)
USE_GIT_TAG=1
;;
r)
REPLACE_IMAGE=1
;;
t)
USE_SPECIFIC_TAG=1
TAGNAME="$OPTARG"
;;
f)
DOCKERFILE_PATH="$OPTARG"
;;
p)
BUILD_PLATFORM="$OPTARG"
;;
n)
NO_PUSH=1
;;
\?)
echo "❌ Error: Invalid option -$OPTARG"
exit 1
;;
:)
echo "❌ Error: Option -$OPTARG requires an argument."
exit 1
;;
esac
done
shift $((OPTIND - 1))
REPO_ARG="${1:-}"
# Validate options
tag_flags_count=0
[[ $USE_BRANCH -eq 1 ]] && ((tag_flags_count++)) || true
[[ $USE_GIT_TAG -eq 1 ]] && ((tag_flags_count++)) || true
[[ $USE_SPECIFIC_TAG -eq 1 ]] && ((tag_flags_count++)) || true
if [[ $tag_flags_count -gt 1 ]]; then
echo "❌ Error: Only one of -b, -g, or -t can be used at a time."
exit 1
fi
if [[ $USE_SPECIFIC_TAG -eq 1 && -z "$TAGNAME" ]]; then
echo "❌ Error: Tag name cannot be empty."
exit 1
fi
# Read git info
branch=$(git symbolic-ref --short -q HEAD)
commit_sha="$(git rev-parse --verify HEAD)"
dirname=$(basename "$(pwd)")
# Get git tag if using -g flag
git_tag=""
if [[ $USE_GIT_TAG -eq 1 ]]; then
set +e # Temporarily disable exit on error
git_tag=$(git describe --tags --exact-match 2>/dev/null)
git_tag_status=$?
set -e # Re-enable exit on error
if [[ $git_tag_status -ne 0 || -z "$git_tag" ]]; then
echo ""
echo "❌ Error: No git tag found at current commit."
echo " Current commit: $commit_sha"
echo ""
echo "πŸ’‘ To create a tag, run:"
echo " git tag v1.0.0"
echo " git push origin v1.0.0"
echo ""
exit 1
fi
fi
# validate dirname
if [[ -z "$dirname" ]]; then
echo "❌ Error: Could not determine directory name. Are you in a valid directory?"
exit 1
fi
# Validate platform format (simple check)
if [[ ! "$BUILD_PLATFORM" =~ ^[a-z]+/[a-z0-9]+$ ]]; then
echo "❌ Error: Invalid platform format. Expected: os/arch (e.g. linux/amd64)"
exit 1
fi
# Parse build args from file if provided
BUILD_ARGS=()
if [[ -n "$BUILD_ARGS_FILE" ]]; then
if [[ ! -f "$BUILD_ARGS_FILE" ]]; then
echo "❌ Error: Build args file not found: $BUILD_ARGS_FILE"
exit 1
fi
while IFS= read -r line; do
[[ -z "$line" || "$line" =~ ^# ]] && continue # skip empty lines & comments
BUILD_ARGS+=("$line")
done < "$BUILD_ARGS_FILE"
fi
# Parse image name
image_prefix=""
image_name=""
image_tag=""
if [[ -z "$REPO_ARG" ]]; then
image_name="$dirname"
elif [[ "$REPO_ARG" == */ ]]; then
image_prefix="$REPO_ARG"
image_name="$dirname"
else
if [[ "$REPO_ARG" == *:* ]]; then
image_name=$(echo "$REPO_ARG" | cut -d ":" -f 1)
image_tag=$(echo "$REPO_ARG" | cut -d ":" -f 2)
else
image_name="$REPO_ARG"
fi
fi
# Determine tag
if [[ -z "$image_tag" ]]; then
if [[ $USE_BRANCH -eq 1 ]]; then
image_tag="$branch"
elif [[ $USE_GIT_TAG -eq 1 ]]; then
image_tag="$git_tag"
elif [[ $USE_SPECIFIC_TAG -eq 1 ]]; then
image_tag="$TAGNAME"
else
image_tag="$commit_sha"
fi
fi
# Validate image tag
if [[ ! "$image_tag" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "❌ Error: Image tag '$image_tag' contains invalid characters. Only letters, digits, '.', '_', '-' allowed."
exit 1
fi
full_image_name="${image_prefix}${image_name}:${image_tag}"
# Display summary
printf "${BGreen}Git Branch ${Color_Off}: $branch\n"
printf "${BGreen}Git Commit SHA ${Color_Off}: $commit_sha\n"
if [[ -n "$git_tag" ]]; then
printf "${BGreen}Git Tag ${Color_Off}: $git_tag\n"
fi
printf "${BGreen}Image Prefix ${Color_Off}: $image_prefix\n"
printf "${BGreen}Image Name ${Color_Off}: $image_name\n"
printf "${BGreen}Image Tag ${Color_Off}: $image_tag\n"
printf "${BGreen}Full Image Name ${Color_Off}: ${UYellow}$full_image_name${Color_Off}\n"
printf "${BGreen}Dockerfile Path ${Color_Off}: $DOCKERFILE_PATH\n"
printf "${BGreen}Build Platform ${Color_Off}: ${UYellow}${BUILD_PLATFORM}${Color_Off}\n"
# Safe build args display
if [[ ${#BUILD_ARGS[@]} -eq 0 ]]; then
printf "${BGreen}Build Args ${Color_Off}: ${UYellow}None${Color_Off}\n"
else
printf "${BGreen}Build Args ${Color_Off}: \n"
for arg in "${BUILD_ARGS[@]}"; do
printf " ${UYellow}--build-arg${Color_Off} ${UBlue}$arg${Color_Off}\n"
done
fi
# Confirm build
echo
read -p "Continue building Docker image? (Y/n): " -n 1 -r
echo
REPLY=${REPLY:-y}
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 0
# Validate Dockerfile existence
if [[ ! -f "$DOCKERFILE_PATH" ]]; then
echo "❌ Error: Dockerfile not found at: $DOCKERFILE_PATH"
exit 1
fi
# Build Docker image
image_exists=$(docker images -q "$full_image_name" 2>/dev/null)
# Check if image already exists
if [[ -z "$image_exists" ]]; then
echo "πŸ” Docker image not found: $full_image_name"
echo "πŸ”¨ Building Docker image..."
should_build=1
elif [[ $REPLACE_IMAGE -eq 1 ]]; then
echo "♻️ Rebuilding Docker image due to -r flag..."
should_build=1
else
echo "βœ… Docker image already exists: $full_image_name"
read -p "Rebuild image anyway? (Y/n): " -n 1 -r
echo
REPLY=${REPLY:-y}
if [[ $REPLY =~ ^[Yy]$ ]]; then
should_build=1
else
echo "🚫 Skipping build step."
should_build=0
fi
fi
# Build only if needed
if [[ $should_build -eq 1 ]]; then
# Validate Dockerfile existence
if [[ ! -f "$DOCKERFILE_PATH" ]]; then
echo "❌ Error: Dockerfile not found at: $DOCKERFILE_PATH"
exit 1
fi
# Create an array of actual docker build flags
build_arg_flags=()
# Construct build args string
build_args_str=""
if [[ ${#BUILD_ARGS[@]} -gt 0 ]]; then
for arg in "${BUILD_ARGS[@]}"; do
build_arg_flags+=(--build-arg "$arg")
done
for arg in "${BUILD_ARGS[@]}"; do
build_args_str+="--build-arg $arg \\
"
done
fi
# Construct full build command for display
build_command="docker build \\
--platform $BUILD_PLATFORM \\
-t $full_image_name \\
-f $DOCKERFILE_PATH \\
$build_args_str ."
printf "${BGreen}Build Command ${Color_Off}: $build_command\n"
if [[ ${#BUILD_ARGS[@]} -eq 0 ]]; then
docker build \
--platform "$BUILD_PLATFORM" \
-t "$full_image_name" \
-f "$DOCKERFILE_PATH" \
.
else
docker build \
--platform "$BUILD_PLATFORM" \
-t "$full_image_name" \
-f "$DOCKERFILE_PATH" \
"${build_arg_flags[@]}" \
.
fi
fi
if [[ $NO_PUSH -eq 1 ]]; then
echo "⏭️ Skipping push (--no-push flag used)"
else
# Push confirmation
echo
read -p "Push Docker image to registry? (Y/n): " -n 1 -r
echo
REPLY=${REPLY:-y}
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 0
# Push image
echo "πŸ“¦ Pushing image..."
docker push "$full_image_name"
fi
#!/bin/bash
# Reset
Color_Off='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Underline
UBlack='\033[4;30m' # Black
URed='\033[4;31m' # Red
UGreen='\033[4;32m' # Green
UYellow='\033[4;33m' # Yellow
UBlue='\033[4;34m' # Blue
UPurple='\033[4;35m' # Purple
UCyan='\033[4;36m' # Cyan
UWhite='\033[4;37m' # White
# Background
On_Black='\033[40m' # Black
On_Red='\033[41m' # Red
On_Green='\033[42m' # Green
On_Yellow='\033[43m' # Yellow
On_Blue='\033[44m' # Blue
On_Purple='\033[45m' # Purple
On_Cyan='\033[46m' # Cyan
On_White='\033[47m' # White
# High Intensity
IBlack='\033[0;90m' # Black
IRed='\033[0;91m' # Red
IGreen='\033[0;92m' # Green
IYellow='\033[0;93m' # Yellow
IBlue='\033[0;94m' # Blue
IPurple='\033[0;95m' # Purple
ICyan='\033[0;96m' # Cyan
IWhite='\033[0;97m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
# High Intensity backgrounds
On_IBlack='\033[0;100m' # Black
On_IRed='\033[0;101m' # Red
On_IGreen='\033[0;102m' # Green
On_IYellow='\033[0;103m' # Yellow
On_IBlue='\033[0;104m' # Blue
On_IPurple='\033[0;105m' # Purple
On_ICyan='\033[0;106m' # Cyan
On_IWhite='\033[0;107m' # White
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment