21 Dec 2023

Deploying MinIO with Traefik

Deploying MinIO with Traefik

Context

Traefik

In a conventional deployment setup, the typical approach involves employing a web server such as Nginx or Apache to act as a reverse proxy or load balancer. However, a common challenge with these solutions lies in the need for meticulous configuration, particularly when dealing with aspects like SSL setup. This is where Traefik distinguishes itself. Traefik is designed with modern deployment practices in mind, offering seamless integration with containerized environments. Unlike traditional web servers, Traefik streamlines the process by featuring built-in support for SSL/TLS certificate management and incorporating automated service discovery. This makes Traefik a well-suited choice for contemporary systems that leverage containerization as a fundamental deployment tool.

MinIO

An integral component of cloud infrastructure is object storage, encompassing well-known services such as S3, Azure Blob Storage, and Google Object Storage. These platforms offer cost-effective storage solutions, accommodating diverse data types. Notably, MinIO stands out for its user-friendly approach compared to more traditional alternatives like Ceph, facilitating easier setup and management.

MinIO’s appeal lies in its adherence to familiar user design patterns found in popular cloud providers, resulting in a positive user and development experience. This design philosophy not only simplifies initial adoption but also proves advantageous when transitioning between cloud providers. Whether migrating from one cloud provider to another or integrating MinIO into your existing cloud environment, the seamless compatibility contributes to a smoother and more efficient process.

For this blogpost, I will be showing how we can deploy MinIO behind Traefik.

Setup

I will be using the following technologies to achieve deploying MinIO behind Traefik:

  • Docker
  • Docker Compose

Traefik Configuration Files

Traefik requires the following configuration files. These files dictate the entrypoints and ports that will be used by our applications.

  • traefik_dynamic.toml: Since Traefik has a built-in dashboard which you can use, you can configure this to be protected by defining a simple authentication.
[http.middlewares.simpleAuth.basicAuth]
  users = [
    "admin:<encrypted-password>"
  ]

[http.routers.api]
  rule = "Host(`traefik-dashboard-domain.com`)"
  entrypoints = ["websecure"]
  middlewares = ["simpleAuth"]
  service = "api@internal"

  [http.routers.api.tls]
    certResolver = "lets-encrypt"
  • acme.json: This contains the SSL certificate for your domains. We set this to empty upon creation since this will be populated by traefik. Below are sample contents of this file.
{

  "lets-encrypt": {
    "Account": {
      "Email": "myemail@mydomain.com",
      "Registration": {
        "body": {
          "status": "valid",
          "contact": [
            "mailto:myemail@mydomain.com"
          ]

        },

        "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/...."
      },

      "PrivateKey": "...",
      "KeyType": "4096",
      "Certificates": []
  • traefik.prod.toml: This contains the entrypoints to your ports 80 and 443. This also specifies the configuration for SSL certificate in this case Let's Encrypt like email and the acme.json
[entryPoints]
  [entryPoints.web]
  address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"
  [entryPoints.websecure]
  address = ":443"

[api]
  dashboard = true

[accessLog]
[providers.docker]
  watch = true
  network = "web"

[certificatesResolvers.lets-encrypt.acme]
  email = "myemail@mydomain.com"
  storage = "acme.json"
  [certificatesResolvers.lets-encrypt.acme.tlsChallenge]

[providers.file]
  filename = "traefik_dynamic.toml"

MinIO Configuration Files

MinIO has a simple configuration settings that you may want to configure first and these can be defined as Environment Variables. For this one, we will use the .env of docker file since we will be defining these variables as docker environment variables.

MINIO_ROOT_USER=<minio-root-user>
MINIO_ROOT_PASSWORD=<minio-root-password>
MINIO_DOMAIN=<minio-console-domain>
MINIO_SERVER_URL=<minio-api-domain>

Out of the box, MinIO provides 2 services, one for the dashboard or what they call the MinIO Console. By default, this will be served at port 9001. And the MinIO API where you can connect or access the REST API of MinIO. MinIO has various clients where you can interact with the REST API like Go, Python, NodeJS.

Docker Compose

Once you have defined and prepared all the configuration files above, you can now create the docker-compose.yml file.

version: '3.7'

services:
  traefik:
    image: traefik:v2.10.4
    container_name:traefik
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik/traefik.prod.toml:/traefik.toml
      - ./traefik/traefik_dynamic.toml:/traefik_dynamic.toml
      - ./traefik/acme.json:/acme.json
    ports:
      - 80:80
      - 443:443
    networks:
      - internal
      - web
  storage:
    image: docker.io/bitnami/minio:2023
    container_name: minio_storage
    env_file:
      - ./.env
    expose:
      - 9000
      - 9001
    volumes:
      - 'minio_data:/bitnami/minio/data'
    labels:
      #configuration of the minio console or UI
      - "traefik.http.routers.storage.rule=Host(`storage.mysite.com`)" 
      - "traefik.http.routers.storage.tls=true"
      - "traefik.http.routers.storage.tls.certresolver=lets-encrypt"
      - "traefik.http.routers.storage.service=storage"
      - "traefik.http.services.storage.loadbalancer.server.port=9001"
      #configuration of the minio api
      - "traefik.http.routers.console.rule=Host(``)" 
      - "traefik.http.routers.console.tls=true"
      - "traefik.http.routers.console.service=console"
      - "traefik.http.routers.console.tls.certresolver=lets-encrypt"
      - "traefik.http.services.console.loadbalancer.server.port=9000"
    networks:
      - internal
      - web

volumes:
  minio_data:
    driver: local
    driver_opts:
      o: 'bind'
      device: /minio-storage/storage #this will contain all the files uploaded to minio
      type: 'none'

networks:
  web:
    external: true
  internal:
    external: false

Overall you will have a folder structure similar to this one:

minio-traefik/
└── traefik
│   ├── acme.json
│   ├── traefik.prod.toml
│   ├── traefik_dynamic.toml
├── docker-compose.yml

Execute

Once the docker-compose.yml file has been written, you can now docker compose up to start the service. Open your browser and go to your domain name. You should be able to access the MinIO Console.

minio


Tags: