Metabase configuration file for repeatable deployments

A Metabase config.yml can initialize self-hosted Pro or Enterprise instances with users, databases and settings on every launch. It also overwrites UI changes to those settings on restart, so the file has to be designed alongside your admin workflow.

On this page

How a Metabase configuration file makes deployments repeatable

A platform or data team that has to rebuild, promote or replicate a Metabase instance faces the same problem each time: users, database connections and settings must end up matching the source, and nobody should have to rebuild them by hand in the Admin settings. On self-hosted Pro and Enterprise plans, Metabase can initialize on launch from a configuration file named config.yml or config.yaml. The file covers three areas: users, databases and settings. Used well, it turns a manual setup into a file that can be reviewed, stored in version control and applied to a new instance. This page covers the configuration file only. Exporting content as YAML is covered in the serialization topic, and Git-based promotion is covered in the remote sync topic.

The main design constraint is the restart behavior. On each restart, the configuration file overwrites changes made in the Metabase UI to the settings it defines. An administrator who changes a managed value in the Admin settings may find that change reverted on the next restart, with no warning in the interface. Decide before rollout which areas the file owns and which stay editable in the UI, and tell administrators that the file is the source of truth for those areas. Confirm the exact overwrite behavior for each section against the Metabase version you run, since the documentation for the file is the authority on what is reset and when.

Settings can also come from environment variables, and those behave differently. Unlike settings defined in the configuration file, settings defined by environment variables cannot be changed in the Admin settings. That helps when a value must stay locked, such as one injected by your container platform or secrets manager, but it also means an administrator has no path to change it from the UI. Before go-live, list which settings come from the file and which come from environment variables, and record the source of each one. That record tells the team where a change belongs and prevents two sources from quietly disagreeing.

Three decisions come before the file is written. First, location: the file can sit beside the JAR or at the path set by MB_CONFIG_FILE_PATH, and a container image usually suits the second option, with the file mounted from your deployment tooling. Second, credentials: database and account secrets should come from your secrets store rather than sit in plaintext in version control, so confirm with Metabase how the current version accepts secret values. Third, review: changes to the file should follow the same review path as other infrastructure code, and a test instance should restart with the file before production does. Confirm the accepted user and database fields for your version, because the schema is the detail most likely to change between releases.

Config file, environment variables and Admin settings compared

This table compares the three places a Metabase setting can originate: the config file, environment variables and the Admin settings UI. Read each row to decide which source should own a given setting, then keep that setting in one place so later changes do not collide. The main takeaway is that a setting from the config file or an environment variable has a different lifecycle than one changed in the UI.

SourceWhere it is setChangeable in Admin settingsBehavior on restartTypically owned by
Config fileA config.yml or config.yaml file in the JAR's directory, or the path set by MB_CONFIG_FILE_PATHNot durable: UI changes to settings the file defines are overwrittenThe file is applied again and overwrites UI changes to those settingsPlatform or DevOps team that manages the deployment repository
Environment variablesThe container, service or host environment that starts the Metabase JARNo: settings defined this way cannot be changed in Admin settingsValues are read from the environment at startupPlatform or infrastructure team that owns the runtime and secrets
Admin settings UIMetabase's Admin settings pages in the browserYes: this is the normal place for administrators to change settingsStored values persist in the application database unless a config file or environment variable overrides themMetabase administrators and analytics leads
Initial users and databasesThe users, databases and settings sections of the config file on Pro and EnterpriseUsers and databases created from the file are still managed by the file on restartConfig file values are reapplied, so removals in the file need a deliberate planPlatform team with input from the analytics owner
Secrets such as database passwordsEnvironment variables or a secrets store feeding the runtime, referenced from the config file where supportedNot editable in Admin settings when set by environment variableRotation requires updating the source and restarting MetabaseSecurity or secrets management team
Changes made during an incidentAdmin settings UI for quick edits, then matched in the config file or environmentYes, but a restart can revert them if the file still defines the settingReverted by the config file on restart if the same setting is defined thereOn-call administrator with a follow-up owner in the platform team
Audit of changesGit history for the config file, deployment logs for environment variables, and Metabase activity logs for UI changesAdmin actions are recorded in Metabase activity data on Pro and EnterpriseGit history shows what the file intended at each releaseCompliance or security team reviewing access and configuration changes

Which Metabase plan you need before writing config.yml

The configuration file is documented for self-hosted Pro and Enterprise plans, so the plan decision comes before any file design. The cards below cover the tiers and listed prices, included users, identity features that depend on plan, and the checks to run with Metabase before you commit to a design.

Config file needs a paid plan

Metabase documents initialization from a config.yml or config.yaml file only for self-hosted Pro and Enterprise plans. If you run a lower tier, plan provisioning without the file and confirm with the vendor which methods your edition supports. Check this before you design a file-driven pipeline, because the plan determines whether the pipeline is available at all.

Plan tiers and listed prices

Metabase's pricing page lists four plans: Open Source (free), Starter, Pro and Enterprise. Starter is $100 per month, or $90 per month billed yearly. Pro is $575 per month, or $517.50 per month billed yearly. Enterprise is priced by quote, starting at $20,000 per year. These figures can change, so record the date you checked and the billing option your budget assumes.

Included users and extra seats

According to Metabase's pricing page, Starter includes the first 5 users and Pro includes the first 10. Additional users cost $6 per month on Starter and $12 per month on Pro. Confirm with Metabase how many users Open Source and Enterprise include before you compare totals. Model user growth across the full term you plan to fund, since seat counts drive recurring cost.

Identity features that need Pro or Enterprise

Google sign-in and LDAP are available on Open Source and Starter. JWT, OIDC, SAML, advanced LDAP group and attribute sync, and SCIM provisioning require Pro or Enterprise. Metabase documents SAML setups for Auth0, Entra ID, Google, Keycloak and Okta. Decide early which of these your identity design needs, because that choice determines which plans are viable for your team.

Access controls gated to paid plans

According to Metabase's pricing page, SSO, row and column level permissions, multi-tenant data segregation, and usage analytics and auditing are included only in Pro and Enterprise. Teams that plan permission models or audit trails as part of their deployment should check each control against the plan before building around it. Treat the plan as a design input, not an afterthought.

Confirm the plan before designing

Plan entitlements and file behavior can change between releases, so ask Metabase to confirm which plan your edition needs for config.yml and for each identity feature you intend to use. Get the answer in writing for the exact version you will deploy. Metabase documents that the file overwrites UI changes to its sections on each restart, so record that behavior in your design document before you commit to a provisioning model.

Setting up config.yml for a first repeatable Metabase deployment

This sequence takes a team from plan confirmation to a verified Metabase instance that initializes from config.yml. Each step closes with a check, so the file becomes a reviewed artifact that a restart can reproduce.

  1. Confirm the plan supports file initialization

    Before writing anything, the license owner confirms that the self-hosted deployment is on a Pro or Enterprise plan, because initialization from a config file is documented only for those plans. Compare your plan against the Metabase pricing page and record the decision in the project file. Then check the version support page to confirm the release you intend to run has an end-of-life date your organization can plan around. Done when a named owner has signed off the plan and the target version in writing.

  2. Choose the application database

    The platform engineer selects the application database that will hold Metabase's own metadata. The embedded H2 database suits demos only. For production, the docs recommend PostgreSQL, and MySQL 8.4.0 or MariaDB 10.6.0 and later are also supported when configured with utf8mb4. If a team has already run on H2, plan a load-from-h2 migration using the same Metabase version that last updated the H2 file. Done when a test launch against the chosen database reaches the setup stage with no connection errors in the logs.

  3. Select the config file location

    The platform engineer decides where the file lives. Metabase reads config.yml or config.yaml from the JAR's directory by default, or from the path set in the MB_CONFIG_FILE_PATH variable. Pick the location that fits how your team packages and deploys the service, and make sure the service account can read it but nobody else can write to it. Done when the chosen path is documented in the runbook and the first startup confirms the file was picked up.

  4. Define users, databases and settings

    The platform engineer writes the three sections the file supports: users, databases and settings. Draft these from a written inventory of the people who need accounts, the data connections to create, and the settings your governance policy requires. Remember that on each restart the file overwrites changes made to these settings in the UI, so anything your team expects to adjust in the browser belongs in a different process. Keep the file in version control. Done when a second engineer has reviewed the file against the inventory and approved it.

  5. Supply secrets through a documented method

    Passwords and keys for the application database and data connections should not be stored as plain text in the repository. Confirm in the configuration file documentation which method your Metabase version supports for supplying these values, and use only that method. Also decide which settings will come from environment variables, since those cannot be changed in the Admin settings and the team should know which owner controls each value. Done when a scan of the repository finds no credentials and the instance starts with its secrets supplied from the chosen source.

  6. Launch the instance and verify initialization

    The platform engineer starts Metabase with the file in place and signs in with the administrator the file defines. Compare what appears in the Admin area against the inventory from the earlier step: each user, each database connection and each setting should match. Any mismatch is corrected in the file and the instance is relaunched, not fixed in the UI, because the UI change would be overwritten later. Done when every item in the inventory matches the running instance and the result is recorded.

  7. Test a restart and a UI change

    The platform engineer makes one low-risk settings change in the UI, restarts the instance, and checks the result. The expected outcome is that the file restores the value it defines, which confirms the team understands the overwrite behavior before production use. Repeat the test once with a change to a value that is supplied by an environment variable, to confirm it cannot be altered in the Admin settings. Done when both results are written into the runbook for operators.

How UI changes collide with the config file after a restart

The rule to plan around is that the config file wins on every restart for the settings it defines. On self-hosted Pro and Enterprise plans, Metabase can initialize on launch from a config.yml or config.yaml file placed in the JAR's directory, or at the path set by MB_CONFIG_FILE_PATH. The file covers users, databases and settings. On each restart, it overwrites changes made in the admin UI to those settings. A change an administrator makes in the UI is therefore not durable for any setting the file still defines. Before you rely on the file for repeatable deployments, list which settings it manages so your team knows where a UI edit will be lost.

Collisions usually surface after a routine deploy, not during the change itself. As an illustrative example, an administrator updates a setting in Admin settings, confirms it works, and moves on. The next deploy restarts the container, the file is applied again, and the setting returns to the value in Git. Users then report that a fix disappeared, or the team assumes the change was never saved. The same pattern can occur in reverse: someone edits the file in a branch, but the running instance keeps showing the old value until the next restart, so a staging check run before the restart can look correct while production is still stale.

Settings defined by environment variables behave differently. Metabase's documentation states that these settings cannot be changed in Admin settings, so the UI makes the source clear. That clarity has a cost: the only way to change the value is in the deployment manifest, container definition or orchestration secret that sets the variable. If a team sets the same setting in both the file and an environment variable, the question of which value is in effect becomes a source of confusion. Confirm in the current configuration docs how precedence works for overlapping settings, and test that behavior on a staging instance before you depend on it.

A practical ownership model gives each setting exactly one source of truth. Assign settings defined in the config file to the Git repository, with changes made only through reviewed pull requests. Assign environment-variable settings to the team that owns the deployment manifest. Leave settings that administrators should adjust in the UI out of both places, so the file never defines them. Record the decision for each setting in a short register with its owner, its source and the reason, and keep the register in the same repository as the file so changes to ownership are reviewed like any other change.

Detect drift before it reaches production by comparing the rendered configuration with the values a running instance reports, on a staging instance that mirrors production. After each deploy, check the settings the file defines against what Admin settings shows, and confirm which export or API read is available for your Metabase version. Flag any mismatch, and treat a UI edit to a file-managed setting as a defect to fix in Git. Ask your administrators to agree in writing that production UI edits to file-managed settings are not permitted, and make the check part of the release sign-off so drift is caught before users see it.

Which settings belong in the file, the environment or the UI

Put a setting in config.yml when the value should match on every instance built from the same template and when a reviewer should see the change before it reaches production. On Pro and Enterprise plans, Metabase reads the file on launch from the directory that holds the JAR or from the path set in MB_CONFIG_FILE_PATH. The file covers users, databases and settings, so it works best as the record of what the instance should look like after every restart.

Good candidates for this tab include:

  • Instance-wide settings that should be identical across development, staging and production.
  • Database connections that a rebuilt instance should recreate without manual steps.
  • User definitions for accounts your organization provisions through a repeatable process, checked against your identity setup.
  • Reviewed changes that pass through the same pull request and approval flow as other infrastructure code.

The main risk is overwrite. Each restart applies the file again, so a value changed in Admin settings for a key the file also defines will revert without warning. Treat the file as the source of truth for those keys, and confirm in your version's configuration file documentation exactly which keys and sections it accepts.

Security controls for config files that hold credentials

Metabase's configuration file can define users, database connections and settings, which makes it a credential store in its own right. The six controls below cover who can read and change the file, where secrets come from, how each connection is scoped, and how changes are reviewed and recorded.

Restrict who can read and write the file

Because the file defines users, database connections and settings, anyone who can read it can see connection details, and anyone who can write it can change who has access. Limit read access to the account that runs the Metabase JAR and to the deployment process, and limit write access to the same owners. Check ownership and file mode on the host after each provisioning run. Confirm that the path set by MB_CONFIG_FILE_PATH sits outside shared directories and any web-served location.

Keep plaintext credentials out of version control

Commit only a version of the file without passwords, tokens or keys. Store a template with a placeholder for each secret, and fill in the values at deploy time. Add working copies and local variants to .gitignore, and run a secret scanner in the pipeline to catch values committed by mistake. If a secret has already been committed, treat it as exposed and rotate it, because deleting it in a later commit leaves it in the Git history.

Store secrets in a dedicated secrets store

Keep database passwords, SSO client secrets and mail credentials in a dedicated secrets store, and let the pipeline or host retrieve them when the deployment runs. This separates the people who can deploy the file from the people who can read secret values, and it gives you one place to rotate them. Confirm with your secrets platform how values reach the Metabase host, since a temporary file left on disk during provisioning can recreate the exposure you set out to remove.

Use a least-privilege database user per connection

Create a separate database user for each connection the file defines, and grant it read access only to the schemas and tables that saved questions need. Do not reuse the application database owner or an administrator account. Confirm with your database team where row-level restrictions will be enforced, in the database or in Metabase, because the grants on each user set the ceiling for everything Metabase can read through that connection.

Audit who changes the file

Track every change to the file through version control history and host-level audit logging, so you can tell who changed a user, a connection or a setting and when. Metabase reapplies the file on each restart and overwrites matching settings changed in the UI, so also record restarts and deployments. Ask your team which events your host and Git platform retain, and for how long, before you rely on those records for an access review.

Review every change before it reaches production

Require a second person to review each change to the file before it reaches a production host. Reviewers should check added users and their roles, new connections and their target databases, and any setting that changes authentication or network exposure. Pair the review with a deployment to a non-production instance, so a mistake appears before a restart applies it to production. Confirm who may approve emergency changes and how those approvals are recorded afterward.

How config files interact with Metabase upgrades and rollback

Metabase runs application database migrations automatically when a new JAR starts, and those migrations change the schema that holds the state your config file writes to. Before any upgrade, the Metabase docs recommend backing up the application database. For major upgrades, reduce a clustered deployment to a single node, because the migration takes a lock and a second node must not run against a half-migrated schema. If your instance is on a version older than 40, move through each intermediate release in order. Record the exact version and the config file hash in your change record so you can reproduce the starting state if something fails.

The docs describe two rollback options. The recommended option is restoring the application database backup you took before the upgrade, then starting the previous JAR. This returns the database to its pre-upgrade state, including settings written through the admin UI and any values applied from the config file at the last start. The other option is running the migrate down command with the newer JAR, which reverses schema changes in place. That path depends on the down migrations for your specific versions behaving correctly, so treat it as a fallback and rehearse it in a non-production copy before you need it.

Because the config file overwrites UI changes to its sections on every restart, a rollback changes what gets applied at launch. Confirm three things with Metabase and in your own test environment. First, whether the older JAR reads the same config file keys and sections without error. Second, how it handles any setting the older version does not recognize, whether it ignores the key or fails to start. Third, whether users and database connections defined in the file are reapplied cleanly to a restored database that already contains them. Also confirm the file location, either the JAR's directory or the path set in MB_CONFIG_FILE_PATH, is the same on the rollback target. Config file initialization is available on Pro and Enterprise plans only.

Version support should shape the target you choose for both the upgrade and any rollback point. Metabase LTS versions are supported for 14 months, while non-LTS versions usually reach end of life after 2 months. Metabase 64 is an LTS release with end of life on 1 December 2027, and Metabase 65 was released on 12 October 2026. Before you commit to a target, check the version support page for the current end-of-life date of that line. Then decide which release you will roll back to if the upgrade fails, and confirm that it is still supported and that your config file has been tested against it.

Limits to confirm before you rely on the config file

Before the config file becomes your source of truth, check six limits that decide whether it applies cleanly. Each one depends on your plan, your Metabase release and your environment, so confirm them against the documentation for the exact version you run before you write the file.

Plan and edition that support the file

Initialization from a config file is available on self-hosted Pro and Enterprise plans. Confirm your edition before you design a repeatable process around it, because a file on an unsupported plan will not behave the way your runbook assumes. The same tier matters for SSO-based embedding, which also requires Pro or Enterprise, so review embedding plans together with the file. Ask your Metabase account team to confirm current entitlements for your license.

Sections and settings your version covers

The file covers users, databases and settings. Confirm which individual settings fall inside those sections in your release, since coverage may differ between versions. Build an inventory of every setting your team changes today, then mark each one as managed by the file, set by an environment variable or changed in the admin UI. That inventory becomes the acceptance list for your first test deployment.

Exact key names and format for your release

Key names, nesting, data types and YAML structure must match the documentation for the release you deploy. A misspelled key or wrong indentation may leave a setting unapplied, so confirm the outcome after each start on a staging instance. Check the file name it expects (config.yml or config.yaml) and where it looks for the file: the directory containing the JAR or the path set by MB_CONFIG_FILE_PATH. Keep the file under version control so every change is reviewed.

How secrets are referenced

Database passwords, SSO client secrets and API keys should not sit in plain text in a file that teams commit to Git. Confirm how your release references secrets from the environment or another source, and whether any values must still be written in plain text. Decide who can read the file on the host and where the rendered copy lives in your deployment pipeline. Test that a rotated secret reaches Metabase on restart, since the file is read at launch.

Settings that still need the admin UI

Some settings may only change in the Admin settings screen, and environment variables cannot be changed there. Confirm the UI-only list for your version so those items stay outside the file's ownership. Remember that on each restart the config file overwrites UI changes to the settings it covers. Agree on one owner for each setting and document which team edits the UI for the remainder.

Application database for production

The embedded H2 database is for demos only. Production should use PostgreSQL, or a supported MySQL or MariaDB version: MySQL 8.4.0 or MariaDB 10.6.0 and later, with utf8mb4. Confirm the database version and character set before the first deployment. If a proof of concept starts on H2, moving to PostgreSQL or MySQL uses the load-from-h2 command, which must run with the same Metabase version that last updated the H2 file.

How much effort does a repeatable Metabase configuration take?

What drives the cost of a Metabase config file setup?

The cost depends mostly on the number of environments, the identity provider and how much existing configuration must be captured. Labor is usually the largest one-time component: it covers deciding which settings belong in the file, writing and testing config.yml for users, databases and settings, and confirming that a restart reproduces the same state. Recurring costs come from the Metabase plan and your own operating time, and the file itself adds little to them. Ask any quote to itemize discovery, the file build, environment testing and handover separately, and to state which plan the design assumes.

Does a Pro or Enterprise plan change the cost of this setup?

Yes. Initializing from a config file is available only on self-hosted Pro and Enterprise plans, so a team on Open Source cannot use this approach. Metabase's pricing page lists Pro at $575 per month, or $517.50 per month billed yearly, with the first 10 users included and additional users at $12 per month. Starter is $100 per month, or $90 billed yearly, with the first 5 users included, but SSO is not included on Starter. Enterprise is priced by quote and starts at $20,000 per year. Confirm current figures on the pricing page before budgeting, and check them against your contract.

How long does building a config file for Metabase take?

The duration depends on scope, and no single figure applies to every organization. Timing grows with the number of databases to register, the user and group structure, the identity provider integration and how many environments must match. A narrow scope covering one instance, a few databases and local users is a different project from a multi-environment rollout with SAML group sync. Ask for a written schedule tied to a defined scope, with milestones for discovery, file build, test restore and handover. Your own change process and approval windows will also set the calendar.

What do we need to provide before outside help starts?

Prepare the inputs before the engagement begins. You need an agreed Metabase plan (Pro or Enterprise), a target environment in infrastructure you control, and a production-grade application database such as PostgreSQL, since the embedded H2 database is meant for demos. Provide identity provider details and admin access to it, connection details for each data source, and a named owner for user and group decisions. Also provide your change process: who approves config changes, where secrets are stored and how restarts are scheduled. A written scope turns these inputs into deliverables. If any answer is unknown, treat it as a scoping task before the build starts.

Can our own platform team build this without outside help?

Often yes, if the team has Metabase administration experience, runs the chosen plan and has time to test restarts. The config file is YAML loaded at launch, so the technical work is writing and validating the file. The harder part is deciding ownership of each setting. Your team should be able to answer which settings live in the file and which stay in the UI, how secrets reach the file, and how drift will be caught. If those answers are unclear, a fixed-scope engagement can cover design and handover. Confirm the approach against the configuration file documentation before committing.

What should we do if people already changed settings in the UI?

Plan a reconciliation before the first restart. The config file overwrites changes to the settings it covers each time Metabase restarts, so any UI change you want to keep must be written into config.yml or it will revert. Record what the instance currently holds, compare it with your intended state, and decide which values move into the file. Settings controlled by environment variables cannot be changed in Admin settings, so decide early which mechanism owns each setting. Test the reconciled file on a copy of the instance so that users do not lose a dashboard or permission unexpectedly.

How does the config file relate to moving off the H2 database?

They are separate steps and should be sequenced on purpose. H2 is the embedded application database for demos, and Metabase recommends PostgreSQL for production. Metabase documents a one-time load-from-h2 command that moves the H2 file to PostgreSQL or MySQL, and it must run with the same Metabase version that last updated the H2 file. Complete the database move first and verify the instance. Then introduce the config file, so the first restart does not overwrite settings you have not yet reviewed. Confirm the exact sequence in the H2 migration documentation for your version.

Does DeployOpen publish a price list for this work?

No. DeployOpen does not publish a price list. Most engagements are fixed-scope, and a quote follows from the written scope, which states the deliverables, timeline and assumptions agreed before work starts. Ask that the scope name the Metabase plan assumed, the number of instances, the data sources, the identity provider integration, the test restore and the handover. Ongoing support and upgrades are available as a retainer and can be quoted separately. Check each quote against the same scope items so the comparison is line by line.

How DeployOpen scopes and supports a Metabase configuration file build

DeployOpen builds the Metabase config file as part of a fixed-scope engagement, so users, database connections and settings are defined in version-controlled files and applied the same way in each environment. The work runs in infrastructure you control, and ongoing support is available as a retainer. Confirm your plan first, since initializing from a config file requires Pro or Enterprise.

How we scope

  • The written scope lists which users, database connections and settings the config file will define for each environment.
  • We confirm your license tier first, because config file initialization requires a self-hosted Pro or Enterprise plan.
  • The scope assigns an owner to each setting, so teams know which changes belong in the file.

How we build

  • We write config.yml sections for users, databases and settings, and set the file path explicitly.
  • Environment variables are reviewed separately, since settings they define cannot be changed in the Admin settings.
  • We test a clean restart and a second restart, checking that the file overwrites UI edits on each restart.

How we hand over

  • Handover includes the config file, a restart runbook and the list of settings the file owns.
  • Database passwords and other secrets are documented with their storage location and rotation owner.
  • Operators receive a rule for who edits the file, reviews changes and approves them before a restart.

How we support

  • Upgrades follow Metabase's documented path, including application database backups before migrations run.
  • We check each new release's end-of-life date before planning, since LTS and non-LTS versions are supported differently.
  • Ongoing support, upgrades and testing can run as a retainer after the fixed-scope build is handed over.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.