Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT]: Self-Signed SSL Certificate Support for Local Docker Hosting #2892

Open
spencerthayer opened this issue Dec 24, 2024 · 2 comments
Open
Labels
enhancement New feature or request feature request

Comments

@spencerthayer
Copy link

What would you like to see?

This feature request proposes adding the capability for AnythingLLM to automatically generate and use a self-signed SSL certificate when running locally via Docker. This would enable secure HTTPS connections for local development and testing without requiring manual certificate generation or configuration.

Motivation:

Currently, when running AnythingLLM locally via Docker, the default is to serve the application over HTTP. While sufficient for basic local testing, there are several benefits to enabling HTTPS even in a development environment:

  • Mirrors Production More Closely: Many modern web applications utilize HTTPS, and developing locally with HTTPS can help catch potential issues related to mixed content, secure cookies, and other HTTPS-specific behaviors earlier in the development cycle.
  • Improved Security (Even Self-Signed): While self-signed certificates will trigger browser warnings, they still encrypt communication between the browser and the local server, offering a degree of protection against eavesdropping on local network traffic.
  • Testing Features Requiring HTTPS: Some browser features or APIs might require a secure context (HTTPS) to function correctly. Having built-in HTTPS makes it easier to test such integrations locally.
  • Simplified Local Development Workflow: Manually generating and configuring SSL certificates for local development can be cumbersome. An automated solution streamlines this process.

Proposed Solution:

The core idea is to have AnythingLLM automatically generate a self-signed certificate and configure its internal web server to use it when the application runs within a Docker environment with the potential to control settings via an environment variable).

Implementation Considerations:

Here are some potential ways to implement this, considering the AnythingLLM codebase:

  1. Dockerfile Modification:

    • Certificate Generation Script: Include a script within the Dockerfile that generates a self-signed certificate using tools like openssl. This script could run during the Docker image build process or, ideally, at container startup to ensure the certificate is fresh (though storing it in the image is simpler).
    • Certificate and Key Storage: Decide on a secure location within the Docker container to store the generated certificate and private key (e.g., /etc/ssl/certs/anythingllm.crt and /etc/ssl/private/anythingllm.key).
    • Permissions: Ensure appropriate file permissions are set for the certificate and key.
  2. Backend Application Logic (Node.js):

    • Conditional HTTPS Configuration: Modify the backend code (likely in the main server setup file, potentially within the server.js or equivalent) to conditionally enable HTTPS. This could be based on:
      • Environment Variable: Introduce an environment variable like ENABLE_LOCAL_HTTPS=true.
      • Docker Environment Detection: Check if the application is running inside a Docker container.
    • Loading the Certificate: If HTTPS is enabled, the application should load the generated certificate and key from the specified locations. This typically involves passing these paths to the HTTPS server creation function (e.g., https.createServer() in Node.js).
    • Default Port: Consider using the standard HTTPS port (443) or a configurable port if needed, while retaining the option for HTTP on a separate port.
    • Logging: Add informative logging to indicate whether HTTPS is enabled and the location of the certificate.
  3. Docker Compose Configuration (If applicable):

    • If using Docker Compose, consider adding an environment variable to the anythingllm service to control this feature.
// Hypothetical server.js
const express = require('express');
const https = require('https');
const fs = require('fs');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;
const HTTPS_ENABLED = process.env.ENABLE_LOCAL_HTTPS === 'true';

if (HTTPS_ENABLED) {
  const certPath = '/etc/ssl/certs/anythingllm.crt';
  const keyPath = '/etc/ssl/private/anythingllm.key';

  try {
    const privateKey = fs.readFileSync(keyPath, 'utf8');
    const certificate = fs.readFileSync(certPath, 'utf8');

    const credentials = { key: privateKey, cert: certificate };
    const httpsServer = https.createServer(credentials, app);

    httpsServer.listen(443, () => {
      console.log('Running on HTTPS port 443');
    });
  } catch (error) {
    console.error('Error loading SSL certificate:', error);
    // Fallback to HTTP or exit with an error
    app.listen(PORT, () => {
      console.log(`Running on HTTP port ${PORT} (HTTPS configuration failed)`);
    });
  }
} else {
  app.listen(PORT, () => {
    console.log(`Running on HTTP port ${PORT}`);
  });
}
@spencerthayer spencerthayer added enhancement New feature or request feature request labels Dec 24, 2024
@spencerthayer
Copy link
Author

Is this something of value to the community?

@spencerthayer
Copy link
Author

I loaded the documentation and codebase into an AnythingLLM workspace and asked it this question. This is what is says:

Key Points from Documentation:

  1. Environment Variables for HTTPS:
    • ENABLE_HTTPS: Should be set to "true" to enable HTTPS support in AnythingLLM.
    • HTTPS_CERT_PATH: Should provide the path to the SSL certificate file.
    • HTTPS_KEY_PATH: Should provide the path to the SSL private key file.

Review of the Provided YAML Configuration:

Docker Compose Configuration:

version: "3.8"

services:
  anythingllm:
    image: mintplexlabs/anythingllm:latest
    container_name: anythingllm
    ports:
      - "443:3001" # Map host port 443 to container port 3001
    environment:
      - STORAGE_DIR=/app/server/storage
      - EMBEDDING_ENGINE=native
      - VECTOR_DB=lancedb
      - LLM_PROVIDER=google_vertex_ai
      - LLM_MODEL_NAME=gemini-2.0-flash-exp
      - GOOGLE_API_KEY=${GOOGLE_API_KEY}
      - ENABLE_HTTPS=true  # Enabling HTTPS
      - HTTPS_CERT_PATH=/etc/ssl/certs/cert.pem  # Correct SSL certificate path
      - HTTPS_KEY_PATH=/etc/ssl/private/key.pem  # Correct SSL key path
    volumes:
      - anythingllm_data:/app/server/storage
      - ./sslcert:/etc/ssl # Mount the sslcert directory into the container
    restart: always
    networks:
      - app-network

volumes:
  anythingllm_data:
    driver: local

networks:
  app-network:
    driver: bridge

Validating Each Section:

  1. Ports Configuration:

    • ports: - "443:3001": This maps the host's port 443 to the container's port 3001. Assuming AnythingLLM is configured to listen on port 3001 during HTTPS usage, this setup is correct. Ensure that AnythingLLM can actually accept connections on this port for HTTPS.
  2. Environment Variables:

    • All required environment variables for configuring HTTPS are present, including:
      • ENABLE_HTTPS=true: Correctly enables HTTPS.
      • HTTPS_CERT_PATH and HTTPS_KEY_PATH: Aligned with the paths expected within the container.
  3. Volume Mounting:

    • The volume ./sslcert:/etc/ssl correctly mounts the local directory containing SSL files into the intended directory inside the container. Ensure that the SSL files exist and are correctly named:
      • cert.pem should be placed in ./sslcert/certs/
      • key.pem should be in ./sslcert/private/
  4. Restart Policy and Network Configuration:

    • The usage of restart: always is appropriate for production-like environments, ensuring that the service restarts if it fails.
    • The network configuration is standard and should work correctly, allowing communication between services if you expand the configuration.
  5. Volume for Data Persistence:

    • The anythingllm_data volume allows for data persistence, ensuring that AnyLLM's state is maintained across container restarts.

Conclusion:

Based on your information and the typical configuration practices, the provided docker-compose.yml appears correct if:

  • The certificate and key files are valid and located in the specified directories.
  • AnythingLLM is indeed capable of handling HTTPS using these environment variables as documented.

Important Recommendations:

  • Testing: Once deployed, run tests to access https://localhost (or your server IP). Make sure to confirm that the browser does not throw SSL warnings or errors, keeping in mind that self-signed certificates will always prompt a warning.
  • Documentation Review: Always keep an eye on the official AnythingLLM documentation and codebase for any updates or changes concerning SSL configuration, as software evolves frequently.

If everything aligns with your expectations and setup, you're good to go! If there are specific areas of uncertainty, please share them, and I can help clarify those points.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feature request
Projects
None yet
Development

No branches or pull requests

1 participant