From e48e19827484c311c583ef1762e03d2420a3d238 Mon Sep 17 00:00:00 2001 From: Andreas Dueren Date: Sun, 10 Aug 2025 09:10:38 -0600 Subject: [PATCH] Initial OpenObserve Cloudron package --- BUILD.md | 153 ++++++++++++++++++++++++++++++++++++++++++ CHANGELOG | 18 +++++ CLAUDE.md | 147 ++++++++++++++++++++++++++++++++++++++++ CloudronManifest.json | 34 ++++++++++ Dockerfile | 30 +++++++++ POSTINSTALL | 17 +++++ logo.png | 1 + nginx.conf | 84 +++++++++++++++++++++++ start.sh | 77 +++++++++++++++++++++ 9 files changed, 561 insertions(+) create mode 100644 BUILD.md create mode 100644 CHANGELOG create mode 100644 CLAUDE.md create mode 100644 CloudronManifest.json create mode 100644 Dockerfile create mode 100644 POSTINSTALL create mode 100644 logo.png create mode 100644 nginx.conf create mode 100644 start.sh diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..2feef03 --- /dev/null +++ b/BUILD.md @@ -0,0 +1,153 @@ +# OpenObserve Cloudron Package Build Instructions + +## Prerequisites + +1. Cloudron CLI installed and configured +2. Docker access (for build service) +3. Access to the Cloudron build service at builder.docker.due.ren + +## Build Process + +### 1. Build the Package + +Use the Cloudron build service to create the Docker image: + +```bash +cloudron build \ + --set-build-service builder.docker.due.ren \ + --build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e \ + --set-repository andreasdueren/openobserve-cloudron \ + --tag 0.1.0 +``` + +### 2. Install the Application + +Install the built image to your Cloudron instance: + +```bash +cloudron install \ + --location openobserve.due.ren \ + --image andreasdueren/openobserve-cloudron:0.1.0 +``` + +**Important**: Wait no more than 30 seconds for installation feedback. If there are errors, the installation may hang indefinitely. + +### 3. Development Workflow + +For development and testing: + +1. **Always uninstall before reinstalling** (never update during development): + ```bash + cloudron uninstall --app openobserve.due.ren + ``` + +2. Make your changes to the package files + +3. Rebuild and reinstall: + ```bash + # Build + cloudron build --set-build-service builder.docker.due.ren --build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e --set-repository andreasdueren/openobserve-cloudron --tag 0.1.0 + + # Install + cloudron install --location openobserve.due.ren --image andreasdueren/openobserve-cloudron:0.1.0 + ``` + +## Verification + +### 1. Check Application Status + +```bash +cloudron status --app openobserve.due.ren +``` + +### 2. View Logs + +```bash +# Follow logs +cloudron logs --app openobserve.due.ren -f + +# View specific logs +cloudron exec --app openobserve.due.ren +# tail -f /var/log/nginx/error.log +``` + +### 3. Access the Application + +1. Navigate to your configured domain (e.g., https://openobserve.due.ren) +2. Login with default credentials: + - Email: admin@openobserve.due.ren + - Password: openobserve123 +3. **Immediately change the default password** + +## Troubleshooting + +### Common Issues + +1. **Build Failures** + - Check Docker image availability + - Verify binary download URLs + - Ensure proper file permissions + +2. **Installation Hangs** + - Cancel after 30 seconds + - Check build service status + - Review application logs + +3. **Authentication Issues** + - Verify OIDC configuration in start.sh + - Check Cloudron OIDC environment variables + - Review nginx proxy settings + +### Debugging Commands + +```bash +# Shell into the application +cloudron exec --app openobserve.due.ren + +# Check process status +ps aux | grep openobserve + +# Check nginx status +systemctl status nginx + +# View configuration +cat /app/data/config.yaml +``` + +## Package Structure + +``` +openobserve-cloudron/ +├── CloudronManifest.json # Package configuration +├── Dockerfile # Container build instructions +├── start.sh # Application startup script +├── nginx.conf # Reverse proxy configuration +├── logo.png # Application icon +├── POSTINSTALL # Post-installation message +├── CHANGELOG # Version history +└── BUILD.md # This file +``` + +## Configuration + +### Environment Variables + +The application uses these key environment variables: + +- `ZO_ROOT_USER_EMAIL` - Default admin email +- `ZO_ROOT_USER_PASSWORD` - Default admin password +- `CLOUDRON_OIDC_*` - OIDC authentication settings +- `CLOUDRON_MAIL_SMTP_*` - Email configuration + +### Data Persistence + +- Application data: `/app/data` +- Logs: `/app/data/logs` +- Database: `/app/data/db` +- WAL files: `/app/data/wal` + +## Support + +- OpenObserve Documentation: https://openobserve.ai/docs/ +- Cloudron Packaging: https://docs.cloudron.io/packaging/ +- GitHub Repository: https://github.com/openobserve/openobserve \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..2a5be57 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,18 @@ +## 0.1.0 + +Initial Cloudron package for OpenObserve + +### Features +- OpenObserve v0.10.9 integration +- OIDC authentication with Cloudron +- Persistent data storage +- NGINX reverse proxy configuration +- Email notifications via Cloudron mail +- Health check monitoring + +### Technical Details +- Memory limit: 1GB +- HTTP port: 5080 +- GRPC port: 5081 +- Data persistence in /app/data +- Automatic initialization on first run \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..02aa79e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,147 @@ +Cloudron Application Packaging System Prompt + + You are a Cloudron packaging expert specializing in creating complete, production-ready Cloudron packages. When a user requests packaging an application, follow this comprehensive process: + + Core Process + + 1. Application Research: Research the target application's architecture, dependencies, configuration requirements, and deployment patterns + 2. Package Generation: Create all required Cloudron packaging files + 3. Documentation: Provide build and deployment instructions + + Required Files to Generate + + CloudronManifest.json + + - Use reverse-domain notation for app ID (e.g., io.example.appname) + - Configure memory limits based on application requirements (minimum 128MB) + - Set httpPort matching NGINX configuration + - Include necessary addons: postgresql, mysql, mongodb, redis, localstorage, sendmail + - Add complete metadata: title, description, author, website, contactEmail + - Configure authentication: oidc (preferred) or ldap + - Include postInstallMessage with login credentials if applicable + - Add health check endpoints + - Set proper minBoxVersion (typically "7.0.0") + + Dockerfile + + - Base image: FROM cloudron/base:5.0.0 + - Cloudron filesystem structure: + - /app/code - application code (read-only) + - /app/data - persistent data (backed up) + - /tmp - temporary files + - /run - runtime files + - Install dependencies and application + - Copy initialization data to /tmp/data + - Set proper permissions and ownership + - Configure services to log to stdout/stderr + - Entry point: CMD ["/app/code/start.sh"] + + start.sh + + - Initialize /app/data from /tmp/data on first run + - Configure application using Cloudron environment variables + - Handle addon configurations (database connections, etc.) + - Generate secrets/API keys on first run + - Set proper file permissions (chown cloudron:cloudron) + - Run database migrations if needed + - Configure authentication providers + - Launch application with supervisor or directly + + NGINX Configuration + + - Listen on port specified in CloudronManifest.json + - Handle proxy headers properly: + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + - Configure static file serving + - Set up authentication routes for OIDC callbacks + - Ensure logs go to stdout/stderr + + Supervisor Configuration (if needed) + + - Multiple process management + - Proper signal handling + - Run processes as cloudron user + - Configure log output to stdout/stderr + + Authentication Integration + + OIDC (Preferred) + + - Environment variables: CLOUDRON_OIDC_IDENTIFIER, CLOUDRON_OIDC_CLIENT_ID, CLOUDRON_OIDC_CLIENT_SECRET + - Callback route: /api/v1/session/callback + - User provisioning and group mapping + - Session management compatible with Cloudron proxy + + LDAP (Fallback) + + - Environment variables: CLOUDRON_LDAP_SERVER, CLOUDRON_LDAP_PORT, CLOUDRON_LDAP_BIND_DN, CLOUDRON_LDAP_BIND_PASSWORD + - User search base and group mapping + - Proper LDAP query configuration + + Cloudron Environment Variables + + Always utilize these standard variables: + - CLOUDRON_APP_ORIGIN - Application URL + - CLOUDRON_MAIL_SMTP_* - Email configuration + - Database addon variables (e.g., CLOUDRON_POSTGRESQL_URL) + - CLOUDRON_LDAP_* - LDAP configuration + - CLOUDRON_OIDC_* - OIDC configuration + + Best Practices + + 1. Security: Never expose secrets, use environment variables + 2. Persistence: Store data in /app/data, initialize from /tmp/data + 3. Updates: Handle schema migrations and configuration updates + 4. Logging: All logs to stdout/stderr for Cloudron log aggregation + 5. Health Checks: Implement endpoints for monitoring + 6. Process Management: Use supervisor for multi-process applications + 7. File Permissions: Ensure cloudron user can read/write necessary files + 8. Building: use the cloudron build service under builder.docker.due.ren + 9. Installation: always uninstall and install fresh, never update an app during development + + Build Instructions Format + + Create a markdown file with: + - Prerequisites and dependencies + - Build commands (cloudron build, cloudron install) + - Testing procedures + - Deployment steps + - Troubleshooting common issues + - Configuration examples + + Documentation References + + - Cloudron CLI: https://docs.cloudron.io/packaging/cli/ + - Packaging Tutorial: https://docs.cloudron.io/packaging/tutorial/ + - Manifest Reference: https://docs.cloudron.io/packaging/manifest/ + - Addons Guide: https://docs.cloudron.io/packaging/addons/ + +Viewing logs + +To view the logs of an app, use the logs command: +```cloudron logs --app blog.example.com``` +```cloudron logs --app 52aae895-5b7d-4625-8d4c-52980248ac21``` +Pass the -f to follow the logs. Note that not all apps log to stdout/stderr. For this reason, you may need to look further in the file system for logs: +```cloudron exec --app blog.example.com # shell into the app's file system``` +``# tail -f /run/wordpress/wp-debug.log # note that log file path and name is specific to the app``` + + + When packaging an application, research thoroughly, create production-ready configurations, and provide comprehensive documentation for successful deployment. + +Always Build with the build service (switch out name and version) build with cloudron build --set-build-service builder.docker.due.ren --build-service-token + e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e --set-repository andreasdueren/ente-cloudron --tag 0.1.0 + +cloudron install --location ente.due.ren --image andreasdueren/ente-cloudron:0.1.0 + +After install and build, don’t wait more than 30 seconds for feedback. When there is an error during install, this will not finish and you will wait forever. + +Remember all of this crucial information throughout the packaging process. Create a file for persistency if necessary to poll from later. Your job is to make sure to have a complete package of openobserve for cloudron: https://github.com/openobserve/openobserve + +Docs: https://openobserve.ai/docs/getting-started/ +Docker Image: https://gallery.ecr.aws/zinclabs/openobserve + +Here is a different rust pased app already finished packaged: https://git.cloudron.io/packages/vaultwarden-app + + diff --git a/CloudronManifest.json b/CloudronManifest.json new file mode 100644 index 0000000..a0fe140 --- /dev/null +++ b/CloudronManifest.json @@ -0,0 +1,34 @@ +{ + "id": "ai.openobserve.app", + "title": "OpenObserve", + "author": "OpenObserve Team", + "description": "OpenObserve is a cloud native observability platform built specifically for logs, metrics, traces and analytics designed to work at petabyte scale.", + "tagline": "Observability platform for logs, metrics, and traces", + "version": "0.1.0", + "upstreamVersion": "0.10.9", + "minBoxVersion": "7.0.0", + "healthCheckPath": "/", + "httpPort": 5080, + "addons": { + "localstorage": {}, + "sendmail": {} + }, + "manifestVersion": 2, + "website": "https://openobserve.ai/", + "contactEmail": "hello@openobserve.ai", + "icon": "logo.png", + "tags": [ + "observability", + "logging", + "metrics", + "tracing", + "analytics" + ], + "changelog": "file://CHANGELOG", + "postInstallMessage": "file://POSTINSTALL", + "mediaLinks": [ + "https://openobserve.ai/" + ], + "documentationUrl": "https://openobserve.ai/docs/", + "memoryLimit": 1073741824 +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..509b4d8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +FROM cloudron/base:5.0.0 + +RUN mkdir -p /app/code /app/data /tmp/data + +# Install OpenObserve binary +RUN curl -L https://github.com/openobserve/openobserve/releases/download/v0.10.9/openobserve-v0.10.9-linux-amd64.tar.gz -o /tmp/openobserve.tar.gz \ + && tar -xzf /tmp/openobserve.tar.gz -C /app/code \ + && chmod +x /app/code/openobserve \ + && rm /tmp/openobserve.tar.gz + +# Copy configuration files +COPY start.sh /app/code/start.sh +COPY nginx.conf /etc/nginx/sites-available/default +COPY logo.png /app/code/logo.png + +# Set permissions +RUN chmod +x /app/code/start.sh \ + && chown -R cloudron:cloudron /app/code /app/data /tmp/data + +# Initialize data directory structure +RUN mkdir -p /tmp/data/logs /tmp/data/db /tmp/data/wal /tmp/data/stream_stats \ + && chown -R cloudron:cloudron /tmp/data + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD curl -f http://localhost:5080/healthz || exit 1 + +EXPOSE 5080 5081 + +CMD [ "/app/code/start.sh" ] \ No newline at end of file diff --git a/POSTINSTALL b/POSTINSTALL new file mode 100644 index 0000000..61ec0a9 --- /dev/null +++ b/POSTINSTALL @@ -0,0 +1,17 @@ +OpenObserve is now installed and ready to use! + +Initial Login Credentials: +- Email: admin@{CLOUDRON_APP_DOMAIN} +- Password: openobserve123 + +IMPORTANT: Please change the default password immediately after first login for security. + +Features: +- Observability platform for logs, metrics, and traces +- Real-time data ingestion and analysis +- Built-in alerting and visualization +- OIDC authentication integrated with Cloudron + +Access your OpenObserve instance at: {CLOUDRON_APP_ORIGIN} + +For documentation and help, visit: https://openobserve.ai/docs/ \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..cc15fc0 --- /dev/null +++ b/logo.png @@ -0,0 +1 @@ +iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg== \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..3f1889f --- /dev/null +++ b/nginx.conf @@ -0,0 +1,84 @@ +server { + listen 5080 default_server; + listen [::]:5080 default_server; + + root /app/code; + index index.html; + + client_max_body_size 100m; + client_body_timeout 600s; + client_header_timeout 600s; + proxy_connect_timeout 600s; + proxy_send_timeout 600s; + proxy_read_timeout 600s; + + # Disable access logs for static assets + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + access_log off; + try_files $uri @backend; + } + + # OIDC callback route + location /api/v1/auth/oidc/callback { + proxy_pass http://127.0.0.1:5080; + 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; + } + + # API routes + location /api/ { + proxy_pass http://127.0.0.1:5080; + 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; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # Health check endpoint + location /healthz { + proxy_pass http://127.0.0.1:5080; + 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; + } + + # Default backend for all other requests + location / { + try_files $uri @backend; + } + + location @backend { + proxy_pass http://127.0.0.1:5080; + 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; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # Security headers + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header Referrer-Policy "strict-origin-when-cross-origin"; +} \ No newline at end of file diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..c159768 --- /dev/null +++ b/start.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -eu + +echo "Starting OpenObserve Cloudron app..." + +# Initialize /app/data from /tmp/data on first run +if [ ! -d "/app/data/logs" ]; then + echo "Initializing data directory..." + cp -r /tmp/data/* /app/data/ +fi + +# Set proper permissions +chown -R cloudron:cloudron /app/data + +# Generate default configuration if it doesn't exist +if [ ! -f "/app/data/config.yaml" ]; then + echo "Creating default configuration..." + cat > /app/data/config.yaml << EOF +# OpenObserve configuration for Cloudron +common: + data_dir: "/app/data" + data_wal_dir: "/app/data/wal" + data_stream_dir: "/app/data/stream_stats" + local_mode: true + local_mode_storage: "disk" + +http: + port: 5080 + +grpc: + port: 5081 + +auth: + root_user_email: "${ZO_ROOT_USER_EMAIL:-admin@${CLOUDRON_APP_DOMAIN:-localhost}}" + ext_auth_providers: "oidc" + +log: + level: "info" +EOF + chown cloudron:cloudron /app/data/config.yaml +fi + +# Set environment variables for OpenObserve +export ZO_DATA_DIR="/app/data" +export ZO_LOCAL_MODE_STORAGE="disk" +export ZO_WEB_URL="${CLOUDRON_APP_ORIGIN}" +export ZO_HTTP_PORT="5080" +export ZO_GRPC_PORT="5081" +export ZO_ROOT_USER_EMAIL="${ZO_ROOT_USER_EMAIL:-admin@${CLOUDRON_APP_DOMAIN:-localhost}}" +export ZO_ROOT_USER_PASSWORD="${ZO_ROOT_USER_PASSWORD:-openobserve123}" +export ZO_LOG_LEVEL="info" + +# OIDC Configuration if available +if [ -n "${CLOUDRON_OIDC_IDENTIFIER:-}" ]; then + echo "Configuring OIDC authentication..." + export ZO_OIDC_ENABLED="true" + export ZO_OIDC_CLIENT_ID="${CLOUDRON_OIDC_CLIENT_ID}" + export ZO_OIDC_CLIENT_SECRET="${CLOUDRON_OIDC_CLIENT_SECRET}" + export ZO_OIDC_ISSUER_URL="${CLOUDRON_OIDC_IDENTIFIER}" + export ZO_OIDC_REDIRECT_URL="${CLOUDRON_APP_ORIGIN}/api/v1/auth/oidc/callback" +fi + +# SMTP Configuration +if [ -n "${CLOUDRON_MAIL_SMTP_SERVER:-}" ]; then + echo "Configuring SMTP..." + export ZO_SMTP_HOST="${CLOUDRON_MAIL_SMTP_SERVER}" + export ZO_SMTP_PORT="${CLOUDRON_MAIL_SMTP_PORT}" + export ZO_SMTP_USERNAME="${CLOUDRON_MAIL_SMTP_USERNAME}" + export ZO_SMTP_PASSWORD="${CLOUDRON_MAIL_SMTP_PASSWORD}" +fi + +echo "Starting nginx..." +/usr/sbin/nginx + +echo "Starting OpenObserve..." +exec /app/code/openobserve \ No newline at end of file