mathesar Documentation

An intuitive spreadsheet-like interface that lets users of all technical skill levels view, edit, query, and collaborate on Postgres data directly—100% open...

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy mathesar on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name mathesar -p 80:80 --restart always mathesar/mathesar:latest
Configured Services & Ports
⚙️ service
image: mathesar/mathesar:latest
⚙️ db
image: pgautoupgrade/pgautoupgrade:17-bookworm
⚙️ caddy-reverse-proxy
image: mathesar/mathesar-caddy:latest
🔌 Ports: 80:80, 443:443
docker-compose.yml
yaml (docker-compose.yml)
---
# This file defines a viable production setup for Mathesar.
#
# It can be used in production directly, or used as an example to help define
# your own infrastructure.
#
#-------------------------------------------------------------------------------
# PREREQUISITES
#
# Please double-check that your docker setup meets the following criteria:
#
# OS: Linux, Mac, Windows(WSL).
# Docker v23+  $ docker version
# Docker Compose v2.10+  $ docker compose version
#
#-------------------------------------------------------------------------------
# HOW TO USE THIS FILE
#
# First, make sure you meet the prerequisites, and then run:
#
# $ docker compose -f docker-compose.yml up
#
# Note: You may need to run Docker commands using sudo, depending on your setup.
# Running Docker in rootless mode isn't currently supported.
#
#-------------------------------------------------------------------------------
# CONFIG
#
# Customize your Mathesar installation with the following variables.
# See https://docs.mathesar.org/configuration/env-variables/ for more info.
#
x-config: &config
  # (Optional) Replace 'http://localhost' with custom domain(s) e.g.
  # 'yourdomain.com, 127.0.0.1' to manage the host(s) at which you want to
  # access Mathesar over http or https
  DOMAIN_NAME: ${DOMAIN_NAME:-http://localhost}

  # Edit the POSTGRES_* variables if you are not using the db service provided
  # below, or if you want to use a custom database user.

  # (Optional) Replace 'mathesar_django' with any custom name for the internal
  # database managed by mathesar web-service
  POSTGRES_DB: ${POSTGRES_DB:-mathesar_django}

  # (Optional) Replace 'mathesar' with any custom username for the
  # aforementioned database
  POSTGRES_USER: ${POSTGRES_USER:-mathesar}

  # (Optional) Replace 'mathesar' with any custom password for the
  # aforementioned database
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mathesar}

  # (Optional) Replace 'mathesar_db' with the name of the host running postgres
  POSTGRES_HOST: ${POSTGRES_HOST:-mathesar_db}

  # (Optional) Replace '5432' with the port on which postgres is running
  POSTGRES_PORT: ${POSTGRES_PORT:-5432}

  # (Optional) Can be used to configure an S3-compliant file storage backend
  # instead of a file_storage.yml configuration file.
  FILE_STORAGE_DICT: ${FILE_STORAGE_DICT:-{}}

  # (Optional) Can be used to configure single-sign on (sso) instead of an
  # sso.yml configuration file.
  # See https://docs.mathesar.org/administration/single-sign-on/ for additional
  # details on how to configure this variable. OIDC_CONFIG_DICT is the legacy
  # name, kept for backwards compatibility.
  SSO_CONFIG_DICT: ${SSO_CONFIG_DICT:-{}}
  OIDC_CONFIG_DICT: ${OIDC_CONFIG_DICT:-{}} # deprecated, use SSO_CONFIG_DICT

  # (Optional) Set to 'true' to disable password-based login and require all
  # users to sign in via a configured SSO provider. Has no effect unless at
  # least one SSO provider is configured.
  REQUIRE_SSO_LOGIN: ${REQUIRE_SSO_LOGIN:-false}

  # (Optional) Set to 'true' to enable Django's built-in admin at /admin/.
  # This does not affect Mathesar's own /administration/ pages.
  MATHESAR_DJANGO_ADMIN_ENABLED: ${MATHESAR_DJANGO_ADMIN_ENABLED:-false}

  # (Optional) Redirect anonymous visits to "/" to an external landing page.
  MATHESAR_LANDING_PAGE_URL: ${MATHESAR_LANDING_PAGE_URL:-}

  # (Optional) Customize the instance branding shown on login/auth pages.
  MATHESAR_INSTANCE_NAME: ${MATHESAR_INSTANCE_NAME:-Mathesar}
  MATHESAR_AUTH_LOGO_URL: ${MATHESAR_AUTH_LOGO_URL:-}

  # (Optional) Customize localized plain text copy shown on the login page
  # instead of a login_page.yml configuration file.
  MATHESAR_LOGIN_PAGE_TEXT_DICT: ${MATHESAR_LOGIN_PAGE_TEXT_DICT:-{}}
  MATHESAR_LOGIN_PAGE_BACKGROUND: ${MATHESAR_LOGIN_PAGE_BACKGROUND:-}

  # (Optional) Set one or both to show links to your terms of service and
  # privacy policy pages at the bottom of the login page.
  MATHESAR_TERMS_OF_SERVICE_URL: ${MATHESAR_TERMS_OF_SERVICE_URL:-}
  MATHESAR_PRIVACY_POLICY_URL: ${MATHESAR_PRIVACY_POLICY_URL:-}

#-------------------------------------------------------------------------------
# ADDITIONAL INFO ABOUT CONFIG VARIABLES
#
# DOMAIN_NAME:
#     Default: http://localhost
#     Info: Specifies the domains that can access Mathesar over http(port 80)
#           or https(port 443), also automatically creating SSL certificates
#           for the same. If you want to host an instance of Mathesar over the
#           internet or over your local network, add those domains here.
#     Example: yourdomain.com, *.subdomain.com, 127.0.0.1
#
# POSTGRES_DB:
#     Default: mathesar_django
#     Info: Specifies a name for the database that will be created and used by
#           Mathesar for managing internal data.
#     Example: zeus
#
# POSTGRES_USER:
#     Default: mathesar
#     Info: Specifies creation of a user with superuser privileges
#           and a database with the same name.
#     Example: athena
#
# POSTGRES_PASSWORD:
#     Default: mathesar
#     Info: Specifies the superuser password that is required to be set for the
#           PostgreSQL docker image.
#     Example: apollo
#
# POSTGRES_HOST:
#     Default: mathesar_db (name of the db service provided below)
#     Info: Specifies the host name on which portgres listen for connections
#           from client applications. Can be a docker compose service name,
#           a A TCP host address (e.g., host.docker.internal), or a Unix
#           socket path (e.g., /var/run/postgresql).
#     Example: kratos
#
# POSTGRES_PORT:
#     Default: 5432
#     Info: Specifies the port on which portgres listen for connections from
#           client applications.
#     Example: 5555
#
# FILE_STORAGE_DICT:
#     Default: {}
#     Info: Specifies the settings necessary to configure an S3-complaint
#           filestorage backend.
#
# SSO_CONFIG_DICT (alias: OIDC_CONFIG_DICT):
#   Default: {}
#   Info: Specifies the settings necessary to configure Single Sign-on (SSO)
#   identity providers for Mathesar login (including OIDC providers and
#   GitHub). This is an optional, alternative approach to configuring SSO
#   via a configuration file. OIDC_CONFIG_DICT is the legacy name and is
#   still accepted.
#
# REQUIRE_SSO_LOGIN:
#   Default: false
#   Info: When set to 'true', Mathesar disables password-based login and only
#   allows users to sign in via a configured SSO provider. Users will not be
#   able to update their own passwords or email addresses. Administrators can
#   still reset another user's password and edit other users' emails as a
#   break-glass mechanism. Has no effect unless at least one SSO provider is
#   configured.
#
#-------------------------------------------------------------------------------
# INFO ABOUT VOLUMES
#
# Volumes are used by Mathesar to persist essential data.
#
# Running this compose file will automatically create a subdirectory named
# "msar" with the following file structure:
#
# msar
# ├── caddy/  (stores certificates, keys, and other information for Caddy)
# ├── media/  (stores user uploaded datafiles(.csv/.tsv) to Mathesar)
# ├── pgdata/ (stores PostgreSQL data)
# ├── secrets/ (stores the SECRET_KEY, eventually other secret info)
# └── static/ (stores static files for Mathesar)
#
#
#-------------------------------------------------------------------------------
# MATHESAR SERVICES
#
# The next section defines various containers in a workable production setup.
#
services:
  #-----------------------------------------------------------------------------
  # Mathesar web service
  #
  # This service provides the main web server required to run Mathesar, using
  # our official Docker image hosted on Docker Hub
  #
  # As configured, this service exposes port 8000 to other services but not the
  # host system. This isolates it from being directly accessed  by the host
  # while allowing access via caddy.
  #
  service:
    container_name: mathesar_service
    image: mathesar/mathesar:latest
    environment:
      # First we load the variables configured above.
      <<: *config

      DJANGO_SETTINGS_MODULE: config.settings.production

      # We set ALLOWED_HOSTS to * (allow all hosts) by default here since we are
      # relying on caddy to manage which domains could access the mathesar web
      # service.  If you do not want to use caddy add the domain(s) that you
      # want to ALLOWED_HOSTS. Doing so will restrict traffic from all other
      # domains.
      ALLOWED_HOSTS: ${ALLOWED_HOSTS:-*}

      # SECURITY WARNING: don't run with DEBUG=true in production!
      DEBUG: ${DEBUG:-false}

      # To use a custom secret key, use an .env file, or add a sufficiently
      # random 50 character string after '-'. Otherwise a random value will be
      # generated when you start Mathesar. If you aren't sure, it's safe to
      # leave this as-is.
      SECRET_KEY: ${SECRET_KEY-}

      # If you are running Mathesar on a particularly powerful machine, you can
      # improve performance by increasing this setting. Replace '3' below with
      # 2 * $(NUM_CORES) + 1. So if you have a VPS with 4 vCPUs you can use a
      # value of 2 * 4 + 1, or 9. The default is workable as long as you have at
      # least 1 logical core.
      WEB_CONCURRENCY: ${WEB_CONCURRENCY-3}

      # EXPERIMENTAL FEATURE: Behavior might change in future Mathesar versions.
      # If this is set to true, each new use in Mathesar will receive a role
      # with the same name as their username on the internal DB server, and a
      # database owned by that role will be created and connected for that user.
      PER_USER_DATABASES_ENABLED: ${PER_USER_DATABASES_ENABLED-false}

    volumes:
      - ./msar/static:/code/static
      - ./msar/media:/code/.media
      - ./msar/secrets:/code/.secrets
      # Uncomment the following to mount file_storage.yml and enable
      #  an S3-compliant file storage backend
      # - ./file_storage.yml:/code/file_storage.yml
      # Uncomment the following to mount sso.yml and enable Single Sign-On (SSO).
      # - ./sso.yml:/code/sso.yml
      # Uncomment the following to mount login_page.yml and customize localized
      # plain text copy on the login page.
      # - ./login_page.yml:/code/login_page.yml
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: curl -f http://localhost:8000/healthz/ready/
      interval: 10s
      timeout: 5s
      retries: 30
      start_period: 5s
    # If using caddy, expose the internal port 8000 only to other containers and
    # not the docker host.
    expose:
      - "8000"
    # Uncomment the following if not using caddy
    # ports:
    #   - ${HOST_PORT:-8000}:8000

  #-----------------------------------------------------------------------------
  # PostgreSQL Database
  #
  # This service provides a Postgres database instance for holding both internal
  # Mathesar data, as well as user data if desired, using the official
  # PostgreSQL image hosted on Docker Hub
  #
  # As configured, this service exposes Postgres' default port (5432) to other
  # services, allowing the Mathesar web sevice to connect to it.
  #
  db:
    image: pgautoupgrade/pgautoupgrade:17-bookworm
    container_name: mathesar_db
    # This service needs the config variables defined above.
    environment: *config
    # Expose the internal port 5432 only to other containers and not
    # the underlying host.
    expose:
      - "5432"
    volumes:
      - ./msar/pgdata:/var/lib/postgresql/data

  #-----------------------------------------------------------------------------
  # Caddy
  #
  # This service provides a reverse proxy for the Mathesar web server, using our
  # custom Caddy image hosted on Docker Hub. That image is customized to use a
  # Caddyfile with an appropriate configuration for Mathesar.
  #
  # Specifically, this service routes the requests to backend and the web
  # frontend of Mathesar while also serving essential staic files and user
  # uploaded datafiles(.csv/.tsv). It also provides SSL certificates
  # automatically for any custom domain(s) listed in DOMAIN_NAME that you might
  # want to use to access Mathesar.
  #
  # This service maps the default port for http(80) and https(443) of the host
  # system to that of docker's for allowing access to Mathesar over http or
  # https.
  #
  caddy-reverse-proxy:
    image: mathesar/mathesar-caddy:latest
    # This service needs the config variables defined above.
    environment: *config
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./msar/media:/code/.media
      - ./msar/static:/code/static
      - ./msar/caddy:/data

Chapter: README (docs/README.md)

Mathesar's Documentation

This directory contains the source code for Mathesar's user and administrator documentation published to https://docs.mathesar.org/

Preview your documentation edits locally

  1. Install requirements

    text
    pip install -r requirements.txt
  2. Start MkDocs

    text
    mkdocs serve -a localhost:9000
  3. Preview the docs at http://localhost:9000

  4. Keep mkdocs running while you edit and your local preview will refresh automatically.

Contribution process

  • For small documentation improvements, we welcome PRs without any prior issues. For larger edits, please open an issue first to discuss your changes and get approval from the team before proceeding.

  • Take care when choosing the git branch on which to base your edits

    • Target master if you have an important fix which needs to be published for the currently-released version of Mathesar.
    • Target develop if you are adding/updating documentation along with yet-to-be-released changes to the product.

    The docs site is published from the master branch. This is important because we want to ensure that it reflects the latest released version of Mathesar so that docs readers who are installing or using Mathesar don't see content before it's actually applicable.

See our Contribution guidelines for more information about our pull-request workflow.

For docs content, we adhere to CiviCRM's Documentation Style Guide.

MkDocs Material

  • Our docs run on a distribution of mkdocs called mkdocs-material. For basics of doc writing, see the Writing your docs section of mkdocs user guide.

  • For some customization basics, see Customization section of mkdocs-material's Getting started guide. To learn about some of mkdocs-material's features (annotations, code blocks, content tabs, etc.), see its Reference.

Hosting

We use GitHub pages to host https://docs.mathesar.org/

Here's how this works:

  1. In our main Mathesar repo, there's a branch called gh-pages.
  2. The gh-pages branch is not like other branches though. It has nothing in common with develop or master. The files in that branch are static HTML files for the docs site.
  3. Whenever GitHub sees new commits pushed to that branch, a GitHub action publishes the content to the live docs site.

Publication process

Changes to documentation is published manually. This may change in the future.

Versioning

  • We use mike to publish docs for multiple versions of Mathesar.
  • Mike integrates with mkdocs-material to provide a version switcher within the site header.

How to publish a single version of Mathesar's docs

  1. Check out the git branch corresponding to the version you'd like to publish. For example:

    text
    git checkout master

    As a convention, we use branches named like docs_1.2.3 to retain changes to documentation which are made after a specific release is tagged. So you may end up needing to check out (or even create) a branch like that.

  2. Go to the docs directory within the project root.

    text
    cd docs
  3. Ensure you have the docs-related dependencies:

    text
    pip install -r ./requirements.txt

    Note that these dependencies are different from the Mathesar application dependencies.

  4. Pull the gh-pages branch locally.

    text
    git pull origin gh-pages:gh-pages

    Note that you don't need to checkout the gh-pages branch locally. This command just ensures that you have all the commits locally which have been made to that branch upstream.

  5. Run mike

    text
    mike deploy -u 1.2.3 latest

    Modify before running:

    • Change 1.2.3 to the version you want to deploy.
    • Keep latest in the command to set the version to be the latest one. Remove that string from the command if you are publishing a non-latest version.

    What this does:

    • Despite the very public-sounding name "deploy" this command actually only makes a commit on the gh-pages branch locally. You're not "deploying" anything here.
    • To make that commit, mike will run mkdocs build against the files in your current directory.
  6. Preview the site

    text
    mike serve

    This will let you open up a browser to preview the new site as GitHub will serve it from the gh-pages branch. You'll see the version switcher and be able to change it. However, it won't allow you to test our custom version redirection behavior (described below).

    If you're not satisfied, you can always hard-reset the commit you made with mike before pushing.

  7. Push your changes to GitHub

    text
    git push origin gh-pages:gh-pages
  8. Monitor publication status

    Open the Actions tab in our GitHub repo and you should see a yellow indicator aside the top-most action. When this turns green, your changes are published and can be viewed on the live docs site.

Now to manage our custom version redirection behavior

We have some custom code in overrides/404.html which is pretty weird!

  • Here's the problem that code is intended to solve:

    At the time we switched to multi-version docs, Mathesar 0.1.7 (and several previous versions) had application code which rendered a hyperlink to the release notes of the latest stable release of Mathesar. This hyperlink was coded without any docs version path segments, so for example it would point to https://docs.mathesar.org/releases/0.1.7/. However, urls like that unfortunately don't resolve in a site built with mike because they don't point to a specific version. We can't change the hyperlink because it's in an already-released version of Mathesar, so we'd like to find a way of catching traffic to links like that. Our 404.html file is a somewhat hacky way of handling this problem.

  • Interestingly, the GitHub Pages server will handle Page Not Found errors by serving the content from a 404.html file if present in the root of the gh-pages branch. It's worth noting that this is a bit unconventional. Most web servers do not behave this way by default. Sean (who wrote our 404.html code) was not even easily able to identify a way to mimic this behavior locally. So it's hard to test without setting up a sandbox repo to be served by GitHub Pages.

  • MkDocs (and by extension, mkdocs-material) features an extensible templating system that we leverage to alter the 404.html page which gets generated when mkdocs runs. When we use mike to publish a version, we end up with our custom 404.html page published in the version subdirectory of the live site. But being published in a subdirectory actually accomplishes nothing by itself because the GitHub Pages server doesn't look for 404.html pages in subdirectories. So additionally we have a symlink at the root which points to latest/404.html. Since mike also maintains a symlink to point latest to the latest version, GitHub is able to see the custom 404 page at the site root.

  • Within 404.html we have some javascript. Here's how it works:

    1. It fetches the versions JSON blob that mike maintains.
    2. It checks the current URL to see if it contains a version specifier within the path.
    3. If the current URL has a version specifier, then it serves the 404 page.
    4. If the current URL has no version specifier, then the javascript code redirects to the same URL with latest prepended to the path.

How to manage our customizations applied to the version switcher

  • We have some customizations to the version switcher which are applied within the extra.css file.
  • If you modify this, you'll need to port those modifications to all published versions so that the user experience is consistent when switching between versions.

Spell-checking

We use the mkdocs-spellcheck plugin to spell-check our documentation.

  • CI will fail if there are any spelling errors.

  • To check for spelling errors locally, run:

    text
    mkdocs build --strict

    Spelling errors will be reported as warnings when building in strict mode.

  • To configure ignored words, see the spellcheck section in mkdocs.yml and refer to the plugin docs as needed.

  • If you happen to be writing documentation content using VS Code, we recommend the Code Spell Checker extension (id: streetsidesoftware.code-spell-checker). It will highlight spelling errors in real-time as you type.

Page redirects

We use mkdocs-redirects to redirect pages internally when moving things around.

Macros

We use the macros plugin to show the same content in different places, and we generally put such content in the snippets directory.

Placeholders

We use the placeholder plugin to allow the user to customize small tokens which get repeated throughout a page. Here's how it works:

  1. Add a token like PLACEHOLDER_NAME in placeholder-plugin.yaml with a default value.

  2. Put an input on the page to allow the reader to customize the value of the token.

    html
    <input data-input-for="PLACEHOLDER_NAME">
  3. Then put the customized value anywhere in the page

    text
    xPLACEHOLDER_NAMEx