Claude super rough first cut of a few packages. Almost certainly entirely unusable...

This commit is contained in:
2025-07-07 17:20:00 -05:00
parent c315498391
commit b0ca0ef49c
135 changed files with 0 additions and 183 deletions

View File

@@ -0,0 +1,53 @@
{
"id": "com.rundeck.cloudron",
"title": "Rundeck",
"author": "Rundeck, Inc.",
"description": "Job scheduler and runbook automation for teams. Rundeck enables self-service operations with policy-based access control, audit trail, and integrations with your existing tools.",
"tagline": "Job scheduling and runbook automation",
"version": "1.0.0",
"healthCheckPath": "/api/40/system/info",
"httpPort": 8080,
"manifestVersion": 2,
"website": "https://www.rundeck.com/",
"contactEmail": "support@rundeck.com",
"icon": "file://logo.png",
"addons": {
"localstorage": {},
"postgresql": {
"version": "14"
}
},
"tags": [
"automation",
"devops",
"scheduler",
"workflow"
],
"minBoxVersion": "7.4.0",
"memoryLimit": 1024,
"documentationUrl": "https://docs.rundeck.com/",
"postInstallMessage": "Rundeck has been installed. The initial admin credentials are:\nUsername: admin\nPassword: {{ .password }}\n\nPlease change this password immediately after login.",
"startCommand": "/app/code/start.sh",
"configurePath": "/login",
"mediaLinks": [],
"changelog": [
{
"versionCode": 1,
"version": "1.0.0",
"releaseDate": "2025-04-21",
"changes": [
"Initial release of Rundeck for Cloudron"
]
}
],
"forumUrl": "https://github.com/cloudron-io/cloudron-app/issues",
"features": {
"ldap": true,
"oauth": {
"callback": "/user/oidclogin",
"clientId": "{{ cloudron.oauth.clientId }}",
"clientSecret": "{{ cloudron.oauth.clientSecret }}",
"scope": "profile email"
}
}
}

View File

@@ -0,0 +1,65 @@
FROM cloudron/base:4.2.0
# Install dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
openjdk-11-jre-headless \
curl \
supervisor \
nginx \
procps \
&& rm -rf /var/lib/apt/lists/*
# Set Environment Variables
ENV RDECK_BASE=/app/data \
RUNDECK_SERVER_DATASTORE_DRIVER="org.postgresql.Driver" \
RUNDECK_GRAILS_URL="https://{{ cloudron_app_domain }}" \
RUNDECK_SERVER_CONTEXTPATH="/" \
RUNDECK_SERVER_FORWARDED=true \
RUNDECK_LOGGING_STRATEGY=CONSOLE \
SERVER_SERVLET_CONTEXT_PATH="/" \
RUNDECK_JAASLOGIN=true \
RUNDECK_SERVER_ADDRESS=127.0.0.1 \
RUNDECK_SERVER_PORT=4440
# Create necessary directories
RUN mkdir -p /app/code /app/data \
/app/data/etc \
/app/data/server/data \
/app/data/var/logs \
/app/data/projects \
/app/data/libext \
/app/data/.ssh \
/tmp/data/etc \
/tmp/data/server/data \
/tmp/data/var/logs \
/tmp/data/projects \
/tmp/data/libext
# Download and install Rundeck
WORKDIR /tmp
RUN curl -Lo rundeck.war "https://repo1.maven.org/maven2/org/rundeck/rundeck/4.17.0/rundeck-4.17.0.war" && \
mkdir -p /app/code/rundeck/webapps && \
mv rundeck.war /app/code/rundeck/webapps/rundeck.war
# Copy configuration files
COPY start.sh /app/code/
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY nginx.conf /etc/nginx/sites-available/rundeck
COPY realm.properties /tmp/data/etc/
COPY framework.properties /tmp/data/etc/
COPY rundeck-config.properties /tmp/data/etc/
COPY jaas-ldap.conf /tmp/data/etc/
COPY jaas-oidc.conf /tmp/data/etc/
# Configure NGINX
RUN rm -f /etc/nginx/sites-enabled/default && \
ln -sf /etc/nginx/sites-available/rundeck /etc/nginx/sites-enabled/rundeck
# Set permissions
RUN chmod +x /app/code/start.sh && \
chown -R cloudron:cloudron /app/code /app/data /tmp/data
WORKDIR /app/code
CMD ["/app/code/start.sh"]

View File

@@ -0,0 +1,101 @@
# Rundeck Cloudron Package Build Notes
## Overview
This package deploys Rundeck, an open-source automation and job scheduling tool, on Cloudron. It uses PostgreSQL for data storage and can be configured to use either Cloudron's LDAP or OIDC for authentication.
## Package Contents
- **CloudronManifest.json**: Defines the app for Cloudron
- **Dockerfile**: Builds the container with Rundeck and dependencies
- **start.sh**: Initializes the app and manages configuration
- **nginx.conf**: Configures web server to proxy requests to Rundeck
- **supervisord.conf**: Manages Rundeck and Nginx processes
- **Configuration files**:
- framework.properties: Core Rundeck configuration
- rundeck-config.properties: Database and server settings
- jaas-ldap.conf: LDAP authentication configuration
- jaas-oidc.conf: OAuth/OIDC authentication configuration
- realm.properties: Default user credentials
## Building the Package
1. Create a new directory for your Cloudron package
2. Place all the files in this package in that directory
3. Download a Rundeck logo and save it as `logo.png` in the package directory
4. Build the package with the Cloudron CLI:
```
cloudron build
```
## Testing
1. Install the package on a test Cloudron instance:
```
cloudron install --image [your-image-name]
```
2. After installation, access the app at its Cloudron URL
3. Log in with the credentials shown in the post-install message
4. Test basic functionality:
- Create a project
- Define a simple job
- Run the job and verify it executes correctly
- Check that logs are saved correctly
5. Test authentication:
- If LDAP is enabled, test login with a Cloudron user
- If OIDC is enabled, test single sign-on functionality
- Verify proper permissions mapping
## Deploying to Production
1. After successful testing, publish the package for your production Cloudron:
```
cloudron install --app rundeck --image [your-image-name]
```
2. Configure backup schedules through the Cloudron UI
3. Update the admin password immediately after installation
4. Configure necessary projects and jobs
## Authentication Configuration
The package supports two authentication methods:
### OIDC/OAuth (Preferred)
- Automatically configured if Cloudron provides OAuth environment variables
- Uses Cloudron's identity provider for single sign-on
- User roles mapped from Cloudron groups
- No additional configuration needed
### LDAP
- Automatically configured if Cloudron provides LDAP environment variables
- Uses Cloudron's LDAP server for authentication
- Groups are mapped to Rundeck roles
- Works with all Cloudron user accounts
## Troubleshooting
- If the app fails to start, check the Cloudron logs:
```
cloudron logs -f
```
- Common issues:
- Database connection problems: Check the PostgreSQL addon status
- Authentication issues: Verify LDAP/OIDC configuration
- File permissions: Ensure files in /app/data are owned by cloudron:cloudron
- Memory limits: If Rundeck is slow or crashing, consider increasing the memory limit
## Updating the Package
1. Update the app version in CloudronManifest.json
2. Update the Rundeck version in the Dockerfile
3. Make any necessary changes to configuration files
4. Rebuild and reinstall the package
## Backup and Restore
Cloudron automatically backs up the /app/data directory and PostgreSQL database. No additional configuration is required for backup functionality.
## Security Notes
- Rundeck stores sensitive data (credentials, private keys) in its database and file system
- All sensitive data is stored in the /app/data directory, which is backed up by Cloudron
- API keys and other secrets are encrypted using Jasypt encryption
- Always use HTTPS (provided by Cloudron) for secure access

View File

@@ -0,0 +1,57 @@
# framework.properties
#
# The base directory for the rundeck server
#
rdeck.base=/app/data
# Indicates a file contains credentials for writing to the output log file.
#
# The contents of this file must contain a single line with 2 comma separated
# strings:
# <username>,<password>
framework.output.password.file=/app/data/etc/output.password
# Framework crypto options
# framework.crypto.keystore.filename=
# framework.crypto.keystore.password=
# framework.crypto.secretkey.password=
# SSH connection timeout after a specified number of milliseconds.
# Default timeout is 30 seconds.
framework.ssh.timeout=30000
# Set the follow to true if you want ssh-agent forwarding to work.
framework.ssh.user.enableagentforward=false
# ssh key storage
framework.ssh.keypath=/app/data/.ssh
framework.ssh.keystore.path=/app/data/var/storage
# SSH authentication type (password or privateKey)
framework.ssh.authentication=privateKey
# Set this to true to use the ssh-key storage for ssh plugin tests
framework.ssh.fileCopier.use.storage=false
#
# Extra environment variables to pass to throttled/queued commands
#
# comma separated list of environment variables to pass from parent process to
# to child process as is
framework.env.retain=JVM_OPTS
# API Tokens File
framework.tokens.file=/app/data/etc/tokens.properties
# For Server URL and Port
framework.server.name=Rundeck
framework.server.hostname=${CLOUDRON_APP_DOMAIN}
framework.server.port=443
framework.server.url=https://${CLOUDRON_APP_DOMAIN}
# Define auth resources
framework.authorization.resource.file.path=/app/data/etc/resources.xml
# Logging
framework.log.dispatch.console.format=[%d{ISO8601}] %-5p %c{2} - %m%n
framework.log.dispatch.file=/app/data/var/logs/rundeck.log

View File

@@ -0,0 +1,22 @@
ldap {
com.dtolabs.rundeck.jetty.jaas.JettyCachingLdapLoginModule required
debug="true"
contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
providerUrl="{{ldap.url}}"
bindDn="{{ldap.bindDn}}"
bindPassword="{{ldap.bindPassword}}"
authenticationMethod="simple"
forceBindingLogin="true"
userBaseDn="{{ldap.userBaseDn}}"
userRdnAttribute="uid"
userIdAttribute="uid"
userPasswordAttribute="userPassword"
userObjectClass="inetOrgPerson"
roleBaseDn="{{ldap.groupBaseDn}}"
roleNameAttribute="cn"
roleMemberAttribute="member"
roleObjectClass="groupOfNames"
cacheDurationMillis="300000"
supplementalRoles="user"
reportStatistics="true";
};

View File

@@ -0,0 +1,12 @@
oauth {
org.rundeck.jaas.jetty.JettyRolePropertyFileLoginModule required
debug="true"
useFirstPass="true"
supplementalRoles="user"
file="/app/data/etc/realm.properties";
com.dtolabs.rundeck.jetty.jaas.JettyOIDCUserGroupsLoginModule required
debug="true"
useFirstPass="false"
storePass="true";
};

View File

@@ -0,0 +1,34 @@
server {
listen 8080;
server_name localhost;
access_log /dev/stdout;
error_log /dev/stderr;
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:4440;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
# OIDC callback
location /user/oidclogin {
proxy_pass http://127.0.0.1:4440/user/oidclogin;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
}
}

View File

@@ -0,0 +1,2 @@
# Initial Admin User - will be set up by start.sh
admin:admin,user,admin

View File

@@ -0,0 +1,33 @@
# rundeck-config.properties
#
# Database connection
dataSource.driverClassName = org.postgresql.Driver
dataSource.url = ${RUNDECK_SERVER_DATASTORE_URL}
dataSource.username = ${CLOUDRON_POSTGRESQL_USERNAME}
dataSource.password = ${CLOUDRON_POSTGRESQL_PASSWORD}
dataSource.dbCreate = update
# Plugin installation
rundeck.plugin.dir = /app/data/libext
# Server settings
grails.serverURL = https://${CLOUDRON_APP_DOMAIN}
rundeck.gui.startpage = jobs
rundeck.enableSelfSignedCertDownload = false
rundeck.jetty.connector.forwarded = true
rundeck.security.useHMacRequestTokens = true
rundeck.security.csrf.referer.filterMethod = NONE
rundeck.api.tokens.duration.max = 30d
# Logging
rundeck.log4j.config.file = /app/data/server/config/log4j2.properties
rundeck.logging.dir = /app/data/var/logs
# File storage
rundeck.projectsStorageType=filesystem
rundeck.storage.provider.1.type=file
rundeck.storage.provider.1.path=/app/data/var/storage
rundeck.storage.converter.1.type=jasypt-encryption
rundeck.storage.converter.1.key=keys
rundeck.storage.converter.1.path=keys

View File

@@ -0,0 +1,104 @@
#!/bin/bash
set -eu
# Setup runtime environment
echo "Setting up Rundeck runtime environment..."
# Initialize data directories if they don't exist
for dir in etc server/data var/logs projects libext .ssh; do
if [ ! -d "/app/data/$dir" ]; then
mkdir -p "/app/data/$dir"
if [ -d "/tmp/data/$dir" ] && [ -n "$(ls -A "/tmp/data/$dir" 2>/dev/null)" ]; then
cp -r "/tmp/data/$dir/"* "/app/data/$dir/"
fi
fi
done
# Setup database connection
DB_URL="jdbc:postgresql://${CLOUDRON_POSTGRESQL_HOST}:${CLOUDRON_POSTGRESQL_PORT}/${CLOUDRON_POSTGRESQL_DATABASE}?user=${CLOUDRON_POSTGRESQL_USERNAME}&password=${CLOUDRON_POSTGRESQL_PASSWORD}"
export RUNDECK_SERVER_DATASTORE_URL="$DB_URL"
export RUNDECK_DATABASE_URL="$DB_URL"
export RUNDECK_DATABASE_DRIVER="org.postgresql.Driver"
export RUNDECK_DATABASE_USERNAME="${CLOUDRON_POSTGRESQL_USERNAME}"
export RUNDECK_DATABASE_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}"
# Generate initial admin password if not exists
if ! grep -q "^admin:" /app/data/etc/realm.properties 2>/dev/null; then
PASSWORD=$(openssl rand -hex 8)
echo "admin:admin,user,admin" > /app/data/etc/realm.properties
sed -i "s|{{ .password }}|$PASSWORD|g" /run/cloudron/app.json
else
sed -i "s|{{ .password }}|<existing password>|g" /run/cloudron/app.json
fi
# Update configurations
if [ -f "/app/data/etc/framework.properties" ]; then
# Set domain in framework.properties
sed -i "s|framework.server.url = .*|framework.server.url = https://${CLOUDRON_APP_DOMAIN}|g" /app/data/etc/framework.properties
sed -i "s|framework.server.hostname = .*|framework.server.hostname = ${CLOUDRON_APP_DOMAIN}|g" /app/data/etc/framework.properties
fi
if [ -f "/app/data/etc/rundeck-config.properties" ]; then
# Update database connection in rundeck-config.properties
sed -i "s|dataSource.url = .*|dataSource.url = ${RUNDECK_SERVER_DATASTORE_URL}|g" /app/data/etc/rundeck-config.properties
sed -i "s|grails.serverURL = .*|grails.serverURL = https://${CLOUDRON_APP_DOMAIN}|g" /app/data/etc/rundeck-config.properties
fi
# Configure authentication
if [[ -n "${CLOUDRON_OAUTH_IDENTIFIER:-}" ]]; then
echo "Configuring OAuth/OIDC authentication..."
export RUNDECK_SECURITY_OAUTH_ENABLED=true
export RUNDECK_SECURITY_OAUTH_CLIENTID="${CLOUDRON_OAUTH_CLIENT_ID}"
export RUNDECK_SECURITY_OAUTH_CLIENTSECRET="${CLOUDRON_OAUTH_CLIENT_SECRET}"
export RUNDECK_SECURITY_OAUTH_AUTHORIZEURL="${CLOUDRON_OAUTH_ORIGIN}/auth/realms/${CLOUDRON_OAUTH_IDENTIFIER}/protocol/openid-connect/auth"
export RUNDECK_SECURITY_OAUTH_TOKENURL="${CLOUDRON_OAUTH_ORIGIN}/auth/realms/${CLOUDRON_OAUTH_IDENTIFIER}/protocol/openid-connect/token"
export RUNDECK_SECURITY_OAUTH_USERINFOURI="${CLOUDRON_OAUTH_ORIGIN}/auth/realms/${CLOUDRON_OAUTH_IDENTIFIER}/protocol/openid-connect/userinfo"
cp /tmp/data/etc/jaas-oidc.conf /app/data/etc/jaas-oidc.conf
export RUNDECK_JAASLOGIN=true
export RDECK_JVM_OPTS="${RDECK_JVM_OPTS:-} -Drundeck.jaaslogin=true -Dloginmodule.name=oauth -Djava.security.auth.login.config=/app/data/etc/jaas-oidc.conf"
# Add necessary properties to rundeck-config.properties
echo "rundeck.security.oauth.enabled=true" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.oauth.clientId=${CLOUDRON_OAUTH_CLIENT_ID}" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.oauth.clientSecret=${CLOUDRON_OAUTH_CLIENT_SECRET}" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.oauth.authorizeUrl=${CLOUDRON_OAUTH_ORIGIN}/auth/realms/${CLOUDRON_OAUTH_IDENTIFIER}/protocol/openid-connect/auth" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.oauth.tokenUrl=${CLOUDRON_OAUTH_ORIGIN}/auth/realms/${CLOUDRON_OAUTH_IDENTIFIER}/protocol/openid-connect/token" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.oauth.userInfoUri=${CLOUDRON_OAUTH_ORIGIN}/auth/realms/${CLOUDRON_OAUTH_IDENTIFIER}/protocol/openid-connect/userinfo" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.oauth.autoCreateUsers=true" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.oauth.defaultRoles=user" >> /app/data/etc/rundeck-config.properties
elif [[ -n "${CLOUDRON_LDAP_SERVER:-}" ]]; then
echo "Configuring LDAP authentication..."
cp /tmp/data/etc/jaas-ldap.conf /app/data/etc/jaas-ldap.conf
# Replace placeholders in JAAS config
sed -i "s|{{ldap.url}}|${CLOUDRON_LDAP_SERVER}:${CLOUDRON_LDAP_PORT}|g" /app/data/etc/jaas-ldap.conf
sed -i "s|{{ldap.bindDn}}|${CLOUDRON_LDAP_BIND_DN}|g" /app/data/etc/jaas-ldap.conf
sed -i "s|{{ldap.bindPassword}}|${CLOUDRON_LDAP_BIND_PASSWORD}|g" /app/data/etc/jaas-ldap.conf
sed -i "s|{{ldap.userBaseDn}}|${CLOUDRON_LDAP_USERS_BASE_DN}|g" /app/data/etc/jaas-ldap.conf
sed -i "s|{{ldap.groupBaseDn}}|${CLOUDRON_LDAP_GROUPS_BASE_DN}|g" /app/data/etc/jaas-ldap.conf
export RUNDECK_JAASLOGIN=true
export RDECK_JVM_OPTS="${RDECK_JVM_OPTS:-} -Drundeck.jaaslogin=true -Dloginmodule.name=ldap -Djava.security.auth.login.config=/app/data/etc/jaas-ldap.conf"
# Enable JAAS LDAP in rundeck-config.properties
echo "rundeck.security.jaasLoginModuleName=ldap" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.jaasProviderName=ldap" >> /app/data/etc/rundeck-config.properties
echo "rundeck.jaaslogin=true" >> /app/data/etc/rundeck-config.properties
echo "rundeck.feature.caseInsensitiveUsername.enabled=true" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.syncLdapUser=true" >> /app/data/etc/rundeck-config.properties
else
# Use file-based authentication
echo "Using file-based authentication..."
export RDECK_JVM_OPTS="${RDECK_JVM_OPTS:-} -Drundeck.jaaslogin=true -Dloginmodule.name=file -Djava.security.auth.login.config=/app/data/etc/jaas-file.conf"
echo 'RDpropertyfilelogin { org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required debug="true" file="/app/data/etc/realm.properties"; };' > /app/data/etc/jaas-file.conf
echo "rundeck.security.jaasLoginModuleName=file" >> /app/data/etc/rundeck-config.properties
echo "rundeck.security.jaasProviderName=file" >> /app/data/etc/rundeck-config.properties
fi
# Set permissions
chown -R cloudron:cloudron /app/data
echo "Starting Rundeck services..."
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

View File

@@ -0,0 +1,29 @@
[supervisord]
nodaemon=true
user=root
logfile=/dev/stdout
logfile_maxbytes=0
pidfile=/var/run/supervisord.pid
[program:rundeck]
command=java -Xmx512m -Dserver.http.port=4440 -Drdeck.base=/app/data -jar /app/code/rundeck/webapps/rundeck.war
directory=/app/code/rundeck
user=cloudron
environment=RDECK_BASE="/app/data",RUNDECK_SERVER_DATASTORE_URL="%(ENV_RUNDECK_SERVER_DATASTORE_URL)s",RUNDECK_SERVER_DATASTORE_DRIVER="%(ENV_RUNDECK_SERVER_DATASTORE_DRIVER)s",RUNDECK_GRAILS_URL="%(ENV_RUNDECK_GRAILS_URL)s",RUNDECK_SERVER_CONTEXTPATH="%(ENV_RUNDECK_SERVER_CONTEXTPATH)s",RUNDECK_SERVER_FORWARDED=%(ENV_RUNDECK_SERVER_FORWARDED)s,RUNDECK_LOGGING_STRATEGY="%(ENV_RUNDECK_LOGGING_STRATEGY)s",SERVER_SERVLET_CONTEXT_PATH="%(ENV_SERVER_SERVLET_CONTEXT_PATH)s",RUNDECK_JAASLOGIN=%(ENV_RUNDECK_JAASLOGIN)s,RUNDECK_SERVER_ADDRESS=%(ENV_RUNDECK_SERVER_ADDRESS)s,RUNDECK_SERVER_PORT=%(ENV_RUNDECK_SERVER_PORT)s
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=true
priority=10
startretries=5
stopwaitsecs=60
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=true
priority=20