Skip to main content

Configuration Reference

All configuration is via environment variables.

Control Plane (muvee-server)

VariableDefaultDescription
DATABASE_URLpostgres://muvee:muvee@localhost:5432/muvee?sslmode=disablePostgreSQL connection string
MIGRATIONS_DIR./db/migrationsPath to SQL migration files
PORT8080HTTP listen port
BASE_DOMAINlocalhostRoot domain; projects are served at {prefix}.BASE_DOMAIN. Also distributed to agents via /api/agent/config.
BASE_DOMAINSOptional comma-separated list of additional base domains to serve the same instance under (multi-domain). BASE_DOMAIN stays the canonical default. See Multi-domain below.
GOOGLE_CLIENT_IDGoogle OAuth2 client ID. If set, enables Google login. See Google OAuth2.
GOOGLE_CLIENT_SECRETGoogle OAuth2 client secret
GOOGLE_REDIRECT_URLhttp://localhost:8080/auth/google/callbackGoogle OAuth2 callback URL
FEISHU_APP_IDFeishu / Lark App ID. If set, enables Feishu login. See Feishu / Lark.
FEISHU_APP_SECRETFeishu / Lark App Secret
FEISHU_REDIRECT_URLhttp://localhost:8080/auth/feishu/callbackFeishu OAuth2 callback URL
FEISHU_BASE_URLhttps://open.feishu.cnFeishu API base URL. Set to https://open.larksuite.com for international Lark.
WECOM_CORP_IDWeCom (企业微信) Corp ID. If set, enables WeCom login. See WeCom.
WECOM_CORP_SECRETWeCom App Secret
WECOM_AGENT_IDWeCom Agent ID of the internal app
WECOM_REDIRECT_URLhttp://localhost:8080/auth/wecom/callbackWeCom OAuth2 callback URL
DINGTALK_CLIENT_IDDingTalk (钉钉) App Key. If set, enables DingTalk login. See DingTalk.
DINGTALK_CLIENT_SECRETDingTalk App Secret
DINGTALK_REDIRECT_URLhttp://localhost:8080/auth/dingtalk/callbackDingTalk OAuth2 callback URL
ALLOWED_DOMAINS(allow all)Comma-separated email domains allowed to sign in (e.g. company.com). Applied to Google; enterprise SSO providers (Feishu, WeCom, DingTalk) bypass this check when no real email is available and a synthetic *.local address is used instead.
ADMIN_EMAILSComma-separated email addresses that are auto-promoted to admin on login and can access traefik.BASE_DOMAIN
JWT_SECRETchange-me-in-productionSecret for signing JWT session tokens
AGENT_SECRETShared secret for agent ↔ server authentication (set the same value on all agents). If unset, agent endpoints are unauthenticated (dev only).
AUTH_SERVICE_URLhttp://muvee-authservice:4181Internal URL of muvee-authservice; used when generating per-project ForwardAuth config for Traefik
REGISTRY_ADDRlocalhost:5000Docker registry address. Distributed to agents via /api/agent/config — agents do not need this set locally.
REGISTRY_USERRegistry Basic Auth username. Distributed to agents — they run docker login automatically on startup.
REGISTRY_PASSWORDRegistry Basic Auth password. Distributed to agents.
SECRET_ENCRYPTION_KEY64-character hex string (32 bytes) used to encrypt secrets at rest with AES-256-GCM. Required to enable the Secrets feature. Generate with openssl rand -hex 32.
VOLUME_NFS_BASE_PATHBase NFS directory on the control plane host used for project workspace volumes (e.g. /mnt/nfs/volumes). A per-project subdirectory is created automatically under this path. Also distributed to deploy agents via /api/agent/config so they can bind-mount the volume into containers. If unset, the workspace feature is disabled.
DATASET_NFS_BASE_PATHBase NFS directory for datasets (e.g. /mnt/nfs/datasets). Dataset nfs_path is treated as a relative sub-path under this base (e.g. warehouse/mnt/nfs/datasets/warehouse). Mount at the same absolute path on all relevant nodes. The control-plane server needs write access (:rw) — it runs the file monitor and serves dataset file operations (upload/delete/mkdir/move/copy), so the NFS export must allow the server host to write. Deploy agents only need read access (:ro, for rsync and bind-mount into user containers).
GIT_REPO_BASE_PATHDirectory where bare git repositories are stored for hosted projects (e.g. /data/git). Each hosted project gets a {project_id}.git subdirectory. If unset, the hosted repository feature is disabled and all projects must use an external git URL.
TUNNEL_BACKEND_URLInternal URL that Traefik uses to route adhoc tunnel traffic back to this server (e.g. http://muvee-server:8080). Required to enable muveectl tunnel. Set automatically in the default Docker Compose setup.

ForwardAuth Service (muvee-authservice)

VariableDefaultDescription
PORT4181HTTP listen port
GOOGLE_CLIENT_IDSame as control plane
GOOGLE_CLIENT_SECRETSame as control plane
FORWARD_AUTH_REDIRECT_URLhttp://localhost:4181/_oauthOAuth2 callback URL for ForwardAuth. In production set to https://BASE_DOMAIN/_oauth and register it in Google Cloud Console alongside GOOGLE_REDIRECT_URL.
BASE_DOMAINRoot domain. Required so the session cookie is shared across all *.BASE_DOMAIN subdomains (e.g. traefik.BASE_DOMAIN, project subdomains).
JWT_SECRETMust match the control plane value
ADMIN_EMAILSMust match the control plane value; used to gate /verify-admin (Traefik dashboard)

Agent (muvee-agent)

VariableDefaultDescription
NODE_ROLE(required)builder or deploy
CONTROL_PLANE_URLhttp://localhost:8080Internal address of the control plane (e.g. http://10.0.0.1:8080). Do not use the public domain — see Agent Nodes for details.
AGENT_SECRETMust match the value set on the control plane
DATA_DIR/muvee/dataLocal dataset cache root (deploy nodes)
HOST_IP(auto-detect)IP address Traefik uses to reach containers on this node. Auto-detected from the network interface used to reach CONTROL_PLANE_URL. Override if auto-detection selects the wrong interface (e.g. on multi-NIC hosts).
Registry credentials and BASE_DOMAIN are distributed automatically

Agents fetch REGISTRY_ADDR, REGISTRY_USER, REGISTRY_PASSWORD, and BASE_DOMAIN from the control plane via GET /api/agent/config on startup. You only need to set these on the control plane — there is no need to configure them on individual agent nodes.

Multi-domain

By default muvee serves everything under a single BASE_DOMAIN. To host the same instance under more than one apex — for example an overseas domain and a mainland/ICP domain — set BASE_DOMAINS to a comma-separated list of the additional base domains:

BASE_DOMAIN=muveeai.com          # canonical default
BASE_DOMAINS=muveeai.com,muvee.ai

BASE_DOMAIN remains the canonical fallback (used when a request host matches none of the configured domains). Per request muvee resolves which base domain the host belongs to, so all of the following follow the domain the user is actually on:

  • Auth cookies are scoped to the matching base domain (a login on muvee.ai yields a .muvee.ai cookie, shared across its subdomains).
  • OAuth redirect_uri is rebased onto the matching base domain, kept canonical to a single host per domain (e.g. https://app.muvee.ai/_oauth/google) so project subdomains still bounce through the panel/authservice host.
  • Traefik routers match every project/tunnel prefix under each base domain via a single OR'd Host() rule, each with its own TLS cert entry.
  • CORS / origin checks accept the canonical origin of every configured base domain and any of their subdomains.

Requirements per extra base domain

  • DNS: point <base> (A record) and *.<base> (wildcard A record) at this server's IP, same as the canonical domain.
  • TLS: there is no wildcard cert for the extra base domains — every project subdomain obtains its own Let's Encrypt HTTP-01 certificate, so the domain must be publicly reachable on port 80 for the ACME challenge.
  • OAuth provider dashboards: register each domain's callback URLs with every provider you use, e.g. https://app.<base>/auth/google/callback (control-panel login) and https://app.<base>/_oauth/google (per-project ForwardAuth).

Runtime settings (admin UI)

A few knobs are stored in the system_settings table and edited through the admin UI rather than environment variables. They take effect without a restart.

KeyDefaultNotes
auto_deploy_master_enabledtrueGlobal kill switch for both auto-deploy triggers.
auto_deploy_poll_interval_seconds60Git poll cadence for external repos (min 10).
auto_deploy_image_watch_interval_seconds600Image-digest poll cadence for compose projects (min 60).

See Auto Deploy for the full behaviour and the per-project toggle.