Automating MinIO Installation on Ubuntu or Debian Using Ansible

Step-by-step guide to automating MinIO installation on Ubuntu or Debian using Ansible. Full playbook, variables, systemd service, and verification.

When managing large volumes of unstructured data — images, logs, or backups — object storage is often the best fit. MinIO is an open-source, S3-compatible object storage server you can run on your own infrastructure. This guide automates installing and configuring MinIO using Ansible on Ubuntu or Debian (e.g. Debian 12).

You will use a single playbook that updates the system, installs the MinIO binary, creates a dedicated user and directories, configures environment variables and a systemd service, and starts MinIO. The S3 API will listen on port 9000 and the web console on port 9001.

Prerequisites: Ansible installed on your control node (see How to Install and Configure Ansible on Rocky Linux or install via pip/apt); SSH access to one or more Ubuntu or Debian hosts; an inventory file defining your target hosts (e.g. citizixsrv).

What is Object Storage?

Object storage is a way of storing data as objects, rather than as files in a hierarchy or blocks on a disk. It’s ideal for large-scale, distributed systems. MinIO brings this architecture to your own infrastructure and is often used as a self-hosted alternative to AWS S3.

Why Use Ansible?

Ansible is an agentless configuration management tool that allows you to describe server configuration using YAML. It’s perfect for automating repeatable tasks like software installation and systemd configuration.

What This Playbook Does

This playbook will:

  • Update and upgrade system packages
  • Install common utilities like vim, git, and ufw
  • Download the latest MinIO binary
  • Create a non-login system user for MinIO
  • Set up the necessary directory structure
  • Configure environment variables and a systemd service
  • Start and enable the MinIO service

Set Up Required Variables

Here are the core variables used in the playbook. These make the playbook more reusable and configurable:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
vars:
  minio_user: minio
  minio_bin_path: /usr/local/bin/minio
  minio_data_dir: /data
  minio_work_dir: /usr/local/minio
  minio_env_file: /etc/default/minio
  minio_service_file: /etc/systemd/system/minio.service
  minio_download_url: https://dl.min.io/server/minio/release/linux-amd64/minio
  minio_root_user: admin
  minio_root_password: "Admin@123$"

You can update the password or path values to match your environment. Security: avoid committing plain-text passwords to version control. Use Ansible Vault to encrypt minio_root_password (e.g. in a vars file or --extra-vars) and pass the vault password at run time.

Step-by-Step Breakdown

Update the OS

We start by ensuring the server is up-to-date:

1
2
3
4
5
6
- name: Update and upgrade apt packages
  apt:
    update_cache: yes
    upgrade: dist
    cache_valid_time: 3600
    force_apt_get: yes

Install Useful Utilities

These are helpful tools to have on any server:

1
2
3
4
5
6
7
- name: Install essential utilities
  apt:
    name:
      - vim
      - git
      - ufw
    state: present

Download the MinIO Binary

We fetch the MinIO binary directly from MinIO’s official release:

1
2
3
4
5
- name: Download MinIO binary
  get_url:
    url: "{{ minio_download_url }}"
    dest: "{{ minio_bin_path }}"
    mode: "0750"

Create a Dedicated System User

We’ll run MinIO as a non-login system user for security:

1
2
3
4
5
6
- name: Create dedicated system user for MinIO
  user:
    name: "{{ minio_user }}"
    shell: /sbin/nologin
    system: yes
    state: present

Create Required Directories

Create the working and data directories for MinIO:

1
2
3
4
5
6
7
8
9
- name: Create MinIO data and working directories
  file:
    path: "{{ item }}"
    state: directory
    owner: "{{ minio_user }}"
    group: "{{ minio_user }}"
  loop:
    - "{{ minio_data_dir }}"
    - "{{ minio_work_dir }}"

Set Up MinIO Environment Configuration

We define runtime configuration in /etc/default/minio:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
- name: Create MinIO environment file
  copy:
    dest: "{{ minio_env_file }}"
    owner: "{{ minio_user }}"
    group: "{{ minio_user }}"
    mode: "0600"
    content: |
      MINIO_ROOT_USER={{ minio_root_user }}
      MINIO_ROOT_PASSWORD={{ minio_root_password }}
      MINIO_VOLUMES={{ minio_data_dir }}
      MINIO_OPTS="--address :9000 --console-address :9001"

Create systemd Service

This service file ensures MinIO is managed by systemd:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- name: Create MinIO systemd service file
  copy:
    dest: "{{ minio_service_file }}"
    owner: root
    group: root
    mode: "0644"
    content: |
      [Unit]
      Description=MinIO S3-compatible Object Storage
      Documentation=https://min.io/docs/
      Wants=network-online.target
      After=network-online.target
      AssertFileIsExecutable={{ minio_bin_path }}

      [Service]
      WorkingDirectory={{ minio_work_dir }}
      User={{ minio_user }}
      Group={{ minio_user }}

      EnvironmentFile=-{{ minio_env_file }}
      ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo 'MINIO_VOLUMES not set'; exit 1; fi"
      ExecStart={{ minio_bin_path }} server ${MINIO_OPTS} ${MINIO_VOLUMES}

      Restart=always
      LimitNOFILE=65536
      TimeoutStopSec=infinity
      SendSIGKILL=no

      [Install]
      WantedBy=multi-user.target

Enable and Start the MinIO Service

This ensures MinIO starts on boot and is running:

1
2
3
4
5
6
- name: Reload systemd and enable MinIO service
  systemd:
    daemon_reload: true
    name: minio
    enabled: true
        state: started

Full Playbook: setup-minio.yml

Here is the complete playbook for reference:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
---
- name: Set up MinIO on Debian
  hosts: citizixsrv
  become: true
  gather_facts: false

  vars:
    minio_user: minio
    minio_bin_path: /usr/local/bin/minio
    minio_data_dir: /data
    minio_work_dir: /usr/local/minio
    minio_env_file: /etc/default/minio
    minio_service_file: /etc/systemd/system/minio.service
    minio_download_url: https://dl.min.io/server/minio/release/linux-amd64/minio
    minio_root_user: admin
    minio_root_password: "Admin@123$"

  tasks:
    - name: Update and upgrade apt packages
      apt:
        update_cache: yes
        upgrade: dist
        cache_valid_time: 3600
        force_apt_get: yes

    - name: Install essential utilities
      apt:
        name:
          - vim
          - git
          - ufw
        state: present

    - name: Download MinIO binary
      get_url:
        url: "{{ minio_download_url }}"
        dest: "{{ minio_bin_path }}"
        mode: "0750"

    - name: Create dedicated system user for MinIO
      user:
        name: "{{ minio_user }}"
        shell: /sbin/nologin
        system: yes
        state: present

    - name: Create MinIO data and working directories
      file:
        path: "{{ item }}"
        state: directory
        owner: "{{ minio_user }}"
        group: "{{ minio_user }}"
      loop:
        - "{{ minio_data_dir }}"
        - "{{ minio_work_dir }}"

    - name: Create MinIO environment file
      copy:
        dest: "{{ minio_env_file }}"
        owner: "{{ minio_user }}"
        group: "{{ minio_user }}"
        mode: "0600"
        content: |
          MINIO_ROOT_USER={{ minio_root_user }}
          MINIO_ROOT_PASSWORD={{ minio_root_password }}
          MINIO_VOLUMES={{ minio_data_dir }}
          MINIO_OPTS="--address :9000 --console-address :9001"

    - name: Create MinIO systemd service file
      copy:
        dest: "{{ minio_service_file }}"
        owner: root
        group: root
        mode: "0644"
        content: |
          [Unit]
          Description=MinIO S3-compatible Object Storage
          Documentation=https://min.io/docs/
          Wants=network-online.target
          After=network-online.target
          AssertFileIsExecutable={{ minio_bin_path }}

          [Service]
          WorkingDirectory={{ minio_work_dir }}
          User={{ minio_user }}
          Group={{ minio_user }}

          EnvironmentFile=-{{ minio_env_file }}
          ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo 'MINIO_VOLUMES not set'; exit 1; fi"
          ExecStart={{ minio_bin_path }} server ${MINIO_OPTS} ${MINIO_VOLUMES}

          Restart=always
          LimitNOFILE=65536
          TimeoutStopSec=infinity
          SendSIGKILL=no

          [Install]
          WantedBy=multi-user.target

    - name: Reload systemd and enable MinIO service
      systemd:
        daemon_reload: true
        name: minio
        enabled: true
        state: started

Running the Playbook

Save the playbook as setup-minio.yml and run it with your inventory (replace inventory with your inventory file or group name):

1
ansible-playbook -i inventory setup-minio.yml

If you use Ansible Vault for minio_root_password, add --ask-vault-pass or provide a vault password file.

Verifying MinIO

After a successful run, MinIO should be listening on the target host:

  1. Check the service:

    1
    
    ssh your-user@your-server-ip 'systemctl status minio'
    
  2. Open the console: In a browser, go to http://your-server-ip:9001 and log in with minio_root_user and minio_root_password from your vars.

  3. Test the API: Use the MinIO Client (mc) or any S3-compatible client (e.g. AWS CLI with --endpoint-url http://your-server-ip:9000).

If you enabled ufw on the host, allow ports 9000 and 9001 (e.g. ufw allow 9000/tcp, ufw allow 9001/tcp, ufw reload) or restrict them to your IP/subnet.

Troubleshooting

  • Service fails to start: Check journalctl -u minio -n 50. Ensure MINIO_VOLUMES is set in /etc/default/minio and the data directory exists and is owned by the MinIO user. Ensure the binary at minio_bin_path is executable (chmod +x /usr/local/bin/minio).
  • Port already in use: Another process may be using 9000 or 9001. Change MINIO_OPTS in the env file (e.g. --address :9002 --console-address :9003) and reload the playbook or service.
  • Ansible “Permission denied” or “Failed to connect”: Ensure SSH keys or credentials are set up for the inventory host and that become (sudo) is allowed for the user.

Summary

You automated MinIO installation on Ubuntu or Debian with Ansible: system update, MinIO binary, dedicated user, directories, environment file, and systemd service. MinIO gives you S3-compatible object storage on your own infrastructure for backups, logs, or custom applications.

For other deployment options, see How to Run MinIO in Docker and Docker Compose or How to Set Up MinIO as Object Storage on Rocky Linux.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy