.
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"id": "org.elabftw.cloudron",
|
||||
"title": "eLabFTW",
|
||||
"author": "Nicolas CARPi",
|
||||
"description": "Electronic laboratory notebook to track experiments, manage protocols, store laboratory inventory, communicate with others and more. Your best lab companion.",
|
||||
"tagline": "Electronic lab notebook for researchers",
|
||||
"version": "1.0.0",
|
||||
"healthCheckPath": "/",
|
||||
"httpPort": 8000,
|
||||
"addons": {
|
||||
"mysql": {},
|
||||
"localstorage": {}
|
||||
},
|
||||
"manifestVersion": 2,
|
||||
"website": "https://www.elabftw.net",
|
||||
"contactEmail": "support@example.com",
|
||||
"icon": "file://logo.png",
|
||||
"memoryLimit": 1024,
|
||||
"tags": ["science", "lab", "research", "notebook", "eln"],
|
||||
"minBoxVersion": "7.4.0",
|
||||
"postInstallMessage": "eLabFTW has been successfully installed! You will need to create a Sysadmin account when you first access the application.",
|
||||
"documentationUrl": "https://doc.elabftw.net/",
|
||||
"forwardedHeaders": ["X-Forwarded-For", "X-Forwarded-Proto", "X-Forwarded-Host"],
|
||||
"tcpPorts": {},
|
||||
"optionalSso": {
|
||||
"ldap": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
FROM cloudron/base:4.2.0
|
||||
|
||||
# Install required packages
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
php-cli \
|
||||
php-fpm \
|
||||
php-mysql \
|
||||
php-curl \
|
||||
php-gd \
|
||||
php-intl \
|
||||
php-mbstring \
|
||||
php-xml \
|
||||
php-zip \
|
||||
php-bcmath \
|
||||
nginx \
|
||||
supervisor \
|
||||
curl \
|
||||
zip \
|
||||
unzip \
|
||||
git \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Composer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
|
||||
# Get the latest eLabFTW release
|
||||
WORKDIR /app/code
|
||||
RUN git clone https://github.com/elabftw/elabftw.git . && \
|
||||
composer install --no-dev --optimize-autoloader
|
||||
|
||||
# Configure NGINX
|
||||
COPY nginx.conf /etc/nginx/sites-available/default
|
||||
|
||||
# Prepare directory structure
|
||||
RUN mkdir -p /app/data/uploads /app/data/config /app/data/logs /run/php && \
|
||||
chown -R cloudron:cloudron /app/data /run/php
|
||||
|
||||
# Copy initialization data
|
||||
RUN mkdir -p /tmp/data/config /tmp/data/uploads /tmp/data/logs && \
|
||||
cp -r /app/code/config-example.yml /tmp/data/config/config.yml && \
|
||||
chown -R cloudron:cloudron /tmp/data
|
||||
|
||||
# Copy start script and supervisor config
|
||||
COPY start.sh /app/code/
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
RUN chmod +x /app/code/start.sh
|
||||
|
||||
# Configure PHP-FPM
|
||||
RUN sed -i 's/www-data/cloudron/g' /etc/php/*/fpm/pool.d/www.conf && \
|
||||
sed -i 's/listen = \/run\/php\/php[0-9]\.[0-9]-fpm.sock/listen = \/run\/php\/php-fpm.sock/g' /etc/php/*/fpm/pool.d/www.conf && \
|
||||
echo 'catch_workers_output = yes' >> /etc/php/*/fpm/pool.d/www.conf
|
||||
|
||||
# Create logo image
|
||||
RUN curl -o /app/code/logo.png https://raw.githubusercontent.com/elabftw/elabftw/master/src/ts/img/logo.png
|
||||
|
||||
WORKDIR /app/code
|
||||
|
||||
CMD ["/app/code/start.sh"]
|
@@ -1,109 +0,0 @@
|
||||
# eLabFTW Cloudron Package Build Notes
|
||||
|
||||
This document provides instructions for building, testing, and deploying the eLabFTW Cloudron package.
|
||||
|
||||
## Package Overview
|
||||
|
||||
This package deploys eLabFTW, an open-source electronic laboratory notebook (ELN) for researchers, on Cloudron. The package:
|
||||
|
||||
- Uses the MySQL addon for database storage
|
||||
- Uses the localstorage addon for file storage
|
||||
- Includes NGINX and PHP-FPM configuration
|
||||
- Supports optional LDAP authentication through Cloudron
|
||||
|
||||
## Building the Package
|
||||
|
||||
1. Create a new directory for your package:
|
||||
```bash
|
||||
mkdir elabftw-cloudron
|
||||
cd elabftw-cloudron
|
||||
```
|
||||
|
||||
2. Save all the provided files to this directory:
|
||||
- CloudronManifest.json
|
||||
- Dockerfile
|
||||
- start.sh
|
||||
- nginx.conf
|
||||
- supervisord.conf
|
||||
|
||||
3. Make the start.sh file executable:
|
||||
```bash
|
||||
chmod +x start.sh
|
||||
```
|
||||
|
||||
4. Download the eLabFTW logo for the package icon:
|
||||
```bash
|
||||
curl -o logo.png https://raw.githubusercontent.com/elabftw/elabftw/master/src/ts/img/logo.png
|
||||
```
|
||||
|
||||
5. Build the package:
|
||||
```bash
|
||||
cloudron build
|
||||
```
|
||||
|
||||
## Testing the Package
|
||||
|
||||
1. Install the package on your Cloudron for testing:
|
||||
```bash
|
||||
cloudron install —location elabftw.example.com
|
||||
```
|
||||
|
||||
2. After installation, visit the application URL and complete the initial setup:
|
||||
- Create the Sysadmin account
|
||||
- Configure your teams and user groups
|
||||
- Set up any initial templates or protocols
|
||||
|
||||
3. Test the following functionality:
|
||||
- User authentication (local accounts)
|
||||
- File uploads (should be stored in /app/data/uploads)
|
||||
- Database connection (should be using Cloudron MySQL)
|
||||
- LDAP authentication (if enabled)
|
||||
- General application functionality
|
||||
|
||||
## Deploying to Production
|
||||
|
||||
1. Once testing is complete, you can deploy to production:
|
||||
```bash
|
||||
cloudron install —location elabftw.yourdomain.com
|
||||
```
|
||||
|
||||
2. For production use, consider:
|
||||
- Setting up regular backups of the Cloudron app
|
||||
- Configuring LDAP authentication if needed (via Cloudron UI)
|
||||
- Adjusting memory limits in CloudronManifest.json if necessary based on usage
|
||||
|
||||
## Post-Installation
|
||||
|
||||
After installation, you’ll need to:
|
||||
|
||||
1. Create a Sysadmin account when first accessing the application
|
||||
2. Configure teams and user groups
|
||||
3. Set up experiment templates and protocols as needed
|
||||
4. Consider enabling and configuring LDAP authentication for easier user management
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Check logs with `cloudron logs -f elabftw`
|
||||
- If database issues occur, verify the MySQL addon is properly configured
|
||||
- For file storage issues, check permissions on /app/data directories
|
||||
- For authentication issues, verify LDAP configuration (if using LDAP)
|
||||
|
||||
## Updates
|
||||
|
||||
When a new version of eLabFTW is released:
|
||||
|
||||
1. Update the git clone command in the Dockerfile to point to the latest release (or specific tag)
|
||||
2. Rebuild and update your package:
|
||||
```bash
|
||||
cloudron build
|
||||
cloudron update —app elabftw.yourdomain.com
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
You can customize the package by:
|
||||
|
||||
1. Modifying the config.yml template in /tmp/data/config to set default values
|
||||
2. Adjusting PHP settings in the Dockerfile or php.ini
|
||||
3. Modifying NGINX configuration for special requirements
|
||||
4. Adjusting memory limits in CloudronManifest.json based on usage patterns
|
@@ -1,38 +0,0 @@
|
||||
server {
|
||||
listen 8000;
|
||||
server_name _;
|
||||
root /app/code/web;
|
||||
index index.php;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_pass unix:/run/php/php-fpm.sock;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param HTTPS on;
|
||||
|
||||
# Forward Cloudron proxy headers
|
||||
fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for;
|
||||
fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;
|
||||
fastcgi_param HTTP_X_FORWARDED_HOST $http_x_forwarded_host;
|
||||
}
|
||||
|
||||
# Deny access to other PHP files
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# Rewrite app routes
|
||||
location @rewriteapp {
|
||||
rewrite ^(.*)$ /index.php/$1 last;
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Create directory structure if it doesn't exist
|
||||
if [ ! -d /app/data/uploads ]; then
|
||||
mkdir -p /app/data/uploads
|
||||
cp -r /tmp/data/uploads/* /app/data/uploads/ 2>/dev/null || true
|
||||
chown -R cloudron:cloudron /app/data/uploads
|
||||
fi
|
||||
|
||||
if [ ! -d /app/data/logs ]; then
|
||||
mkdir -p /app/data/logs
|
||||
cp -r /tmp/data/logs/* /app/data/logs/ 2>/dev/null || true
|
||||
chown -R cloudron:cloudron /app/data/logs
|
||||
fi
|
||||
|
||||
if [ ! -f /app/data/config/config.yml ]; then
|
||||
mkdir -p /app/data/config
|
||||
cp -r /tmp/data/config/* /app/data/config/ 2>/dev/null || true
|
||||
|
||||
# Configure database connection
|
||||
sed -i "s/host: .*/host: ${CLOUDRON_MYSQL_HOST}/" /app/data/config/config.yml
|
||||
sed -i "s/port: .*/port: ${CLOUDRON_MYSQL_PORT}/" /app/data/config/config.yml
|
||||
sed -i "s/database: .*/database: ${CLOUDRON_MYSQL_DATABASE}/" /app/data/config/config.yml
|
||||
sed -i "s/username: .*/username: ${CLOUDRON_MYSQL_USERNAME}/" /app/data/config/config.yml
|
||||
sed -i "s/password: .*/password: ${CLOUDRON_MYSQL_PASSWORD}/" /app/data/config/config.yml
|
||||
|
||||
# Configure paths
|
||||
sed -i "s|uploads: .*|uploads: /app/data/uploads|" /app/data/config/config.yml
|
||||
sed -i "s|logs: .*|logs: /app/data/logs|" /app/data/config/config.yml
|
||||
|
||||
# Configure LDAP if enabled
|
||||
if [ "${CLOUDRON_LDAP_ENABLED}" == "true" ]; then
|
||||
# Update LDAP settings in config
|
||||
sed -i "s/ldap_enabled: .*/ldap_enabled: true/" /app/data/config/config.yml
|
||||
sed -i "s/ldap_host: .*/ldap_host: ${CLOUDRON_LDAP_SERVER}/" /app/data/config/config.yml
|
||||
sed -i "s/ldap_port: .*/ldap_port: ${CLOUDRON_LDAP_PORT}/" /app/data/config/config.yml
|
||||
sed -i "s/ldap_username: .*/ldap_username: ${CLOUDRON_LDAP_BIND_DN}/" /app/data/config/config.yml
|
||||
sed -i "s/ldap_password: .*/ldap_password: ${CLOUDRON_LDAP_BIND_PASSWORD}/" /app/data/config/config.yml
|
||||
sed -i "s/ldap_base_dn: .*/ldap_base_dn: ${CLOUDRON_LDAP_USERS_BASE_DN}/" /app/data/config/config.yml
|
||||
fi
|
||||
|
||||
chown -R cloudron:cloudron /app/data/config
|
||||
fi
|
||||
|
||||
# Create a symlink to the config file
|
||||
ln -sf /app/data/config/config.yml /app/code/config.yml
|
||||
|
||||
# Set proper permissions
|
||||
chown -R cloudron:cloudron /app/data
|
||||
|
||||
# Start the supervisord
|
||||
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
@@ -1,24 +0,0 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/dev/stdout
|
||||
logfile_maxbytes=0
|
||||
|
||||
[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
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=10
|
||||
|
||||
[program:php-fpm]
|
||||
command=/usr/sbin/php-fpm8.1 -F
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=5
|
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"id": "software.homebox.cloudronapp",
|
||||
"title": "Homebox",
|
||||
"author": "CloudronApp",
|
||||
"description": "Homebox is an inventory and organization system built for home users. Manage your home inventory with a simple, fast, and lightweight application.",
|
||||
"tagline": "Simple home inventory management",
|
||||
"version": "1.0.0",
|
||||
"healthCheckPath": "/",
|
||||
"httpPort": 7745,
|
||||
"addons": {
|
||||
"localstorage": {
|
||||
"description": "Data directory for Homebox"
|
||||
}
|
||||
},
|
||||
"manifestVersion": 2,
|
||||
"website": "https://homebox.software/",
|
||||
"contactEmail": "support@homebox.software",
|
||||
"icon": "file://logo.png",
|
||||
"tags": [
|
||||
"inventory",
|
||||
"organization",
|
||||
"asset-management",
|
||||
"home"
|
||||
],
|
||||
"minBoxVersion": "7.5.0",
|
||||
"documentationUrl": "https://homebox.software/en/",
|
||||
"forumUrl": "https://github.com/sysadminsmedia/homebox/discussions",
|
||||
"postInstallMessage": "Homebox has been successfully installed! The first user to register will be the administrator. You can disable registration after creating the first account.",
|
||||
"memoryLimit": 256000000,
|
||||
"targetBoxVersion": "7.5.0",
|
||||
"changelog": "Initial Cloudron package",
|
||||
"mediaLinks": [],
|
||||
"containerOptions": {
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
FROM cloudron/base:4.2.0
|
||||
|
||||
# Add version specifics
|
||||
ARG VERSION=latest
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Update the system and install dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
curl \
|
||||
ca-certificates \
|
||||
wget \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set up directory structure following Cloudron filesystem layout
|
||||
RUN mkdir -p /app/code /app/data /tmp/data
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app/code
|
||||
|
||||
# Download and install the latest Homebox release
|
||||
RUN if [ "$VERSION" = "latest" ]; then \
|
||||
DOWNLOAD_URL=$(curl -s https://api.github.com/repos/sysadminsmedia/homebox/releases/latest | grep "browser_download_url.*linux_amd64" | cut -d '"' -f 4); \
|
||||
else \
|
||||
DOWNLOAD_URL="https://github.com/sysadminsmedia/homebox/releases/download/v${VERSION}/homebox_${VERSION}_linux_amd64.tar.gz"; \
|
||||
fi && \
|
||||
wget -O /tmp/homebox.tar.gz ${DOWNLOAD_URL} && \
|
||||
tar -xzf /tmp/homebox.tar.gz -C /app/code && \
|
||||
rm /tmp/homebox.tar.gz && \
|
||||
chmod +x /app/code/homebox
|
||||
|
||||
# Copy initialization template for /app/data
|
||||
COPY data_init /tmp/data/
|
||||
|
||||
# Copy application scripts
|
||||
COPY start.sh /app/code/
|
||||
RUN chmod +x /app/code/start.sh
|
||||
|
||||
# Copy NGINX configuration
|
||||
COPY nginx.conf /app/code/
|
||||
|
||||
# Set ownership to cloudron user
|
||||
RUN chown -R cloudron:cloudron /app/code /tmp/data
|
||||
|
||||
# Set entrypoint
|
||||
ENTRYPOINT ["/app/code/start.sh"]
|
@@ -1,67 +0,0 @@
|
||||
worker_processes auto;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 768;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
server_tokens off;
|
||||
|
||||
# Mime types
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Logging
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr;
|
||||
|
||||
# Gzip settings
|
||||
gzip on;
|
||||
gzip_disable "msie6";
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
# Virtual Host Configs
|
||||
server {
|
||||
listen 8000 default_server;
|
||||
listen [::]:8000 default_server;
|
||||
|
||||
server_name _;
|
||||
|
||||
# Maximum upload size
|
||||
client_max_body_size 100M;
|
||||
|
||||
# Proxy settings
|
||||
proxy_buffers 16 16k;
|
||||
proxy_buffer_size 16k;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:7745;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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-Port $server_port;
|
||||
|
||||
# Set timeouts
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,108 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Ensure proper directory structure in /app/data
|
||||
if [ ! -d "/app/data/.database" ]; then
|
||||
echo "Initializing data directory structure..."
|
||||
mkdir -p /app/data/.database
|
||||
mkdir -p /app/data/uploads
|
||||
|
||||
# Copy initialization files if provided
|
||||
if [ -d "/tmp/data" ]; then
|
||||
cp -r /tmp/data/* /app/data/
|
||||
fi
|
||||
|
||||
# Fix permissions
|
||||
chown -R cloudron:cloudron /app/data
|
||||
chmod -R 750 /app/data
|
||||
fi
|
||||
|
||||
# Set environment variables for Homebox
|
||||
export HBOX_MODE=production
|
||||
export HBOX_STORAGE_DATA=/app/data
|
||||
export HBOX_DATABASE_DRIVER=sqlite3
|
||||
export HBOX_DATABASE_SQLITE_PATH="/app/data/.database/homebox.db"
|
||||
export HBOX_WEB_PORT=7745
|
||||
export HBOX_WEB_HOST=127.0.0.1
|
||||
export HBOX_LOG_LEVEL=info
|
||||
export HBOX_LOG_FORMAT=text
|
||||
export HBOX_WEB_MAX_FILE_UPLOAD=50
|
||||
|
||||
# Check if registration should be disabled by default
|
||||
# If this is a fresh install, we'll allow registration for first user
|
||||
if [ ! -f "/app/data/.database/homebox.db" ]; then
|
||||
export HBOX_OPTIONS_ALLOW_REGISTRATION=true
|
||||
else
|
||||
export HBOX_OPTIONS_ALLOW_REGISTRATION=false
|
||||
fi
|
||||
|
||||
# Configure NGINX
|
||||
echo "Configuring NGINX..."
|
||||
mkdir -p /run/nginx
|
||||
cat > /app/data/nginx.conf <<EOF
|
||||
worker_processes auto;
|
||||
daemon off;
|
||||
pid /run/nginx/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
client_max_body_size 50M;
|
||||
|
||||
# Logging to stdout for Cloudron to capture
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr;
|
||||
|
||||
server {
|
||||
listen 8000;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:7745;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Start Supervisor which will manage our processes
|
||||
echo "Starting supervisor..."
|
||||
cat > /etc/supervisor/conf.d/homebox.conf <<EOF
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
|
||||
[program:homebox]
|
||||
command=/app/code/homebox
|
||||
directory=/app/code
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
user=cloudron
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=10
|
||||
|
||||
[program:nginx]
|
||||
command=nginx -c /app/data/nginx.conf
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=20
|
||||
EOF
|
||||
|
||||
# Start supervisor
|
||||
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"id": "app.homechart.cloudron",
|
||||
"title": "HomeChart",
|
||||
"author": "HomeChart Package Maintainer",
|
||||
"description": "Your all-in-one household management platform. Organize calendars, budgets, shopping lists, and more in one place. Enjoy features like shared calendars, meal planning, task management, and multilingual support. Secure, private, and ad-free.",
|
||||
"tagline": "Your Family's Mission Control",
|
||||
"version": "1.0.0",
|
||||
"upstreamVersion": "2024.09.0",
|
||||
"healthCheckPath": "/",
|
||||
"httpPort": 3000,
|
||||
"memoryLimit": 512,
|
||||
"addons": {
|
||||
"localstorage": {},
|
||||
"postgresql": {
|
||||
"version": "16"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"household",
|
||||
"family",
|
||||
"organization",
|
||||
"calendar",
|
||||
"budget",
|
||||
"tasks"
|
||||
],
|
||||
"postInstallMessage": "HomeChart has been installed successfully! You can now access your family's mission control panel.\n\nThe default administrator credentials are:\nUsername: admin@example.com\nPassword: changeme\n\nPlease login and change these credentials immediately.",
|
||||
"manifestVersion": 2,
|
||||
"website": "https://homechart.app/",
|
||||
"contactEmail": "support@example.com",
|
||||
"icon": "file://logo.png",
|
||||
"minBoxVersion": "5.4.0",
|
||||
"forumUrl": "https://forum.cloudron.io/",
|
||||
"documentationUrl": "https://homechart.app/docs/",
|
||||
"changelog": "Initial Cloudron package for HomeChart",
|
||||
"configurePath": "/settings",
|
||||
"oauth": {
|
||||
"loginRedirectUri": "/oidc",
|
||||
"scope": "openid email profile"
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
FROM cloudron/base:4.2.0
|
||||
|
||||
# Install required dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
supervisor \
|
||||
nginx \
|
||||
tzdata \
|
||||
gosu && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create the application directory structure
|
||||
RUN mkdir -p /app/code /app/data /run/nginx
|
||||
|
||||
# Create homechart data directories structure
|
||||
RUN mkdir -p /tmp/data
|
||||
|
||||
# Download the latest HomeChart release
|
||||
RUN curl -L -o /app/code/homechart.tar.gz https://github.com/candiddev/homechart/releases/latest/download/homechart_linux_amd64.tar.gz && \
|
||||
tar -xzf /app/code/homechart.tar.gz -C /app/code && \
|
||||
rm /app/code/homechart.tar.gz && \
|
||||
mv /app/code/homechart_linux_amd64 /app/code/homechart && \
|
||||
chmod +x /app/code/homechart
|
||||
|
||||
# Add NGINX configuration
|
||||
COPY nginx.conf /etc/nginx/sites-enabled/homechart.conf
|
||||
RUN rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Add Supervisor configuration
|
||||
COPY supervisor.conf /etc/supervisor/conf.d/homechart.conf
|
||||
|
||||
# Add the startup script
|
||||
COPY start.sh /app/code/
|
||||
RUN chmod +x /app/code/start.sh
|
||||
|
||||
# Set permissions
|
||||
RUN chown -R cloudron:cloudron /app/code /app/data /run/nginx
|
||||
|
||||
# Expose the port (should match the httpPort in the CloudronManifest.json)
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["/app/code/start.sh"]
|
@@ -1,107 +0,0 @@
|
||||
# HomeChart Cloudron Package - Build Notes
|
||||
|
||||
This document provides instructions for building, testing, and deploying the HomeChart Cloudron package.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. A running Cloudron instance
|
||||
2. Docker installed on your local machine
|
||||
3. Cloudron CLI tool installed (`npm install -g cloudron`)
|
||||
4. Git for cloning the repository
|
||||
|
||||
## Files Overview
|
||||
|
||||
- **CloudronManifest.json**: Contains metadata and configuration for the Cloudron app
|
||||
- **Dockerfile**: Defines how to build the Docker image for HomeChart
|
||||
- **start.sh**: Startup script that handles initialization and configuration
|
||||
- **nginx.conf**: NGINX configuration for proxying requests
|
||||
- **supervisor.conf**: Supervisor configuration for process management
|
||||
|
||||
## Building and Deploying
|
||||
|
||||
### Step 1: Clone the repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/yourusername/homechart-cloudron.git
|
||||
cd homechart-cloudron
|
||||
```
|
||||
|
||||
### Step 2: Build the Docker image
|
||||
|
||||
```bash
|
||||
# Login to Docker Hub if not already logged in
|
||||
docker login
|
||||
|
||||
# Build the image
|
||||
cloudron build
|
||||
```
|
||||
|
||||
When prompted, enter a repository name in the format `username/homechart` where `username` is your Docker Hub username.
|
||||
|
||||
### Step 3: Install on your Cloudron
|
||||
|
||||
```bash
|
||||
# Install the app
|
||||
cloudron install —image username/homechart:latest
|
||||
```
|
||||
|
||||
You’ll be prompted to select a subdomain for the app.
|
||||
|
||||
### Step 4: Configure the app
|
||||
|
||||
After installation, you’ll need to:
|
||||
|
||||
1. Log in using the default credentials provided in the post-install message
|
||||
2. Change the default administrator password
|
||||
3. Set up your household and invite family members
|
||||
|
||||
## Updating the App
|
||||
|
||||
To update the app after making changes:
|
||||
|
||||
```bash
|
||||
# Rebuild the Docker image
|
||||
cloudron build
|
||||
|
||||
# Update the installed app
|
||||
cloudron update —app homechart
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
HomeChart is configured to use Cloudron’s OIDC provider for authentication. Users from your Cloudron instance can log in to HomeChart using their Cloudron credentials.
|
||||
|
||||
## Data Persistence
|
||||
|
||||
All HomeChart data is stored in:
|
||||
- PostgreSQL database (managed by Cloudron)
|
||||
- `/app/data` directory (backed up by Cloudron)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
cloudron logs -f —app homechart
|
||||
```
|
||||
|
||||
### Database access
|
||||
|
||||
To access the PostgreSQL database directly:
|
||||
|
||||
```bash
|
||||
cloudron exec —app homechart
|
||||
psql -U “$CLOUDRON_POSTGRESQL_USERNAME” -h “$CLOUDRON_POSTGRESQL_HOST” “$CLOUDRON_POSTGRESQL_DATABASE”
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
|
||||
- **OIDC configuration issues**: Ensure the Cloudron environment variables are correctly passed to the app
|
||||
- **Database connection errors**: Check PostgreSQL connection details in the app config
|
||||
- **Memory limits**: If the app crashes due to memory issues, increase the memory limit in the CloudronManifest.json
|
||||
|
||||
## Resources
|
||||
|
||||
- [HomeChart Documentation](https://homechart.app/docs/)
|
||||
- [Cloudron Documentation](https://docs.cloudron.io/)
|
||||
- [HomeChart GitHub Repository](https://github.com/candiddev/homechart)
|
@@ -1,42 +0,0 @@
|
||||
server {
|
||||
listen 3000;
|
||||
server_name localhost;
|
||||
|
||||
# Add proper headers for running behind Cloudron's proxy
|
||||
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;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
# Custom Cloudron error pages
|
||||
error_page 403 /error/403.html;
|
||||
error_page 404 /error/404.html;
|
||||
error_page 50x /error/50x.html;
|
||||
location ^~ /error/ {
|
||||
alias /app/code/public/error/;
|
||||
internal;
|
||||
}
|
||||
|
||||
# Use Cloudron's runtime directory for nginx (read-only filesystem)
|
||||
client_body_temp_path /run/nginx/body;
|
||||
proxy_temp_path /run/nginx/proxy;
|
||||
fastcgi_temp_path /run/nginx/fastcgi;
|
||||
uwsgi_temp_path /run/nginx/uwsgi;
|
||||
scgi_temp_path /run/nginx/scgi;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
}
|
||||
|
||||
# Needed for Cloudron's health checks
|
||||
location = /healthcheck {
|
||||
access_log off;
|
||||
return 200;
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Create required runtime directories
|
||||
mkdir -p /run/nginx/body /run/nginx/proxy /run/nginx/fastcgi /run/nginx/uwsgi /run/nginx/scgi
|
||||
chown -R cloudron:cloudron /run/nginx
|
||||
|
||||
# Initialize data directory if not existing
|
||||
if [ ! -d "/app/data/config" ]; then
|
||||
mkdir -p /app/data/config
|
||||
chown -R cloudron:cloudron /app/data
|
||||
fi
|
||||
|
||||
# Configuration
|
||||
CONFIG_FILE="/app/data/config/homechart.json"
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
echo "Creating initial configuration file..."
|
||||
cat > "$CONFIG_FILE" <<EOL
|
||||
{
|
||||
"app": {
|
||||
"baseURL": "${CLOUDRON_APP_ORIGIN}",
|
||||
"proxyAddr": "127.0.0.1, 172.18.0.1"
|
||||
},
|
||||
"postgresql": {
|
||||
"hostname": "${CLOUDRON_POSTGRESQL_HOST}",
|
||||
"username": "${CLOUDRON_POSTGRESQL_USERNAME}",
|
||||
"password": "${CLOUDRON_POSTGRESQL_PASSWORD}",
|
||||
"database": "${CLOUDRON_POSTGRESQL_DATABASE}"
|
||||
},
|
||||
"oidc": {
|
||||
"cloudron": {
|
||||
"clientID": "${CLOUDRON_OIDC_CLIENT_ID}",
|
||||
"clientSecret": "${CLOUDRON_OIDC_CLIENT_SECRET}",
|
||||
"displayName": "Cloudron",
|
||||
"oidcIssuerURL": "${CLOUDRON_OIDC_ISSUER}"
|
||||
}
|
||||
},
|
||||
"logging": {
|
||||
"level": "info"
|
||||
}
|
||||
}
|
||||
EOL
|
||||
chown cloudron:cloudron "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# Link HomeChart configuration
|
||||
export HOMECHART_CONFIG_FILE="$CONFIG_FILE"
|
||||
|
||||
# Set the port for HomeChart to run on (internal port)
|
||||
export HOMECHART_APP_PORT=8000
|
||||
|
||||
# Start supervisor which manages nginx and homechart
|
||||
exec /usr/bin/supervisord --configuration /etc/supervisor/supervisord.conf
|
@@ -1,28 +0,0 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
pidfile=/var/run/supervisord.pid
|
||||
|
||||
[program:nginx]
|
||||
priority=10
|
||||
command=nginx -g "daemon off;"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:homechart]
|
||||
priority=20
|
||||
directory=/app/code
|
||||
command=/app/code/homechart
|
||||
user=cloudron
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
environment=HOME="/app/data"
|
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"id": "org.inventree.cloudronapp",
|
||||
"title": "InvenTree",
|
||||
"author": "Your Name",
|
||||
"description": "InvenTree is an open-source inventory management system which provides intuitive parts management and stock control.",
|
||||
"tagline": "Open Source Inventory Management System",
|
||||
"version": "1.0.0",
|
||||
"healthCheckPath": "/",
|
||||
"httpPort": 8000,
|
||||
"manifestVersion": 2,
|
||||
"website": "https://inventree.org",
|
||||
"contactEmail": "your.email@example.com",
|
||||
"icon": "logo.png",
|
||||
"documentationUrl": "https://docs.inventree.org",
|
||||
"memoryLimit": 1024000000,
|
||||
"configurePath": "/admin",
|
||||
"minBoxVersion": "7.0.0",
|
||||
"changelog": "Initial version",
|
||||
"addons": {
|
||||
"localstorage": {},
|
||||
"postgresql": {}
|
||||
},
|
||||
"postInstallMessage": "InvenTree has been installed. The default admin credentials are:\n\nUsername: admin\nPassword: admin\n\nPlease change the admin password after your first login."
|
||||
}
|
@@ -1,74 +0,0 @@
|
||||
FROM cloudron/base:4.2.0
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
INVENTREE_HOME=/app/data \
|
||||
INVENTREE_MEDIA_ROOT=/app/data/media \
|
||||
INVENTREE_STATIC_ROOT=/app/data/static \
|
||||
INVENTREE_SECRET_KEY_FILE=/app/data/secret_key.txt \
|
||||
INVENTREE_PLUGINS_ENABLED=true \
|
||||
INVENTREE_PLUGINS_DIR=/app/data/plugins \
|
||||
INVENTREE_ADMIN_USER=admin \
|
||||
INVENTREE_ADMIN_PASSWORD=admin \
|
||||
INVENTREE_ADMIN_EMAIL=admin@example.com
|
||||
|
||||
# Install required packages
|
||||
RUN apt-get update && apt-get install -y \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-dev \
|
||||
python3-venv \
|
||||
build-essential \
|
||||
libpq-dev \
|
||||
git \
|
||||
nginx \
|
||||
supervisor \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Setup nginx for Cloudron
|
||||
RUN rm /etc/nginx/sites-enabled/* \
|
||||
&& sed -e 's,^ErrorLog.*,ErrorLog "/dev/stderr",' -i /etc/nginx/nginx.conf \
|
||||
&& echo "daemon off;" >> /etc/nginx/nginx.conf
|
||||
|
||||
# Create InvenTree directories
|
||||
RUN mkdir -p /app/code \
|
||||
&& mkdir -p /tmp/data/media \
|
||||
&& mkdir -p /tmp/data/static \
|
||||
&& mkdir -p /tmp/data/plugins \
|
||||
&& mkdir -p /tmp/data/env \
|
||||
&& mkdir -p /tmp/data/config
|
||||
|
||||
# Create Python virtual environment
|
||||
RUN python3 -m venv /app/code/env
|
||||
|
||||
# Clone InvenTree source code
|
||||
RUN git clone --depth 1 https://github.com/inventree/InvenTree.git /app/code/inventree
|
||||
|
||||
# Install InvenTree requirements
|
||||
WORKDIR /app/code/inventree
|
||||
RUN /app/code/env/bin/pip install --upgrade pip \
|
||||
&& /app/code/env/bin/pip install wheel \
|
||||
&& /app/code/env/bin/pip install --no-cache-dir -r requirements.txt \
|
||||
&& /app/code/env/bin/pip install psycopg2 gunicorn
|
||||
|
||||
# Create default configuration files
|
||||
COPY config.yaml /tmp/data/config/config.yaml
|
||||
COPY nginx.conf /etc/nginx/sites-available/inventree
|
||||
RUN ln -s /etc/nginx/sites-available/inventree /etc/nginx/sites-enabled/
|
||||
|
||||
# Copy supervisor configuration
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
# Add startup script
|
||||
COPY start.sh /app/code/start.sh
|
||||
RUN chmod +x /app/code/start.sh
|
||||
|
||||
# Setup NGINX runtime directory
|
||||
RUN mkdir -p /run/nginx \
|
||||
&& chown -R cloudron:cloudron /run/nginx
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["/app/code/start.sh"]
|
@@ -1,74 +0,0 @@
|
||||
# InvenTree Cloudron Build Notes
|
||||
|
||||
## Package Contents
|
||||
- CloudronManifest.json - App metadata and resource configuration
|
||||
- Dockerfile - Container build instructions
|
||||
- start.sh - App initialization and startup script
|
||||
- config.yaml - InvenTree configuration template
|
||||
- nginx.conf - Web server configuration
|
||||
- supervisord.conf - Process management configuration
|
||||
|
||||
## Build & Deploy Steps
|
||||
|
||||
### 1. Prepare Local Directory
|
||||
```bash
|
||||
mkdir -p inventree-cloudron
|
||||
cd inventree-cloudron
|
||||
# Copy all files into this directory
|
||||
```
|
||||
|
||||
### 2. Build & Push to Gitea Registry
|
||||
```bash
|
||||
# Login to your Gitea Docker registry
|
||||
docker login gitea.yourdomain.com
|
||||
|
||||
# Build the Docker image
|
||||
docker build -t gitea.yourdomain.com/yourusername/inventree:1.0.0 .
|
||||
|
||||
# Push the image to your registry
|
||||
docker push gitea.yourdomain.com/yourusername/inventree:1.0.0
|
||||
```
|
||||
|
||||
### 3. Install on Cloudron
|
||||
```bash
|
||||
# Login to your Cloudron
|
||||
cloudron login my.cloudron.example
|
||||
|
||||
# Install the app
|
||||
cloudron install --image gitea.yourdomain.com/yourusername/inventree:1.0.0
|
||||
```
|
||||
|
||||
### 4. Update Process
|
||||
```bash
|
||||
# Build with new version tag
|
||||
docker build -t gitea.yourdomain.com/yourusername/inventree:1.0.1 .
|
||||
docker push gitea.yourdomain.com/yourusername/inventree:1.0.1
|
||||
|
||||
# Update existing installation
|
||||
cloudron update --app inventree.my.cloudron.example --image gitea.yourdomain.com/yourusername/inventree:1.0.1
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Database Issues
|
||||
If database migrations fail:
|
||||
```bash
|
||||
cloudron exec --app inventree.my.cloudron.example -- /app/code/env/bin/python /app/code/inventree/manage.py migrate
|
||||
```
|
||||
|
||||
### Inspect Logs
|
||||
```bash
|
||||
cloudron logs --app inventree.my.cloudron.example
|
||||
```
|
||||
|
||||
### Debug Mode
|
||||
```bash
|
||||
cloudron debug --app inventree.my.cloudron.example
|
||||
```
|
||||
|
||||
## Initial Access
|
||||
After installation, access InvenTree at your configured domain with:
|
||||
- Username: admin
|
||||
- Password: admin
|
||||
|
||||
**Important**: Change this password immediately after first login!
|
@@ -1,49 +0,0 @@
|
||||
# InvenTree configuration file for Cloudron
|
||||
# Refer to InvenTree documentation for detailed configuration options
|
||||
|
||||
# Database connection settings will be provided via environment variables
|
||||
|
||||
# General settings
|
||||
debug: False
|
||||
log_level: WARNING
|
||||
|
||||
# Secret key will be stored in a file
|
||||
secret_key_file: /app/data/secret_key.txt
|
||||
|
||||
# Plugin settings
|
||||
plugins:
|
||||
enabled: True
|
||||
plugin_dir: /app/data/plugins
|
||||
|
||||
# File storage locations
|
||||
media_root: /app/data/media
|
||||
static_root: /app/data/static
|
||||
|
||||
# Email settings - adjust with your Cloudron email settings if needed
|
||||
email:
|
||||
host: localhost
|
||||
port: 25
|
||||
tls: false
|
||||
ssl: false
|
||||
sender: inventree@localhost
|
||||
|
||||
# Login settings
|
||||
login:
|
||||
default_protocol: https
|
||||
allow_unverified_signup: False
|
||||
allow_signup: True
|
||||
signup_email_verification: False
|
||||
login_confirm_days: 3
|
||||
password_reset_timeout_days: 3
|
||||
|
||||
# Display settings
|
||||
customization:
|
||||
instance_name: InvenTree
|
||||
default_currency: USD
|
||||
base_url: "" # Will be set by environment variable in start.sh
|
||||
|
||||
# Server settings
|
||||
server:
|
||||
workers: 2
|
||||
allowed_hosts:
|
||||
- '*' # Cloudron handles this
|
@@ -1,35 +0,0 @@
|
||||
server {
|
||||
listen 8000; # This should match the httpPort in CloudronManifest.json
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr;
|
||||
|
||||
# Serve static files
|
||||
location /static/ {
|
||||
alias /app/data/static/;
|
||||
expires 30d;
|
||||
add_header Pragma public;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
# Serve media files
|
||||
location /media/ {
|
||||
alias /app/data/media/;
|
||||
expires 30d;
|
||||
add_header Pragma public;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
# Proxy requests to gunicorn
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8001;
|
||||
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_redirect off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# PostgreSQL configuration from Cloudron environment variables
|
||||
if [ -n "${CLOUDRON_POSTGRESQL_HOST}" ]; then
|
||||
export INVENTREE_DB_ENGINE="postgresql"
|
||||
export INVENTREE_DB_NAME="${CLOUDRON_POSTGRESQL_DATABASE}"
|
||||
export INVENTREE_DB_USER="${CLOUDRON_POSTGRESQL_USERNAME}"
|
||||
export INVENTREE_DB_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}"
|
||||
export INVENTREE_DB_HOST="${CLOUDRON_POSTGRESQL_HOST}"
|
||||
export INVENTREE_DB_PORT="${CLOUDRON_POSTGRESQL_PORT}"
|
||||
else
|
||||
echo "PostgreSQL addon not configured!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure data directories exist
|
||||
if [ ! -d "${INVENTREE_HOME}/media" ]; then
|
||||
echo "Creating media directory..."
|
||||
mkdir -p "${INVENTREE_HOME}/media"
|
||||
cp -rn /tmp/data/media/* "${INVENTREE_HOME}/media/" || true
|
||||
fi
|
||||
|
||||
if [ ! -d "${INVENTREE_HOME}/static" ]; then
|
||||
echo "Creating static directory..."
|
||||
mkdir -p "${INVENTREE_HOME}/static"
|
||||
cp -rn /tmp/data/static/* "${INVENTREE_HOME}/static/" || true
|
||||
fi
|
||||
|
||||
if [ ! -d "${INVENTREE_HOME}/plugins" ]; then
|
||||
echo "Creating plugins directory..."
|
||||
mkdir -p "${INVENTREE_HOME}/plugins"
|
||||
cp -rn /tmp/data/plugins/* "${INVENTREE_HOME}/plugins/" || true
|
||||
fi
|
||||
|
||||
if [ ! -d "${INVENTREE_HOME}/config" ]; then
|
||||
echo "Creating config directory..."
|
||||
mkdir -p "${INVENTREE_HOME}/config"
|
||||
cp -rn /tmp/data/config/* "${INVENTREE_HOME}/config/" || true
|
||||
fi
|
||||
|
||||
# Generate secret key if it doesn't exist
|
||||
if [ ! -f "${INVENTREE_SECRET_KEY_FILE}" ]; then
|
||||
echo "Generating secret key..."
|
||||
python3 -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())" > "${INVENTREE_SECRET_KEY_FILE}"
|
||||
fi
|
||||
|
||||
cd /app/code/inventree
|
||||
|
||||
# Set InvenTree base URL (from Cloudron environment)
|
||||
export INVENTREE_BASE_URL="https://${CLOUDRON_APP_DOMAIN}"
|
||||
|
||||
# Apply database migrations and collect static files
|
||||
echo "Applying database migrations..."
|
||||
/app/code/env/bin/python manage.py migrate --noinput
|
||||
|
||||
echo "Collecting static files..."
|
||||
/app/code/env/bin/python manage.py collectstatic --noinput
|
||||
|
||||
# Create superuser if not exists
|
||||
echo "Checking for superuser..."
|
||||
DJANGO_SUPERUSER_PASSWORD="${INVENTREE_ADMIN_PASSWORD}" \
|
||||
/app/code/env/bin/python manage.py createsuperuser --noinput \
|
||||
--username "${INVENTREE_ADMIN_USER}" \
|
||||
--email "${INVENTREE_ADMIN_EMAIL}" || true
|
||||
|
||||
# Set proper permissions
|
||||
chown -R cloudron:cloudron "${INVENTREE_HOME}"
|
||||
|
||||
# Start supervisor to manage processes
|
||||
echo "Starting supervisor..."
|
||||
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
@@ -1,26 +0,0 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
user=root
|
||||
logfile=/dev/stdout
|
||||
logfile_maxbytes=0
|
||||
|
||||
[program:gunicorn]
|
||||
command=/app/code/env/bin/gunicorn InvenTree.wsgi --bind 127.0.0.1:8001 --workers 2 --timeout 60 --preload --forwarded-allow-ips='*'
|
||||
directory=/app/code/inventree
|
||||
user=cloudron
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
environment=PYTHONUNBUFFERED=1,INVENTREE_CONFIG_FILE=/app/data/config/config.yaml
|
||||
|
||||
[program:nginx]
|
||||
command=/usr/sbin/nginx
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
@@ -1,26 +0,0 @@
|
||||
jenkins:
|
||||
systemMessage: "Jenkins configured with local authentication"
|
||||
securityRealm:
|
||||
local:
|
||||
allowsSignup: false
|
||||
enableCaptcha: false
|
||||
users:
|
||||
- id: "admin"
|
||||
password: "adminpass"
|
||||
|
||||
authorizationStrategy:
|
||||
globalMatrix:
|
||||
permissions:
|
||||
- "Overall/Administer:admin"
|
||||
- "Overall/Read:authenticated"
|
||||
- "Job/Read:authenticated"
|
||||
- "Job/Build:authenticated"
|
||||
- "Job/Create:authenticated"
|
||||
- "Job/Configure:authenticated"
|
||||
- "View/Read:authenticated"
|
||||
- "View/Create:authenticated"
|
||||
- "View/Configure:authenticated"
|
||||
|
||||
unclassified:
|
||||
location:
|
||||
url: "${JENKINS_URL}"
|
@@ -1,32 +0,0 @@
|
||||
jenkins:
|
||||
systemMessage: "Jenkins configured with Cloudron LDAP authentication"
|
||||
securityRealm:
|
||||
ldap:
|
||||
configurations:
|
||||
- server: "${CLOUDRON_LDAP_SERVER}"
|
||||
rootDN: "${CLOUDRON_LDAP_USERS_BASE_DN}"
|
||||
managerDN: "${CLOUDRON_LDAP_BIND_DN}"
|
||||
managerPasswordSecret: "${CLOUDRON_LDAP_BIND_PASSWORD}"
|
||||
userSearchBase: ""
|
||||
userSearch: "uid={0}"
|
||||
groupSearchBase: "${CLOUDRON_LDAP_GROUPS_BASE_DN}"
|
||||
groupSearchFilter: "memberUid={0}"
|
||||
displayNameAttributeName: "displayName"
|
||||
mailAddressAttributeName: "mail"
|
||||
|
||||
authorizationStrategy:
|
||||
globalMatrix:
|
||||
permissions:
|
||||
- "Overall/Administer:admin"
|
||||
- "Overall/Read:authenticated"
|
||||
- "Job/Read:authenticated"
|
||||
- "Job/Build:authenticated"
|
||||
- "Job/Create:authenticated"
|
||||
- "Job/Configure:authenticated"
|
||||
- "View/Read:authenticated"
|
||||
- "View/Create:authenticated"
|
||||
- "View/Configure:authenticated"
|
||||
|
||||
unclassified:
|
||||
location:
|
||||
url: "${JENKINS_URL}"
|
@@ -1,35 +0,0 @@
|
||||
jenkins:
|
||||
systemMessage: "Jenkins configured with Cloudron OpenID Connect authentication"
|
||||
securityRealm:
|
||||
oic:
|
||||
clientId: "${CLOUDRON_OAUTH_CLIENT_ID}"
|
||||
clientSecret: "${CLOUDRON_OAUTH_CLIENT_SECRET}"
|
||||
wellKnownOpenIDConfigurationUrl: "${CLOUDRON_OAUTH_ORIGIN}/.well-known/openid-configuration"
|
||||
userNameField: "preferred_username"
|
||||
tokenAuthMethod: "client_secret_basic"
|
||||
scopes: "openid email profile groups"
|
||||
fullNameFieldName: "name"
|
||||
emailFieldName: "email"
|
||||
groupsFieldName: "groups"
|
||||
pkceEnabled: true
|
||||
escapeHatchEnabled: true
|
||||
escapeHatchUsername: "admin"
|
||||
escapeHatchSecret: "adminpass"
|
||||
escapeHatchGroup: "admin"
|
||||
|
||||
authorizationStrategy:
|
||||
globalMatrix:
|
||||
permissions:
|
||||
- "Overall/Administer:admin"
|
||||
- "Overall/Read:authenticated"
|
||||
- "Job/Read:authenticated"
|
||||
- "Job/Build:authenticated"
|
||||
- "Job/Create:authenticated"
|
||||
- "Job/Configure:authenticated"
|
||||
- "View/Read:authenticated"
|
||||
- "View/Create:authenticated"
|
||||
- "View/Configure:authenticated"
|
||||
|
||||
unclassified:
|
||||
location:
|
||||
url: "${JENKINS_URL}"
|
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"id": "org.reviewboard.cloudron",
|
||||
"title": "ReviewBoard",
|
||||
"author": "Beanbag, Inc.",
|
||||
"description": "ReviewBoard is a web-based code review tool that helps projects and companies keep their code quality high and their bug count low.",
|
||||
"tagline": "A powerful web-based code review tool",
|
||||
"version": "1.0.0",
|
||||
"healthCheckPath": "/",
|
||||
"httpPort": 8000,
|
||||
"manifestVersion": 2,
|
||||
"website": "https://www.reviewboard.org",
|
||||
"documentationUrl": "https://www.reviewboard.org/docs/",
|
||||
"contactEmail": "support@cloudron.io",
|
||||
"icon": "file://logo.png",
|
||||
"tags": [
|
||||
"developer",
|
||||
"code-review",
|
||||
"collaboration"
|
||||
],
|
||||
"memoryLimit": 768,
|
||||
"addons": {
|
||||
"localstorage": {},
|
||||
"postgresql": {
|
||||
"version": "14"
|
||||
},
|
||||
"oidc": {
|
||||
"loginRedirectUri": "/api/v1/session/callback",
|
||||
"logoutRedirectUri": "/home",
|
||||
"tokenSignatureAlgorithm": "RS256"
|
||||
}
|
||||
},
|
||||
"minBoxVersion": "7.0.0",
|
||||
"postInstallMessage": "The initial admin account is created automatically using your Cloudron credentials. Please open the app to complete the setup process.",
|
||||
"installationProgress": {
|
||||
"message": "Installing ReviewBoard. This might take a few minutes...",
|
||||
"steps": [
|
||||
{ "id": "download", "title": "Downloading" },
|
||||
{ "id": "install", "title": "Installing Dependencies" },
|
||||
{ "id": "setup", "title": "Setting up ReviewBoard" },
|
||||
{ "id": "configure", "title": "Configuring for Cloudron" }
|
||||
]
|
||||
}
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
FROM cloudron/base:4.2.0
|
||||
|
||||
# Install required packages
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
python3 python3-pip python3-dev python3-venv \
|
||||
nginx supervisor \
|
||||
memcached libpq-dev \
|
||||
libldap2-dev libsasl2-dev \
|
||||
git-core subversion \
|
||||
libxml2-dev libxslt1-dev \
|
||||
libmagic-dev \
|
||||
gcc && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create Python virtual environment
|
||||
RUN python3 -m venv /app/code/venv
|
||||
ENV PATH="/app/code/venv/bin:${PATH}"
|
||||
|
||||
# Install Review Board dependencies
|
||||
RUN pip3 install --no-cache-dir --upgrade pip wheel setuptools && \
|
||||
pip3 install --no-cache-dir psycopg2-binary gunicorn django-storages
|
||||
|
||||
# Install Review Board
|
||||
RUN pip3 install --no-cache-dir reviewboard
|
||||
|
||||
# Install OIDC authentication
|
||||
RUN pip3 install --no-cache-dir mozilla-django-oidc
|
||||
|
||||
# Install LDAP authentication
|
||||
RUN pip3 install --no-cache-dir django-auth-ldap
|
||||
|
||||
# Make the data directories ready
|
||||
RUN mkdir -p /app/data/media /app/data/static /app/data/logs /app/data/conf /app/data/site
|
||||
|
||||
# Copy configuration files
|
||||
COPY nginx.conf /etc/nginx/sites-available/default
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
COPY start.sh /app/code/start.sh
|
||||
RUN chmod +x /app/code/start.sh
|
||||
|
||||
# Set up the entry point
|
||||
CMD ["/app/code/start.sh"]
|
@@ -1,147 +0,0 @@
|
||||
# Review Board - Cloudron Build Notes
|
||||
|
||||
This document provides instructions for building, testing, and deploying the Review Board Cloudron package.
|
||||
|
||||
## Package Overview
|
||||
|
||||
Review Board is a powerful web-based code review tool that helps teams review code, documents, and images before they are committed. This package configures Review Board to run on Cloudron with the following features:
|
||||
|
||||
- PostgreSQL database for data storage
|
||||
- Memcached for caching
|
||||
- Nginx as the web server
|
||||
- Gunicorn as the WSGI server
|
||||
- Support for Cloudron’s OIDC and LDAP authentication
|
||||
- Proper data separation following Cloudron’s filesystem layout
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Cloudron CLI tool installed (`npm install -g cloudron`)
|
||||
2. Docker installed and running
|
||||
3. Cloudron account with administrative access
|
||||
|
||||
## Files Included in the Package
|
||||
|
||||
1. **CloudronManifest.json** - Defines the application for Cloudron
|
||||
2. **Dockerfile** - Instructions for building the Docker image
|
||||
3. **start.sh** - Initialization and startup script
|
||||
4. **supervisord.conf** - Process management configuration
|
||||
5. **nginx.conf** - Web server configuration
|
||||
|
||||
## Building the Package
|
||||
|
||||
1. Create a new directory for your package files:
|
||||
```bash
|
||||
mkdir reviewboard-cloudron
|
||||
cd reviewboard-cloudron
|
||||
```
|
||||
|
||||
2. Create all the package files in this directory.
|
||||
|
||||
3. Download the Review Board icon and save it as `icon.png`:
|
||||
```bash
|
||||
curl -L “https://raw.githubusercontent.com/reviewboard/reviewboard/master/reviewboard/static/rb/images/logo.png” -o icon.png
|
||||
```
|
||||
|
||||
4. Build the package:
|
||||
```bash
|
||||
cloudron build
|
||||
```
|
||||
|
||||
## Testing Locally (Optional)
|
||||
|
||||
1. Run the Docker image locally to test basic functionality:
|
||||
```bash
|
||||
docker run -p 8000:8000 cloudron/reviewboard-app:1.0.0
|
||||
```
|
||||
|
||||
2. Access the application at http://localhost:8000 to check if it starts correctly.
|
||||
|
||||
## Deploying to Cloudron
|
||||
|
||||
1. Install the package on your Cloudron:
|
||||
```bash
|
||||
cloudron install —image cloudron/reviewboard-app:1.0.0
|
||||
```
|
||||
|
||||
2. Or, to update an existing installation:
|
||||
```bash
|
||||
cloudron update —image cloudron/reviewboard-app:1.0.0 —app reviewboard.yourdomain.com
|
||||
```
|
||||
|
||||
## Post-Installation
|
||||
|
||||
1. Access your Review Board instance at the URL assigned by Cloudron.
|
||||
2. Log in using the initial admin credentials:
|
||||
- Username: `admin`
|
||||
- Password: Check the file `/app/data/admin_password.txt` inside the app container:
|
||||
```bash
|
||||
cloudron exec —app reviewboard.yourdomain.com cat /app/data/admin_password.txt
|
||||
```
|
||||
|
||||
3. Configure your repository connections in the Review Board admin interface at `/admin/`.
|
||||
|
||||
## Authentication Details
|
||||
|
||||
### OIDC Authentication (Default)
|
||||
|
||||
The package is configured to use Cloudron’s OIDC provider when available. Users logging in via OIDC will be automatically provisioned in Review Board.
|
||||
|
||||
### LDAP Authentication (Alternative)
|
||||
|
||||
If OIDC is not available, the package will fall back to using Cloudron’s LDAP server for authentication.
|
||||
|
||||
## Repository Support
|
||||
|
||||
Review Board supports the following repository types:
|
||||
- Git
|
||||
- SVN
|
||||
- Mercurial
|
||||
- Perforce
|
||||
- Bazaar
|
||||
- CVS
|
||||
- IBM Rational ClearCase
|
||||
- And more
|
||||
|
||||
Configure these in the Admin > Repositories section after login.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
1. Check application logs:
|
||||
```bash
|
||||
cloudron logs —app reviewboard.yourdomain.com
|
||||
```
|
||||
|
||||
2. Access the container directly to troubleshoot:
|
||||
```bash
|
||||
cloudron exec —app reviewboard.yourdomain.com bash
|
||||
```
|
||||
|
||||
3. Validate database connectivity:
|
||||
```bash
|
||||
cloudron exec —app reviewboard.yourdomain.com psql “$CLOUDRON_POSTGRESQL_URL”
|
||||
```
|
||||
|
||||
4. If Review Board shows errors about missing repositories, ensure they are accessible from the Cloudron container.
|
||||
|
||||
## Backup and Restore
|
||||
|
||||
Cloudron automatically backs up the `/app/data` directory, which includes:
|
||||
- Database (via PostgreSQL addon)
|
||||
- Media files (uploaded files, screenshots, etc.)
|
||||
- Configuration files
|
||||
- Repository cache
|
||||
|
||||
No additional backup configuration is necessary.
|
||||
|
||||
## Upgrading Review Board
|
||||
|
||||
When a new version of Review Board is released:
|
||||
|
||||
1. Update the Dockerfile to install the new version
|
||||
2. Rebuild the Docker image
|
||||
3. Update the Cloudron app using the `cloudron update` command
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Review Board Documentation](https://www.reviewboard.org/docs/)
|
||||
- [Cloudron Documentation](https://docs.cloudron.io/)
|
@@ -1,43 +0,0 @@
|
||||
server {
|
||||
listen 8000;
|
||||
server_name CLOUDRON_APP_DOMAIN;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
# Handle static and media files
|
||||
location /static/ {
|
||||
alias /app/data/static/;
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
location /media/ {
|
||||
alias /app/data/media/;
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
# Forward requests to the Django application
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8001;
|
||||
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_connect_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
# Set up OIDC callback path
|
||||
location /api/v1/session/callback {
|
||||
proxy_pass http://127.0.0.1:8001;
|
||||
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;
|
||||
}
|
||||
|
||||
# Handle errors
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
@@ -1,187 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Create data directories if they don't exist
|
||||
if [ ! -f /app/data/.initialized ]; then
|
||||
echo "Initializing Review Board data directories..."
|
||||
|
||||
# Create directories
|
||||
mkdir -p /app/data/conf
|
||||
mkdir -p /app/data/media
|
||||
mkdir -p /app/data/static
|
||||
mkdir -p /app/data/logs
|
||||
|
||||
# Generate a random admin password and save it
|
||||
ADMIN_PASSWORD=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16)
|
||||
echo $ADMIN_PASSWORD > /app/data/admin_password.txt
|
||||
chmod 640 /app/data/admin_password.txt
|
||||
|
||||
# Mark as initialized
|
||||
touch /app/data/.initialized
|
||||
echo "Initialization complete."
|
||||
fi
|
||||
|
||||
# Set proper ownership
|
||||
chown -R cloudron:cloudron /app/data
|
||||
|
||||
# Configure database connection
|
||||
if [ ! -f /app/data/conf/settings_local.py ]; then
|
||||
echo "Creating Review Board configuration..."
|
||||
|
||||
# Get database connection details from CLOUDRON_POSTGRESQL_URL
|
||||
DB_HOST=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d@ -f2 | cut -d/ -f1)
|
||||
DB_NAME=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d/ -f4)
|
||||
DB_USER=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d/ -f3 | cut -d: -f1)
|
||||
DB_PASSWORD=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d: -f3 | cut -d@ -f1)
|
||||
|
||||
# Create settings_local.py
|
||||
cat > /app/data/conf/settings_local.py << EOF
|
||||
# Cloudron Review Board Settings
|
||||
import os
|
||||
|
||||
# Database settings
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql',
|
||||
'NAME': '${DB_NAME}',
|
||||
'USER': '${DB_USER}',
|
||||
'PASSWORD': '${DB_PASSWORD}',
|
||||
'HOST': '${DB_HOST}',
|
||||
}
|
||||
}
|
||||
|
||||
# Site settings
|
||||
SITE_ROOT = '/'
|
||||
MEDIA_ROOT = '/app/data/media'
|
||||
STATIC_ROOT = '/app/data/static'
|
||||
|
||||
# Email settings
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = 'mail'
|
||||
EMAIL_PORT = 25
|
||||
DEFAULT_FROM_EMAIL = 'reviewboard@${CLOUDRON_APP_DOMAIN}'
|
||||
SERVER_EMAIL = 'reviewboard@${CLOUDRON_APP_DOMAIN}'
|
||||
|
||||
# Cache settings
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||
'LOCATION': '127.0.0.1:11211',
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Add authentication settings based on Cloudron's environment
|
||||
if [ -n "${CLOUDRON_LDAP_SERVER}" ]; then
|
||||
# LDAP Authentication
|
||||
cat >> /app/data/conf/settings_local.py << EOF
|
||||
# LDAP Authentication
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'django_auth_ldap.backend.LDAPBackend',
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
)
|
||||
|
||||
import ldap
|
||||
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
|
||||
|
||||
AUTH_LDAP_SERVER_URI = "ldap://${CLOUDRON_LDAP_SERVER}:${CLOUDRON_LDAP_PORT}"
|
||||
AUTH_LDAP_BIND_DN = "${CLOUDRON_LDAP_BIND_DN}"
|
||||
AUTH_LDAP_BIND_PASSWORD = "${CLOUDRON_LDAP_BIND_PASSWORD}"
|
||||
AUTH_LDAP_USER_SEARCH = LDAPSearch(
|
||||
"${CLOUDRON_LDAP_USERS_BASE_DN}",
|
||||
ldap.SCOPE_SUBTREE,
|
||||
"(${CLOUDRON_LDAP_USERNAME_FIELD}=%(user)s)"
|
||||
)
|
||||
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
|
||||
"${CLOUDRON_LDAP_GROUPS_BASE_DN}",
|
||||
ldap.SCOPE_SUBTREE,
|
||||
"(objectClass=groupOfNames)"
|
||||
)
|
||||
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
|
||||
AUTH_LDAP_USER_ATTR_MAP = {
|
||||
"first_name": "givenName",
|
||||
"last_name": "sn",
|
||||
"email": "mail"
|
||||
}
|
||||
AUTH_LDAP_ALWAYS_UPDATE_USER = True
|
||||
EOF
|
||||
elif [ -n "${CLOUDRON_OIDC_IDENTIFIER}" ]; then
|
||||
# OIDC Authentication
|
||||
cat >> /app/data/conf/settings_local.py << EOF
|
||||
# OIDC Authentication
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'mozilla_django_oidc.auth.OIDCAuthenticationBackend',
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
)
|
||||
|
||||
OIDC_RP_CLIENT_ID = "${CLOUDRON_OIDC_CLIENT_ID}"
|
||||
OIDC_RP_CLIENT_SECRET = "${CLOUDRON_OIDC_CLIENT_SECRET}"
|
||||
OIDC_OP_AUTHORIZATION_ENDPOINT = "${CLOUDRON_OIDC_ENDPOINT}/authorize"
|
||||
OIDC_OP_TOKEN_ENDPOINT = "${CLOUDRON_OIDC_ENDPOINT}/token"
|
||||
OIDC_OP_USER_ENDPOINT = "${CLOUDRON_OIDC_ENDPOINT}/userinfo"
|
||||
OIDC_OP_JWKS_ENDPOINT = "${CLOUDRON_OIDC_ENDPOINT}/jwks"
|
||||
OIDC_AUTHENTICATE_CLASS = 'mozilla_django_oidc.views.OIDCAuthenticationRequestView'
|
||||
OIDC_CALLBACK_CLASS = 'mozilla_django_oidc.views.OIDCAuthenticationCallbackView'
|
||||
LOGIN_REDIRECT_URL = '/'
|
||||
LOGOUT_REDIRECT_URL = '/'
|
||||
|
||||
def oidc_username_transform(username):
|
||||
return username.split('@')[0]
|
||||
|
||||
OIDC_USERNAME_ALGO = oidc_username_transform
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
# Initialize the Review Board site if not already done
|
||||
if [ ! -f /app/data/.db_initialized ]; then
|
||||
echo "Setting up the Review Board site..."
|
||||
|
||||
# Get database connection details
|
||||
DB_HOST=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d@ -f2 | cut -d/ -f1)
|
||||
DB_NAME=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d/ -f4)
|
||||
DB_USER=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d/ -f3 | cut -d: -f1)
|
||||
DB_PASSWORD=$(echo "${CLOUDRON_POSTGRESQL_URL}" | cut -d: -f3 | cut -d@ -f1)
|
||||
|
||||
# Create a site directory for Review Board
|
||||
rb-site install --noinput \
|
||||
--domain-name=${CLOUDRON_APP_DOMAIN} \
|
||||
--site-root=/ \
|
||||
--static-url=static/ \
|
||||
--media-url=media/ \
|
||||
--db-type=postgresql \
|
||||
--db-name=${DB_NAME} \
|
||||
--db-user=${DB_USER} \
|
||||
--db-pass=${DB_PASSWORD} \
|
||||
--db-host=${DB_HOST} \
|
||||
--cache-type=memcached \
|
||||
--cache-info=localhost:11211 \
|
||||
--web-server-type=wsgi \
|
||||
--admin-user=admin \
|
||||
--admin-password=$(cat /app/data/admin_password.txt) \
|
||||
--admin-email=admin@${CLOUDRON_APP_DOMAIN} \
|
||||
/app/data/site
|
||||
|
||||
# Copy settings_local.py to the site
|
||||
cp /app/data/conf/settings_local.py /app/data/site/conf/settings_local.py
|
||||
|
||||
# Mark as initialized
|
||||
touch /app/data/.db_initialized
|
||||
echo "Database initialization complete."
|
||||
fi
|
||||
|
||||
# Collect static files if they don't exist yet
|
||||
if [ ! -f /app/data/.static_collected ]; then
|
||||
echo "Collecting static files..."
|
||||
cd /app/data/site
|
||||
PYTHONPATH=/app/data/site python /app/data/site/manage.py collectstatic --noinput
|
||||
touch /app/data/.static_collected
|
||||
echo "Static files collected."
|
||||
fi
|
||||
|
||||
# Configure NGINX to use the static and media directories
|
||||
sed -i "s|CLOUDRON_APP_DOMAIN|${CLOUDRON_APP_DOMAIN}|g" /etc/nginx/sites-available/default
|
||||
|
||||
# Start services using supervisord
|
||||
echo "Starting Review Board..."
|
||||
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
@@ -1,35 +0,0 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/dev/stdout
|
||||
logfile_maxbytes=0
|
||||
user=root
|
||||
|
||||
[program:memcached]
|
||||
command=/usr/bin/memcached -m 64 -p 11211 -u nobody -l 127.0.0.1
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:reviewboard]
|
||||
command=/app/code/venv/bin/gunicorn --bind 127.0.0.1:8001 --workers 2 --timeout 90 wsgi:application
|
||||
directory=/app/data/site
|
||||
user=cloudron
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
environment=HOME="/app/data",PYTHONPATH="/app/data/site"
|
||||
|
||||
[program:nginx]
|
||||
command=/usr/sbin/nginx -g "daemon off;"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
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"]
|
@@ -1,101 +0,0 @@
|
||||
# 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
|
@@ -1,57 +0,0 @@
|
||||
# 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
|
@@ -1,22 +0,0 @@
|
||||
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";
|
||||
};
|
@@ -1,12 +0,0 @@
|
||||
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";
|
||||
};
|
@@ -1,34 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
@@ -1,2 +0,0 @@
|
||||
# Initial Admin User - will be set up by start.sh
|
||||
admin:admin,user,admin
|
@@ -1,33 +0,0 @@
|
||||
# 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
|
@@ -1,104 +0,0 @@
|
||||
#!/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
|
@@ -1,29 +0,0 @@
|
||||
[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
|
Reference in New Issue
Block a user