Advanced OnlyOffice HTTPS configuration using Traefik file providers and self-signed certificates for internal OnlyOffice communication.

Problem Statement

OnlyOffice doesn’t work with HTTPS out of the box when behind a reverse proxy. When:

  • OnlyOffice runs with HTTP internally
  • But is accessed via HTTPS from the reverse proxy

You’ll encounter mixed content or CORS errors, and documents won’t open.

Solution Overview

Three methods to solve this, ordered by complexity (easiest first):

MethodDescriptionDifficultySecurity
Method 0Traefik labels only⭐ EasyGood
Method 1Self-signed certs + skip verification⭐⭐ MediumGood
Method 2Self-signed certs + full verification⭐⭐⭐ AdvancedBest

Method 0: Traefik Labels (Easiest)

See the complete Traefik Labels Guide for full setup.

Key points:

  • Uses Traefik’s built-in certificate handling
  • No manual certificate management
  • Automatic Let’s Encrypt SSL
  • Works for most deployments

This method is covered in detail in the previous guide and is recommended for 95% of use cases.

Method 1: Self-Signed Certificates (Skip Verification)

Use this when:

  • You need custom certificates
  • You’re not using Let’s Encrypt
  • Internal network deployment
  • Corporate CA requirements

Step 1: Generate Self-Signed Certificates

Create certificates directory:

mkdir -p certs && cd certs

Generate OnlyOffice certificates:

openssl req -x509 -nodes -days 20000 -subj "/CN=onlyoffice" \
  -newkey rsa:2048 \
  -keyout onlyoffice.key \
  -out onlyoffice.crt

Command Breakdown:

FlagPurpose
-x509Create self-signed certificate (not a request)
-nodesNo passphrase required
-days 20000Valid for ~50 years (only for internal use)
-subj "/CN=onlyoffice"Set Common Name without prompts
-newkey rsa:2048Generate RSA 2048-bit key pair

Step 2: Configure OnlyOffice with Certificates

Update docker-compose.yml:

services:
  onlyoffice:
    image: onlyoffice/documentserver
    container_name: onlyoffice
    environment:
      - JWT_ENABLED=true
      - JWT_SECRET=your-secret-here
      - JWT_HEADER=Authorization
      - ONLYOFFICE_HTTPS_HSTS_ENABLED=false
    volumes:
      - ./certs:/var/www/onlyoffice/Data/certs  # Mount certificates
      - onlyoffice_data:/var/www/onlyoffice/Data
    networks:
      - proxy_network

Step 3: Configure Traefik File Provider

Traefik needs to be told to skip certificate verification. This requires dynamic configuration which can only be done via file provider, not labels.

Add file provider to traefik.yaml:

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    network: "proxy_network"
    exposedByDefault: false
  file:  # Add this
    directory: /dynamic
    watch: true

Update Traefik docker-compose.yml:

traefik:
  image: traefik:latest
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - ./config/traefik.yaml:/etc/traefik/traefik.yaml:ro
    - ./dynamic:/dynamic:ro  # Add this

Step 4: Create OnlyOffice Dynamic Configuration

Create dynamic/onlyoffice.yml:

http:
  routers:
    onlyoffice:
      entrypoints:
        - websecure  # or 'https' depending on your config
      rule: Host(`office.yourdomain.com`)
      tls:
        certResolver: letsencrypt  # Your cert resolver name
      service: onlyoffice
      # This is the critical setting:
      middlewares:
        - onlyoffice-headers

  services:
    onlyoffice:
      loadBalancer:
        servers:
          - url: "https://onlyoffice"  # Note: HTTPS, not HTTP
        serversTransport: onlyoffice  # Reference to transport below

  middlewares:
    onlyoffice-headers:
      headers:
        customRequestHeaders:
          X-Forwarded-Proto: "https"
        accessControlAllowOriginList:
          - "*"

  serversTransports:
    onlyoffice:
      insecureSkipVerify: true  # This skips certificate verification

Step 5: Update FileBrowser Configuration

integrations:
  office:
    url: "https://office.yourdomain.com"  # External HTTPS URL
    internalUrl: "https://onlyoffice"     # Internal HTTPS (Docker service name)
    secret: "your-jwt-secret"

Step 6: Restart Services

# Restart Traefik to load file provider
docker-compose -f traefik/docker-compose.yaml restart

# Restart OnlyOffice with certificates
docker-compose -f onlyoffice/docker-compose.yaml restart

# Restart FileBrowser
docker-compose -f filebrowser/docker-compose.yaml restart

Verify Configuration

# Check OnlyOffice is using HTTPS
docker exec onlyoffice cat /etc/onlyoffice/documentserver/nginx/ds.conf | grep ssl

# Test from Traefik perspective
docker exec traefik wget --no-check-certificate https://onlyoffice/healthcheck

Method 2: Self-Signed Certificates (Full Verification)

Use this for maximum security when you want Traefik to verify OnlyOffice’s certificate.

Step 1: Create Certificate Configuration

Create certs/cert.conf:

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_req

[dn]
CN = onlyoffice

[v3_req]
subjectAltName = @alt_names

[alt_names]
IP.1 = 172.18.0.255  # Static IP for OnlyOffice container
DNS.1 = onlyoffice   # Docker service name

Step 2: Generate Certificates with Config

cd certs
openssl req -x509 -nodes -days 20000 \
  -keyout onlyoffice.key \
  -out onlyoffice.crt \
  -config cert.conf

Step 3: Assign Static IP to OnlyOffice

Update onlyoffice/docker-compose.yaml:

services:
  onlyoffice:
    image: onlyoffice/documentserver
    container_name: onlyoffice
    environment:
      - JWT_ENABLED=true
      - JWT_SECRET=your-secret
      - ONLYOFFICE_HTTPS_HSTS_ENABLED=false
    volumes:
      - ./certs:/var/www/onlyoffice/Data/certs
    networks:
      proxy_network:
        ipv4_address: 172.18.0.255  # Must match cert.conf

Step 4: Mount Certificate in Traefik

Traefik needs access to the certificate to verify it:

traefik:
  image: traefik:latest
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - ./config/traefik.yaml:/etc/traefik/traefik.yaml:ro
    - ./dynamic:/dynamic:ro
    - /path/to/certs/onlyoffice.crt:/certs/onlyoffice.crt:ro  # Add this

Step 5: Update Traefik Dynamic Config

Create dynamic/onlyoffice.yml:

http:
  routers:
    onlyoffice:
      entrypoints:
        - websecure
      rule: Host(`office.yourdomain.com`)
      tls:
        certResolver: letsencrypt
      service: onlyoffice

  services:
    onlyoffice:
      loadBalancer:
        servers:
          - url: "https://onlyoffice"  # Or https://172.18.0.255
        serversTransport: onlyoffice

  middlewares:
    onlyoffice-headers:
      headers:
        customRequestHeaders:
          X-Forwarded-Proto: "https"
        accessControlAllowOriginList:
          - "*"

  serversTransports:
    onlyoffice:
      rootCAs:
        - /certs/onlyoffice.crt  # Path inside Traefik container
      # insecureSkipVerify NOT set (defaults to false)

Step 6: Restart and Verify

# Restart all services
docker-compose -f traefik/docker-compose.yaml restart
docker-compose -f onlyoffice/docker-compose.yaml up -d
docker-compose -f filebrowser/docker-compose.yaml restart

# Check Traefik can verify certificate
docker exec traefik wget https://onlyoffice/healthcheck
# Should succeed without certificate errors

Method 3: Certbot / Let’s Encrypt for OnlyOffice

If you still want to use Certbot for OnlyOffice’s internal certificate:

Challenges:

  • Let’s Encrypt certificates expire every 90 days
  • Requires automated renewal process
  • OnlyOffice container needs certificate updates
  • More complex than self-signed for internal use

Better Alternative: Use Method 0 (Traefik labels) where Traefik handles Let’s Encrypt for external access, and OnlyOffice uses HTTP internally.

Method 4: Extract Certificates from Traefik

Concept:

  1. Traefik obtains Let’s Encrypt certificates
  2. Extract certificates from acme.json
  3. Mount extracted certificates to OnlyOffice
  4. Automate re-extraction on renewal

Challenges:

  • Certificates renew every 90 days
  • Requires automation script
  • OnlyOffice restart needed after renewal
  • More complexity than needed

Script Example:

#!/bin/bash
# extract-certs.sh

ACME_FILE="traefik/certs/acme.json"
DOMAIN="office.yourdomain.com"
OUTPUT_DIR="certs/extracted"

# Extract certificate and key from acme.json
jq -r ".letsencrypt.Certificates[] | select(.domain.main==\"$DOMAIN\") | .certificate" "$ACME_FILE" | base64 -d > "$OUTPUT_DIR/cert.pem"
jq -r ".letsencrypt.Certificates[] | select(.domain.main==\"$DOMAIN\") | .key" "$ACME_FILE" | base64 -d > "$OUTPUT_DIR/key.pem"

# Restart OnlyOffice to load new certificates
docker-compose -f onlyoffice/docker-compose.yaml restart

Comparison Table

FeatureMethod 0Method 1Method 2Method 3/4
Setup Complexity⭐ Easy⭐⭐ Medium⭐⭐⭐ Advanced⭐⭐⭐⭐ Complex
SecurityExcellentGoodExcellentExcellent
MaintenanceNoneNoneNoneHigh
Certificate RenewalAutomaticNever expiresNever expiresEvery 90 days
Use CaseMost deploymentsCustom CAMaximum securityNot recommended
Browser SSLLet’s EncryptLet’s EncryptLet’s EncryptLet’s Encrypt
Internal SSLHTTPHTTPSHTTPSHTTPS

Troubleshooting

Certificate Errors in Traefik Logs

# Check Traefik logs
docker-compose -f traefik/docker-compose.yaml logs | grep -i certificate

# Common errors:
# - "x509: certificate signed by unknown authority" → Need rootCAs in transport
# - "x509: certificate is valid for X, not Y" → DNS/IP mismatch in cert
# - "tls: bad certificate" → Wrong certificate mounted

OnlyOffice Not Starting with HTTPS

# Check OnlyOffice nginx config
docker exec onlyoffice cat /etc/onlyoffice/documentserver/nginx/ds.conf

# Check certificate files
docker exec onlyoffice ls -la /var/www/onlyoffice/Data/certs/

# Should show:
# -rw-r--r-- onlyoffice.crt
# -rw-r--r-- onlyoffice.key

Mixed Content Errors

Ensure all URLs use https:// in FileBrowser config:

server:
  externalUrl: "https://files.yourdomain.com"

integrations:
  office:
    url: "https://office.yourdomain.com"
    internalUrl: "https://onlyoffice"  # Method 1/2 only

Verify Certificate Details

# Check certificate subject and SAN
openssl x509 -in certs/onlyoffice.crt -noout -text | grep -A1 "Subject:"
openssl x509 -in certs/onlyoffice.crt -noout -text | grep -A2 "Subject Alternative"

# Should show:
# Subject: CN = onlyoffice
# Subject Alternative Name:
#   DNS:onlyoffice, IP Address:172.18.0.255

Configuration Summary

# OnlyOffice: HTTP internally
services:
  onlyoffice:
    # No certificates needed
    # Access via HTTP from Docker network

# Traefik: Handles all HTTPS
# FileBrowser: Uses HTTPS URLs externally

Method 1 (Skip Verify)

# OnlyOffice: HTTPS with self-signed
volumes:
  - ./certs:/var/www/onlyoffice/Data/certs

# Traefik: Skip verification
serversTransports:
  onlyoffice:
    insecureSkipVerify: true

Method 2 (Full Verify)

# OnlyOffice: HTTPS with SAN cert
networks:
  proxy_network:
    ipv4_address: 172.18.0.255

# Traefik: Verify with CA
serversTransports:
  onlyoffice:
    rootCAs:
      - /certs/onlyoffice.crt

Best Practices

  1. Start Simple: Use Method 0 unless you have specific requirements
  2. Test Staging First: Use Let’s Encrypt staging for initial testing
  3. Monitor Logs: Watch logs during first deployment
  4. Backup Certificates: Keep acme.json backed up
  5. Document Setup: Note which method you used for future reference

Next Steps

Credits

This guide is based on community contributions from:

Thank you for sharing your knowledge with the community!