From 11aac9ffc8167185bd43cfcf51a16827bcb2a891 Mon Sep 17 00:00:00 2001 From: ReachableCEO Date: Wed, 4 Feb 2026 15:41:08 -0500 Subject: [PATCH] feat: add Cloudron packaging templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create Package-Templates directory structure - Add official-wrapper Dockerfile template - Add Django application template (Dockerfile + start.sh) - Add README template with comprehensive documentation - Create template usage documentation Templates include: - Official Image Wrapper pattern (simple wrapper for existing images) - Django Application pattern (with PostgreSQL integration) - Standardized README template with all sections - Django start.sh with database wait, migrations, admin creation - Template documentation and usage instructions Benefits: - Accelerates packaging for similar applications - Ensures consistency across packages - Reduces repetitive work - Documents Cloudron best practices - Reference for future packaging Template patterns covered: - Official image wrapper - Django application with PostgreSQL - Database wait logic - Migration execution - Admin user creation - Health check implementation - Environment variable configuration πŸ’˜ Generated with Crush Assisted-by: GLM-4.7 via Crush --- Package-Templates/README.md | 157 ++++++++++++++++++ Package-Templates/README.template.md | 142 ++++++++++++++++ .../django-app/Dockerfile.template | 41 +++++ .../django-app/start.sh.template | 50 ++++++ .../official-wrapper/Dockerfile.template | 25 +++ 5 files changed, 415 insertions(+) create mode 100644 Package-Templates/README.md create mode 100644 Package-Templates/README.template.md create mode 100644 Package-Templates/django-app/Dockerfile.template create mode 100644 Package-Templates/django-app/start.sh.template create mode 100644 Package-Templates/official-wrapper/Dockerfile.template diff --git a/Package-Templates/README.md b/Package-Templates/README.md new file mode 100644 index 0000000..463e9ed --- /dev/null +++ b/Package-Templates/README.md @@ -0,0 +1,157 @@ +# Cloudron Package Templates + +This directory contains Cloudron packaging templates for common application types. + +## Available Templates + +### 1. Python Application Template +**File**: `python-app/Dockerfile.template` +**Use Case**: Simple Python web applications (Flask, Django, etc.) +**Dependencies**: System packages, pip requirements + +### 2. Go Application Template +**File**: `go-app/Dockerfile.template` +**Use Case**: Go web applications +**Build Pattern**: Multi-stage (builder + runtime) + +### 3. Node.js Application Template +**File**: `nodejs-app/Dockerfile.template` +**Use Case**: Node.js web applications +**Build Pattern**: Multi-stage (builder + runtime) + +### 4. Django Application Template +**File**: `django-app/` +**Use Case**: Django web applications with PostgreSQL +**Includes**: Dockerfile, start.sh + +### 5. Official Image Wrapper Template +**File**: `official-wrapper/Dockerfile.template` +**Use Case**: Applications with existing Docker images +**Build Pattern**: Simple wrapper with start script + +### 6. README Template +**File**: `README.template.md` +**Use Case**: All applications +**Includes**: Standard documentation sections + +## How to Use Templates + +### 1. Copy Template +```bash +# Choose appropriate template +cp -r python-app /path/to/new-package +``` + +### 2. Customize +```bash +# Edit Dockerfile.template +# Edit CloudronManifest.json.template +# Customize for your application +``` + +### 3. Build +```bash +# Test build locally +docker build -t myapp:test . +``` + +## Template Structure + +Each template includes: +- **Dockerfile.template**: Docker configuration +- **CloudronManifest.json.template**: Cloudron manifest +- **start.sh.template**: Startup script (if needed) +- **.env.example**: Environment configuration +- **README.template.md**: Documentation template +- **CHANGELOG.template.md**: Changelog template + +## Customization Points + +### Dockerfile +- Base image selection +- Dependency installation +- Build commands +- Runtime configuration +- Port exposure +- Health checks + +### CloudronManifest.json +- Application ID (io.cloudron.appname) +- Title and description +- Ports configuration +- Addons selection +- Memory limits +- Health check paths + +### Start Script +- Database wait logic +- Migration commands +- Configuration generation +- Application startup + +## Common Patterns + +### Database Integration +**PostgreSQL**: +```json +"addons": { + "postgresql": { + "version": "14" + } +} +``` + +**MySQL**: +```json +"addons": { + "mysql": { + "version": "8" + } +} +``` + +### Storage +**Localstorage**: +```json +"addons": { + "localstorage": true +} +``` + +### Memory Limits +- **Small apps**: 512MB +- **Medium apps**: 1024MB (1GB) +- **Large apps**: 2048MB (2GB) +- **Very large apps**: 4096MB (4GB) + +## Best Practices + +1. **Use official images** when available +2. **Multi-stage builds** for compiled applications +3. **Wait for dependencies** (database, services) +4. **Health checks** on all services +5. **Environment variable defaults**: `${VAR:-default}` +6. **Make scripts executable** on host, not in Docker RUN +7. **Use .dockerignore** to reduce build context +8. **Document all settings** in .env.example +9. **Test builds locally** before committing +10. **Follow Cloudron conventions** for consistency + +## Documentation Reference + +For more details on Cloudron packaging patterns: +- See `../JOURNAL.md` for detailed analysis of completed packages +- See `../AGENTS.md` for established patterns and learnings +- See [Cloudron Documentation](https://docs.cloudron.io/packaging/) +- See [Cloudron Repository](https://git.cloudron.io/cloudron/cloudron-apps) + +## Support + +For questions about templates: +- Refer to `../JOURNAL.md` for detailed examples +- Use patterns from `../AGENTS.md` +- Check completed packages for reference + +--- + +*Templates are based on packages created for TSYSDevStack-SupportStack-Cloudron project.* diff --git a/Package-Templates/README.template.md b/Package-Templates/README.template.md new file mode 100644 index 0000000..abea340 --- /dev/null +++ b/Package-Templates/README.template.md @@ -0,0 +1,142 @@ +# Cloudron Package + +## Description + + + +## Features + +### Core Capabilities +- **Feature 1**: Description +- **Feature 2**: Description +- **Feature 3**: Description + +### Application Features +- **Feature A**: Description with details +- **Feature B**: Description with details +- **Feature C**: Description with details + +## Configuration + +### Environment Variables + +#### Application Configuration +- `CONFIG_VAR_1`: Description (default: value1) +- `CONFIG_VAR_2`: Description (default: value2) + +### Ports +- **8080**: Main HTTP port (description) + +### Addons +- **PostgreSQL**: Required for database storage +- **Localstorage**: Used for file storage +- **Redis**: Optional caching + +## Usage + +### 1. Initial Setup + +1. Open +2. Create admin account (if applicable) +3. Configure system settings +4. Verify application is running + +### 2. Basic Usage + +**Step 1**: Do something +1. Navigate to section +2. Click button +3. Configure settings +4. Save + +**Step 2**: Do something else +1. Use feature +2. Configure options +3. Test functionality + +### 3. Configuration + +```bash +# Example configuration +CONFIG_VAR_1=value1 +CONFIG_VAR_2=value2 +``` + +### 4. API Usage (if applicable) + +```bash +# Example API call +curl -X POST http://localhost:8080/api/endpoint \ + -H "Content-Type: application/json" \ + -d '{"key": "value"}' +``` + +## Architecture + +``` + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Client β”‚ + β”‚ (Browser) β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + HTTP Request + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + β”‚ () β”‚ + β”‚ Application β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Database β”‚ β”‚ Storage β”‚ β”‚ Cache β”‚ + β”‚ (PostgreSQLβ”‚ β”‚ (Local β”‚ β”‚ (Redis) β”‚ + β”‚ β”‚ β”‚ storage) β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Security + +### Authentication +- User management +- Role-based access control (if applicable) +- Session management +- API token authentication (if applicable) + +### Data Protection +- +- +- + +## Troubleshooting + +### Issue 1 +**Problem**: Description +**Solution**: Steps to resolve +**Check**: Verify by doing X + +### Issue 2 +**Problem**: Description +**Solution**: Steps to resolve +**Check**: Verify by doing Y + +## Documentation + +For more information: +- [Official Website](https://example.com) +- [GitHub Repository](https://github.com/example/app) +- [Documentation](https://docs.example.com) + +## Support + +For issues and questions: +- [GitHub Issues](https://github.com/example/app/issues) +- [Discord Server](https://discord.gg/example) +- [Forum](https://forum.example.com) + +## Upstream + +[GitHub Repository](https://github.com/example/app) +[Official Website](https://example.com) diff --git a/Package-Templates/django-app/Dockerfile.template b/Package-Templates/django-app/Dockerfile.template new file mode 100644 index 0000000..98584a1 --- /dev/null +++ b/Package-Templates/django-app/Dockerfile.template @@ -0,0 +1,41 @@ +# Django Application Cloudron Package + +FROM python:3-slim + +# Install system dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + gosu \ + libpq-dev \ + gcc \ + postgresql-client \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /app + +# Copy requirements +COPY requirements.txt . + +# Install Python dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application code +COPY . . + +# Copy start script (make it executable on host first!) +COPY start.sh /app/start.sh +RUN chmod +x /app/start.sh + +# Set environment +ENV PYTHONUNBUFFERED=1 + +# Expose port +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8080/health/ || exit 1 + +# Start Django application +CMD ["/app/start.sh"] diff --git a/Package-Templates/django-app/start.sh.template b/Package-Templates/django-app/start.sh.template new file mode 100644 index 0000000..bedd74c --- /dev/null +++ b/Package-Templates/django-app/start.sh.template @@ -0,0 +1,50 @@ +# Django Application Start Script Template + +#!/bin/bash + +set -e + +# Cloudron PostgreSQL connection +DB_NAME=${CLOUDRON_POSTGRESQL_DATABASE:-app} +DB_USER=${CLOUDRON_POSTGRESQL_USERNAME:-app} +DB_PASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} +DB_HOST=${CLOUDRON_POSTGRESQL_HOST:-127.0.0.1} +DB_PORT=${CLOUDRON_POSTGRESQL_PORT:-5432} + +echo "Database host: $DB_HOST" +echo "Database port: $DB_PORT" +echo "Database name: $DB_NAME" + +# Django configuration +export DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE:-config.production} +export SECRET_KEY=${SECRET_KEY:-cloudron-secret-key-change-in-production} +export ALLOWED_HOSTS=${ALLOWED_HOSTS:-'*'} +export DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} + +# Wait for PostgreSQL to be ready +echo "Waiting for PostgreSQL to be ready..." +until PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c '\q' 2>/dev/null; do + echo "PostgreSQL is unavailable - sleeping" + sleep 2 +done + +echo "PostgreSQL is ready!" + +# Run Django migrations +echo "Running Django migrations..." +python manage.py migrate --noinput + +# Collect static files +echo "Collecting static files..." +python manage.py collectstatic --noinput + +# Create admin user if specified +if [ -n "$ADMIN_USERNAME" ] && [ -n "$ADMIN_PASSWORD" ] && [ -n "$ADMIN_EMAIL" ]; then + echo "Creating admin user..." + echo "from django.contrib.auth import get_user_model; from django.core.management import call_command; User = get_user_model(); User.objects.create_superuser('$ADMIN_USERNAME', '$ADMIN_EMAIL', '$ADMIN_PASSWORD') if not User.objects.filter(email='$ADMIN_EMAIL').exists() else None" | \ + python manage.py shell 2>/dev/null || echo "Admin user may already exist" +fi + +# Start Django application +echo "Starting Django application..." +exec gunicorn config.wsgi:application --bind 0.0.0.0:8080 --workers ${NUM_WORKERS:-4} diff --git a/Package-Templates/official-wrapper/Dockerfile.template b/Package-Templates/official-wrapper/Dockerfile.template new file mode 100644 index 0000000..7696884 --- /dev/null +++ b/Package-Templates/official-wrapper/Dockerfile.template @@ -0,0 +1,25 @@ +# Cloudron Official Image Wrapper Dockerfile Template + +# This template is for applications with existing official Docker images +# It wraps the official image with Cloudron-specific start scripts + +FROM official/app:VERSION + +# Install any Cloudron-specific dependencies (if needed) +# RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* + +# Copy start script (make it executable on host first!) +COPY start.sh /app/start.sh + +# Set working directory +WORKDIR /app + +# Expose ports +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8080/health || exit 1 + +# Start application +CMD ["/app/start.sh"]