When managing large volumes of unstructured data — like images, logs, or backups — object storage is often the best fit. In this guide, we’ll automate the installation and configuration of MinIO, an open-source, high-performance, S3-compatible object storage server, using Ansible on a Debian 12 server.
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
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:
Click to expand
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
|
Final Steps
Save the following as setup-minio.yml
and run it with your inventory.
1
| ansible-playbook -i inventory setup-minio.yml
|
MinIO should now be available at:
Summary
MinIO gives you the power of AWS S3, but in your own infrastructure. Whether you’re building a backup service, log storage, or analytics system — it’s a powerful, scalable solution.
You can now use it for storing backups, hosting artifacts, or even building your own S3-compatible service locally or on the cloud.
Happy automating! 🛠️📦💡