diff --git a/Caddyfile.example b/Caddyfile.example index e96ebaf..2db4b2d 100644 --- a/Caddyfile.example +++ b/Caddyfile.example @@ -1,6 +1,7 @@ -import ./common/monitoring/Caddyfile -import ./common/minio/Caddyfile -import ./common/environment/Caddyfile +#import ./common/monitoring/Caddyfile +#import ./common/minio/Caddyfile +#import ./common/environment/Caddyfile #import ./common/fusionauth/Caddyfile # The registry doesn't have a auth thus exposing it publicly means anyone can access the images pushed to this registry -#import ./common/registry/Caddyfile \ No newline at end of file +#import ./common/registry/Caddyfile +import ./common/hasura/Caddyfile \ No newline at end of file diff --git a/application.yaml b/application.yaml new file mode 100644 index 0000000..7bbc9cb --- /dev/null +++ b/application.yaml @@ -0,0 +1,8 @@ +services: + SERVICE_NAME: + image: ${DOCKER_REGISTRY_URL:-ghcr.io}/${org}/IMAGE_URL:${SERVICE_NAME_IMAGE_TAG:-${DEFAULT_IMAGE_TAG:?DEFAULT_IMAGE_TAG is not set}} + deploy: + replicas: ${SERVICE_NAME_REPLICAS:-1} + mem_limit: ${SERVICE_NAME_MEM_LIMIT:-${DEFAULT_MEM_LIMIT:-256m}} + cpus: ${SERVICE_NAME_CPU_LIMIT:-${DEFAULT_CPU_LIMIT:-0.5}} + # Removed environment, ports, depends_on, command,restart and volumes sections diff --git a/cli.sh b/cli.sh new file mode 100755 index 0000000..45976af --- /dev/null +++ b/cli.sh @@ -0,0 +1,159 @@ +#!/bin/bash + +# Prompt messages +PROMPT_SERVICE_NAME="Enter Service Name: " +PROMPT_IMAGE_URL="Enter Image URL: " +PROMPT_SERVICE_PORT="Enter Service Port: " +EXPOSE_SERVICE="Enter Service Name to expose: " +ENTER_YOUR_CHOICE="Enter your choice: " +OUTPUT_INVALID_INPUT="Invalid input. Returning to the main menu." +OUTPUT_RETURN_MAIN_MENU="Returning to the main menu." +OUTPUT_SERVICE_NOT_FOUND="Service not found in docker-compose.yaml." + +# Define an array for menu options +MENU_OPTIONS=( + "Onboard a service" + "Expose a service using Caddy" + "Abort" +) + +# Function to validate that the input is a number +validate_number() { + if ! [[ "$1" =~ ^[0-9]+$ ]]; then + echo "Invalid input. It must be a number." + return 1 + else + return 0 + fi +} + +# Function to prompt the user for input and validate it +prompt_input() { + local prompt_message=$1 + local validation_function=$2 + local input_variable=$3 + local input_value + + while true; do + read -p "$prompt_message" input_value + if [ -z "$validation_function" ] || $validation_function "$input_value"; then + eval "$input_variable='$input_value'" + break + else + echo "$OUTPUT_INVALID_INPUT" + fi + done +} + +# Function to create or update docker-compose.yaml +update_docker_compose() { + local template_file="application.yaml" + local output_file="docker-compose.yaml" + + # Load the template content + local template_content + template_content=$(cat "$template_file") + + # Replace placeholders in the template with actual values + template_content="${template_content//SERVICE_NAME/$SERVICE_NAME}" + template_content="${template_content//IMAGE_URL/${IMAGE_URL}}" + + # Replace DEMO_SERVICE with SERVICE_NAME + template_content="${template_content//DEMO_SERVICE/$SERVICE_NAME}" + + # Convert the template content to a valid YAML structure + local service_yaml + service_yaml=$(echo "$template_content" | yq eval -o=json | jq -c '.services') + + # Check if the file exists and append the service + if [ -f "$output_file" ]; then + echo -e "\n" >> "$output_file" + yq eval -i ".services += $service_yaml" "$output_file" + else + touch "$output_file" + echo "$service_yaml" | yq eval -o=json | jq -c '.services' | yq eval -i ".services = $service_yaml" "$output_file" + fi +} + +# Function to create or update Caddyfile +update_caddyfile() { + local service_name=$1 + local service_port=$2 + local caddy_entry="\${DOMAIN_SCHEME}://${service_name}.\${DOMAIN_NAME} { + reverse_proxy ${service_name}:${service_port} +}" + + if [ -f "Caddyfile" ]; then + if grep -q "$service_name" "Caddyfile"; then + echo "Service $service_name is already exposed in Caddyfile." + else + echo -e "\n$caddy_entry" >> Caddyfile + echo "Added $service_name to Caddyfile." + fi + else + echo -e "$caddy_entry" > Caddyfile + echo "Caddyfile created and $service_name added." + fi +} + +# Function to expose a service in Caddyfile +expose_service() { + local service_name=$1 + local service_port=$2 + + # Check if the file docker-compose.yaml exists + if [ ! -f "docker-compose.yaml" ]; then + echo "docker-compose.yaml not found." + echo "$OUTPUT_SERVICE_NOT_FOUND" + return + fi + + # Check if the service exists in docker-compose.yaml + local service_exists + service_exists=$(yq eval ".services | has(\"$service_name\")" docker-compose.yaml) + + if [ "$service_exists" = "true" ]; then + echo "Service $service_name found." + + # Update the Caddyfile with the provided port + update_caddyfile "$service_name" "$service_port" + else + # Use printf to include the service name in the output message + printf "%s %s\n" "$service_name" "$OUTPUT_SERVICE_NOT_FOUND" + fi +} + +# Function to handle onboarding a service +onboard_service() { + prompt_input "$PROMPT_SERVICE_NAME" "" SERVICE_NAME + prompt_input "$PROMPT_IMAGE_URL" "" IMAGE_URL + + update_docker_compose +} + +# Function to display the main menu +display_main_menu() { + echo + echo "Choose an option:" + for i in "${!MENU_OPTIONS[@]}"; do + echo "$((i + 1))) ${MENU_OPTIONS[$i]}" + done + echo +} + +# Main menu +while true; do + display_main_menu + read -p "$ENTER_YOUR_CHOICE" choice + + case "$choice" in + 1) onboard_service;; + 2) + read -p "$EXPOSE_SERVICE" expose_service_name + prompt_input "$PROMPT_SERVICE_PORT" validate_number expose_service_port + expose_service "$expose_service_name" "$expose_service_port" + ;; + 3) echo "Aborting."; exit 0;; + *) echo "$OUTPUT_INVALID_INPUT";; + esac +done diff --git a/common/hasura/Caddyfile b/common/hasura/Caddyfile new file mode 100644 index 0000000..4eafda4 --- /dev/null +++ b/common/hasura/Caddyfile @@ -0,0 +1,3 @@ +{$DOMAIN_SCHEME}://hasura.{$DOMAIN_NAME} { + reverse_proxy hasura:8080 +} diff --git a/common/hasura/docker-compose.yaml b/common/hasura/docker-compose.yaml new file mode 100644 index 0000000..a427632 --- /dev/null +++ b/common/hasura/docker-compose.yaml @@ -0,0 +1,12 @@ + services: + hasura: + image: hasura/graphql-engine:latest + restart: always + environment: + HASURA_GRAPHQL_ENABLE_CONSOLE: 'true' + HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET:?HASURA_GRAPHQL_ADMIN_SECRET is not set} + healthcheck: + test: ['CMD', 'curl', '-f', 'http://localhost:8080/healthz'] + interval: 10s + timeout: 10s + retries: 5 \ No newline at end of file diff --git a/common/sample.env b/common/sample.env index 2789a8f..badfe8c 100644 --- a/common/sample.env +++ b/common/sample.env @@ -35,4 +35,7 @@ FUSIONAUTH_POSTGRES_PASSWORD= FUSIONAUTH_APP_RUNTIME_MODE=development FUSIONAUTH_API_KEY= FUSIONAUTH_ADMIN_EMAIL= -FUSIONAUTH_ADMIN_PASSWORD= \ No newline at end of file +FUSIONAUTH_ADMIN_PASSWORD= + +#hasura +HASURA_GRAPHQL_ADMIN_SECRET= \ No newline at end of file diff --git a/docker-compose.yaml.example b/docker-compose.yaml.example index 01627f1..bcd2ae4 100644 --- a/docker-compose.yaml.example +++ b/docker-compose.yaml.example @@ -3,8 +3,8 @@ include: # - ./common/minio/docker-compose.yaml # - ./common/environment/docker-compose.yaml # - ./common/fusionauth/docker-compose.yaml - - ./common/registry/docker-compose.yaml - +# - ./common/registry/docker-compose.yaml +# - ./common/hasura/docker-compose.yaml services: caddy: