Package or bust!
This commit is contained in:
@@ -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 <app>:dev CloudronPackages/<AppName>`
|
|
||||||
- ✅ 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(<app>): 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
|
|
@@ -3,17 +3,17 @@
|
|||||||
"id": "io.knel.apisix",
|
"id": "io.knel.apisix",
|
||||||
"title": "Apache APISIX",
|
"title": "Apache APISIX",
|
||||||
"author": "KNEL",
|
"author": "KNEL",
|
||||||
"description": "Apache APISIX API Gateway for microservices and API management",
|
"description": "Cloudron packaging template for Apache APISIX",
|
||||||
"website": "https://apisix.apache.org",
|
"website": "https://example.com",
|
||||||
"contactEmail": "admin@knownelement.com",
|
"contactEmail": "admin@example.com",
|
||||||
"version": "3.8.0",
|
"version": "0.1.0",
|
||||||
"changelog": "Initial Cloudron package for Apache APISIX API Gateway",
|
"changelog": "Initial package template",
|
||||||
"healthCheckPath": "/apisix/admin/routes",
|
"healthCheckPath": "/",
|
||||||
"httpPort": 9180,
|
"httpPort": 9180,
|
||||||
"addons": {
|
"addons": {
|
||||||
"localstorage": {}
|
"localstorage": {}
|
||||||
},
|
},
|
||||||
"tags": ["api", "gateway", "microservices", "proxy"],
|
"tags": ["template", "example"],
|
||||||
"icon": "logo.png"
|
"icon": "logo.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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.title="Apache APISIX"
|
||||||
LABEL org.opencontainers.image.description="Cloudron package for Apache APISIX API Gateway"
|
LABEL org.opencontainers.image.description="Cloudron package for Apache APISIX"
|
||||||
LABEL org.opencontainers.image.source="https://github.com/apache/apisix"
|
LABEL org.opencontainers.image.source="https://example.com"
|
||||||
|
|
||||||
# Switch to root to modify the image
|
# Install OS dependencies here as needed
|
||||||
USER root
|
# 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
|
# App code lives in /app/code (read-only at runtime)
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
WORKDIR /app/code
|
||||||
curl \
|
|
||||||
ca-certificates \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Create cloudron user
|
# Copy application code (adjust as needed)
|
||||||
RUN useradd -r -s /bin/bash -d /app -m cloudron
|
# COPY . /app/code
|
||||||
|
|
||||||
# Create APISIX data directories
|
# Create persistent directory for application data
|
||||||
RUN mkdir -p /app/data/apisix && \
|
RUN mkdir -p /app/data && chown -R cloudron:cloudron /app/data
|
||||||
mkdir -p /app/data/apisix/logs && \
|
|
||||||
mkdir -p /app/data/apisix/conf && \
|
|
||||||
chown -R cloudron:cloudron /app/data
|
|
||||||
|
|
||||||
# Copy startup script
|
# Copy startup script
|
||||||
COPY start.sh /app/pkg/start.sh
|
COPY start.sh /app/pkg/start.sh
|
||||||
RUN chmod +x /app/pkg/start.sh && chown cloudron:cloudron /app/pkg/start.sh
|
RUN chmod +x /app/pkg/start.sh && chown cloudron:cloudron /app/pkg/start.sh
|
||||||
|
|
||||||
# Switch to cloudron user
|
|
||||||
USER cloudron
|
USER cloudron
|
||||||
|
|
||||||
# Expose APISIX ports
|
# Expose the app port specified in manifest
|
||||||
EXPOSE 9180 9080
|
EXPOSE 9180
|
||||||
|
|
||||||
# APISIX environment variables
|
# Default environment (customize per app)
|
||||||
ENV APISIX_HOME=/app/data/apisix \
|
ENV NODE_ENV=production \
|
||||||
APISIX_WORKDIR=/app/data/apisix \
|
|
||||||
APP_PORT=9180
|
APP_PORT=9180
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
||||||
CMD curl -fsS http://127.0.0.1:${APP_PORT}/apisix/admin/routes || exit 1
|
CMD curl -fsS http://127.0.0.1:${APP_PORT}/ || exit 1
|
||||||
|
|
||||||
CMD ["/app/pkg/start.sh"]
|
CMD ["/app/pkg/start.sh"]
|
||||||
|
@@ -9,15 +9,31 @@ abort() { echo "[start] ERROR: $*" >&2; exit 1; }
|
|||||||
|
|
||||||
log "Starting Apache APISIX on port ${APP_PORT}"
|
log "Starting Apache APISIX on port ${APP_PORT}"
|
||||||
|
|
||||||
# Ensure APISIX data directory exists
|
# Example: ensure /app/data exists and is writable
|
||||||
mkdir -p /app/data/apisix
|
mkdir -p /app/data
|
||||||
chown -R cloudron:cloudron /app/data || true
|
chown -R cloudron:cloudron /app/data || true
|
||||||
|
|
||||||
# Set APISIX environment
|
# Example addon integration (uncomment and adapt as needed)
|
||||||
export APISIX_HOME=/app/data/apisix
|
# if [[ -n "${CLOUDRON_POSTGRESQL_URL:-}" ]]; then
|
||||||
export APISIX_WORKDIR=/app/data/apisix
|
# log "Detected PostgreSQL addon"
|
||||||
|
# # Use $CLOUDRON_POSTGRESQL_* env vars
|
||||||
|
# fi
|
||||||
|
|
||||||
# Start APISIX using the official entrypoint
|
# if [[ -n "${CLOUDRON_REDIS_URL:-}" ]]; then
|
||||||
log "Starting APISIX API Gateway"
|
# log "Detected Redis addon"
|
||||||
exec /docker-entrypoint.sh docker-start
|
# 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
|
||||||
|
|
||||||
|
@@ -3,17 +3,17 @@
|
|||||||
"id": "io.knel.jenkins",
|
"id": "io.knel.jenkins",
|
||||||
"title": "Jenkins CI/CD",
|
"title": "Jenkins CI/CD",
|
||||||
"author": "KNEL",
|
"author": "KNEL",
|
||||||
"description": "Jenkins CI/CD Platform for automated builds, testing, and deployment",
|
"description": "Cloudron packaging template for Jenkins CI/CD",
|
||||||
"website": "https://jenkins.io",
|
"website": "https://example.com",
|
||||||
"contactEmail": "admin@knownelement.com",
|
"contactEmail": "admin@example.com",
|
||||||
"version": "2.450.0",
|
"version": "0.1.0",
|
||||||
"changelog": "Initial Cloudron package for Jenkins CI/CD Platform",
|
"changelog": "Initial package template",
|
||||||
"healthCheckPath": "/login",
|
"healthCheckPath": "/",
|
||||||
"httpPort": 8080,
|
"httpPort": 8080,
|
||||||
"addons": {
|
"addons": {
|
||||||
"localstorage": {}
|
"localstorage": {}
|
||||||
},
|
},
|
||||||
"tags": ["ci", "cd", "automation", "build", "deployment"],
|
"tags": ["template", "example"],
|
||||||
"icon": "logo.png"
|
"icon": "logo.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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.description="Cloudron package for Jenkins CI/CD Platform"
|
||||||
LABEL org.opencontainers.image.source="https://github.com/jenkinsci/jenkins"
|
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 \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
openjdk-17-jdk \
|
openjdk-17-jdk \
|
||||||
curl \
|
curl \
|
||||||
@@ -23,7 +23,7 @@ RUN mkdir -p /app/data/jenkins_home && \
|
|||||||
mkdir -p /app/pkg && \
|
mkdir -p /app/pkg && \
|
||||||
chown -R cloudron:cloudron /app/data
|
chown -R cloudron:cloudron /app/data
|
||||||
|
|
||||||
# Download and install Jenkins WAR file
|
# Download Jenkins WAR file
|
||||||
ARG JENKINS_VERSION=2.450
|
ARG JENKINS_VERSION=2.450
|
||||||
RUN cd /tmp && \
|
RUN cd /tmp && \
|
||||||
curl -fsSL "https://get.jenkins.io/war/${JENKINS_VERSION}/jenkins.war" -o jenkins.war && \
|
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 start.sh /app/pkg/start.sh
|
||||||
COPY CloudronManifest.json /app/pkg/CloudronManifest.json
|
COPY CloudronManifest.json /app/pkg/CloudronManifest.json
|
||||||
COPY CloudronManifest.json /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
|
USER cloudron
|
||||||
|
|
||||||
# Expose Jenkins port
|
# Expose port
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
# Jenkins environment variables
|
# Set environment variables
|
||||||
ENV JENKINS_HOME=/app/data/jenkins_home \
|
ENV JENKINS_HOME=/app/data/jenkins_home \
|
||||||
JENKINS_OPTS="--httpPort=8080 --httpListenAddress=0.0.0.0" \
|
JENKINS_OPTS="--httpPort=8080 --httpListenAddress=0.0.0.0" \
|
||||||
APP_PORT=8080
|
APP_PORT=8080
|
||||||
|
|
||||||
|
# Health check
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
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"]
|
@@ -15,100 +15,8 @@ mkdir -p "${JENKINS_HOME}"
|
|||||||
chown -R cloudron:cloudron /app/data || true
|
chown -R cloudron:cloudron /app/data || true
|
||||||
|
|
||||||
# Set Jenkins environment variables
|
# Set Jenkins environment variables
|
||||||
export JENKINS_HOME="${JENKINS_HOME}"
|
export JENKINS_HOME
|
||||||
export JENKINS_OPTS="--httpPort=${APP_PORT} --httpListenAddress=0.0.0.0"
|
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'
|
|
||||||
<?xml version='1.1' encoding='UTF-8'?>
|
|
||||||
<org.jenkinsci.plugins.openid_connect.OpenIdConnectSecurityRealm plugin="openid-connect@2.4">
|
|
||||||
<issuer>${CLOUDRON_OIDC_ISSUER_URL}</issuer>
|
|
||||||
<clientId>${CLOUDRON_OIDC_CLIENT_ID}</clientId>
|
|
||||||
<clientSecret>${CLOUDRON_OIDC_CLIENT_SECRET}</clientSecret>
|
|
||||||
<scopes>openid,email,profile</scopes>
|
|
||||||
<usernameField>preferred_username</usernameField>
|
|
||||||
<fullNameField>name</fullNameField>
|
|
||||||
<emailField>email</emailField>
|
|
||||||
<disableSslVerification>false</disableSslVerification>
|
|
||||||
<logoutFromOpenidProvider>true</logoutFromOpenidProvider>
|
|
||||||
<postLogoutRedirectUrl>${CLOUDRON_OIDC_REDIRECT_URI}</postLogoutRedirectUrl>
|
|
||||||
<escapeHatchEnabled>false</escapeHatchEnabled>
|
|
||||||
<escapeHatchUsername>admin</escapeHatchUsername>
|
|
||||||
<escapeHatchSecret>jenkins-escape-hatch</escapeHatchSecret>
|
|
||||||
<escapeHatchGroup>admin</escapeHatchGroup>
|
|
||||||
<automanualconfigure>false</automanualconfigure>
|
|
||||||
<wellKnownOpenIDConfigurationUrl></wellKnownOpenIDConfigurationUrl>
|
|
||||||
<readTimeout>20</readTimeout>
|
|
||||||
<connectTimeout>10</connectTimeout>
|
|
||||||
<tokenServerUrl></tokenServerUrl>
|
|
||||||
<authorizationServerUrl></authorizationServerUrl>
|
|
||||||
<userInfoServerUrl></userInfoServerUrl>
|
|
||||||
<userNameField></userNameField>
|
|
||||||
<tokenFieldToCheckKey></tokenFieldToCheckKey>
|
|
||||||
<tokenFieldToCheckValue></tokenFieldToCheckValue>
|
|
||||||
</org.jenkinsci.plugins.openid_connect.OpenIdConnectSecurityRealm>
|
|
||||||
OIDC_XML
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create basic config.xml for Jenkins
|
|
||||||
cat > "${JENKINS_HOME}/config.xml" <<'XML'
|
|
||||||
<?xml version='1.1' encoding='UTF-8'?>
|
|
||||||
<hudson>
|
|
||||||
<version>2.450</version>
|
|
||||||
<numExecutors>2</numExecutors>
|
|
||||||
<mode>NORMAL</mode>
|
|
||||||
<useSecurity>true</useSecurity>
|
|
||||||
<authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy"/>
|
|
||||||
<securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
|
|
||||||
<disableSignup>true</disableSignup>
|
|
||||||
</securityRealm>
|
|
||||||
<disableRememberMe>false</disableRememberMe>
|
|
||||||
<projectNamingStrategy class="jenkins.model.ProjectNamingStrategy$DefaultProjectNamingStrategy"/>
|
|
||||||
<workspaceDir>${JENKINS_HOME}/workspace/${ITEM_FULLNAME}</workspaceDir>
|
|
||||||
<buildsDir>${JENKINS_HOME}/builds/${ITEM_FULLNAME}</buildsDir>
|
|
||||||
<markupFormatter class="hudson.markup.RawHtmlMarkupFormatter" plugin="antisamy-markup-formatter@3.1"/>
|
|
||||||
<jdks/>
|
|
||||||
<viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
|
|
||||||
<myViewsTabBar class="hudson.views.DefaultMyViewsTabBar"/>
|
|
||||||
<clouds/>
|
|
||||||
<slaves/>
|
|
||||||
<scm class="hudson.scm.NullSCM"/>
|
|
||||||
<views>
|
|
||||||
<hudson.model.AllView>
|
|
||||||
<owner class="hudson" reference="../../.."/>
|
|
||||||
<name>all</name>
|
|
||||||
<filterExecutors>false</filterExecutors>
|
|
||||||
<filterQueue>false</filterQueue>
|
|
||||||
<properties class="hudson.model.View$PropertyList"/>
|
|
||||||
</hudson.model.AllView>
|
|
||||||
</views>
|
|
||||||
<primaryView>all</primaryView>
|
|
||||||
<slaveAgentPort>50000</slaveAgentPort>
|
|
||||||
<disabledAgentProtocols>
|
|
||||||
<string>JNLP-connect</string>
|
|
||||||
<string>JNLP2-connect</string>
|
|
||||||
</disabledAgentProtocols>
|
|
||||||
<label></label>
|
|
||||||
<nodeProperties/>
|
|
||||||
<globalNodeProperties/>
|
|
||||||
</hudson>
|
|
||||||
XML
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start Jenkins
|
|
||||||
log "Starting Jenkins WAR file"
|
log "Starting Jenkins WAR file"
|
||||||
exec java -jar /app/pkg/jenkins.war ${JENKINS_OPTS}
|
exec java -jar /app/pkg/jenkins.war
|
||||||
|
|
@@ -5,20 +5,21 @@ ARG ARCH=x86_64-unknown-linux-gnu
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
RUN apt-get update \
|
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/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /app/pkg
|
WORKDIR /app/pkg
|
||||||
|
|
||||||
# Download Rathole release binary (adjust version/arch via build args)
|
# Download Rathole release binary (adjust version/arch via build args)
|
||||||
RUN set -eux; \
|
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}"; \
|
echo "Fetching ${url}"; \
|
||||||
curl -fsSL "$url" -o rathole.zip; \
|
curl -fsSL "$url" -o rathole.tar.gz; \
|
||||||
unzip rathole.zip; \
|
tar -xzf rathole.tar.gz; \
|
||||||
rm rathole.zip; \
|
rm rathole.tar.gz; \
|
||||||
chmod +x rathole; \
|
mv rathole /app/pkg/rathole; \
|
||||||
chown cloudron:cloudron rathole
|
chmod +x /app/pkg/rathole; \
|
||||||
|
chown cloudron:cloudron /app/pkg/rathole
|
||||||
|
|
||||||
# Start script
|
# Start script
|
||||||
COPY start.sh /app/pkg/start.sh
|
COPY start.sh /app/pkg/start.sh
|
||||||
|
11
CloudronPackages/Rundeck/.dockerignore
Normal file
11
CloudronPackages/Rundeck/.dockerignore
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Ignore typical build context clutter
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
*.log
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
Dockerfile.*
|
||||||
|
.DS_Store
|
||||||
|
|
19
CloudronPackages/Rundeck/CloudronManifest.json
Normal file
19
CloudronPackages/Rundeck/CloudronManifest.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
|
38
CloudronPackages/Rundeck/Dockerfile
Normal file
38
CloudronPackages/Rundeck/Dockerfile
Normal file
@@ -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"]
|
33
CloudronPackages/Rundeck/README.md
Normal file
33
CloudronPackages/Rundeck/README.md
Normal file
@@ -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**: `<appname>:dev` (built locally for testing)
|
||||||
|
- **Production Images**: `<appname>:latest` (final packaged versions)
|
||||||
|
- **Container Names**: Use descriptive names like `<appname>-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.
|
11
CloudronPackages/Rundeck/config.yaml
Normal file
11
CloudronPackages/Rundeck/config.yaml
Normal file
@@ -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}
|
||||||
|
|
26
CloudronPackages/Rundeck/nginx.conf
Normal file
26
CloudronPackages/Rundeck/nginx.conf
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
CloudronPackages/Rundeck/start.sh
Normal file
39
CloudronPackages/Rundeck/start.sh
Normal file
@@ -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
|
||||||
|
|
12
CloudronPackages/Rundeck/supervisord.conf
Normal file
12
CloudronPackages/Rundeck/supervisord.conf
Normal file
@@ -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
|
||||||
|
|
@@ -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.
|
|
@@ -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
|
|
16
docker-compose.yml
Normal file
16
docker-compose.yml
Normal file
@@ -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"
|
Reference in New Issue
Block a user