skip to Main Content

I’m relative new to Bash and i’m trying to clean things up and have a better folder structure.

I’m currently trying to build a script that have options up and down like the famous command "Docker-Compose Up" & "Docker-Compose Down"

My only issue is that i’m not too familiar with If function or if anyother function to make Up and Down as options or arguments

My current scripts is below

compose-up.sh

#!/bin/bash

sudo docker-compose -f /home/home/compose/tools.yml -f /home/home/compose/dashboards.yml up -d

compose-down.sh

#!/bin/bash

sudo docker-compose -f /home/home/compose/tools.yml -f /home/home/compose/dashboards.yml down

The new script should be named compose.sh and i would like if i can just type

./compose.sh up to run and create those containers in Docker

./compose-sh down to stop and delete those containers in Docker

MAKING IT DYNAMIC = IDEAL SCRIPT

The biggest design flaw with my code is that its not dynamic. This is probably a more complicated code down the road for improvement but if its easier for someone to create a code to basically run Docker-Compose Up on all xml files within specific directory such as /home/home/compose. For example, all xml files within the folder "compose" will be automatically docker-compose up and if i want to do docker-compose down too

2

Answers


  1. Chosen as BEST ANSWER

    SCRIPT

    #!/bin/bash
    This script is a bash script that manages Docker Compose operations such as starting, stopping, restarting, and pulling services defined in YAML files
    
    # down() function stops and removes all Docker Compose containers defined in the YAML files in the current folder.
    
    # @return: Outputs a message indicating whether the containers were successfully removed or if no containers were found.
    down() {
        local yml_files=($(find "$(pwd)" -maxdepth 1 -name "*.yml"))  # Find all yml files in the current directory
    
        # Check if any YAML files are found
        if [ ${#yml_files[@]} -eq 0 ]; then
            echo "No yml files found in the current folder."
            exit 1
        fi
    
        local compose_files=""
        for file in "${yml_files[@]}"; do
            compose_files+="-f $file "  # Append each yml file to the command
        done
    
        local output=$(sudo docker-compose $compose_files down 2>&1)  # Capture the output of the command
    
        # Check if the output contains the message "No resource found to remove"
        if [[ $output == *"No resource found to remove"* ]]; then
            echo "No compose files are running in the current folder."
        else
            echo "All compose-related containers are removed in the current folder."
        fi
    }
    
    # up() function starts Docker Compose containers defined in the YAML files in the current folder.
    
    # @return: No return value.
    up() {
        local yml_files=($(find "$(pwd)" -maxdepth 1 -name "*.yml"))  # Find all yml files in the current directory
    
        # Check if any YAML files are found
        if [ ${#yml_files[@]} -eq 0 ]; then
            echo "No yml files found in the current folder."
            exit 1
        fi
    
        local compose_files=""
        for file in "${yml_files[@]}"; do
            compose_files+="-f $file "  # Append each yml file to the command
        done
    
        sudo docker-compose $compose_files up -d
    }
    
    # restart() function restarts Docker Compose containers defined in the YAML files in the current folder.
    
    # @return: No return value.
    restart() {
        local yml_files=($(find "$(pwd)" -maxdepth 1 -name "*.yml"))  # Find all yml files in the current directory
    
        # Check if any YAML files are found
        if [ ${#yml_files[@]} -eq 0 ]; then
            echo "No yml files found in the current folder."
            exit 1
        fi
    
        local compose_files=""
        for file in "${yml_files[@]}"; do
            compose_files+="-f $file "  # Append each yml file to the command
        done
    
        sudo docker-compose $compose_files restart
    }
    
    # stop() function stops Docker Compose containers defined in the YAML files in the current folder.
    
    # @return: No return value.
    stop() {
        local yml_files=($(find "$(pwd)" -maxdepth 1 -name "*.yml"))  # Find all yml files in the current directory
    
        # Check if any YAML files are found
        if [ ${#yml_files[@]} -eq 0 ]; then
            echo "No yml files found in the current folder."
            exit 1
        fi
    
        local compose_files=""
        for file in "${yml_files[@]}"; do
            compose_files+="-f $file "  # Append each yml file to the command
        done
    
        sudo docker-compose $compose_files stop
    }
    
    # pull() function stops and removes all Docker Compose containers, then starts new containers defined in the YAML files in the current folder.
    
    # @return: No return value.
    pull() {
        down
        up
    }
    
    # start() function starts Docker Compose containers defined in the YAML files in the current folder.
    
    # @return: No return value.
    start() {
        local yml_files=($(find "$(pwd)" -maxdepth 1 -name "*.yml"))  # Find all yml files in the current directory
    
        # Check if any YAML files are found
        if [ ${#yml_files[@]} -eq 0 ]; then
            echo "No yml files found in the current folder."
            exit 1
        fi
    
        local compose_files=""
        for file in "${yml_files[@]}"; do
            compose_files+="-f $file "  # Append each yml file to the command
        done
    
        sudo docker-compose $compose_files start
    }
    
    # main() function is the entry point of the script. It calls the appropriate function based on the user's input.
    
    # @param $1: The command to execute (down, up, restart, stop, pull, start).
    # @return: No return value.
    main() {
        if [ "$1" == "down" ]; then
            down
        elif [ "$1" == "up" ]; then
            up
        elif [ "$1" == "restart" ]; then
            restart
        elif [ "$1" == "stop" ]; then
            stop
        elif [ "$1" == "pull" ]; then
            pull
        elif [ "$1" == "start" ]; then
            start
        else
            echo "Invalid option. Please choose one of the following: down, up, restart, stop, pull, start."
        fi
    }
    
    # Check if the script is being executed directly (not sourced) and call the main() function with the provided arguments.
    if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
        main "$@"
    fi
    

    I managed to create a bash code with the assistance of an old friend to make my code dynamic. Enjoy :)

    The script provides functions for common Docker Compose commands such as down, up, restart, stop, pull, and start.

    The main goal was to able to automate and run docker-compose files based on the current folder of pwd.

    The functions correctly find all YAML files in the current directory and use them as input for the Docker Compose commands.

    ADD TO PATH

    1. sudo mv <CurrentPathofScript>/<ScriptName> /usr/local/bin/
    
    2. sudo chmod 755 /usr/local/bin/<ScriptName>
    

  2. In a shell script, any additional command-line parameters are passed in numbered variables $1, $2, and so on.

    You have a couple of invocations of docker-compose with similar options. I’d wrap these in a shell function. Here "$@" means "and all of the additional options passed to the function".

    run_compose() {
      docker-compose -f /home/home/compose/tools.yml -f /home/home/compose/dashboards.yml "$@"
    }
    

    In the main script, there are a couple of ways to check what the argument is. I might use the shell case statement here

    case "$1" in
      up) run_compose up -d ;;
      down) run_compose down ;;
      *) echo 'usage: ./compose.sh [up|down]' >&2; exit 1 ;;
    esac
    

    In the case statement, there are a series of lines starting with a shell glob and a close parenthesis. If the expression "$1" matches the pattern, then the command is executed, up to the next ;;. esac ends the block.

    Make sure to start the script with a "shebang" line, #!/bin/sh on a line on its own, and mark the script executable before you commit it to source control.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search