From 72cb0122c4b5e6440e7a6cff3b1ded4d3ae0f772 Mon Sep 17 00:00:00 2001 From: Charles N Wyble Date: Mon, 21 Apr 2025 16:31:23 -0400 Subject: [PATCH] first cut of grist package --- .../CloudronManifest.json | 0 .../netmon.knownelement.com/Dockerfile | 0 .../LibrenmsBuildNotes.md | 0 .../netmon.knownelement.com/config.php | 0 .../netmon.knownelement.com/nginx.conf | 0 .../netmon.knownelement.com/start.sh | 0 .../netmon.knownelement.com/supervisord.conf | 0 .../CloudronManifest.json | 46 ++++++ Techops/grist.knownelement.com/Dockerfile | 79 +++++++++++ .../grist.knownelement.com/GristBuildNotes.md | 131 ++++++++++++++++++ .../grist.knownelement.com/docker-compose.yml | 1 - .../grist.knownelement.com/input-files/info | 1 - Techops/grist.knownelement.com/nginx-app.conf | 53 +++++++ Techops/grist.knownelement.com/nginx.conf | 43 ++++++ .../grist.knownelement.com/output-files/info | 1 - Techops/grist.knownelement.com/start.sh | 63 +++++++++ .../grist.knownelement.com/supervisor.conf | 32 +++++ .../grist.knownelement.com/vendor-files/info | 1 - .../docker-compose.yml | 3 - .../input-files/info | 1 - .../output-files/info | 1 - .../vendor-files/info | 4 - 22 files changed, 447 insertions(+), 13 deletions(-) rename {Techops => Cloudron}/netmon.knownelement.com/CloudronManifest.json (100%) rename {Techops => Cloudron}/netmon.knownelement.com/Dockerfile (100%) rename {Techops => Cloudron}/netmon.knownelement.com/LibrenmsBuildNotes.md (100%) rename {Techops => Cloudron}/netmon.knownelement.com/config.php (100%) rename {Techops => Cloudron}/netmon.knownelement.com/nginx.conf (100%) rename {Techops => Cloudron}/netmon.knownelement.com/start.sh (100%) rename {Techops => Cloudron}/netmon.knownelement.com/supervisord.conf (100%) create mode 100644 Techops/grist.knownelement.com/CloudronManifest.json create mode 100644 Techops/grist.knownelement.com/Dockerfile create mode 100644 Techops/grist.knownelement.com/GristBuildNotes.md delete mode 100644 Techops/grist.knownelement.com/docker-compose.yml delete mode 100644 Techops/grist.knownelement.com/input-files/info create mode 100644 Techops/grist.knownelement.com/nginx-app.conf create mode 100644 Techops/grist.knownelement.com/nginx.conf delete mode 100644 Techops/grist.knownelement.com/output-files/info create mode 100644 Techops/grist.knownelement.com/start.sh create mode 100644 Techops/grist.knownelement.com/supervisor.conf delete mode 100644 Techops/grist.knownelement.com/vendor-files/info delete mode 100644 Techops/openboxes.knownelement.com copy/docker-compose.yml delete mode 100644 Techops/openboxes.knownelement.com copy/input-files/info delete mode 100644 Techops/openboxes.knownelement.com copy/output-files/info delete mode 100644 Techops/openboxes.knownelement.com copy/vendor-files/info diff --git a/Techops/netmon.knownelement.com/CloudronManifest.json b/Cloudron/netmon.knownelement.com/CloudronManifest.json similarity index 100% rename from Techops/netmon.knownelement.com/CloudronManifest.json rename to Cloudron/netmon.knownelement.com/CloudronManifest.json diff --git a/Techops/netmon.knownelement.com/Dockerfile b/Cloudron/netmon.knownelement.com/Dockerfile similarity index 100% rename from Techops/netmon.knownelement.com/Dockerfile rename to Cloudron/netmon.knownelement.com/Dockerfile diff --git a/Techops/netmon.knownelement.com/LibrenmsBuildNotes.md b/Cloudron/netmon.knownelement.com/LibrenmsBuildNotes.md similarity index 100% rename from Techops/netmon.knownelement.com/LibrenmsBuildNotes.md rename to Cloudron/netmon.knownelement.com/LibrenmsBuildNotes.md diff --git a/Techops/netmon.knownelement.com/config.php b/Cloudron/netmon.knownelement.com/config.php similarity index 100% rename from Techops/netmon.knownelement.com/config.php rename to Cloudron/netmon.knownelement.com/config.php diff --git a/Techops/netmon.knownelement.com/nginx.conf b/Cloudron/netmon.knownelement.com/nginx.conf similarity index 100% rename from Techops/netmon.knownelement.com/nginx.conf rename to Cloudron/netmon.knownelement.com/nginx.conf diff --git a/Techops/netmon.knownelement.com/start.sh b/Cloudron/netmon.knownelement.com/start.sh similarity index 100% rename from Techops/netmon.knownelement.com/start.sh rename to Cloudron/netmon.knownelement.com/start.sh diff --git a/Techops/netmon.knownelement.com/supervisord.conf b/Cloudron/netmon.knownelement.com/supervisord.conf similarity index 100% rename from Techops/netmon.knownelement.com/supervisord.conf rename to Cloudron/netmon.knownelement.com/supervisord.conf diff --git a/Techops/grist.knownelement.com/CloudronManifest.json b/Techops/grist.knownelement.com/CloudronManifest.json new file mode 100644 index 0000000..57b0370 --- /dev/null +++ b/Techops/grist.knownelement.com/CloudronManifest.json @@ -0,0 +1,46 @@ +{ + "id": "com.getgrist.cloudron", + "title": "Grist", + "author": "Grist Labs", + "description": "A modern, open source spreadsheet that goes beyond the grid. Grist combines the flexibility of a spreadsheet with the robustness of a database to organize your data your way.", + "tagline": "Modern relational spreadsheet with Python formulas", + "version": "1.0.0", + "healthCheckPath": "/healthz", + "httpPort": 8080, + "addons": { + "localstorage": {}, + "postgresql": { + "userName": "grist", + "databaseName": "grist" + } + }, + "manifestVersion": 2, + "website": "https://www.getgrist.com/", + "documentationUrl": "https://support.getgrist.com/", + "contactEmail": "support@getgrist.com", + "icon": "file://logo.png", + "memoryLimit": 1024, + "tags": ["spreadsheet", "database", "python", "dashboard"], + "minBoxVersion": "7.0.0", + "installationNotes": { + "en": "The default administrator account is set to your Cloudron email. Access Grist at the configured subdomain." + }, + "postInstallationNotes": { + "en": "Grist has been successfully installed. The administrator account is set to your Cloudron email. Sign in using your Cloudron account credentials." + }, + "forumUrl": "https://community.getgrist.com/", + "mediaLinks": [ + "https://www.getgrist.com/assets/images/grist-demo.png" + ], + "authentication": { + "loginPath": "/auth/login", + "logoutPath": "/auth/logout", + "impl": "oauth", + "oauth": { + "clientId": "{{cloudronOAuthClientId}}", + "clientSecret": "{{cloudronOAuthClientSecret}}", + "callbackPath": "/oauth2/callback", + "scope": "profile email" + } + } +} \ No newline at end of file diff --git a/Techops/grist.knownelement.com/Dockerfile b/Techops/grist.knownelement.com/Dockerfile new file mode 100644 index 0000000..03e3eea --- /dev/null +++ b/Techops/grist.knownelement.com/Dockerfile @@ -0,0 +1,79 @@ +FROM cloudron/base:4.2.0 + +# Add Cloudron specific environment +ENV CLOUDRON=1 \ + HOME=/app/data \ + LC_ALL=C.UTF-8 \ + LANG=C.UTF-8 \ + USER=cloudron \ + PORT=8080 \ + PYTHON_VERSION=3 \ + PYTHON_VERSION_ON_CREATION=3 \ + DEBUG=0 + +# Install required dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + wget \ + gnupg \ + supervisor \ + python3 \ + python3-pip \ + python3-setuptools \ + python3-wheel \ + python3-venv \ + build-essential \ + pkg-config \ + xvfb \ + xauth \ + libcairo2-dev \ + libpango1.0-dev \ + libglib2.0-dev \ + nodejs \ + npm \ + git \ + sqlite3 \ + curl \ + ca-certificates && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create required directories +RUN mkdir -p /app/code /app/data /app/pkg /app/log && \ + mkdir -p /app/data/docs + +# Clone Grist +WORKDIR /app/pkg +RUN git clone --depth 1 https://github.com/gristlabs/grist-core.git && \ + cd grist-core && \ + npm install && \ + npm run build && \ + cd /app/pkg + +# Set up supervisor config +COPY supervisor.conf /etc/supervisor/conf.d/grist.conf +COPY nginx.conf /app/pkg/nginx.conf + +# Nginx site configuration +COPY nginx-app.conf /etc/nginx/sites-available/grist +RUN ln -sf /etc/nginx/sites-available/grist /etc/nginx/sites-enabled/grist && \ + rm -f /etc/nginx/sites-enabled/default + +# Add scripts +COPY start.sh /app/pkg/ +RUN chmod +x /app/pkg/start.sh + +# Set up initialization data +COPY --chown=cloudron:cloudron init_data/ /app/pkg/init_data/ + +# Set ownership +RUN chown -R cloudron:cloudron /app/code /app/data /app/pkg /app/log + +# Set working directory +WORKDIR /app/pkg + +# Run as cloudron user +USER cloudron + +# Start application +CMD ["/app/pkg/start.sh"] \ No newline at end of file diff --git a/Techops/grist.knownelement.com/GristBuildNotes.md b/Techops/grist.knownelement.com/GristBuildNotes.md new file mode 100644 index 0000000..e55d518 --- /dev/null +++ b/Techops/grist.knownelement.com/GristBuildNotes.md @@ -0,0 +1,131 @@ +# Grist Cloudron Package Build Notes + +## Overview + +This document provides instructions for building, testing, and deploying the Grist Cloudron package. Grist is a modern, open-source spreadsheet application with database capabilities, Python formulas, and collaborative features. + +## Package Components + +The package includes the following files: + +1. `CloudronManifest.json` - Configuration file for Cloudron +2. `Dockerfile` - Instructions for building the Docker image +3. `start.sh` - Initialization and startup script +4. `supervisor.conf` - Process management configuration +5. `nginx-app.conf` - NGINX site configuration +6. `nginx.conf` - NGINX main configuration +7. `logo.png` - Grist logo for Cloudron (needs to be added) + +## Prerequisites + +- Cloudron server (v7.0.0 or newer) +- Docker installed on your build machine +- Cloudron CLI installed on your build machine + +## Build Instructions + +1. **Prepare the package directory** + + Create a directory for your package and place all the files in it: + + ```bash + mkdir -p grist-cloudron + cd grist-cloudron + # Copy all files into this directory + ``` + +2. **Add the Grist logo** + + Download the Grist logo and save it as `logo.png` in the package directory: + + ```bash + curl -o logo.png https://raw.githubusercontent.com/gristlabs/grist-core/main/static/favicon.png + ``` + +3. **Create an initialization data directory** + + ```bash + mkdir -p init_data + ``` + +4. **Build the Docker image** + + ```bash + cloudron build + ``` + +## Testing the Package + +1. **Install the package on your Cloudron for testing** + + ```bash + cloudron install —image your-docker-image-name + ``` + +2. **Verify the installation** + + Once installed, navigate to the app’s URL and verify that: + - The login page appears correctly + - You can log in using your Cloudron credentials + - You can create and edit documents + - Document imports and exports work properly + - Python formulas are functioning correctly + +3. **Test authentication** + + Verify that: + - Authentication with Cloudron accounts works + - User permissions are applied correctly + - Logging out works properly + +## Common Issues and Troubleshooting + +1. **Authentication Issues** + - Check that the OAuth configuration is correct in `CloudronManifest.json` + - Verify environment variables in `start.sh` related to OIDC + +2. **Database Connection Problems** + - Verify PostgreSQL addon configuration + - Check logs for database connection errors + +3. **Grist Not Starting** + - Check supervisord logs: `cloudron logs -f` + - Verify that the required directories exist and have proper permissions + +4. **File Upload Issues** + - Verify the `client_max_body_size` setting in the NGINX configuration + +## Deployment + +1. **Prepare the package for production** + + ```bash + cloudron build + cloudron upload + ``` + +2. **Install from the Cloudron App Store** + + After submission and approval, users can install directly from the Cloudron App Store. + +## Maintenance + +1. **Updating Grist** + + To update Grist to a newer version: + - Update the git clone command in the `Dockerfile` + - Update the version in `CloudronManifest.json` + - Rebuild and redeploy + +2. **Backing Up** + + Cloudron automatically backs up: + - The PostgreSQL database + - The `/app/data` directory containing all Grist documents + +## Additional Resources + +- [Grist Documentation](https://support.getgrist.com/) +- [Grist GitHub Repository](https://github.com/gristlabs/grist-core) +- [Cloudron Documentation](https://docs.cloudron.io/) +- [Grist Community Forum](https://community.getgrist.com/) \ No newline at end of file diff --git a/Techops/grist.knownelement.com/docker-compose.yml b/Techops/grist.knownelement.com/docker-compose.yml deleted file mode 100644 index b380c97..0000000 --- a/Techops/grist.knownelement.com/docker-compose.yml +++ /dev/null @@ -1 +0,0 @@ -#grist docker compose for tsys \ No newline at end of file diff --git a/Techops/grist.knownelement.com/input-files/info b/Techops/grist.knownelement.com/input-files/info deleted file mode 100644 index bc15867..0000000 --- a/Techops/grist.knownelement.com/input-files/info +++ /dev/null @@ -1 +0,0 @@ -This directory contains template files for the application at FQDN indidicated by the parent directory. They will be processed using mo (bash mustache). diff --git a/Techops/grist.knownelement.com/nginx-app.conf b/Techops/grist.knownelement.com/nginx-app.conf new file mode 100644 index 0000000..7e6ebb3 --- /dev/null +++ b/Techops/grist.knownelement.com/nginx-app.conf @@ -0,0 +1,53 @@ +server { + listen 8080; + server_name localhost; + + # Set maximum upload size + client_max_body_size 300M; + + # Add security headers + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Frame-Options SAMEORIGIN; + add_header Referrer-Policy strict-origin-when-cross-origin; + + # Main location for Grist + location / { + proxy_pass http://127.0.0.1:8484; + 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; + proxy_read_timeout 90; + proxy_buffering off; + } + + # Health check endpoint + location = /healthz { + access_log off; + add_header Content-Type text/plain; + return 200 'OK'; + } + + # Static file caching + location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { + proxy_pass http://127.0.0.1:8484; + 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; + expires 30d; + add_header Cache-Control "public, no-transform"; + } + + # Error pages + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} \ No newline at end of file diff --git a/Techops/grist.knownelement.com/nginx.conf b/Techops/grist.knownelement.com/nginx.conf new file mode 100644 index 0000000..3d972ec --- /dev/null +++ b/Techops/grist.knownelement.com/nginx.conf @@ -0,0 +1,43 @@ +user cloudron; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + # Basic Settings + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # SSL Settings + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + + # Logging Settings + 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 + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} \ No newline at end of file diff --git a/Techops/grist.knownelement.com/output-files/info b/Techops/grist.knownelement.com/output-files/info deleted file mode 100644 index fe6b01e..0000000 --- a/Techops/grist.knownelement.com/output-files/info +++ /dev/null @@ -1 +0,0 @@ -This directory contains final docker compose files for the application at FQDN indidicated by the parent directory. diff --git a/Techops/grist.knownelement.com/start.sh b/Techops/grist.knownelement.com/start.sh new file mode 100644 index 0000000..d75dc5e --- /dev/null +++ b/Techops/grist.knownelement.com/start.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -e + +# Cloudron environment variables +export GRIST_APP_ROOT="/app/pkg/grist-core" +export GRIST_DATA_DIR="/app/data/docs" +export GRIST_SESSION_SECRET="${CLOUDRON_SESSION_SECRET}" +export APP_HOME_URL="${CLOUDRON_APP_URL}" +export GRIST_DOMAIN="${CLOUDRON_APP_DOMAIN}" +export GRIST_SINGLE_ORG="cloudron" +export GRIST_HIDE_UI_ELEMENTS="billing" +export GRIST_MAX_UPLOAD_ATTACHMENT_MB=100 +export GRIST_MAX_UPLOAD_IMPORT_MB=300 +export GRIST_SANDBOX_FLAVOR="gvisor" +export GRIST_USER_ROOT="/app/data" +export GRIST_THROTTLE_CPU="true" +export GRIST_DEFAULT_EMAIL="${CLOUDRON_ADMIN_EMAIL}" +export GRIST_FORCE_LOGIN="true" +export GRIST_SUPPORT_ANON="false" +export COOKIE_MAX_AGE=2592000000 # 30 days in milliseconds + +# Setup OpenID Connect for Cloudron authentication +export GRIST_OIDC_IDP_ISSUER="${CLOUDRON_APP_ORIGIN}" +export GRIST_OIDC_IDP_CLIENT_ID="${CLOUDRON_OAUTH_CLIENT_ID}" +export GRIST_OIDC_IDP_CLIENT_SECRET="${CLOUDRON_OAUTH_CLIENT_SECRET}" +export GRIST_OIDC_IDP_SCOPES="openid profile email" +export GRIST_OIDC_SP_HOST="${CLOUDRON_APP_URL}" +export GRIST_OIDC_SP_PROFILE_EMAIL_ATTR="email" +export GRIST_OIDC_SP_PROFILE_NAME_ATTR="name" +export GRIST_OIDC_IDP_ENABLED_PROTECTIONS="PKCE,STATE" + +# Database configuration using Cloudron PostgreSQL addon +export TYPEORM_TYPE="postgres" +export TYPEORM_DATABASE="${CLOUDRON_POSTGRESQL_DATABASE}" +export TYPEORM_USERNAME="${CLOUDRON_POSTGRESQL_USERNAME}" +export TYPEORM_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}" +export TYPEORM_HOST="${CLOUDRON_POSTGRESQL_HOST}" +export TYPEORM_PORT="${CLOUDRON_POSTGRESQL_PORT}" +export TYPEORM_LOGGING="false" + +# Initialize or update data directories if they don't exist +if [ ! -d "/app/data/docs" ]; then + mkdir -p /app/data/docs + echo "Created docs directory" +fi + +if [ ! -d "/app/data/home" ]; then + mkdir -p /app/data/home + echo "Created home directory" +fi + +# Copy initialization data if needed +if [ -d "/app/pkg/init_data" ] && [ ! -f "/app/data/.initialized" ]; then + cp -R /app/pkg/init_data/* /app/data/ + touch /app/data/.initialized + echo "Copied initialization data" +fi + +# Ensure proper permissions +chown -R cloudron:cloudron /app/data + +# Start supervisor to manage Grist and Nginx +exec /usr/bin/supervisord --nodaemon -c /etc/supervisor/supervisord.conf \ No newline at end of file diff --git a/Techops/grist.knownelement.com/supervisor.conf b/Techops/grist.knownelement.com/supervisor.conf new file mode 100644 index 0000000..fd6e93b --- /dev/null +++ b/Techops/grist.knownelement.com/supervisor.conf @@ -0,0 +1,32 @@ +[supervisord] +nodaemon=true +logfile=/app/log/supervisord.log +logfile_maxbytes=10MB +logfile_backups=3 +loglevel=info +pidfile=/run/supervisord.pid +user=cloudron + +[program:nginx] +command=/usr/sbin/nginx -g "daemon off;" +priority=10 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +autostart=true +autorestart=true + +[program:grist] +command=bash -c "cd /app/pkg/grist-core && node sandbox/pyodide.js" +user=cloudron +environment=HOME=/app/data +directory=/app/pkg/grist-core +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +autostart=true +autorestart=true +startretries=3 +priority=20 \ No newline at end of file diff --git a/Techops/grist.knownelement.com/vendor-files/info b/Techops/grist.knownelement.com/vendor-files/info deleted file mode 100644 index 110d921..0000000 --- a/Techops/grist.knownelement.com/vendor-files/info +++ /dev/null @@ -1 +0,0 @@ -This directory contains files from the vendor unmodified. They serve as a base for the input-files sibling directory diff --git a/Techops/openboxes.knownelement.com copy/docker-compose.yml b/Techops/openboxes.knownelement.com copy/docker-compose.yml deleted file mode 100644 index 09eff98..0000000 --- a/Techops/openboxes.knownelement.com copy/docker-compose.yml +++ /dev/null @@ -1,3 +0,0 @@ -#cfssl docker compose for tsys - -#git subtree add --prefix upstream/cloudflare-cfssl https://github.com/rjrivero/docker-cfssl.git master --squash \ No newline at end of file diff --git a/Techops/openboxes.knownelement.com copy/input-files/info b/Techops/openboxes.knownelement.com copy/input-files/info deleted file mode 100644 index bc15867..0000000 --- a/Techops/openboxes.knownelement.com copy/input-files/info +++ /dev/null @@ -1 +0,0 @@ -This directory contains template files for the application at FQDN indidicated by the parent directory. They will be processed using mo (bash mustache). diff --git a/Techops/openboxes.knownelement.com copy/output-files/info b/Techops/openboxes.knownelement.com copy/output-files/info deleted file mode 100644 index fe6b01e..0000000 --- a/Techops/openboxes.knownelement.com copy/output-files/info +++ /dev/null @@ -1 +0,0 @@ -This directory contains final docker compose files for the application at FQDN indidicated by the parent directory. diff --git a/Techops/openboxes.knownelement.com copy/vendor-files/info b/Techops/openboxes.knownelement.com copy/vendor-files/info deleted file mode 100644 index 82e1a79..0000000 --- a/Techops/openboxes.knownelement.com copy/vendor-files/info +++ /dev/null @@ -1,4 +0,0 @@ -This directory contains files from the vendor unmodified. They serve as a base for the input-files sibling directory - - -https://github.com/openboxes/openboxes/tree/develop/docker \ No newline at end of file