Last active
December 30, 2025 06:31
-
-
Save faytranevozter/7c17cf936c0a0cf659507e5722191d54 to your computer and use it in GitHub Desktop.
Build docker from repository
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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