#!/bin/zsh while [[ "$#" -gt 0 ]] do case $1 in --app_name) app_name="$2" shift;; *) echo "Unknown parameter passed: $1" exit 1;; esac shift done # Make sure app_name exists and is not empty if [[ -z "$app_name" ]]; then echo "app_name is unset or empty." exit 1; fi # Define the base directory for the new application structure # This will be one level up from where this script is executed. app_base_dir="../${app_name}" app_data_dir="${app_base_dir}/data" compose_file="${app_base_dir}/compose.yaml" readme_file="${app_base_dir}/README.md" start_script="${app_base_dir}/start.sh" echo "--- Setting up files and directories for application: ${app_name} ---" echo "Base directory: ${app_base_dir}" # 1. Create the application base directory and data directory echo "Creating directory: ${app_data_dir}" mkdir -p "${app_data_dir}" || { echo "Error: Failed to create directory ${app_data_dir}"; exit 1; } # 2. Create compose.yaml and README.md echo "Creating file: ${compose_file}" touch "${compose_file}" || { echo "Error: Failed to create file ${compose_file}"; exit 1; } echo "Creating file: ${readme_file}" touch "${readme_file}" || { echo "Error: Failed to create file ${readme_file}"; exit 1; } # 3. Prepopulate README.md with title case app name # Convert app_name to title case (first letter of each word capitalized) # This is a simple conversion; for more robust title casing, a function would be better. app_name_title_case=$(echo "$app_name" | awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) tolower(substr($i,2)) }}1') echo "Prepopulating ${readme_file}..." cat > "${readme_file}" << EOF # ${app_name_title_case} This is the README file for the **${app_name}** application. ## Overview Provide a brief description of your application here. ## Setup Instructions for setting up the application. EOF # 4. Ask the user if secrets will be required read "requires_secrets?Will this application require secrets (yes/no)? " requires_secrets=$(echo "$requires_secrets" | tr '[:upper:]' '[:lower:]') # Convert to lowercase # 5. Prepopulate compose.yaml based on user selection re. secrets echo "Prepopulating ${compose_file} based on secrets requirement..." if [[ "$requires_secrets" == "yes" || "$requires_secrets" == "y" ]]; then cat > "${compose_file}" << EOF version: '3.8' services: ${app_name}: image: your-app-image:latest container_name: ${app_name}-container ports: - "8080:8080" volumes: - ./data:/app/data environment: # Example of how to pass secrets as environment variables # These would typically be loaded from a .env file or a secrets management system - DATABASE_URL=\${DATABASE_URL} - API_KEY=\${API_KEY} # Example of secrets usage with Docker Compose secrets (requires Docker Swarm or specific setup) # secrets: # - my_database_password # - my_api_key # deploy: # resources: # limits: # cpus: '0.5' # memory: 512M secrets: my_database_password: external: true # Assumes secret is created externally (e.g., docker secret create) my_api_key: external: true EOF else cat > "${compose_file}" << EOF services: ${app_name}: image: your-app-image:latest container_name: ${app_name}-container ports: - "8080:8080" volumes: - ./data:/app/data # No secrets configuration needed for this version # deploy: # resources: # limits: # cpus: '0.5' # memory: 512M EOF fi # 6. If secrets will be used - touch ../"app_name"/start.sh and prepopulate it if [[ "$requires_secrets" == "yes" || "$requires_secrets" == "y" ]]; then echo "Creating and prepopulating ${start_script}..." cat > "${start_script}" << EOF #!/bin/zsh # Example start script for an application using secrets # This script assumes you have a .env file or similar mechanism # for loading secrets into the environment before starting Docker Compose. # --- IMPORTANT: Replace with your actual secret loading mechanism --- # Example 1: Load from a .env file # if [[ -f ".env" ]]; then # echo "Loading environment variables from .env" # source .env # else # echo "Warning: .env file not found. Secrets might be missing." # fi # Example 2: Using a secrets management tool (e.g., HashiCorp Vault, AWS Secrets Manager) # echo "Fetching secrets from Vault..." # export DATABASE_URL=\$(vault read -field=value secret/myapp/database_url) # export API_KEY=\$(vault read -field=value secret/myapp/api_key) # ------------------------------------------------------------------- echo "Starting Docker Compose services for ${app_name}..." docker compose -f "${compose_file}" up -d echo "Application ${app_name} started. Check logs with: docker compose logs -f ${app_name}" EOF chmod +x "${start_script}" # Make the start script executable fi # 7. If secrets will be used, append another chapter at the end of the README.md file if [[ "$requires_secrets" == "yes" || "$requires_secrets" == "y" ]]; then echo "Appending 'Secrets Management' chapter to ${readme_file}..." cat >> "${readme_file}" << EOF ## Secrets Management This application utilizes secrets for sensitive configurations (e.g., database credentials, API keys). ### Configuration Secrets are expected to be provided via environment variables or Docker Compose secrets. Refer to the \`start.sh\` script for an example of how to load these secrets before application startup. **Example Environment Variables (to be set in your environment or a \`.env\` file):** \`\`\` DATABASE_URL="postgres://user:password@host:port/database" API_KEY="your_super_secret_api_key" \`\`\` **For Docker Compose secrets:** Ensure the necessary Docker secrets are created on your Docker host or Swarm cluster. \`\`\`bash docker secret create my_database_password <(echo "your_db_password") docker secret create my_api_key <(echo "your_api_key") \`\`\` Then, update the \`compose.yaml\` to reference these secrets. EOF fi echo "--- Setup complete for ${app_name} ---" echo "Check the '${app_base_dir}' directory for your new files."