From 65cd9a73bb695316126e0e7277c02c078dbb7ed0 Mon Sep 17 00:00:00 2001 From: Andreas Dueren Date: Tue, 15 Jul 2025 13:13:03 -0600 Subject: [PATCH] Initial commit: Docmost Cloudron package with customizable configuration --- CONFIGURATION.md | 127 ++++++++++++++++++++++++++++++++++++++++++ CloudronManifest.json | 2 +- Dockerfile | 13 +++-- LICENSE | 21 +++++++ env.sample | 66 ++++++++++++++++++++++ start.sh | 109 +++++++++++++++++++++++++++++------- 6 files changed, 314 insertions(+), 24 deletions(-) create mode 100644 CONFIGURATION.md create mode 100644 LICENSE create mode 100644 env.sample diff --git a/CONFIGURATION.md b/CONFIGURATION.md new file mode 100644 index 0000000..dd5b7a7 --- /dev/null +++ b/CONFIGURATION.md @@ -0,0 +1,127 @@ +# Docmost Cloudron Configuration + +Your Docmost instance is configured with Cloudron defaults but can be customized after installation. + +## Current Configuration + +**Email**: Uses Cloudron's internal email server by default +**Storage**: Uses local storage in `/app/data/uploads` by default +**Database**: PostgreSQL (managed by Cloudron) +**Cache**: Redis (managed by Cloudron) + +## Custom Configuration + +To customize your Docmost installation, you can create a `.env` file in the app's data directory: + +### 1. Access Your App's Data Directory + +```bash +# SSH into your Cloudron server +cloudron exec --app docmost + +# Navigate to the data directory +cd /app/data + +# Copy the sample configuration +cp env.sample .env +``` + +### 2. Edit the Configuration + +```bash +# Edit the .env file +nano .env +``` + +### 3. Restart the App + +After making changes to the `.env` file, restart the app: + +```bash +cloudron restart --app docmost +``` + +## Common Customizations + +### Custom Email Server + +To use Gmail instead of Cloudron's email server: + +```bash +# In /app/data/.env +MAIL_DRIVER=smtp +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_USERNAME=your-email@gmail.com +SMTP_PASSWORD=your-app-password +SMTP_SECURE=true +MAIL_FROM_ADDRESS=your-email@gmail.com +MAIL_FROM_NAME=Docmost +``` + +### S3 Storage + +To use Amazon S3 or compatible storage: + +```bash +# In /app/data/.env +STORAGE_DRIVER=s3 +AWS_S3_ACCESS_KEY_ID=your-access-key +AWS_S3_SECRET_ACCESS_KEY=your-secret-key +AWS_S3_REGION=us-east-1 +AWS_S3_BUCKET=your-bucket-name +AWS_S3_ENDPOINT=https://s3.amazonaws.com +``` + +### File Upload Limits + +To increase file upload limits: + +```bash +# In /app/data/.env +FILE_UPLOAD_SIZE_LIMIT=100MB +FILE_IMPORT_SIZE_LIMIT=100MB +``` + +### Custom Draw.io Server + +To use a self-hosted draw.io server: + +```bash +# In /app/data/.env +DRAWIO_URL=https://your-drawio-server.com +``` + +## Available Environment Variables + +See the full list of available environment variables in the [Docmost documentation](https://docmost.com/docs/self-hosting/environment-variables). + +## Troubleshooting + +### Check Current Configuration + +```bash +cloudron exec --app docmost -- env | grep -E "(MAIL|STORAGE|S3)" | sort +``` + +### View App Logs + +```bash +cloudron logs --app docmost +``` + +### Reset to Defaults + +To reset to Cloudron defaults, simply remove the custom .env file: + +```bash +cloudron exec --app docmost -- rm -f /app/data/.env +cloudron restart --app docmost +``` + +## Security Notes + +- The `.env` file is stored in `/app/data/` which is included in Cloudron backups +- Database and Redis credentials are managed by Cloudron and should not be changed +- Email credentials are stored in plaintext in the `.env` file +- Consider using app-specific passwords for email providers \ No newline at end of file diff --git a/CloudronManifest.json b/CloudronManifest.json index d61e6f5..1c4a19b 100644 --- a/CloudronManifest.json +++ b/CloudronManifest.json @@ -23,7 +23,7 @@ "wiki", "knowledge-base" ], - "postInstallMessage": "Docmost has been installed successfully!\n\nTo get started:\n1. Access your Docmost instance at https://%s\n2. Create your first workspace and admin account\n3. Start collaborating on documentation\n\nDefault features include:\n- Real-time collaborative editing\n- Diagram support (Draw.io, Excalidraw, Mermaid)\n- Page history and permissions\n- Multilingual support\n\nFor more information, visit: https://docmost.com/docs", + "postInstallMessage": "Docmost has been installed successfully!\n\nTo get started:\n1. Access your Docmost instance at https://{{CLOUDRON_APP_DOMAIN}}\n2. Create your first workspace and admin account\n3. Start collaborating on documentation\n\nDefault configuration:\n- Email: Uses Cloudron's internal email server\n- Storage: Local storage in /app/data/uploads\n- Database: PostgreSQL (managed by Cloudron)\n- Cache: Redis (managed by Cloudron)\n\nCustomization:\nTo customize email, storage, or other settings, create /app/data/.env file:\n cloudron exec --app docmost\n cp /app/data/env.sample /app/data/.env\n nano /app/data/.env\n exit\n cloudron restart --app docmost\n\nFeatures include:\n- Real-time collaborative editing\n- Diagram support (Draw.io, Excalidraw, Mermaid)\n- Page history and permissions\n- Multilingual support\n\nFor more information, visit: https://docmost.com/docs", "minBoxVersion": "7.0.0", "maxBoxVersion": "9.0.0", "memoryLimit": 512000000, diff --git a/Dockerfile b/Dockerfile index 8fc07af..420fc0d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,19 +14,24 @@ WORKDIR /app/code RUN git clone https://github.com/docmost/docmost.git . && \ rm -rf .git && \ pnpm install && \ - pnpm build + pnpm build && \ + mv apps/client/dist /app/client-dist-original && \ + ln -s /app/data/client-dist apps/client/dist # Create necessary directories RUN mkdir -p /tmp/data /app/data && \ chown -R cloudron:cloudron /app/data /tmp/data -# Copy startup scripts +# Copy startup scripts and configuration files COPY start.sh /app/code/ COPY healthcheck.js /app/code/ COPY nginx.conf /etc/nginx/sites-available/default +COPY env.sample /app/code/env.sample +COPY CONFIGURATION.md /app/code/CONFIGURATION.md -# Override nginx global error log to prevent read-only filesystem error -RUN sed -i 's|error_log /var/log/nginx/error.log;|error_log /dev/stderr;|' /etc/nginx/nginx.conf +# Override nginx global logs to prevent read-only filesystem errors +RUN sed -i 's|error_log /var/log/nginx/error.log;|error_log /dev/stderr;|' /etc/nginx/nginx.conf && \ + sed -i 's|access_log /var/log/nginx/access.log;|access_log /dev/stdout;|' /etc/nginx/nginx.conf # Make scripts executable RUN chmod +x /app/code/start.sh /app/code/healthcheck.js diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..612612d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Andreas Dueren + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/env.sample b/env.sample new file mode 100644 index 0000000..24cd9e6 --- /dev/null +++ b/env.sample @@ -0,0 +1,66 @@ +# Docmost Cloudron Configuration +# Copy this file to /app/data/.env and customize as needed +# Restart the app after making changes: cloudron restart --app docmost + +# ====================== +# EMAIL CONFIGURATION +# ====================== + +# By default, Docmost uses Cloudron's internal email server +# Uncomment and modify these lines to use a custom email server + +# MAIL_DRIVER=smtp +# SMTP_HOST=smtp.gmail.com +# SMTP_PORT=587 +# SMTP_USERNAME=your-email@gmail.com +# SMTP_PASSWORD=your-app-password +# SMTP_SECURE=true +# MAIL_FROM_ADDRESS=your-email@gmail.com +# MAIL_FROM_NAME="Docmost" + +# Alternative: Use Postmark for email +# MAIL_DRIVER=postmark +# POSTMARK_TOKEN=your-postmark-token + +# ====================== +# STORAGE CONFIGURATION +# ====================== + +# By default, files are stored locally in /app/data/uploads +# Uncomment and modify these lines to use S3-compatible storage + +# STORAGE_DRIVER=s3 +# AWS_S3_ACCESS_KEY_ID=your-access-key +# AWS_S3_SECRET_ACCESS_KEY=your-secret-key +# AWS_S3_REGION=us-east-1 +# AWS_S3_BUCKET=your-bucket-name +# AWS_S3_ENDPOINT=https://s3.amazonaws.com +# AWS_S3_FORCE_PATH_STYLE=false + +# For other S3-compatible services (like MinIO, DigitalOcean Spaces): +# AWS_S3_ENDPOINT=https://your-minio-server.com +# AWS_S3_FORCE_PATH_STYLE=true + +# ====================== +# FILE UPLOAD LIMITS +# ====================== + +# FILE_UPLOAD_SIZE_LIMIT=50MB +# FILE_IMPORT_SIZE_LIMIT=50MB + +# ====================== +# APPLICATION SETTINGS +# ====================== + +# JWT_TOKEN_EXPIRES_IN=7d +# DRAWIO_URL=https://embed.diagrams.net + +# Privacy: Disable telemetry (enabled by default) +# DISABLE_TELEMETRY=true + +# ====================== +# DATABASE & REDIS +# ====================== +# These are managed by Cloudron and should not be changed +# DATABASE_URL=postgresql://... +# REDIS_URL=redis://... \ No newline at end of file diff --git a/start.sh b/start.sh index 0d25c80..17f3ed6 100644 --- a/start.sh +++ b/start.sh @@ -4,6 +4,21 @@ set -eu echo "=> Starting Docmost setup" +# Set up writable client dist directory +if [ ! -d "/app/data/client-dist" ]; then + echo "=> Setting up writable client dist directory" + cp -r /app/client-dist-original /app/data/client-dist + chown -R cloudron:cloudron /app/data/client-dist +fi + +# Copy sample .env file and documentation for user reference +if [ ! -f "/app/data/env.sample" ]; then + echo "=> Copying configuration files to /app/data/" + cp /app/code/env.sample /app/data/env.sample + cp /app/code/CONFIGURATION.md /app/data/CONFIGURATION.md + chown cloudron:cloudron /app/data/env.sample /app/data/CONFIGURATION.md +fi + # Initialize /app/data if it's empty (first run) if [ ! -f /app/data/.initialized ]; then echo "=> Initializing data directory" @@ -42,13 +57,21 @@ echo "=> Configuring Redis..." echo "=> Original CLOUDRON_REDIS_URL: ${CLOUDRON_REDIS_URL}" if [ -n "${CLOUDRON_REDIS_URL}" ]; then - # Try to use the original URL first and see if it's valid - export REDIS_URL="${CLOUDRON_REDIS_URL}" + # Parse the URL components first # Also extract components for individual env vars - REDIS_PASSWORD=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://:\([^@]*\)@.*|\1|p') - REDIS_HOST=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://[^@]*@\([^:]*\):.*|\1|p') - REDIS_PORT=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://[^@]*@[^:]*:\([0-9]*\).*|\1|p') + # Handle both formats: redis://default:password@host and redis://:password@host:port + if echo "$CLOUDRON_REDIS_URL" | grep -q "redis://default:"; then + # Format: redis://default:password@host + REDIS_PASSWORD=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://default:\([^@]*\)@.*|\1|p') + REDIS_HOST=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://default:[^@]*@\([^:/]*\).*|\1|p') + REDIS_PORT=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://default:[^@]*@[^:]*:\([0-9]*\).*|\1|p') + else + # Format: redis://:password@host:port + REDIS_PASSWORD=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://:\([^@]*\)@.*|\1|p') + REDIS_HOST=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://[^@]*@\([^:]*\):.*|\1|p') + REDIS_PORT=$(echo "$CLOUDRON_REDIS_URL" | sed -n 's|redis://[^@]*@[^:]*:\([0-9]*\).*|\1|p') + fi # Default port if not found if [ -z "$REDIS_PORT" ]; then @@ -61,29 +84,77 @@ if [ -n "${CLOUDRON_REDIS_URL}" ]; then export REDIS_PASSWORD="${REDIS_PASSWORD}" export REDIS_DB="0" - echo "=> Redis configured: host=${REDIS_HOST}, port=${REDIS_PORT}" - echo "=> Using Redis URL: ${REDIS_URL}" + echo "=> Redis configured: host=${REDIS_HOST}, port=${REDIS_PORT}, has password: $([ -n "$REDIS_PASSWORD" ] && echo "yes" || echo "no")" - # Try alternative formats if the original fails - if [ -z "$REDIS_PASSWORD" ]; then + # Reconstruct the Redis URL in the correct format for ioredis + if [ -n "$REDIS_PASSWORD" ]; then + export REDIS_URL="redis://:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_PORT}" + else export REDIS_URL="redis://${REDIS_HOST}:${REDIS_PORT}" fi + + echo "=> Using Redis URL: ${REDIS_URL}" else echo "=> Error: Redis URL not provided by Cloudron" exit 1 fi -# Email configuration -export MAIL_DRIVER=smtp -export SMTP_HOST="${CLOUDRON_MAIL_SMTP_SERVER}" -export SMTP_PORT="${CLOUDRON_MAIL_SMTP_PORT}" -export SMTP_USERNAME="${CLOUDRON_MAIL_SMTP_USERNAME}" -export SMTP_PASSWORD="${CLOUDRON_MAIL_SMTP_PASSWORD}" -export MAIL_FROM_ADDRESS="${CLOUDRON_MAIL_FROM}" +# Load custom environment variables if they exist +if [ -f "/app/data/.env" ]; then + echo "=> Loading custom environment variables from /app/data/.env" + set -a # automatically export all variables + source /app/data/.env + set +a # stop automatically exporting +else + echo "=> No custom .env file found, using Cloudron defaults" +fi -# Storage configuration (using local storage) -export STORAGE_DRIVER=local -export STORAGE_LOCAL_PATH="/app/data/uploads" +# Email configuration - use custom settings if provided, otherwise use Cloudron defaults +export MAIL_DRIVER="${MAIL_DRIVER:-smtp}" +export SMTP_HOST="${SMTP_HOST:-${CLOUDRON_MAIL_SMTP_SERVER}}" +export SMTP_PORT="${SMTP_PORT:-${CLOUDRON_MAIL_SMTP_PORT}}" +export SMTP_USERNAME="${SMTP_USERNAME:-${CLOUDRON_MAIL_SMTP_USERNAME}}" +export SMTP_PASSWORD="${SMTP_PASSWORD:-${CLOUDRON_MAIL_SMTP_PASSWORD}}" +export SMTP_SECURE="${SMTP_SECURE:-false}" +export MAIL_FROM_ADDRESS="${MAIL_FROM_ADDRESS:-${CLOUDRON_MAIL_FROM}}" +export MAIL_FROM_NAME="${MAIL_FROM_NAME:-Docmost}" + +# Storage configuration - use custom settings if provided, otherwise use local storage +export STORAGE_DRIVER="${STORAGE_DRIVER:-local}" +export STORAGE_LOCAL_PATH="${STORAGE_LOCAL_PATH:-/app/data/uploads}" + +# S3 Storage configuration (only used if STORAGE_DRIVER=s3) +export AWS_S3_ACCESS_KEY_ID="${AWS_S3_ACCESS_KEY_ID:-}" +export AWS_S3_SECRET_ACCESS_KEY="${AWS_S3_SECRET_ACCESS_KEY:-}" +export AWS_S3_REGION="${AWS_S3_REGION:-}" +export AWS_S3_BUCKET="${AWS_S3_BUCKET:-}" +export AWS_S3_ENDPOINT="${AWS_S3_ENDPOINT:-}" +export AWS_S3_FORCE_PATH_STYLE="${AWS_S3_FORCE_PATH_STYLE:-false}" + +# File upload limits +export FILE_UPLOAD_SIZE_LIMIT="${FILE_UPLOAD_SIZE_LIMIT:-50MB}" +export FILE_IMPORT_SIZE_LIMIT="${FILE_IMPORT_SIZE_LIMIT:-50MB}" + +# Application configuration +export APP_URL="${APP_URL:-https://${CLOUDRON_APP_DOMAIN}}" +export APP_SECRET="${APP_SECRET:-${CLOUDRON_APP_ORIGIN}-$(date +%s)}" +export PORT="${PORT:-3001}" +export JWT_TOKEN_EXPIRES_IN="${JWT_TOKEN_EXPIRES_IN:-7d}" + +# Diagrams configuration +export DRAWIO_URL="${DRAWIO_URL:-https://embed.diagrams.net}" + +# Telemetry (disabled by default for privacy) +export DISABLE_TELEMETRY="${DISABLE_TELEMETRY:-true}" + +# Postmark email (alternative to SMTP) +export POSTMARK_TOKEN="${POSTMARK_TOKEN:-}" + +echo "=> Email configuration: ${MAIL_DRIVER} via ${SMTP_HOST}:${SMTP_PORT}" +echo "=> Storage configuration: ${STORAGE_DRIVER}" +if [ "${STORAGE_DRIVER}" = "s3" ]; then + echo "=> S3 storage: ${AWS_S3_BUCKET} in ${AWS_S3_REGION}" +fi # Authentication will use built-in email/password system echo "=> Using built-in email/password authentication"