This guide documents the steps used to set up Docker CE and a MariaDB instance on a minimal VPS (1 vCPU, 1 GB RAM) running Ubuntu 22.04. It's designed to be simple and portable β ideal for DevOps-style projects, dashboards, and APIs that may later be migrated to a cloud platform like Azure Container Apps.
The goal is to:
This method works well even on small servers, and can easily be integrated into Terraform, Ansible, or CI workflows later on.
β
#!/bin/bash # install-docker-ce.sh β Installs Docker Engine on Ubuntu 22.04+ set -e sudo apt-get update sudo apt-get install -y \ ca-certificates \ curl \ gnupg \ lsb-release # Add Dockerβs official GPG key sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # Add the repository echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # Install Docker Engine sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Enable Docker service sudo systemctl enable docker sudo systemctl start docker echo "Docker installed successfully!"
β
This Compose file defines a MariaDB service with a persistent volume. The `restart: unless-stopped` line ensures it comes back after a reboot, unless stopped manually.
services: mariadb: image: mariadb:latest container_name: mariadb restart: unless-stopped environment: - MYSQL_ROOT_PASSWORD=your_root_pass ports: - "3306:3306" volumes: - mariadb_data:/var/lib/mysql volumes: mariadb_data: external: true
β
This setup stores your MariaDB data inside a Docker-managed volume (not inside the container). You can move this volume to another server like this:
1. Find the volume's path on the source server:
docker inspect mariadb | grep Source
2. Stop the container, then tar the volume contents:
docker stop mariadb sudo tar -czvf mariadb_data.tar.gz /var/lib/docker/volumes/your_volume_name/_data
3. Copy the `.tar.gz` to the new server:
scp mariadb_data.tar.gz user@newserver:~
4. Extract into a Docker volume path (on the new server):
docker volume create mariadb_data sudo tar -xzvf mariadb_data.tar.gz -C /var/lib/docker/volumes/mariadb_data/_data
5. Now `docker compose up -d` with the same `docker-compose.yml`, and your DB will be live.
β
Example for copying the volume:
#!/bin/bash set -e VOLUME_ID="4042cf30bc39026f2b18ef4f2fcd2893470efba3637f5e18f1a762856debba0d" VOLUME_PATH="/var/lib/docker/volumes/${VOLUME_ID}/_data" ARCHIVE_NAME="mariadb_volume_backup.tar.gz" DEST_HOST="[email protected]" DEST_PATH="/tmp" echo "==> Stopping any container using the volume..." docker ps -q --filter volume="$VOLUME_ID" | while read cid; do docker stop "$cid" done echo "==> Creating archive from volume data..." sudo tar -czf "$ARCHIVE_NAME" -C "$VOLUME_PATH" . echo "==> Copying archive to destination server..." scp "$ARCHIVE_NAME" "$DEST_HOST:$DEST_PATH" echo "==> Done. You can now restore it on serv1 using the corresponding import steps."
then restore in the destination serverβ¦
#!/bin/bash set -e VOLUME_ID="mariadb_restored_volume" ARCHIVE_PATH="/tmp/mariadb_volume_backup.tar.gz" VOLUME_PATH="/var/lib/docker/volumes/${VOLUME_ID}/_data" echo "==> Creating target volume..." docker volume create "$VOLUME_ID" echo "==> Extracting data into new volume..." sudo tar -xzf "$ARCHIVE_PATH" -C "$VOLUME_PATH" echo "==> Fixing permissions..." sudo chown -R 999:999 "$VOLUME_PATH" # 999 is default mysql UID/GID in official image echo "==> Starting MariaDB container..." docker run -d \ --name mariadb \ -v "${VOLUME_ID}:/var/lib/mysql" \ -e MYSQL_ROOT_PASSWORD=your_root_pass \ -p 3306:3306 \ mariadb:latest echo "==> Done! MariaDB should be up with old data."
This method allows you to:
You can add your Flask API and Dashboard apps into the same Compose file, or deploy them independently. This is the foundation of a production-ready system built from tiny building blocks.
Enjoy!