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

Closed
opened 2026-02-22 18:26:47 -05:00 by yindo · 2 comments
Owner

Originally created by @spencerthayer on GitHub (Dec 23, 2024).
Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/2892

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}`);
  });
}
Originally created by @spencerthayer on GitHub (Dec 23, 2024). Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/2892 ### 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. ```javascript // 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}`); }); } ```
yindo added the enhancementfeature request labels 2026-02-22 18:26:47 -05:00
yindo closed this issue 2026-02-22 18:26:47 -05:00
Author
Owner

@spencerthayer commented on GitHub (Dec 24, 2024):

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.
@spencerthayer commented on GitHub (Dec 24, 2024): 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:** ```yaml 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.
Author
Owner

@timothycarambat commented on GitHub (Dec 28, 2024):

This is out of scope for the repo. Specific desires on how one would like to run anythingLLM is not something we will dictate or force for anyone beyond the configurations we already provide and can be used.

We support SSL certs so that people can provision or use their own. Building an automatic provisioning system is a lot of effort for something most won't use since using a web server like NGINX or otherwise with a reverse proxy is usually sufficient.

We have enabled people to use whatever setup they or their IT are compliant with and forcing a paradigm onto people or otherwise is not something we should take any firm stance on and instead leave that up to the system admin when deploying AnythingLLM in their environment so it remains maximally flexible

@timothycarambat commented on GitHub (Dec 28, 2024): This is out of scope for the repo. Specific desires on how one would like to run anythingLLM is not something we will dictate or force for anyone beyond the configurations we already provide and can be used. We support SSL certs so that people can provision or use their own. Building an automatic provisioning system is a lot of effort for something most won't use since using a web server like NGINX or otherwise with a reverse proxy is usually sufficient. We have enabled people to use whatever setup they or their IT are compliant with and forcing a paradigm onto people or otherwise is not something we should take any firm stance on and instead leave that up to the system admin when deploying AnythingLLM in their environment so it remains maximally flexible
yindo changed title from [FEAT]: Self-Signed SSL Certificate Support for Local Docker Hosting to [GH-ISSUE #2892] [FEAT]: Self-Signed SSL Certificate Support for Local Docker Hosting 2026-06-05 14:43:00 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Mintplex-Labs/anything-llm#1840