Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
VGSources
Blog

How to Run MariaDB in Docker on a Linux VPS (Secure, Persistent Setup)

Deploy MariaDB on a Linux VPS with Docker Compose using secure MARIADB_* variables, Docker secret files, a persistent named volume, private networking, health checks, and tested backup procedures.
WorldDocker on a Linux VPS Length9 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run MariaDB as a container from the official MariaDB Docker image, pin an explicit image tag, load credentials through Docker secrets, and mount a named volume at /var/lib/mysql. Keep port 3306 on an internal Docker network or bind it only to 127.0.0.1; never expose the database directly to the public internet.

The procedure below creates an application database and user, adds a health check, survives container recreation, and provides backup, restore, upgrade, and troubleshooting procedures for a Linux VPS.

As an Amazon Associate I earn from qualifying purchases.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What you need before creating the container

You need a Linux VPS with Docker Engine and the Docker Compose plugin already installed, a user allowed to run Docker commands, and enough disk space for the database plus backups. Your application can run in another container on the same Compose network or directly on the VPS. Decide that connection model first because it determines whether MariaDB needs any published host port.

  • Containerized application: put the application and MariaDB in the same Compose project. The application connects to the service name mariadb on port 3306; no host port is required.
  • Application running on the VPS host: publish MariaDB only on the loopback interface with 127.0.0.1:3306:3306. The database remains unreachable from the VPS’s public interface.
  • Remote administration: use an SSH tunnel or a private network rather than opening 3306 in the firewall.

The image’s startup scripts initialize a new data directory only when it is empty. Environment variables such as passwords and database names are therefore initialization settings, not a general-purpose configuration API for an already-running database.

Choose and pin the MariaDB image

Use the Docker Official Image, whose packaging is maintained in the MariaDB Corporation Docker repository. Docker Hub documents moving latest and lts tags, but both can point to a different release later. For a VPS, select an explicit tag that you have validated with your application and keep that tag in version control.

Tag style Meaning Production guidance
latest Current stable image according to Docker Hub at pull time Convenient for experiments; it can move across major versions, so do not use it for an unattended production deployment.
lts Current long-term-support line according to Docker Hub at pull time Still moves as maintenance releases change; treat it as a channel, not a permanent version pin.
Explicit tag, for example 10.11 A chosen release line Record the exact tag, test upgrades, and change it deliberately.

The example below uses mariadb:10.11 only as an explicit-tag example. Check the image’s current tags and your application’s compatibility before selecting a release for your own VPS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a deployment directory and secret files

Keep the Compose file and its persistent volume definition in a dedicated directory. Store passwords in files with restrictive permissions instead of placing cleartext credentials in the Compose YAML.

  1. Create the directory structure and make the secrets directory accessible only to its owner:

    sudo mkdir -p /opt/mariadb/secrets
    sudo chown -R "$USER":"$USER" /opt/mariadb
    cd /opt/mariadb
    umask 077
    mkdir -p secrets
  2. Generate separate random passwords for the MariaDB root account and the application account. The files contain only the password and a trailing newline:

    openssl rand -base64 32 > secrets/root_password
    openssl rand -base64 32 > secrets/app_password
    chmod 600 secrets/root_password secrets/app_password
  3. Do not commit these files to Git, copy them into a public backup, or reuse an example password from a tutorial. Back up the secret files through the same protected process you use for other production credentials.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Define MariaDB with Docker Compose

Save the following as /opt/mariadb/compose.yaml. It uses the current MARIADB_* variable names, Docker secret files, a named data volume, an internal network, and the community health-check pattern healthcheck.sh --connect --innodb_initialized.

services:
  mariadb:
    image: mariadb:10.11
    container_name: mariadb
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
      MARIADB_DATABASE: game_db
      MARIADB_USER: game_app
      MARIADB_PASSWORD_FILE: /run/secrets/mariadb_app_password
    secrets:
      - mariadb_root_password
      - mariadb_app_password
    volumes:
      - mariadb_data:/var/lib/mysql
    networks:
      - db_net
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s

secrets:
  mariadb_root_password:
    file: ./secrets/root_password
  mariadb_app_password:
    file: ./secrets/app_password

volumes:
  mariadb_data:

networks:
  db_net:
    internal: true

What each setting does

  • image selects the pinned MariaDB release. Change it only as part of a planned upgrade.
  • restart: unless-stopped brings the service back after a Docker or VPS restart unless you intentionally stop it.
  • MARIADB_DATABASE requests creation of game_db during first initialization.
  • MARIADB_USER and MARIADB_PASSWORD_FILE create game_app only when both a user and password are supplied. The created user receives all privileges on the database named by MARIADB_DATABASE.
  • _FILE variables make the image read the value from a file inside the container. This is the form that lets Docker secrets provide credentials without putting them directly in the YAML.
  • The named volume mounted at /var/lib/mysql keeps the database files when the container is replaced.
  • An internal network lets containers attached to it communicate without publishing MariaDB to the VPS network interfaces.
  • The health check reports whether the server accepts connections and InnoDB has initialized. It is a community Compose pattern, not an official Compose template.

Why the variable names matter

For image tags beginning with 10.2.38, 10.3.29, 10.4.19, 10.5.10, and for all 10.6 and newer tags, MARIADB_* variables take precedence over their MYSQL_* counterparts. Older examples often use MYSQL_ROOT_PASSWORD and related names; treat those names as legacy when writing a new deployment. Each supported variable also has a _FILE form, such as MARIADB_ROOT_PASSWORD_FILE.

Start MariaDB and verify first initialization

  1. From /opt/mariadb, pull the selected image and start the service:

    docker compose pull
    docker compose up -d
  2. Follow the startup log until initialization completes:

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
    docker compose logs -f mariadb

    Press Ctrl+C to stop following logs; it does not stop the container.

  3. Check the Compose health state:

    docker compose ps

    Wait for the service to show a healthy state. A first initialization can take longer than later restarts because system tables and the requested database are created.

  4. Confirm the database and application account from inside the container. The client will prompt for the root password stored in secrets/root_password:

    docker compose exec mariadb mariadb -uroot -p

    At the MariaDB prompt, run:

    SHOW DATABASES;
    SELECT User, Host FROM mysql.user;
    EXIT;

After this first successful initialization, changing MARIADB_DATABASE, MARIADB_USER, or a password variable in Compose does not rewrite the existing data directory. The image leaves an initialized directory intact on subsequent starts.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Connect an application safely

Application in another container

Attach the application service to db_net and configure its database settings as follows:

Application setting Value
Host mariadb
Port 3306
Database game_db
User game_app
Password The contents of secrets/app_password, supplied through the application’s own secret mechanism

Docker’s internal DNS resolves the service name mariadb. Do not use localhost from the application container: that address points back to the application container itself.

Application running directly on the VPS

Add this mapping under the MariaDB service only when a host process must connect:

    ports:
      - "127.0.0.1:3306:3306"

Reapply the configuration with docker compose up -d. A process on the VPS can then use host 127.0.0.1 and port 3306. Do not change the binding to 0.0.0.0:3306:3306 unless you intentionally accept public exposure and have a separate private-network design.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Persist data and manage the container lifecycle

The mariadb_data named volume is the boundary between the disposable container and durable database files. Recreating the container with docker compose up -d --force-recreate keeps the data because the same volume is mounted again.

  • Inspect the volume with docker volume ls and docker volume inspect mariadb_mariadb_data (the project name can change the full volume name).
  • Use docker compose stop when you need a reversible pause.
  • Use docker compose down to remove the container and network while retaining named volumes.
  • Never use docker compose down -v on this production project unless you have deliberately made and verified an external backup; the -v option removes the named volume and its data.

Environment variables do not rotate credentials after initialization. To change a password, connect with an account that has sufficient privileges and execute an explicit SQL change, for example:

docker compose exec mariadb mariadb -uroot -p
ALTER USER 'game_app'@'%' IDENTIFIED BY 'new-password-value';

The account’s host component may differ from '%'. Check the result of SELECT User, Host FROM mysql.user; and alter the matching account. Update the application secret only after the SQL password has been changed, then restart the application so it reloads the new value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Back up MariaDB correctly

Do not back up a live database by copying files from /var/lib/mysql. Use a logical dump with mariadb-dump (also known as mysqldump) or a physical backup tool such as mariabackup.

Logical dump with mariadb-dump

Create a dated dump on the VPS and enter the root password when prompted:

mkdir -p /opt/mariadb/backups
docker compose exec mariadb mariadb-dump 
  --all-databases 
  --single-transaction 
  --routines 
  --events 
  -uroot -p > /opt/mariadb/backups/mariadb-$(date +%F).sql

--single-transaction gives transactional tables a consistent snapshot without taking a long write lock. Keep dumps outside the Docker volume, copy them to separate storage, and periodically test that a dump can be restored.

Restore a dump

For a destructive full restore, stop applications that write to MariaDB, then stream the SQL file into the client:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
cat /opt/mariadb/backups/mariadb-2026-10-14.sql 
  | docker compose exec -T mariadb mariadb -uroot -p

The client prompts for the root password. Restore into a disposable MariaDB instance first when possible, especially before replacing a production data volume.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Upgrade the image without losing the volume

  1. Read the release notes for the target MariaDB line and confirm that your application and SQL features support it.
  2. Run and verify a fresh logical dump, and copy that dump off the VPS.
  3. Record the current image tag and container configuration so you can roll back to the previous tag if needed.
  4. Change only the image tag in compose.yaml, then pull and recreate:
docker compose pull mariadb
docker compose up -d mariadb
docker compose logs -f mariadb

Do not delete the named volume during an upgrade. Let the new image start against the existing directory, watch the logs for errors, and verify application queries before scheduling the next upgrade. Avoid jumping across multiple major versions without an intermediate test and a tested restore path.

Lock down the Linux VPS

At the host firewall, allow only the SSH port and the web ports your services actually use. MariaDB should be reachable only through the internal Docker network or the loopback mapping described above. If administrators need a database client from another machine, establish an authenticated SSH tunnel instead of adding a public 3306 rule.

Protect the Compose directory and secret files with filesystem permissions, restrict who can run Docker (Docker access is effectively root-level access), and keep the operating system and Docker packages patched. Enable MariaDB slow-query logging and size the InnoDB buffer pool for the workload after measuring memory use; these are host and database administration tasks rather than image initialization settings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshooting common failures

Symptom Likely cause Action
Container exits immediately with a password error No accepted root-password setting was supplied. Check that exactly one of MARIADB_ROOT_PASSWORD_HASH, MARIADB_ROOT_PASSWORD, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD, or MARIADB_RANDOM_ROOT_PASSWORD (or its _FILE form) is present. For a VPS, use a non-empty secret file.
Changing a variable has no effect The named volume already contains an initialized data directory. Keep the volume and change the value explicitly with SQL. Reinitializing by deleting the volume destroys the database.
Application reports “connection refused” Wrong hostname, service not healthy, or the application is on a different network. Use mariadb:3306 from a peer container, run docker compose ps, inspect docker compose logs mariadb, and confirm both services share db_net.
Host application cannot connect No host port is published, or it is bound to a different address. Add the loopback mapping, recreate the service, and connect to 127.0.0.1:3306. Do not expose the port publicly just to solve a local binding mistake.
Health check remains unhealthy InnoDB is still initializing, credentials or permissions are wrong, or startup encountered an error. Allow the configured start period to elapse, then inspect logs and run docker inspect --format '{{json .State.Health}}' mariadb.
Database disappeared after cleanup The named volume was removed, commonly by docker compose down -v. Restore the latest verified dump into a newly created volume and review which cleanup command removed the volume.
Legacy Compose file behaves unexpectedly It uses MYSQL_* names alongside newer MARIADB_* names. Standardize on MARIADB_* variables and their _FILE equivalents for supported current image tags.

Production readiness checklist

  • Explicit MariaDB image tag selected and recorded.
  • Root and application passwords generated separately and stored with mode 600.
  • /var/lib/mysql mounted to a named volume.
  • Application database and least-privilege application account created during first initialization.
  • Port 3306 absent from the public interface, or bound only to 127.0.0.1.
  • Health check reports a healthy service before the application starts writing.
  • Logical dumps or mariabackup jobs run on a schedule and are copied off the VPS.
  • A restore has been tested, and image upgrades are performed against a verified backup.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.