From da629c05d8c4b6a325dfe30f51b902b96ff1ff93 Mon Sep 17 00:00:00 2001 From: Nick Yeoman Date: Thu, 25 Jul 2024 12:20:36 -0700 Subject: [PATCH] added builder script --- _builder/dc-env.sh | 29 ++++++++++++ _builder/dc-image.sh | 15 ++++++ _builder/dc-new.sh | 22 +++++++++ _builder/dc-vols.sh | 44 ++++++++++++++++++ _builder/debug.sh | 8 ++++ _builder/extends-new.sh | 19 ++++++++ _builder/getdir.bash | 22 +++++++++ _builder/olddcf.bash | 19 ++++++++ _builder/parse.bash | 32 +++++++++++++ _builder/precheck.sh | 43 +++++++++++++++++ _builder/readme-new.sh | 50 ++++++++++++++++++++ _builder/se-new.sh | 23 ++++++++++ bookstack/README.md | 4 ++ bookstack/docker-compose.yml | 50 +++----------------- bookstack/sample-extends.yml | 12 +++++ bookstack/sample.env | 7 +++ builder.bash | 89 ++++++++++++++++++++++++++++++++++++ mariadb/README.md | 27 +++++++++++ mariadb/docker-compose.yml | 17 +++++++ mariadb/sample-extends.yml | 7 +++ mariadb/sample.env | 9 ++++ paisa/docker-compose.yml | 5 -- stashapp/docker-compose.yml | 6 +-- stashapp/sample.env | 1 - 24 files changed, 506 insertions(+), 54 deletions(-) create mode 100644 _builder/dc-env.sh create mode 100644 _builder/dc-image.sh create mode 100644 _builder/dc-new.sh create mode 100644 _builder/dc-vols.sh create mode 100644 _builder/debug.sh create mode 100644 _builder/extends-new.sh create mode 100644 _builder/getdir.bash create mode 100644 _builder/olddcf.bash create mode 100644 _builder/parse.bash create mode 100644 _builder/precheck.sh create mode 100644 _builder/readme-new.sh create mode 100644 _builder/se-new.sh create mode 100644 bookstack/README.md create mode 100644 bookstack/sample-extends.yml create mode 100644 bookstack/sample.env create mode 100644 builder.bash create mode 100644 mariadb/README.md create mode 100644 mariadb/docker-compose.yml create mode 100644 mariadb/sample-extends.yml create mode 100644 mariadb/sample.env diff --git a/_builder/dc-env.sh b/_builder/dc-env.sh new file mode 100644 index 0000000..f02fdd1 --- /dev/null +++ b/_builder/dc-env.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +process_env_vars() { + local env_vars="$1" # Accept the environment variables as the first parameter + local APP_NAME="$(echo "$2" | tr '[:lower:]' '[:upper:]')" # Convert app name to uppercase + local results=() # Array to collect results + + # Loop through each environment variable + while IFS= read -r env_var; do + # Split into name and value parts based on '=' + var_name="${env_var%%=*}" # Variable name + var_value="${env_var#*=}" # Variable value + + # Handle variables with and without default values + if [[ "$var_value" == *'${'*:*'}'* ]]; then + # For variables with default values + modified_var="${var_name}=\${${APP_NAME}_${var_value#\$\{}" + else + # For variables without default values + modified_var="${var_name}=\${${APP_NAME}_${var_name}:-${var_value}}" + fi + + # Append the modified variable to results + results+=("$modified_var") + done <<< "$env_vars" + + # Output the results joined with new lines + printf "%s\n" "${results[@]}" | sort +} \ No newline at end of file diff --git a/_builder/dc-image.sh b/_builder/dc-image.sh new file mode 100644 index 0000000..35a8e04 --- /dev/null +++ b/_builder/dc-image.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Function to parse and handle the variable +extract_image_name() { + local dirty_img="$1" + + if [[ "$dirty_img" == *\$* ]]; then + extracted_value=$(echo "$dirty_img" | sed -n 's/.*:-\([^}]*\)}.*/\1/p') + else + extracted_value=$dirty_img + fi + + echo "$extracted_value" +} + diff --git a/_builder/dc-new.sh b/_builder/dc-new.sh new file mode 100644 index 0000000..631e3ee --- /dev/null +++ b/_builder/dc-new.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +BLDR_IMAGE_VAR="\${${BLDR_APP^^}_IMAGE:-$BLDR_DC_IMAGE}" + +# Generate Docker Compose content and save it to a variable +BLDR_NEW_DCF=$(cat </dev/null) + + # Print the volumes, preserving line breaks + printf "%s\n" "$volumes" +} + +get_env_vars() { + local compose_content="$1" + local env_vars="" + + # Use yq to extract environment variables from services + env_vars=$(echo "$compose_content" | yq eval '.services.*.environment[]' - 2>/dev/null) + + echo "$env_vars" +} + +get_image() { + local compose_content="$1" + local images="" + + # Use yq to extract image names from services + images=$(echo "$compose_content" | yq eval '.services.*.image' - 2>/dev/null) + + echo "$images" +} \ No newline at end of file diff --git a/_builder/precheck.sh b/_builder/precheck.sh new file mode 100644 index 0000000..b3ea989 --- /dev/null +++ b/_builder/precheck.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Function to check if a command is installed and provide installation instructions if not +check_command() { + local command_name="$1" + + if ! command -v "$command_name" &> /dev/null; then + echo "$command_name is not installed." + echo "To install $command_name:" + + case "$(uname -s)" in + Linux*) + if [ -f /etc/os-release ]; then + . /etc/os-release + case "$ID" in + fedora) + echo " - Fedora: sudo dnf install $command_name" + ;; + arch) + echo " - Arch: sudo pacman -S $command_name" + ;; + debian | ubuntu) + echo " - Debian/Ubuntu: sudo apt install $command_name" + ;; + *) + echo " - On other Linux distros, refer to your package manager's documentation." + ;; + esac + else + echo " - Linux: refer to your package manager's documentation for installation." + fi + ;; + Darwin*) + echo " - macOS: brew install $command_name (Homebrew)" + ;; + *) + echo " - Unsupported OS. Please install $command_name manually." + ;; + esac + + exit 1 + fi +} diff --git a/_builder/readme-new.sh b/_builder/readme-new.sh new file mode 100644 index 0000000..270a3ae --- /dev/null +++ b/_builder/readme-new.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Variables for README content +DESCRIPTION="${DESCRIPTION:-This is a sample project.}" +AUTHOR="${AUTHOR:-Nick Yeoman}" +UPDATED=$(date +"%a %B %d, %Y %H:%M:%S %Z") + +# Function to generate a README file +generate_readme() { + local readme_content="" + + # Header + readme_content+="# $BLDR_APP\n\n" + readme_content+="Last Updated: $UPDATED\n\n" + + # Description + readme_content+="## Description\n" + readme_content+="$DESCRIPTION\n\n" + + # Usage + readme_content+="## Usage\n" + readme_content+="Provide examples of how to use the project:\n\n" + readme_content+="\`\`\`bash\n" + readme_content+="# Example command\n" + readme_content+="\`\`\`\n\n" + + # Environment Variables + readme_content+="## Environment Variables\n" + readme_content+="List of environment variables used in the project:\n\n" + + # Extract environment variables from BLDR_NEW_SE + while IFS= read -r line; do + # Use regex to match and extract variable names and defaults + if [[ $line =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then + var_name="${BASH_REMATCH[1]}" + var_value="${BASH_REMATCH[2]}" + readme_content+="* \`$var_name\`: $var_value\n" + fi + done <<< "$BLDR_NEW_SE" + + readme_content+="\n" + + # Author + readme_content+="## Author\n" + readme_content+="Developed by $AUTHOR.\n" + + # Output the README content to a file + echo -e "$readme_content" +} + diff --git a/_builder/se-new.sh b/_builder/se-new.sh new file mode 100644 index 0000000..514cc3d --- /dev/null +++ b/_builder/se-new.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +BLDR_NEW_SE+="# $BLDR_APP\n" + +while IFS= read -r line; do + # Use a regex to match and extract variable names and defaults + if [[ $line =~ \$\{([A-Za-z_][A-Za-z0-9_]*)\} ]]; then + # Matched ${VAR_NAME} (without default) + var_name="${BASH_REMATCH[1]}" + BLDR_NEW_SE+="${var_name}=\n" + elif [[ $line =~ \$\{([A-Za-z_][A-Za-z0-9_]*)[:-](.*)\} ]]; then + # Matched ${VAR_DEF:-default} (with default) + var_name="${BASH_REMATCH[1]}" + default_value="${BASH_REMATCH[2]:1}" + BLDR_NEW_SE+="${var_name}=${default_value}\n" + fi +done <<< "$BLDR_NEW_DCF" + +# Remove duplicates from the output +BLDR_NEW_SE=$(echo -e "$BLDR_NEW_SE" | sort -u) + +echo "***** NEW sample.env *****" +echo "$BLDR_NEW_SE" \ No newline at end of file diff --git a/bookstack/README.md b/bookstack/README.md new file mode 100644 index 0000000..7ce574a --- /dev/null +++ b/bookstack/README.md @@ -0,0 +1,4 @@ +# Bookstack + +Dockerhub: https://hub.docker.com/r/solidnerd/bookstack +Reverse Proxy Port: 8080 diff --git a/bookstack/docker-compose.yml b/bookstack/docker-compose.yml index 540dff0..5f220ac 100644 --- a/bookstack/docker-compose.yml +++ b/bookstack/docker-compose.yml @@ -1,56 +1,20 @@ -################################################################################ -# Bookstack -# -# Sample .env -# -# DB_USER=bookstack -# DB_PASSWORD=ChangeThisPassword -# APP_URL=http://localhost:8248 -# APP_KEY=32CharacterKey123456789012345678 -# NETWORKNAME=admin_web -################################################################################ version: '3.8' -networks: - default: - external: - name: ${NETWORKNAME:-default} - services: - bookstack-db: - image: mariadb:latest # https://hub.docker.com/_/mariadb - restart: always - volumes: - - ./data/db:/var/lib/mysql - - "/etc/timezone:/etc/timezone:ro" - - "/etc/localtime:/etc/localtime:ro" - command: --max_allowed_packet=32505856 - environment: - MYSQL_ROOT_PASSWORD: ChangeThisToRandom - MYSQL_USER: ${DB_USER} - MYSQL_PASSWORD: ${DB_PASSWORD} - MYSQL_DATABASE: ${DB_USER} - bookstack: - image: solidnerd/bookstack:latest # https://hub.docker.com/r/solidnerd/bookstack - depends_on: - - bookstack-db + image: ${BOOKSTACK_IMAGE:-solidnerd/bookstack:latest} environment: - DB_HOST=bookstack-db:3306 - - DB_DATABASE=${DB_USER} - - DB_USERNAME=${DB_USER} - - DB_PASSWORD=${DB_PASSWORD} + - DB_DATABASE=dbuser + - DB_USERNAME=dbuser + - DB_PASSWORD=dbpass - APP_URL=${APP_URL:-http://localhost:8248} - REVISION_LIMIT=false - - APP_KEY=${APP_KEY} + - APP_KEY=APP_KEY - APP_TIMEZONE=America/Vancouver volumes: + - "/etc/timezone:/etc/timezone:ro" - ./data/uploads:/var/www/bookstack/public/uploads - ./data/storage:/var/www/bookstack/storage/uploads - - ./php.ini:/usr/local/etc/php/php.ini - - "/etc/timezone:/etc/timezone:ro" - - "/etc/localtime:/etc/localtime:ro" - ports: - - "8248:8080" - + - ./config/php.ini:/usr/local/etc/php/php.ini diff --git a/bookstack/sample-extends.yml b/bookstack/sample-extends.yml new file mode 100644 index 0000000..78aa6bc --- /dev/null +++ b/bookstack/sample-extends.yml @@ -0,0 +1,12 @@ +version: '3.4' + +services: + bookstack: + extends: + file: ${COOKBOOK}/bookstack/docker-compose.yml + service: bookstack + + bookstack-mariadb: + extends: + file: ${COOKBOOK}/mariadb/docker-compose.yml + service: mariadb \ No newline at end of file diff --git a/bookstack/sample.env b/bookstack/sample.env new file mode 100644 index 0000000..f5e183c --- /dev/null +++ b/bookstack/sample.env @@ -0,0 +1,7 @@ +# Bookstack App +PRODDIR=/var/www/stashdomain-com/ #HELP: project_path +COOKBOOK=/home/user/git/docker-compose-cookbooks #HELP: cookbooks +VOL_PATH=/project-dir/project-name/data #HELP: volpath +# Bookstack Container +BOOKSTACK_IMAGE=solidnerd/bookstack:latest +APP_KEY=012345679801234567980123645678921 #HELP: gen32 \ No newline at end of file diff --git a/builder.bash b/builder.bash new file mode 100644 index 0000000..6a35bea --- /dev/null +++ b/builder.bash @@ -0,0 +1,89 @@ +#!/bin/bash + +BLDR_DIR="" +BLDR_APP="" +BLDR_PARENT_PATH=$(dirname "$(realpath "${BASH_SOURCE[0]}")") +BLDR_OLD_DCF="" # Content of Old Docker Compose File +BLDR_NEW_DCF="" # Content of New Docker Compose File +BLDR_NEW_SE="" # sample-extends +BLDR_NEW_README="" +BLDR_DC_VOLS="" +BLDR_DC_IMAGE="" +BLDR_DC_ENV="" +BLDR_ENV_FILE="" + +source ./_builder/debug.sh +#debug_print_helper_variables + +################################################ +# Pre Check +################################################ +source ./_builder/precheck.sh +check_command "fzf" +check_command "yq" + +################################################ +# Get Directory we are working with +################################################ +source ./_builder/getdir.bash +get_directory + +################################################ +# Save file to work with +################################################ +source ./_builder/olddcf.bash + +################################################ +# Take out the stuff we need +################################################ +source ./_builder/parse.bash +BLDR_DC_VOLS=$(get_vols "$BLDR_OLD_DCF") +BLDR_DC_ENV=$(get_env_vars "$BLDR_OLD_DCF") +BLDR_DC_IMAGE=$(get_image "$BLDR_OLD_DCF") +unset BLDR_OLD_DCF # Done, got the stuff we need + +################################################ +# Clean up the IMAGE +################################################ +source ./_builder/dc-image.sh +BLDR_DC_IMAGE=$(extract_image_name "$BLDR_DC_IMAGE") + +################################################ +# Clean up VOLS +################################################ +source ./_builder/dc-vols.sh +BLDR_DC_VOLS=$(process_volumes "$BLDR_DC_VOLS") + +################################################ +# Clean up ENV +################################################ +source ./_builder/dc-env.sh +BLDR_DC_ENV=$(process_env_vars "$BLDR_DC_ENV" "$BLDR_APP") + +################################################ +# Compile New Docker Var BLDR_NEW_DCF +################################################ +source ./_builder/dc-new.sh + +################################################ +# Create sample-env +################################################ +source ./_builder/se-new.sh + +################################################ +# Create sample-extends +################################################ +source ./_builder/extends-new.sh + +################################################ +# Create Readme.md +################################################ +source ./_builder/readme-new.sh +BLDR_NEW_README=$(generate_readme) +echo "***** README *****" +echo "$BLDR_NEW_README" + +# TODO: for readme file do mkdir -p data/vols for vols +# Do a git diff on the directory +# fuzzy find latest image using skopeo +# skopeo list-tags docker://docker.io/solidnerd/book \ No newline at end of file diff --git a/mariadb/README.md b/mariadb/README.md new file mode 100644 index 0000000..497575d --- /dev/null +++ b/mariadb/README.md @@ -0,0 +1,27 @@ +# Mariadb + +Dockerhub: https://hub.docker.com/_/mariadb + +It will be quite uncommon to just use this compose file, it's likely you are extending this from another project. +That's the main context of this container. + +## Sample + +### Run multiple databases + +initdb/init.sql + +```sql + +-- Create BookStack database and user +CREATE DATABASE IF NOT EXISTS bookstack_db; +CREATE USER IF NOT EXISTS 'bookstack_user'@'%' IDENTIFIED BY 'bookstack_password'; +GRANT ALL PRIVILEGES ON bookstack_db.* TO 'bookstack_user'@'%'; + +-- Create WordPress database and user +CREATE DATABASE IF NOT EXISTS wordpress_db; +CREATE USER IF NOT EXISTS 'wordpress_user'@'%' IDENTIFIED BY 'wordpress_password'; +GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wordpress_user'@'%'; + +FLUSH PRIVILEGES; +``` \ No newline at end of file diff --git a/mariadb/docker-compose.yml b/mariadb/docker-compose.yml new file mode 100644 index 0000000..ee25000 --- /dev/null +++ b/mariadb/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' # or any version you prefer + +services: + mariadb: + image: ${MARIADB_IMAGE:-mariadb:latest} + environment: + MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD:-ChangeThisPassword} + MARIADB_DATABASE: ${MARIADB_DATABASE:-mydb} + MARIADB_USER: ${MARIADB_USER:-dbuser} + MARIADB_PASSWORD: ${MARIADB_PASSWORD:-AlsoChangeThisPassword} + volumes: + - ${VOL_PATH:-./data/}mariadb_data:/var/lib/mysql + ports: + - "3306:3306" + networks: + - mariadb_network + diff --git a/mariadb/sample-extends.yml b/mariadb/sample-extends.yml new file mode 100644 index 0000000..dbce636 --- /dev/null +++ b/mariadb/sample-extends.yml @@ -0,0 +1,7 @@ +version: '3.4' + +services: + mariadb: + extends: + file: ${COOKBOOK}/mariadb/docker-compose.yml + service: mariadb \ No newline at end of file diff --git a/mariadb/sample.env b/mariadb/sample.env new file mode 100644 index 0000000..9928991 --- /dev/null +++ b/mariadb/sample.env @@ -0,0 +1,9 @@ +# Mariadb +PRODDIR=/var/www/stashdomain-com/ #HELP: project_path +COOKBOOK=/home/user/git/docker-compose-cookbooks #HELP: cookbooks +VOL_PATH=/project-dir/project-name/data #HELP: volpath +MARIADB_IMAGE=mariadb:latest +MARIADB_ROOT_PASSWORD=ChangeThisPassword #HELP: gen32 +MARIADB_DATABASE=mydb +MARIADB_USER=dbuser +MARIADB_PASSWORD=AlsoChangeThisPassword #HELP: gen32 \ No newline at end of file diff --git a/paisa/docker-compose.yml b/paisa/docker-compose.yml index fa6ee28..78632e9 100644 --- a/paisa/docker-compose.yml +++ b/paisa/docker-compose.yml @@ -7,11 +7,6 @@ ################################################################################ version: '3.8' -networks: - default: - external: - name: ${NETWORKNAME:-default} - services: paisa: image: ananthakumaran/paisa:latest diff --git a/stashapp/docker-compose.yml b/stashapp/docker-compose.yml index c946c82..da2bb09 100644 --- a/stashapp/docker-compose.yml +++ b/stashapp/docker-compose.yml @@ -3,11 +3,6 @@ version: '3.4' services: stash: image: ${STASH_IMAGE:-stashapp/stash:latest} - logging: - driver: "json-file" - options: - max-file: "100" - max-size: ${MAX_SIZE:-200m} restart: unless-stopped environment: - STASH_STASH=${STASH_STASH:-/data/} @@ -21,5 +16,6 @@ services: - "${VOL_PATH:-./data}/stash-cache:/cache" - "${VOL_PATH:-./data}/stash-generated:/generated" - "${VOL_PATH:-./data}/stash-root:/root" + # Uncomment and use if needed # network_mode: "host" diff --git a/stashapp/sample.env b/stashapp/sample.env index 79b27db..9567968 100644 --- a/stashapp/sample.env +++ b/stashapp/sample.env @@ -6,7 +6,6 @@ VOL_PATH=/project-dir/project-name/data #HELP: volpath STASH_IMAGE=stashapp/stash:v0.26.2 # Stash Container STASH_DOMAIN_NAME=stash.4lt.ca -MAX_SIZE=200m STASH_STASH=/data/ STASH_GENERATED=/generated/ STASH_METADATA=/metadata/