feat(cloudron): update CloudronStack core components
- Update CloudronStack/QWEN.md with latest development log information - Update CloudronStack/collab/STATUS.md with current project status - Update CloudronStack/output/master-control-script.sh with enhanced automation - Update CloudronStack/output/package-functions.sh with improved packaging logic These changes enhance the CloudronStack automation and packaging capabilities.
This commit is contained in:
		| @@ -10,28 +10,68 @@ package_nodejs_app() { | ||||
|     local app_name=$1 | ||||
|     local app_dir=$2 | ||||
|     local artifact_dir=$3 | ||||
|     local app_url=${4:-"https://github.com/unknown-user/$app_name"}  # Default URL if not provided | ||||
|      | ||||
|     cd "$app_dir" | ||||
|      | ||||
|     # Extract username/repo from the app_url for manifest | ||||
|     local repo_path | ||||
|     if [[ "$app_url" == *"github.com"* ]]; then | ||||
|         repo_path=${app_url#*github.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     elif [[ "$app_url" == *"gitlab.com"* ]]; then | ||||
|         repo_path=${app_url#*gitlab.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     else | ||||
|         repo_path="unknown-user/$app_name" | ||||
|     fi | ||||
|      | ||||
|     # Create Cloudron manifest | ||||
|     cat > app.manifest << EOF | ||||
| { | ||||
|     "id": "com.$(echo "$app_name" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "id": "com.$(echo "$repo_path" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "title": "$app_name", | ||||
|     "version": "1.0.0", | ||||
|     "build": "1", | ||||
|     "description": "Cloudron package for $app_name", | ||||
|     "author": "Auto-generated", | ||||
|     "website": "https://github.com/$app_name", | ||||
|     "website": "$app_url", | ||||
|     "admin": false, | ||||
|     "tags": ["nodejs", "auto-generated"], | ||||
|     "logo": "https://github.com/fluidicon.png", | ||||
|     "documentation": "https://github.com/$app_name", | ||||
|     "documentation": "$app_url", | ||||
|     "changelog": "Initial packaging" | ||||
| } | ||||
| EOF | ||||
|      | ||||
|     # Create Dockerfile for Node.js | ||||
|     # Determine the appropriate start command and port from package.json if available | ||||
|     local start_cmd="npm start" | ||||
|     local port=3000 | ||||
|      | ||||
|     if [ -f "package.json" ]; then | ||||
|         # Try to extract the start script from package.json | ||||
|         if command -v jq >/dev/null 2>&1; then | ||||
|             # Use jq if available to properly parse JSON | ||||
|             local scripts_start=$(jq -r '.scripts.start // empty' package.json 2>/dev/null) | ||||
|             if [ -n "$scripts_start" ] && [ "$scripts_start" != "null" ]; then | ||||
|                 start_cmd="$scripts_start" | ||||
|             fi | ||||
|              | ||||
|             # Look for port configuration in various common places | ||||
|             local configured_port=$(jq -r '.config.port // .port // empty' package.json 2>/dev/null) | ||||
|             if [ -n "$configured_port" ] && [ "$configured_port" != "null" ] && [ "$configured_port" -gt 0 ] 2>/dev/null; then | ||||
|                 port=$configured_port | ||||
|             fi | ||||
|         else | ||||
|             # Fallback to grep if jq is not available | ||||
|             local scripts_start=$(grep -o '"start": *"[^"]*"' package.json | head -1 | cut -d'"' -f4) | ||||
|             if [ -n "$scripts_start" ]; then | ||||
|                 start_cmd="$scripts_start" | ||||
|             fi | ||||
|         fi | ||||
|     fi | ||||
|      | ||||
|     # Create Dockerfile for Node.js with appropriate start command and port | ||||
|     cat > Dockerfile << EOF | ||||
| FROM node:18-alpine | ||||
|  | ||||
| @@ -42,9 +82,9 @@ RUN npm install --only=production | ||||
|  | ||||
| COPY . . | ||||
|  | ||||
| EXPOSE 3000 | ||||
| EXPOSE $port | ||||
|  | ||||
| CMD ["npm", "start"] | ||||
| CMD $start_cmd | ||||
| EOF | ||||
|      | ||||
|     # Build Docker image | ||||
| @@ -70,28 +110,68 @@ package_python_app() { | ||||
|     local app_name=$1 | ||||
|     local app_dir=$2 | ||||
|     local artifact_dir=$3 | ||||
|     local app_url=${4:-"https://github.com/unknown-user/$app_name"}  # Default URL if not provided | ||||
|      | ||||
|     cd "$app_dir" | ||||
|      | ||||
|     # Extract username/repo from the app_url for manifest | ||||
|     local repo_path | ||||
|     if [[ "$app_url" == *"github.com"* ]]; then | ||||
|         repo_path=${app_url#*github.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     elif [[ "$app_url" == *"gitlab.com"* ]]; then | ||||
|         repo_path=${app_url#*gitlab.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     else | ||||
|         repo_path="unknown-user/$app_name" | ||||
|     fi | ||||
|      | ||||
|     # Create Cloudron manifest | ||||
|     cat > app.manifest << EOF | ||||
| { | ||||
|     "id": "com.$(echo "$app_name" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "id": "com.$(echo "$repo_path" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "title": "$app_name", | ||||
|     "version": "1.0.0", | ||||
|     "build": "1", | ||||
|     "description": "Cloudron package for $app_name", | ||||
|     "author": "Auto-generated", | ||||
|     "website": "https://github.com/$app_name", | ||||
|     "website": "$app_url", | ||||
|     "admin": false, | ||||
|     "tags": ["python", "auto-generated"], | ||||
|     "logo": "https://github.com/fluidicon.png", | ||||
|     "documentation": "https://github.com/$app_name", | ||||
|     "documentation": "$app_url", | ||||
|     "changelog": "Initial packaging" | ||||
| } | ||||
| EOF | ||||
|      | ||||
|     # Create Dockerfile for Python | ||||
|     # Try to determine the appropriate start command and port | ||||
|     local start_cmd="python app.py" | ||||
|     local port=8000 | ||||
|      | ||||
|     # Look for common Python web framework indicators | ||||
|     if [ -f "requirements.txt" ]; then | ||||
|         if grep -E -i "flask" requirements.txt >/dev/null; then | ||||
|             start_cmd="python -m flask run --host=0.0.0.0 --port=$port" | ||||
|         elif grep -E -i "django" requirements.txt >/dev/null; then | ||||
|             start_cmd="python manage.py runserver 0.0.0.0:$port" | ||||
|             port=8000 | ||||
|         elif grep -E -i "fastapi" requirements.txt >/dev/null; then | ||||
|             start_cmd="uvicorn main:app --host 0.0.0.0 --port $port" | ||||
|             if [ ! -f "main.py" ] && [ -f "app.py" ]; then | ||||
|                 start_cmd="uvicorn app:app --host 0.0.0.0 --port $port" | ||||
|             fi | ||||
|         elif grep -E -i "gunicorn" requirements.txt >/dev/null; then | ||||
|             if [ -f "wsgi.py" ]; then | ||||
|                 start_cmd="gunicorn wsgi:application --bind 0.0.0.0:$port" | ||||
|             elif [ -f "app.py" ]; then | ||||
|                 start_cmd="gunicorn app:app --bind 0.0.0.0:$port" | ||||
|             else | ||||
|                 start_cmd="gunicorn app:application --bind 0.0.0.0:$port" | ||||
|             fi | ||||
|         fi | ||||
|     fi | ||||
|      | ||||
|     # Create Dockerfile for Python with appropriate start command and port | ||||
|     cat > Dockerfile << EOF | ||||
| FROM python:3.11-slim | ||||
|  | ||||
| @@ -102,9 +182,9 @@ RUN pip install --no-cache-dir -r requirements.txt | ||||
|  | ||||
| COPY . . | ||||
|  | ||||
| EXPOSE 8000 | ||||
| EXPOSE $port | ||||
|  | ||||
| CMD ["python", "app.py"] | ||||
| CMD $start_cmd | ||||
| EOF | ||||
|      | ||||
|     # Build Docker image | ||||
| @@ -130,34 +210,57 @@ package_php_app() { | ||||
|     local app_name=$1 | ||||
|     local app_dir=$2 | ||||
|     local artifact_dir=$3 | ||||
|     local app_url=${4:-"https://github.com/unknown-user/$app_name"}  # Default URL if not provided | ||||
|      | ||||
|     cd "$app_dir" | ||||
|      | ||||
|     # Extract username/repo from the app_url for manifest | ||||
|     local repo_path | ||||
|     if [[ "$app_url" == *"github.com"* ]]; then | ||||
|         repo_path=${app_url#*github.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     elif [[ "$app_url" == *"gitlab.com"* ]]; then | ||||
|         repo_path=${app_url#*gitlab.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     else | ||||
|         repo_path="unknown-user/$app_name" | ||||
|     fi | ||||
|      | ||||
|     # Create Cloudron manifest | ||||
|     cat > app.manifest << EOF | ||||
| { | ||||
|     "id": "com.$(echo "$app_name" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "id": "com.$(echo "$repo_path" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "title": "$app_name", | ||||
|     "version": "1.0.0", | ||||
|     "build": "1", | ||||
|     "description": "Cloudron package for $app_name", | ||||
|     "author": "Auto-generated", | ||||
|     "website": "https://github.com/$app_name", | ||||
|     "website": "$app_url", | ||||
|     "admin": false, | ||||
|     "tags": ["php", "auto-generated"], | ||||
|     "logo": "https://github.com/fluidicon.png", | ||||
|     "documentation": "https://github.com/$app_name", | ||||
|     "documentation": "$app_url", | ||||
|     "changelog": "Initial packaging" | ||||
| } | ||||
| EOF | ||||
|      | ||||
|     # Create Dockerfile for PHP | ||||
|     # Create Dockerfile for PHP with better configuration | ||||
|     cat > Dockerfile << EOF | ||||
| FROM php:8.1-apache | ||||
|  | ||||
| RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli | ||||
| # Install common PHP extensions | ||||
| RUN docker-php-ext-install mysqli pdo pdo_mysql && docker-php-ext-enable mysqli pdo pdo_mysql | ||||
|  | ||||
| COPY . /var/www/html/ | ||||
| # Enable Apache rewrite module | ||||
| RUN a2enmod rewrite | ||||
|  | ||||
| # Set working directory to Apache web root | ||||
| WORKDIR /var/www/html | ||||
|  | ||||
| COPY . . | ||||
|  | ||||
| # Make sure permissions are set correctly | ||||
| RUN chown -R www-data:www-data /var/www/html | ||||
|  | ||||
| EXPOSE 80 | ||||
|  | ||||
| @@ -187,41 +290,72 @@ package_go_app() { | ||||
|     local app_name=$1 | ||||
|     local app_dir=$2 | ||||
|     local artifact_dir=$3 | ||||
|     local app_url=${4:-"https://github.com/unknown-user/$app_name"}  # Default URL if not provided | ||||
|      | ||||
|     cd "$app_dir" | ||||
|      | ||||
|     # Extract username/repo from the app_url for manifest | ||||
|     local repo_path | ||||
|     if [[ "$app_url" == *"github.com"* ]]; then | ||||
|         repo_path=${app_url#*github.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     elif [[ "$app_url" == *"gitlab.com"* ]]; then | ||||
|         repo_path=${app_url#*gitlab.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     else | ||||
|         repo_path="unknown-user/$app_name" | ||||
|     fi | ||||
|      | ||||
|     # Create Cloudron manifest | ||||
|     cat > app.manifest << EOF | ||||
| { | ||||
|     "id": "com.$(echo "$app_name" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "id": "com.$(echo "$repo_path" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "title": "$app_name", | ||||
|     "version": "1.0.0", | ||||
|     "build": "1", | ||||
|     "description": "Cloudron package for $app_name", | ||||
|     "author": "Auto-generated", | ||||
|     "website": "https://github.com/$app_name", | ||||
|     "website": "$app_url", | ||||
|     "admin": false, | ||||
|     "tags": ["go", "auto-generated"], | ||||
|     "logo": "https://github.com/fluidicon.png", | ||||
|     "documentation": "https://github.com/$app_name", | ||||
|     "documentation": "$app_url", | ||||
|     "changelog": "Initial packaging" | ||||
| } | ||||
| EOF | ||||
|      | ||||
|     # Create Dockerfile for Go | ||||
|     # Try to determine the binary name by looking for main.go and possible build files | ||||
|     local binary_name="myapp" | ||||
|     if [ -f "main.go" ]; then | ||||
|         # Try to extract the package name from main.go | ||||
|         local package_line=$(grep -m 1 "^package " main.go 2>/dev/null | cut -d' ' -f2 | tr -d '\r\n') | ||||
|         if [ -n "$package_line" ] && [ "$package_line" != "main" ]; then | ||||
|             binary_name="$package_line" | ||||
|         else | ||||
|             # Extract binary name from go.mod if available | ||||
|             if [ -f "go.mod" ]; then | ||||
|                 local module_line=$(grep -m 1 "^module " go.mod 2>/dev/null | cut -d' ' -f2) | ||||
|                 if [ -n "$module_line" ]; then | ||||
|                     binary_name=$(basename "$module_line") | ||||
|                 fi | ||||
|             fi | ||||
|         fi | ||||
|     fi | ||||
|      | ||||
|     # Create Dockerfile for Go with appropriate binary name | ||||
|     cat > Dockerfile << EOF | ||||
| FROM golang:1.21-alpine AS builder | ||||
|  | ||||
| WORKDIR /app | ||||
| COPY . . | ||||
| RUN CGO_ENABLED=0 GOOS=linux go build -o myapp . | ||||
| RUN CGO_ENABLED=0 GOOS=linux go build -o $binary_name . | ||||
|  | ||||
| FROM alpine:latest | ||||
| RUN apk --no-cache add ca-certificates | ||||
| WORKDIR /root/ | ||||
| COPY --from=builder /app/myapp . | ||||
| COPY --from=builder /app/$binary_name . | ||||
| EXPOSE 8080 | ||||
| CMD ["./myapp"] | ||||
| CMD ["./$binary_name"] | ||||
| EOF | ||||
|      | ||||
|     # Build Docker image | ||||
| @@ -249,32 +383,42 @@ smoke_test_docker_image() { | ||||
|      | ||||
|     echo "Performing smoke test on $docker_image for $app_name" | ||||
|      | ||||
|     # Validate that docker command exists | ||||
|     if ! command -v docker >/dev/null 2>&1; then | ||||
|         echo "Docker command not found, cannot perform smoke test" | ||||
|         return 1 | ||||
|     fi | ||||
|      | ||||
|     # Run the container briefly to test if it starts correctly | ||||
|     local container_name="smoke-test-${app_name//[^a-zA-Z0-9]/-}-$(date +%s)" | ||||
|      | ||||
|     # Try to run the container and check if it starts without immediate failure | ||||
|     if docker run -d --name "$container_name" --health-cmd="curl -f http://localhost/ || exit 1" --health-interval=5s --health-timeout=3s --health-retries=3 "$docker_image"; then | ||||
|         # Wait a few seconds to see if the container stays running | ||||
|         sleep 10 | ||||
|          | ||||
|         # Check if the container is still running and healthy | ||||
|         if [ "$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)" = "running" ]; then | ||||
|             echo "Smoke test passed for $app_name" | ||||
|             # Stop and remove the test container | ||||
|             docker stop "$container_name" > /dev/null 2>&1 | ||||
|             docker rm "$container_name" > /dev/null 2>&1 | ||||
|             return 0 | ||||
|         else | ||||
|             echo "Container for $app_name did not stay running during smoke test" | ||||
|             # Get logs for debugging | ||||
|             docker logs "$container_name" 2>&1 | head -20 | ||||
|             docker stop "$container_name" > /dev/null 2>&1 | ||||
|             docker rm "$container_name" > /dev/null 2>&1 | ||||
|             return 1 | ||||
|         fi | ||||
|     else | ||||
|     # Run without specific health check initially, just see if container starts and stays running | ||||
|     if ! docker run -d --name "$container_name" "$docker_image" >/dev/null 2>&1; then | ||||
|         echo "Failed to start container for $app_name during smoke test" | ||||
|         docker rm "$container_name" > /dev/null 2>&1 | ||||
|         docker rm "$container_name" >/dev/null 2>&1 || true | ||||
|         return 1 | ||||
|     fi | ||||
|      | ||||
|     # Wait a few seconds to see if the container stays running | ||||
|     sleep 15 | ||||
|      | ||||
|     # Check if the container is still running | ||||
|     local container_status | ||||
|     container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null || echo "not_found") | ||||
|      | ||||
|     if [ "$container_status" = "running" ]; then | ||||
|         echo "Smoke test passed for $app_name - container is running" | ||||
|         # Stop and remove the test container | ||||
|         docker stop "$container_name" >/dev/null 2>&1 || true | ||||
|         docker rm "$container_name" >/dev/null 2>&1 || true | ||||
|         return 0 | ||||
|     else | ||||
|         # Container stopped or crashed, get logs for debugging | ||||
|         echo "Container for $app_name did not stay running during smoke test (status: $container_status)" | ||||
|         echo "Container logs:" | ||||
|         docker logs "$container_name" 2>&1 | head -30 | ||||
|         docker stop "$container_name" >/dev/null 2>&1 || true | ||||
|         docker rm "$container_name" >/dev/null 2>&1 || true | ||||
|         return 1 | ||||
|     fi | ||||
| } | ||||
| @@ -284,26 +428,27 @@ detect_and_package() { | ||||
|     local app_name=$1 | ||||
|     local app_dir=$2 | ||||
|     local artifact_dir=$3 | ||||
|     local app_url=${4:-"https://github.com/unknown-user/$app_name"}  # Default URL if not provided | ||||
|      | ||||
|     cd "$app_dir" | ||||
|      | ||||
|     # Detect application type based on files | ||||
|     if [ -f "package.json" ]; then | ||||
|         echo "Detected Node.js application" | ||||
|         package_nodejs_app "$app_name" "$app_dir" "$artifact_dir" | ||||
|         package_nodejs_app "$app_name" "$app_dir" "$artifact_dir" "$app_url" | ||||
|     elif [ -f "requirements.txt" ] || [ -f "setup.py" ]; then | ||||
|         echo "Detected Python application" | ||||
|         package_python_app "$app_name" "$app_dir" "$artifact_dir" | ||||
|         package_python_app "$app_name" "$app_dir" "$artifact_dir" "$app_url" | ||||
|     elif [ -f "composer.json" ]; then | ||||
|         echo "Detected PHP application" | ||||
|         package_php_app "$app_name" "$app_dir" "$artifact_dir" | ||||
|         package_php_app "$app_name" "$app_dir" "$artifact_dir" "$app_url" | ||||
|     elif [ -f "go.mod" ] || [ -f "*.go" ]; then | ||||
|         echo "Detected Go application" | ||||
|         package_go_app "$app_name" "$app_dir" "$artifact_dir" | ||||
|         package_go_app "$app_name" "$app_dir" "$artifact_dir" "$app_url" | ||||
|     else | ||||
|         # Default generic approach | ||||
|         echo "Application type not detected, using generic approach" | ||||
|         package_generic_app "$app_name" "$app_dir" "$artifact_dir" | ||||
|         package_generic_app "$app_name" "$app_dir" "$artifact_dir" "$app_url" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| @@ -312,41 +457,113 @@ package_generic_app() { | ||||
|     local app_name=$1 | ||||
|     local app_dir=$2 | ||||
|     local artifact_dir=$3 | ||||
|     local app_url=${4:-"https://github.com/unknown-user/$app_name"}  # Default URL if not provided | ||||
|      | ||||
|     cd "$app_dir" | ||||
|      | ||||
|     # Extract username/repo from the app_url for manifest | ||||
|     local repo_path | ||||
|     if [[ "$app_url" == *"github.com"* ]]; then | ||||
|         repo_path=${app_url#*github.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     elif [[ "$app_url" == *"gitlab.com"* ]]; then | ||||
|         repo_path=${app_url#*gitlab.com/} | ||||
|         repo_path=${repo_path%.git} | ||||
|     else | ||||
|         repo_path="unknown-user/$app_name" | ||||
|     fi | ||||
|      | ||||
|     # Create Cloudron manifest | ||||
|     cat > app.manifest << EOF | ||||
| { | ||||
|     "id": "com.$(echo "$app_name" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "id": "com.$(echo "$repo_path" | sed 's/[^a-zA-Z0-9]/./g').cloudron", | ||||
|     "title": "$app_name", | ||||
|     "version": "1.0.0", | ||||
|     "build": "1", | ||||
|     "description": "Cloudron package for $app_name", | ||||
|     "author": "Auto-generated", | ||||
|     "website": "https://github.com/$app_name", | ||||
|     "website": "$app_url", | ||||
|     "admin": false, | ||||
|     "tags": ["generic", "auto-generated"], | ||||
|     "logo": "https://github.com/fluidicon.png", | ||||
|     "documentation": "https://github.com/$app_name", | ||||
|     "documentation": "$app_url", | ||||
|     "changelog": "Initial packaging" | ||||
| } | ||||
| EOF | ||||
|      | ||||
|     # Create a basic Dockerfile | ||||
|     cat > Dockerfile << EOF | ||||
|     # Create a basic Dockerfile that tries to run common application types | ||||
|     cat > Dockerfile << 'DOCKERFILE_EOF' | ||||
| FROM alpine:latest | ||||
|  | ||||
| WORKDIR /app | ||||
|  | ||||
| COPY . . | ||||
|  | ||||
| RUN apk add --no-cache bash curl tar | ||||
| # Install only the most essential tools that might be needed | ||||
| RUN apk add --no-cache bash curl | ||||
|  | ||||
| # Create a multi-line run script file | ||||
| RUN { \ | ||||
|     echo '#!/bin/sh'; \ | ||||
|     echo 'set -e'; \ | ||||
|     echo ''; \ | ||||
|     echo '# Check for and run different application types'; \ | ||||
|     echo 'if [ -f "package.json" ]; then'; \ | ||||
|     echo '    echo "Detected Node.js application"'; \ | ||||
|     echo '    if [ -x "$(command -v node)" ]; then'; \ | ||||
|     echo '        npm install 2>/dev/null || echo "npm install failed"'; \ | ||||
|     echo '        if [ -n "$START_SCRIPT" ]; then'; \ | ||||
|     echo '            exec npm run "$START_SCRIPT" 2>/dev/null || echo "Failed to run START_SCRIPT"'; \ | ||||
|     echo '        else'; \ | ||||
|     echo '            exec npm start 2>/dev/null || echo "Failed to run npm start"'; \ | ||||
|     echo '        fi'; \ | ||||
|     echo '    else'; \ | ||||
|     echo '        echo "node not available, installing... (would require internet access)"'; \ | ||||
|     echo '    fi'; \ | ||||
|     echo 'elif [ -f "requirements.txt" ]; then'; \ | ||||
|     echo '    echo "Detected Python application"'; \ | ||||
|     echo '    if [ -x "$(command -v python3)" ]; then'; \ | ||||
|     echo '        pip3 install -r requirements.txt 2>/dev/null || echo "pip install failed"'; \ | ||||
|     echo '        if [ -f "app.py" ]; then'; \ | ||||
|     echo '            exec python3 app.py 2>/dev/null || while true; do sleep 30; done'; \ | ||||
|     echo '        elif [ -f "main.py" ]; then'; \ | ||||
|     echo '            exec python3 main.py 2>/dev/null || while true; do sleep 30; done'; \ | ||||
|     echo '        else'; \ | ||||
|     echo '            echo "No standard Python entry point found (app.py or main.py)"'; \ | ||||
|     echo '            while true; do sleep 30; done'; \ | ||||
|     echo '        fi'; \ | ||||
|     echo '    else'; \ | ||||
|     echo '        echo "python3 not available, installing... (would require internet access)"'; \ | ||||
|     echo '    fi'; \ | ||||
|     echo 'elif [ -f "go.mod" ] || [ -f "main.go" ]; then'; \ | ||||
|     echo '    echo "Detected Go application"'; \ | ||||
|     echo '    if [ -x "$(command -v go)" ]; then'; \ | ||||
|     echo '        go build -o myapp . 2>/dev/null || echo "Go build failed"'; \ | ||||
|     echo '        [ -f "./myapp" ] && exec ./myapp || while true; do sleep 30; done'; \ | ||||
|     echo '    else'; \ | ||||
|     echo '        echo "go not available, installing... (would require internet access)"'; \ | ||||
|     echo '    fi'; \ | ||||
|     echo 'elif [ -f "start.sh" ]; then'; \ | ||||
|     echo '    echo "Found start.sh script"'; \ | ||||
|     echo '    chmod +x start.sh'; \ | ||||
|     echo '    exec ./start.sh'; \ | ||||
|     echo 'elif [ -f "run.sh" ]; then'; \ | ||||
|     echo '    echo "Found run.sh script"'; \ | ||||
|     echo '    chmod +x run.sh'; \ | ||||
|     echo '    exec ./run.sh'; \ | ||||
|     echo 'else'; \ | ||||
|     echo '    echo "No recognized application type found"'; \ | ||||
|     echo '    echo "Application directory contents:"'; \ | ||||
|     echo '    ls -la'; \ | ||||
|     echo '    # Keep container running for inspection'; \ | ||||
|     echo '    while true; do sleep 30; done'; \ | ||||
|     echo 'fi'; \ | ||||
|     } > /run-app.sh && chmod +x /run-app.sh | ||||
|  | ||||
| EXPOSE 8080 | ||||
|  | ||||
| CMD ["sh", "-c", "while true; do sleep 30; done"] | ||||
| EOF | ||||
| CMD ["/run-app.sh"] | ||||
| DOCKERFILE_EOF | ||||
|      | ||||
|     # Build Docker image | ||||
|     local docker_image="tsysdevstack-cloudron-buildtest-${app_name//[^a-zA-Z0-9]/-}:latest" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user