How to Deploy MinIO – Object Storage Server

Updated on 18 December, 2025
Deploy MinIO Object Storage with Docker Compose, Traefik TLS, and S3-Compatible Access.
How to Deploy MinIO – Object Storage Server header image

MinIO is a high-performance, open-source object storage server that is fully compatible with the Amazon S3 API. It is designed for modern cloud-native workloads, making it suitable for backups, media storage, data lakes, analytics, and application storage.

This article demonstrates how to deploy MinIO on Ubuntu 24.04 using Docker Compose and secure both the API and the Console using a Traefik reverse proxy.

Prerequisites

Before you begin:

Set Up the Directory Structure and Environment Variables

MinIO stores object data on disk and relies on environment variables for credentials, domains, and TLS configuration. This section prepares the required directory structure for persistent storage and defines the environment variables used by Docker Compose and Traefik during deployment.

  1. Create the project folders.

    console
    $ mkdir -p ~/minio/{data,letsencrypt}
    
    • data - Stores the actual object data.
    • letsencrypt - Stores Traefik ACME certificates.
  2. Navigate to the root MinIO directory.

    console
    $ cd ~/minio
    
  3. Create an .env file to store your credentials and domain configurations.

    console
    $ nano .env
    
  4. Add the following values:

    ini
    MINIO_ROOT_USER=admin
    MINIO_ROOT_PASSWORD=STRONG_PASSWORD
    DOMAIN_CONSOLE=console.example.com
    DOMAIN_API=s3.example.com
    LETSENCRYPT_EMAIL=admin@example.com
    

    Replace the placeholders with your own values:

    • STRONG_PASSWORD – A secure password for the MinIO admin user.
    • console.example.com – Domain for the MinIO web console.
    • s3.example.com – Domain for the MinIO S3 API endpoint.
    • admin@example.com – Email address for Let’s Encrypt notifications.

Save and close the file.

Deploy with Docker Compose

This section deploys the MinIO server behind Traefik. The configuration exposes two services: the Console (Web UI) on port 9001 and the API (S3 access) on port 9000.

  1. Add your user account to the docker user group.

    console
    $ sudo usermod -aG docker $USER
    
  2. Apply the new group membership.

    console
    $ newgrp docker
    
  3. Create the Docker Compose manifest file.

    console
    $ nano docker-compose.yml
    
  4. Add the following contents:

    yaml
    services:
      traefik:
        image: traefik:latest
        container_name: traefik
        restart: unless-stopped
        environment:
          DOCKER_API_VERSION: "1.44"
        command:
          - "--providers.docker=true"
          - "--providers.docker.exposedbydefault=false"
          - "--entrypoints.web.address=:80"
          - "--entrypoints.websecure.address=:443"
          - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
          - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
          - "--certificatesresolvers.le.acme.httpchallenge=true"
          - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
          - "--certificatesresolvers.le.acme.email=${LETSENCRYPT_EMAIL}"
          - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
          - ./letsencrypt:/letsencrypt
    
      minio:
        image: minio/minio:latest
        container_name: minio
        restart: unless-stopped
        command: server /data --console-address ":9001"
        environment:
          MINIO_ROOT_USER: ${MINIO_ROOT_USER}
          MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
          MINIO_BROWSER_REDIRECT_URL: https://${DOMAIN_CONSOLE}
        volumes:
          - ./data:/data
        healthcheck:
          test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
          interval: 30s
          timeout: 20s
          retries: 3
        labels:
          - "traefik.enable=true"
    
          # Router 1: The S3 API (Port 9000)
          - "traefik.http.routers.minio-api.rule=Host(`${DOMAIN_API}`)"
          - "traefik.http.routers.minio-api.entrypoints=websecure"
          - "traefik.http.routers.minio-api.tls=true"
          - "traefik.http.routers.minio-api.tls.certresolver=le"
          - "traefik.http.routers.minio-api.service=minio-api-svc"
          - "traefik.http.services.minio-api-svc.loadbalancer.server.port=9000"
    
          # Router 2: The Web Console (Port 9001)
          - "traefik.http.routers.minio-console.rule=Host(`${DOMAIN_CONSOLE}`)"
          - "traefik.http.routers.minio-console.entrypoints=websecure"
          - "traefik.http.routers.minio-console.tls=true"
          - "traefik.http.routers.minio-console.tls.certresolver=le"
          - "traefik.http.routers.minio-console.service=minio-console-svc"
          - "traefik.http.services.minio-console-svc.loadbalancer.server.port=9001"
    

    Save and close the file.

    This Docker Compose configuration deploys MinIO and exposes it securely over HTTPS using Traefik. The setup separates MinIO’s S3 API and web console onto different domains while keeping all TLS management centralized in Traefik.

    minio service

    • Runs the official minio/minio image, providing high-performance, S3-compatible object storage.
    • Starts MinIO in server mode, storing all objects in the /data directory, which is persistently mounted from ./data on the host.
    • Exposes two internal ports:
      • 9000 – MinIO S3 API endpoint (used by applications, backups, and clients).
      • 9001 – MinIO web console for administration and monitoring.
    • Uses environment variables to:
      • Define the root access credentials (MINIO_ROOT_USER, MINIO_ROOT_PASSWORD).
      • Set MINIO_BROWSER_REDIRECT_URL so that the web console redirects correctly through Traefik over HTTPS.
    • Includes a health check that verifies MinIO’s internal health endpoint, allowing Docker to track service availability.

    Traefik integration (via labels)

    • Traefik discovers MinIO automatically using Docker labels.
    • Two separate HTTPS routers are defined:
      • MinIO API router
        • Routes traffic for ${DOMAIN_API} to MinIO’s S3 API on port 9000.
        • Intended for programmatic access (SDKs, CLI tools, backups).
      • MinIO Console router
        • Routes traffic for ${DOMAIN_CONSOLE} to the MinIO web console on port 9001.
        • Intended for browser-based administration.
    • Both routers:
      • Listen on the websecure entrypoint.
      • Use Let’s Encrypt (le) to automatically obtain and renew TLS certificates.
    • Each router maps to a dedicated Traefik service to ensure traffic is forwarded to the correct internal port.

    traefik service

    • Acts as the reverse proxy and TLS terminator for MinIO.
    • Listens on ports 80 and 443 on the host.
    • Automatically redirects HTTP traffic to HTTPS.
    • Stores Let’s Encrypt ACME certificates in the ./letsencrypt directory.
    • Uses the Docker socket (read-only) to discover services and apply routing rules dynamically.
  5. Start the services.

    console
    $ docker compose up -d
    
  6. Verify the containers are running.

    console
    $ docker compose ps
    
    Note
    For more information on managing a Docker Compose stack, see the How To Use Docker Compose article.

Access MinIO

  1. Open your web browser and navigate to your Console domain https://console.example.com.

  2. Log in using the MINIO_ROOT_USER and MINIO_ROOT_PASSWORD you configured in the .env file.

  3. On your first login, a License Disclaimer window appears. Click Acknowledge to accept the terms and proceed to the dashboard.

    Dashboard

  4. Upon successful login, the Buckets dashboard loads. You can now create your first storage bucket.

  5. To test the API connection, you can use any S3-compatible client (like s3cmd) using the following details:

    • Endpoint: https://s3.example.com
    • Access Key: Value of MINIO_ROOT_USER
    • Secret Key: Value of MINIO_ROOT_PASSWORD

Conclusion

By following this article, you successfully deployed the MinIO object storage server on Ubuntu 24.04. You configured Traefik to securely route traffic to both the S3 API and the web administration console. Your server is now ready to store data for applications, backups, or AI workloads. For more information, refer to the MinIO Documentation.

Comments