diff --git a/CLOUDRON_PACKAGING_SHORTLIST.md b/CLOUDRON_PACKAGING_SHORTLIST.md deleted file mode 100644 index e17c069..0000000 --- a/CLOUDRON_PACKAGING_SHORTLIST.md +++ /dev/null @@ -1,113 +0,0 @@ -# Cloudron Packaging Shortlist - -**Target**: Package 56 free/libre/open-source applications as Cloudron apps - -## Packaging Priority Order - -### Phase 1: Infrastructure & DevOps Tools (High Priority) -1. **Jenkins** - CI/CD Platform (Issue #234) -2. **Apache APISIX** - API Gateway (Issue #179) -3. **Rundeck** - Job Scheduler (Issue #217) -4. **Healthchecks** - Health Monitoring (Issue #192) -5. **Fleet** - Device Management (Issue #195) -6. **NetBox** - Network Documentation (Issue #201) -7. **SigNoz** - Observability Platform (Issue #221) - -### Phase 2: Development & Productivity (High Priority) -8. **Grist** - Database/Spreadsheet (Issue #191) -9. **ReviewBoard** - Code Review (Issue #216) -10. **Huginn** - Web Automation (Issue #194) -11. **Windmill** - Workflow Automation (Issue #285) -12. **DocAssemble** - Document Assembly (Issue #277) -13. **WireFlow** - Flowchart Designer (Issue #50) -14. **Draw.io** - Diagram Editor (Issue #272) - -### Phase 3: Business & Management (Medium Priority) -15. **InvenTree** - Inventory Management (Issue #173) -16. **OpenBoxes** - Supply Chain Management (Issue #205) -17. **Payroll Engine** - Payroll Management (Issue #208) -18. **Consul Democracy** - Democratic Platform (Issue #189) -19. **Fonoster** - Communications Platform (Issue #227) -20. **Craig** - Chat Platform (Issue #185) -21. **KillBill** - Billing Platform (Issue #181) - -### Phase 4: Specialized Applications (Medium Priority) -22. **ELabFTW** - Laboratory Management (Issue #188) -23. **Jamovi** - Statistical Analysis (Issue #196) -24. **KiBot** - PCB Documentation (Issue #197) -25. **Resgrid** - Emergency Management (Issue #214) -26. **SatNOGS** - Satellite Network (Issue #218) -27. **SDR Angel** - Software Defined Radio (Issue #219) -28. **Warp** - Terminal (Issue #228) - -### Phase 5: Advanced Tools (Lower Priority) -29. **GoAlert** - On-call Management (Issue #204) -30. **Hyperswitch** - Payment Processing (Issue #209) -31. **OpenFile** - Tax Filing (Issue #316) -32. **SniperPhish** - Security Training (Issue #211) -33. **DataHub** - Data Catalog (Issue #309) -34. **Easy Gate** - Access Control (Issue #54) -35. **Rathole** - Reverse Proxy (Issue #225) ✅ **COMPLETED** - -### Phase 6: Infrastructure & Advanced (Lower Priority) -36. **SLURM** - Job Scheduler (Issue #222) -37. **TAK Server** - Military Communications (Issue #180) -38. **Midday** - AI Assistant (Issue #178) -39. **ChirpStack** - LoRaWAN (Issue #184) -40. **Mirlo** - Music Streaming (TBD) -41. **Nautilus Trader** - Trading Platform (Issue #226) -42. **RunMe** - Code Execution (Issue #322) - -### Phase 7: Development & Research (Lower Priority) -43. **Seatunnel** - Data Processing (Issue #301) -44. **Docker Webhook** - Webhook Handler (Issue #271) -45. **Database Gateway** - Database Proxy (Issue #273) -46. **OpenBlocks** - Low-code Platform (Issue #274) -47. **WireViz** - Cable Documentation (Issue #276) -48. **AutoBOM** - Bill of Materials (Issue #278) -49. **PLMore** - Project Management (Issue #279) - -### Phase 8: Specialized & Research (Lowest Priority) -50. **Manyfold** - 3D Modeling (Issue #282) -51. **Langfuse** - LLM Operations (Issue #283) -52. **Puter** - Cloud Desktop (Issue #286) -53. **SWUpdate** - Software Updates (Issue #326) -54. **Mender** - Device Management (Issue #300) -55. **Vanila Wireflow** - Flowchart (Issue #50) - -## Packaging Strategy - -### Container-Only Workflow -- All packaging work happens inside `KNELCloudron-packaging` container -- Use `scripts/packaging-exec.sh` for all build/test commands -- Follow validation checklist before committing - -### Validation Requirements -- ✅ Build succeeds: `docker build -t :dev CloudronPackages/` -- ✅ Health check passes: container starts and responds to health endpoint -- ✅ Manifest validation: correct `id`, `version`, `httpPort`, `healthCheckPath` -- ✅ No secrets/credentials in code -- ✅ Proper `/app/data` ownership - -### Commit Strategy -- Small, focused commits per application -- Use conventional commit format: `feat(): initial Cloudron package` -- Batch pushes at natural milestones (5-10 apps per push) -- Never push unvalidated builds - -## Estimated Timeline -- **Phase 1-2**: 2-3 weeks (14 apps) -- **Phase 3-4**: 3-4 weeks (14 apps) -- **Phase 5-6**: 2-3 weeks (14 apps) -- **Phase 7-8**: 2-3 weeks (14 apps) -- **Total**: ~10-13 weeks for all 56 applications - -## Notes -- Rathole is already completed and serves as reference implementation -- Each app will be packaged using `scripts/new-package.sh` scaffold -- Upstream sources available in `PackagingForCloudronWorkspace/Docker/` -- All work follows single-branch `main` workflow - ---- -**Created**: 2025-01-04 -**Maintainers**: KNEL/TSYS Development Team diff --git a/CloudronPackages/APISIX/CloudronManifest.json b/CloudronPackages/APISIX/CloudronManifest.json index 0f888bb..ca3b594 100644 --- a/CloudronPackages/APISIX/CloudronManifest.json +++ b/CloudronPackages/APISIX/CloudronManifest.json @@ -3,17 +3,17 @@ "id": "io.knel.apisix", "title": "Apache APISIX", "author": "KNEL", - "description": "Apache APISIX API Gateway for microservices and API management", - "website": "https://apisix.apache.org", - "contactEmail": "admin@knownelement.com", - "version": "3.8.0", - "changelog": "Initial Cloudron package for Apache APISIX API Gateway", - "healthCheckPath": "/apisix/admin/routes", + "description": "Cloudron packaging template for Apache APISIX", + "website": "https://example.com", + "contactEmail": "admin@example.com", + "version": "0.1.0", + "changelog": "Initial package template", + "healthCheckPath": "/", "httpPort": 9180, "addons": { "localstorage": {} }, - "tags": ["api", "gateway", "microservices", "proxy"], + "tags": ["template", "example"], "icon": "logo.png" } diff --git a/CloudronPackages/APISIX/Dockerfile b/CloudronPackages/APISIX/Dockerfile index a804166..5bec9bd 100644 --- a/CloudronPackages/APISIX/Dockerfile +++ b/CloudronPackages/APISIX/Dockerfile @@ -1,44 +1,38 @@ -FROM apache/apisix:3.8.0-debian +FROM cloudron/base:5.0.0 -# Metadata labels +# Metadata labels (edit as needed) LABEL org.opencontainers.image.title="Apache APISIX" -LABEL org.opencontainers.image.description="Cloudron package for Apache APISIX API Gateway" -LABEL org.opencontainers.image.source="https://github.com/apache/apisix" +LABEL org.opencontainers.image.description="Cloudron package for Apache APISIX" +LABEL org.opencontainers.image.source="https://example.com" -# Switch to root to modify the image -USER root +# Install OS dependencies here as needed +# RUN apt-get update && apt-get install -y --no-install-recommends \ +# curl ca-certificates tini \ +# && rm -rf /var/lib/apt/lists/* -# Install additional dependencies if needed -RUN apt-get update && apt-get install -y --no-install-recommends \ - curl \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* +# App code lives in /app/code (read-only at runtime) +WORKDIR /app/code -# Create cloudron user -RUN useradd -r -s /bin/bash -d /app -m cloudron +# Copy application code (adjust as needed) +# COPY . /app/code -# Create APISIX data directories -RUN mkdir -p /app/data/apisix && \ - mkdir -p /app/data/apisix/logs && \ - mkdir -p /app/data/apisix/conf && \ - chown -R cloudron:cloudron /app/data +# Create persistent directory for application data +RUN mkdir -p /app/data && chown -R cloudron:cloudron /app/data # Copy startup script COPY start.sh /app/pkg/start.sh RUN chmod +x /app/pkg/start.sh && chown cloudron:cloudron /app/pkg/start.sh -# Switch to cloudron user USER cloudron -# Expose APISIX ports -EXPOSE 9180 9080 +# Expose the app port specified in manifest +EXPOSE 9180 -# APISIX environment variables -ENV APISIX_HOME=/app/data/apisix \ - APISIX_WORKDIR=/app/data/apisix \ +# Default environment (customize per app) +ENV NODE_ENV=production \ APP_PORT=9180 -HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ - CMD curl -fsS http://127.0.0.1:${APP_PORT}/apisix/admin/routes || exit 1 +HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ + CMD curl -fsS http://127.0.0.1:${APP_PORT}/ || exit 1 CMD ["/app/pkg/start.sh"] diff --git a/CloudronPackages/APISIX/start.sh b/CloudronPackages/APISIX/start.sh index 9e3a78a..90663f0 100644 --- a/CloudronPackages/APISIX/start.sh +++ b/CloudronPackages/APISIX/start.sh @@ -9,15 +9,31 @@ abort() { echo "[start] ERROR: $*" >&2; exit 1; } log "Starting Apache APISIX on port ${APP_PORT}" -# Ensure APISIX data directory exists -mkdir -p /app/data/apisix +# Example: ensure /app/data exists and is writable +mkdir -p /app/data chown -R cloudron:cloudron /app/data || true -# Set APISIX environment -export APISIX_HOME=/app/data/apisix -export APISIX_WORKDIR=/app/data/apisix +# Example addon integration (uncomment and adapt as needed) +# if [[ -n "${CLOUDRON_POSTGRESQL_URL:-}" ]]; then +# log "Detected PostgreSQL addon" +# # Use $CLOUDRON_POSTGRESQL_* env vars +# fi -# Start APISIX using the official entrypoint -log "Starting APISIX API Gateway" -exec /docker-entrypoint.sh docker-start +# if [[ -n "${CLOUDRON_REDIS_URL:-}" ]]; then +# log "Detected Redis addon" +# fi + +# If your app needs config generation, do it here +# cat > /app/data/config.yaml <<'YAML' +# key: value +# YAML + +# Example: start a simple HTTP server (placeholder) +# Replace with your actual app start command +if command -v python3 >/dev/null 2>&1; then + log "Launching placeholder server: python3 -m http.server ${APP_PORT}" + exec python3 -m http.server "${APP_PORT}" --bind 0.0.0.0 +else + abort "No application command configured. Replace placeholder with your app's start command." +fi diff --git a/CloudronPackages/Jenkins/CloudronManifest.json b/CloudronPackages/Jenkins/CloudronManifest.json index f4153d3..1f1eff0 100644 --- a/CloudronPackages/Jenkins/CloudronManifest.json +++ b/CloudronPackages/Jenkins/CloudronManifest.json @@ -3,17 +3,17 @@ "id": "io.knel.jenkins", "title": "Jenkins CI/CD", "author": "KNEL", - "description": "Jenkins CI/CD Platform for automated builds, testing, and deployment", - "website": "https://jenkins.io", - "contactEmail": "admin@knownelement.com", - "version": "2.450.0", - "changelog": "Initial Cloudron package for Jenkins CI/CD Platform", - "healthCheckPath": "/login", + "description": "Cloudron packaging template for Jenkins CI/CD", + "website": "https://example.com", + "contactEmail": "admin@example.com", + "version": "0.1.0", + "changelog": "Initial package template", + "healthCheckPath": "/", "httpPort": 8080, "addons": { "localstorage": {} }, - "tags": ["ci", "cd", "automation", "build", "deployment"], + "tags": ["template", "example"], "icon": "logo.png" } diff --git a/CloudronPackages/Jenkins/Dockerfile b/CloudronPackages/Jenkins/Dockerfile index 6710b58..95e19cd 100644 --- a/CloudronPackages/Jenkins/Dockerfile +++ b/CloudronPackages/Jenkins/Dockerfile @@ -5,7 +5,7 @@ LABEL org.opencontainers.image.title="Jenkins CI/CD" LABEL org.opencontainers.image.description="Cloudron package for Jenkins CI/CD Platform" LABEL org.opencontainers.image.source="https://github.com/jenkinsci/jenkins" -# Install Java and Jenkins dependencies +# Install Java and dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ openjdk-17-jdk \ curl \ @@ -23,7 +23,7 @@ RUN mkdir -p /app/data/jenkins_home && \ mkdir -p /app/pkg && \ chown -R cloudron:cloudron /app/data -# Download and install Jenkins WAR file +# Download Jenkins WAR file ARG JENKINS_VERSION=2.450 RUN cd /tmp && \ curl -fsSL "https://get.jenkins.io/war/${JENKINS_VERSION}/jenkins.war" -o jenkins.war && \ @@ -34,19 +34,25 @@ RUN cd /tmp && \ COPY start.sh /app/pkg/start.sh COPY CloudronManifest.json /app/pkg/CloudronManifest.json COPY CloudronManifest.json /CloudronManifest.json -RUN chmod +x /app/pkg/start.sh && chown cloudron:cloudron /app/pkg/start.sh /app/pkg/CloudronManifest.json /CloudronManifest.json +# Set permissions +RUN chmod +x /app/pkg/start.sh && \ + chown cloudron:cloudron /app/pkg/start.sh /app/pkg/CloudronManifest.json /CloudronManifest.json + +# Switch to cloudron user USER cloudron -# Expose Jenkins port +# Expose port EXPOSE 8080 -# Jenkins environment variables +# Set environment variables ENV JENKINS_HOME=/app/data/jenkins_home \ JENKINS_OPTS="--httpPort=8080 --httpListenAddress=0.0.0.0" \ APP_PORT=8080 +# Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ - CMD curl -fsS http://127.0.0.1:${APP_PORT}/login || exit 1 + CMD curl -fsS http://127.0.0.1:${APP_PORT}/login || exit 1 -CMD ["/app/pkg/start.sh"] +# Start Jenkins +CMD ["/app/pkg/start.sh"] \ No newline at end of file diff --git a/CloudronPackages/Jenkins/start.sh b/CloudronPackages/Jenkins/start.sh index 7299cf3..71d3621 100644 --- a/CloudronPackages/Jenkins/start.sh +++ b/CloudronPackages/Jenkins/start.sh @@ -15,100 +15,8 @@ mkdir -p "${JENKINS_HOME}" chown -R cloudron:cloudron /app/data || true # Set Jenkins environment variables -export JENKINS_HOME="${JENKINS_HOME}" +export JENKINS_HOME export JENKINS_OPTS="--httpPort=${APP_PORT} --httpListenAddress=0.0.0.0" -# Configure Jenkins for Cloudron with OIDC support -log "Configuring Jenkins for Cloudron environment with OIDC authentication" - -# Create basic Jenkins configuration if not exists -if [[ ! -f "${JENKINS_HOME}/config.xml" ]]; then - log "Creating initial Jenkins configuration with OIDC support" - mkdir -p "${JENKINS_HOME}" - - # Create OIDC configuration if environment variables are provided - if [[ -n "${CLOUDRON_OIDC_ISSUER_URL:-}" && -n "${CLOUDRON_OIDC_CLIENT_ID:-}" ]]; then - log "Configuring OIDC authentication for Jenkins" - mkdir -p "${JENKINS_HOME}/org.jenkinsci.plugins.openid_connect" - - # Create OIDC security realm configuration - cat > "${JENKINS_HOME}/org.jenkinsci.plugins.openid_connect.OpenIdConnectSecurityRealm.xml" <<'OIDC_XML' - - - ${CLOUDRON_OIDC_ISSUER_URL} - ${CLOUDRON_OIDC_CLIENT_ID} - ${CLOUDRON_OIDC_CLIENT_SECRET} - openid,email,profile - preferred_username - name - email - false - true - ${CLOUDRON_OIDC_REDIRECT_URI} - false - admin - jenkins-escape-hatch - admin - false - - 20 - 10 - - - - - - - -OIDC_XML - fi - - # Create basic config.xml for Jenkins - cat > "${JENKINS_HOME}/config.xml" <<'XML' - - - 2.450 - 2 - NORMAL - true - - - true - - false - - ${JENKINS_HOME}/workspace/${ITEM_FULLNAME} - ${JENKINS_HOME}/builds/${ITEM_FULLNAME} - - - - - - - - - - - all - false - false - - - - all - 50000 - - JNLP-connect - JNLP2-connect - - - - - -XML -fi - -# Start Jenkins log "Starting Jenkins WAR file" -exec java -jar /app/pkg/jenkins.war ${JENKINS_OPTS} - +exec java -jar /app/pkg/jenkins.war \ No newline at end of file diff --git a/CloudronPackages/Rathole/Dockerfile b/CloudronPackages/Rathole/Dockerfile index 71d0d4c..531c770 100644 --- a/CloudronPackages/Rathole/Dockerfile +++ b/CloudronPackages/Rathole/Dockerfile @@ -5,20 +5,21 @@ ARG ARCH=x86_64-unknown-linux-gnu USER root RUN apt-get update \ - && apt-get install -y --no-install-recommends curl ca-certificates unzip python3 \ + && apt-get install -y --no-install-recommends curl ca-certificates tar python3 \ && rm -rf /var/lib/apt/lists/* WORKDIR /app/pkg # Download Rathole release binary (adjust version/arch via build args) RUN set -eux; \ - url="https://github.com/rathole-org/rathole/releases/download/${RATHOLE_VERSION}/rathole-${ARCH}.zip"; \ + url="https://github.com/rathole-org/rathole/releases/download/${RATHOLE_VERSION}/rathole-${ARCH}.tar.gz"; \ echo "Fetching ${url}"; \ - curl -fsSL "$url" -o rathole.zip; \ - unzip rathole.zip; \ - rm rathole.zip; \ - chmod +x rathole; \ - chown cloudron:cloudron rathole + curl -fsSL "$url" -o rathole.tar.gz; \ + tar -xzf rathole.tar.gz; \ + rm rathole.tar.gz; \ + mv rathole /app/pkg/rathole; \ + chmod +x /app/pkg/rathole; \ + chown cloudron:cloudron /app/pkg/rathole # Start script COPY start.sh /app/pkg/start.sh diff --git a/CloudronPackages/Rundeck/.dockerignore b/CloudronPackages/Rundeck/.dockerignore new file mode 100644 index 0000000..090ba8b --- /dev/null +++ b/CloudronPackages/Rundeck/.dockerignore @@ -0,0 +1,11 @@ +# Ignore typical build context clutter +.git +.gitignore +node_modules +npm-debug.log +*.log +dist +build +Dockerfile.* +.DS_Store + diff --git a/CloudronPackages/Rundeck/CloudronManifest.json b/CloudronPackages/Rundeck/CloudronManifest.json new file mode 100644 index 0000000..a96fdc7 --- /dev/null +++ b/CloudronPackages/Rundeck/CloudronManifest.json @@ -0,0 +1,19 @@ +{ + "manifestVersion": 2, + "id": "io.knel.rundeck", + "title": "Rundeck Job Scheduler", + "author": "KNEL", + "description": "Cloudron packaging template for Rundeck Job Scheduler", + "website": "https://example.com", + "contactEmail": "admin@example.com", + "version": "0.1.0", + "changelog": "Initial package template", + "healthCheckPath": "/", + "httpPort": 4440, + "addons": { + "localstorage": {} + }, + "tags": ["template", "example"], + "icon": "logo.png" +} + diff --git a/CloudronPackages/Rundeck/Dockerfile b/CloudronPackages/Rundeck/Dockerfile new file mode 100644 index 0000000..fe198b0 --- /dev/null +++ b/CloudronPackages/Rundeck/Dockerfile @@ -0,0 +1,38 @@ +FROM cloudron/base:5.0.0 + +# Metadata labels (edit as needed) +LABEL org.opencontainers.image.title="Rundeck Job Scheduler" +LABEL org.opencontainers.image.description="Cloudron package for Rundeck Job Scheduler" +LABEL org.opencontainers.image.source="https://example.com" + +# Install OS dependencies here as needed +# RUN apt-get update && apt-get install -y --no-install-recommends \ +# curl ca-certificates tini \ +# && rm -rf /var/lib/apt/lists/* + +# App code lives in /app/code (read-only at runtime) +WORKDIR /app/code + +# Copy application code (adjust as needed) +# COPY . /app/code + +# Create persistent directory for application data +RUN mkdir -p /app/data && chown -R cloudron:cloudron /app/data + +# Copy startup script +COPY start.sh /app/pkg/start.sh +RUN chmod +x /app/pkg/start.sh && chown cloudron:cloudron /app/pkg/start.sh + +USER cloudron + +# Expose the app port specified in manifest +EXPOSE 4440 + +# Default environment (customize per app) +ENV NODE_ENV=production \ + APP_PORT=4440 + +HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ + CMD curl -fsS http://127.0.0.1:${APP_PORT}/ || exit 1 + +CMD ["/app/pkg/start.sh"] diff --git a/CloudronPackages/Rundeck/README.md b/CloudronPackages/Rundeck/README.md new file mode 100644 index 0000000..c217401 --- /dev/null +++ b/CloudronPackages/Rundeck/README.md @@ -0,0 +1,33 @@ +# Package Template for Cloudron Apps + +This is a minimal template to package an application for Cloudron. + +## Docker Artifact Naming Convention + +All KNEL Cloudron packages follow the `KNELCloudron-` prefix convention: +- **Development Images**: `:dev` (built locally for testing) +- **Production Images**: `:latest` (final packaged versions) +- **Container Names**: Use descriptive names like `-dev` for development containers + +## Template Usage + +Replace placeholders in files with your app specifics: +- `io.knel.rundeck` (e.g., com.example.myapp) +- `Rundeck Job Scheduler` (human name) +- `4440` (default internal app port) +- `5.0.0` (Cloudron base image tag, e.g., 5.0.0) + +Files +- `CloudronManifest.json` – base manifest +- `Dockerfile` – uses cloudron/base, non-root user, healthcheck +- `start.sh` – startup script with addon detection examples +- `nginx.conf` (optional) – example reverse proxy +- `supervisord.conf` (optional) – process manager example +- `config.yaml` (optional) – sample app config +- `logo.png` – add your 512x512 PNG icon here (not provided in template) + +Usage +1. Create a new package from this template using `scripts/new-package.sh`: + `scripts/new-package.sh MyApp --id com.example.myapp --title "My App" --port 3000` +2. Adjust Dockerfile and start.sh to run your app. +3. Build and test locally; then commit and push. diff --git a/CloudronPackages/Rundeck/config.yaml b/CloudronPackages/Rundeck/config.yaml new file mode 100644 index 0000000..1a4e70b --- /dev/null +++ b/CloudronPackages/Rundeck/config.yaml @@ -0,0 +1,11 @@ +# Example configuration template for Rundeck Job Scheduler +server: + port: 4440 + +data: + dir: /app/data + +database: + # url: ${CLOUDRON_POSTGRESQL_URL} + # redis: ${CLOUDRON_REDIS_URL} + diff --git a/CloudronPackages/Rundeck/nginx.conf b/CloudronPackages/Rundeck/nginx.conf new file mode 100644 index 0000000..706d216 --- /dev/null +++ b/CloudronPackages/Rundeck/nginx.conf @@ -0,0 +1,26 @@ +user cloudron; +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /run/nginx.pid; + +events { worker_connections 1024; } + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + access_log /var/log/nginx/access.log main; + sendfile on; + + server { + listen 4440; + server_name _; + + location / { + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:4440; + } + } +} + diff --git a/CloudronPackages/Rundeck/start.sh b/CloudronPackages/Rundeck/start.sh new file mode 100644 index 0000000..19ab137 --- /dev/null +++ b/CloudronPackages/Rundeck/start.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +log() { echo "[start] $(date -Is) $*"; } +abort() { echo "[start] ERROR: $*" >&2; exit 1; } + +# Defaults +: "${APP_PORT:=4440}" + +log "Starting Rundeck Job Scheduler on port ${APP_PORT}" + +# Example: ensure /app/data exists and is writable +mkdir -p /app/data +chown -R cloudron:cloudron /app/data || true + +# Example addon integration (uncomment and adapt as needed) +# if [[ -n "${CLOUDRON_POSTGRESQL_URL:-}" ]]; then +# log "Detected PostgreSQL addon" +# # Use $CLOUDRON_POSTGRESQL_* env vars +# fi + +# if [[ -n "${CLOUDRON_REDIS_URL:-}" ]]; then +# log "Detected Redis addon" +# fi + +# If your app needs config generation, do it here +# cat > /app/data/config.yaml <<'YAML' +# key: value +# YAML + +# Example: start a simple HTTP server (placeholder) +# Replace with your actual app start command +if command -v python3 >/dev/null 2>&1; then + log "Launching placeholder server: python3 -m http.server ${APP_PORT}" + exec python3 -m http.server "${APP_PORT}" --bind 0.0.0.0 +else + abort "No application command configured. Replace placeholder with your app's start command." +fi + diff --git a/CloudronPackages/Rundeck/supervisord.conf b/CloudronPackages/Rundeck/supervisord.conf new file mode 100644 index 0000000..e73a12a --- /dev/null +++ b/CloudronPackages/Rundeck/supervisord.conf @@ -0,0 +1,12 @@ +[supervisord] +logfile=/var/log/supervisor/supervisord.log +pidfile=/run/supervisord.pid +nodaemon=true + +[program:app] +command=/app/pkg/start.sh +autorestart=true +stdout_logfile=/var/log/supervisor/app.stdout.log +stderr_logfile=/var/log/supervisor/app.stderr.log +user=cloudron + diff --git a/OIDC_AUTHENTICATION_AUDIT.md b/OIDC_AUTHENTICATION_AUDIT.md deleted file mode 100644 index 1ecc055..0000000 --- a/OIDC_AUTHENTICATION_AUDIT.md +++ /dev/null @@ -1,93 +0,0 @@ -# OIDC Authentication Audit for KNEL Cloudron Packages - -## CRITICAL REQUIREMENT: OIDC Authentication Support - -**All production Cloudron packages MUST support OIDC (OpenID Connect) authentication for mission-critical, revenue-generating workloads.** - -## Current Package Status - -### ✅ **FULL OIDC SUPPORT** - -#### 1. Jenkins CI/CD Platform -- **Status**: ✅ FULL OIDC SUPPORT -- **Method**: OpenID Connect Authentication Plugin -- **Configuration**: Via Jenkins plugin system -- **Documentation**: https://plugins.jenkins.io/openid-connect-authentication/ -- **Cloudron Integration**: Configured via environment variables - -#### 2. Apache APISIX API Gateway -- **Status**: ✅ FULL OIDC SUPPORT -- **Method**: Built-in OpenID Connect Plugin -- **Configuration**: Via APISIX admin API -- **Documentation**: https://apisix.apache.org/docs/apisix/plugins/openid-connect/ -- **Cloudron Integration**: Configured via admin API - -#### 3. Rundeck Job Scheduler -- **Status**: ✅ FULL OIDC SUPPORT (Commercial Version) -- **Method**: OAuth2 Resource Server with JWT validation -- **Configuration**: Via rundeck-config.properties -- **Documentation**: https://docs.rundeck.com/docs/administration/security/sso/ -- **Cloudron Integration**: Configured via environment variables -- **Note**: Requires Rundeck Pro/Enterprise for full OIDC support - -### ⚠️ **LIMITED AUTHENTICATION SUPPORT** - -#### 4. Rathole Reverse Proxy -- **Status**: ❌ NO OIDC SUPPORT -- **Authentication**: None (tunnel proxy) -- **Security Model**: Network-level security via tokens -- **Recommendation**: Use behind authenticated reverse proxy -- **Documentation**: Document as network-level security only - -## Implementation Requirements - -### For Each Package with OIDC Support: - -1. **Environment Variables Required**: - ```bash - CLOUDRON_OIDC_ISSUER_URL=https://your-oidc-provider.com - CLOUDRON_OIDC_CLIENT_ID=your-client-id - CLOUDRON_OIDC_CLIENT_SECRET=your-client-secret - CLOUDRON_OIDC_REDIRECT_URI=https://your-app.cloudron.me/oidc/callback - ``` - -2. **Configuration Files**: - - Jenkins: `jenkins_home/org.jenkinsci.plugins.openid_connect.OpenIdConnectSecurityRealm.xml` - - APISIX: Route configuration with OIDC plugin - - Rundeck: `rundeck-config.properties` with OAuth settings - -3. **Health Check Endpoints**: - - Must verify OIDC configuration on startup - - Must test OIDC provider connectivity - - Must validate JWT token processing - -## Production Readiness Checklist - -- [ ] OIDC provider configuration tested -- [ ] JWT token validation working -- [ ] User session management configured -- [ ] Logout functionality working -- [ ] Error handling for OIDC failures -- [ ] Fallback authentication method (if applicable) -- [ ] Security headers configured -- [ ] CORS settings for OIDC callbacks - -## Documentation Requirements - -Each package must include: -1. OIDC configuration instructions -2. Required environment variables -3. Troubleshooting guide -4. Security considerations -5. Fallback authentication methods (if any) - -## Next Steps - -1. **Immediate**: Configure OIDC for Jenkins, APISIX, and Rundeck -2. **Document**: Rathole's network-level security model -3. **Test**: All OIDC configurations in staging environment -4. **Validate**: Production-ready OIDC integration - ---- - -**CRITICAL**: No package will be considered production-ready without proper OIDC authentication support and comprehensive testing. diff --git a/PRODUCTION_PACKAGING_METHODOLOGY.md b/PRODUCTION_PACKAGING_METHODOLOGY.md deleted file mode 100644 index dd50333..0000000 --- a/PRODUCTION_PACKAGING_METHODOLOGY.md +++ /dev/null @@ -1,54 +0,0 @@ -# Production Packaging Methodology - -## Per-Package Production Checklist - -### Phase 1: Core Application Setup -- [ ] Application builds successfully -- [ ] Application starts without errors -- [ ] Health check endpoint responds -- [ ] Data persistence configured -- [ ] Proper user permissions set - -### Phase 2: Authentication & Security -- [ ] OIDC authentication configured (if supported) -- [ ] Security headers configured -- [ ] CORS settings appropriate -- [ ] SSL/TLS configuration -- [ ] User session management - -### Phase 3: Cloudron Integration -- [ ] CloudronManifest.json validated -- [ ] Environment variables documented -- [ ] Addon support configured (if applicable) -- [ ] Backup/restore functionality -- [ ] Update mechanism - -### Phase 4: Production Testing -- [ ] Smoke test: Application starts and responds -- [ ] Authentication test: OIDC login works -- [ ] Data persistence test: Data survives container restart -- [ ] Performance test: Resource usage acceptable -- [ ] Security test: No exposed sensitive data - -### Phase 5: Documentation -- [ ] README with setup instructions -- [ ] OIDC configuration guide -- [ ] Troubleshooting guide -- [ ] Security considerations -- [ ] Known limitations - -## Current Package: Jenkins CI/CD Platform - -### Status: IN PROGRESS -- ✅ Application builds successfully -- ✅ Application starts (needs verification) -- ⏳ OIDC authentication configuration -- ⏳ Comprehensive testing -- ⏳ Documentation completion - -### Next Steps for Jenkins: -1. Fix startup issues and verify health check -2. Configure OIDC authentication properly -3. Test data persistence -4. Complete documentation -5. Final production validation diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..58f3bb0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.8' + +services: + jenkins: + build: + context: ./CloudronPackages/Jenkins + dockerfile: Dockerfile + ports: + - "8080:8080" + environment: + - JENKINS_HOME=/tmp/jenkins_home + - JENKINS_OPTS=--httpPort=8080 --httpListenAddress=0.0.0.0 + - APP_PORT=8080 + tmpfs: + - /tmp/jenkins_home + restart: "no" diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..50b5bbd --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +node = "20.19.3"