Overview

xlwings Lite is available as Docker image for self-hosting:

docker pull xlwings/xlwings-lite:1.0.0.0-69

It can be hosted on any service that runs Docker containers. As this is just a static file server, the container requires very little CPU and memory.

Note

While xlwings Lite is free via Excel’s add-in store, self-hosting requires a paid license, see Pricing.

Environment variables

The Docker image supports the following environment variables:

  • XLWINGS_LICENSE_KEY (required): your xlwings license key

  • XLWINGS_HOSTNAME (optional): e.g., xlwings-lite.mycompany.com. If the downloaded manifest.xml doesn’t use the correct URL, set this env var.

  • XLWINGS_ENABLE_PYPI (optional, default true): If true, allows installing packages directly from https://pypi.org/. Ignored when XLWINGS_PYPI_INDEX_URL is set.

  • XLWINGS_PYPI_INDEX_URL (optional): full URL of a private PyPI index (e.g., Nexus, Artifactory, devpi) — the same URL you’d pass to pip install --index-url. Example: https://nexus.example.com/repository/pypi-proxy/simple/.

  • XLWINGS_PYODIDE_BASE_URL (optional): base URL from which Pyodide and its packages are served. Defaults to the Pyodide distribution bundled with the Docker image. Set this to an external URL (e.g., https://pyodide.company.com) to serve Pyodide from a separate host instead, see below.

  • XLWINGS_CORS_PROXY_HOSTS (optional): comma-separated allowlist of hostnames that user Python code can reach via the built-in CORS proxy. Supports exact matches and *.domain.com wildcards (e.g., api.example.com,*.trusted.com). HTTPS-only. Unset (the default) disables the proxy.

  • XLWINGS_CORS_PROXY_ALLOW_ALL_HOSTS (optional, default false): if true, proxies all requests, ignoring XLWINGS_CORS_PROXY_HOSTS.

  • XLWINGS_MANIFEST_ID (optional): UUID used as the add-in <Id> in manifest.xml. Defaults to the same UUID as xlwings Lite (cloud), so workbooks created with the cloud add-in (when deployed via Office admin center) keep working when you switch to self-hosted without conversion. Set this to a fresh UUID if you want this self-hosted deployment to have a separate identity (e.g., to run it alongside the cloud add-in in the same tenant).

  • XLWINGS_ENABLE_CLOUD_CONVERTER (optional, default false): if true, exposes a “Convert from cloud add-in” menu item that rewrites .xlsx/.xlsm/.xlsb files in the user’s /data directory so they resolve to this self-hosted deployment. Only needed for migrating workbooks created with individual user installs. Workbooks from admin-center deployments of the cloud add-in already resolve via XLWINGS_MANIFEST_ID.

  • XLWINGS_ENABLE_MISSING_ADDIN_CLEANUP (optional, default true): if true, exposes a “Clean up missing add-in references” menu item that strips orphaned add-in references from workbooks in /data.

  • PORT (optional, default 8000): sets the port on which the application runs, e.g., 8000.

Direct PyPI access

By default (XLWINGS_ENABLE_PYPI=true), end users install packages directly from pypi.org via requirements.txt. This is convenient — users manage their own dependencies, no IT involvement, no internal index to operate.

The trade-offs to consider for production deployments:

  • Supply-chain risk. Any package a user installs runs inside the browser, which is a strict sandbox: the package cannot escape to the user’s operating system, read arbitrary files on disk, launch processes, or reach the local network. What it can see is whatever the add-in itself sees inside that sandbox — the active workbook’s data, xlwings Lite settings, environment variables set in xlwings Lite, and any files the user explicitly mounted or imported into the session. A malicious or compromised package (including typosquats) could exfiltrate anything the add-in has access to over the network.

  • No vetting gate. There is no central review of what gets pulled in.

  • Compliance & audit. Regulated environments often disallow direct egress to a public package index.

  • Availability. A PyPI outage (or a yanked/deleted version) directly breaks user workflows; there is no internal cache to fall back on.

  • Network egress. Reaching pypi.org from end-user machines may conflict with corporate firewall policies.

To mitigate, use an internal PyPI proxy (e.g., Nexus, Artifactory, devpi, Cloudsmith, AWS CodeArtifact, GCP Artifact Registry, Azure Artifacts) via XLWINGS_PYPI_INDEX_URL.

Hosting Solutions

Here are specific instructions for certain providers/hosting solutions: