Set Up MinIO Object Storage Using Nginx Proxy and SSL on Ubuntu 22

Reza Khademi
8 min readJun 28, 2023

--

Set Up MinIO Object Storage Using Nginx Proxy and SSL on Ubuntu 22

In this article we will set up a MinIO object storage using Nginx Proxy and SSL on ubuntu 22.

What is Object Storage?

Object storage is a type of data storage architecture that manages data as objects rather than as blocks or files. In object storage, each object is assigned a unique identifier and stored in a certain address, making it easier to manage and access data at scale.

Object storage systems are designed to be highly scalable and resilient, allowing organizations to store and manage large amounts of unstructured data, such as images, videos, audio files, and documents, across multiple servers and data centers.

What is MinIO?

MinIO is an open-source, high-performance, distributed object storage system that is designed to scale seamlessly from a single server to thousands of nodes.

It is built on top of the Amazon S3 API. MinIO is designed to be lightweight, fast, and easy to deploy. It is written in Golang.

Prerequisites

  • Ubuntu 22 operating system
  • A user account with sudo privileges
  • Command-line/terminal
  • A free or purchased domain (Optional for SSL certificate)

* SSH To Server And Set Up MinIO

In this section, we will set up a standalone MinIO server. (Also known as Single-Node Single-Drive).

First let’s go to our server:

ssh reza@server_ip

And then run apt update and upgrade to ensure everything is safe and sound!

sudo apt update && apt upgrade -y

Then, we will download MinIO server’s official website:

wget https://dl.min.io/server/minio/release/linux-amd64/minio

Meanwhile, we should make the downloaded file executable. To do so, run the following command:

sudo chmod +x ./minio

Now, let’s move the executable file to /usr/local/bin directory. This will ensure that Minio’s systemd startup script can find it. (If the bin directory does not yet exist, you can create it.)

mv ./minio /usr/local/bin

Let’s create a system user called minio to avoid running MinIO as root.

sudo useradd -r minio-user -s /sbin/nologin

Because this process does not require user login is not needed for MinIO we will use -s /sbin/nologin.

After moving the executable to the /usr/local/bin directory, don’t forget to change the ownership of the MinIO binary to the minio user with the following command:

sudo chown minio-user:minio-user /usr/local/bin/minio

After that we will create a dedicated directory for MinIO to store data:

sudo mkdir /usr/local/share/minio

After creating the directory, change the ownership of the directory to the minio user so that MinIO can store data in it using the following command:

sudo chown minio-user:minio-user /usr/local/share/minio

Now, let’s create another directory for MinIO configuration and give ownership of the directory to the minio user with the following command:

sudo mkdir /etc/minio
sudo chown minio-user:minio-user /etc/minio

Now, we should create a default configuration file and set some necessary environment variables:

sudo vim /etc/default/minio

The important env variables we should determine it are just like below:

MINIO_ACCESS_KEY="some_access_key"
MINIO_SECRET_KEY="some_secret_key"

MINIO_VOLUMES="/usr/local/share/minio/"
MINIO_OPTS="-C /etc/minio --address your_server_IP:9000"

In order to ensure that MinIO starts automatically whenever the server is booted, we need to curl default script:

curl -O https://raw.githubusercontent.com/minio/minio-service/master/linux-systemd/minio.service

The result should be similar to what is shown in the image below:

minio-service startup settings

To enable automatic startup of MinIO, we will move the downloaded minio.service script, which includes default configurations for MinIO, from the current directory to the systemd directory.

sudo mv minio.service /etc/systemd/system

Then, reload systemd service files to apply the changes, and enable MinIO to start automatically on system boot using the following commands:

sudo systemctl daemon-reload
sudo systemctl enable minio

Now we have a ready MinIO storage and we can start to use it by running:

sudo systemctl start minio

To ensure that the MinIO server is running properly, we can use the following command:

sudo systemctl status minio

If we did everything right until this section, shown result would be:

● minio.service - MinIO
Loaded: loaded (/etc/systemd/system/minio.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-06-26 11:54:02 UTC; 32s ago
Docs: https://docs.min.io
Process: 3405 ExecStartPre=/bin/bash -c if [ -z "${MINIO_VOLUMES}" ]; then echo "Variable MINIO_VOLUMES not set in /etc/default/minio"; exit 1; fi (code=exited, status=0/SUCCES
Main PID: 3407 (minio)
Tasks: 7 (limit: 1152)
CGroup: /system.slice/minio.service
└─3407 /usr/local/bin/minio server -C /etc/minio --address your_server_IP:9000 /usr/local/share/minio/

Dec 09 21:54:02 cart-Minion-Object-1804-1 systemd[1]: Started MinIO.
Dec 09 21:54:03 cart-Minion-Object-1804-1 minio[3407]: Endpoint: http://your_server_IP:9000
Dec 09 21:54:03 cart-Minion-Object-1804-1 minio[3407]: Browser Access:
Dec 09 21:54:03 cart-Minion-Object-1804-1 minio[3407]: http://your_server_IP:9000

In order to allow access to the MinIO server from outside, we need to activate access through the firewall.

To do so, we need to open port 9000 in the firewall to allow incoming traffic:

sudo ufw allow 9000
sudo ufw allow 22
sudo ufw allow 443
sudo ufw allow 80

Note that port 22 is used for SSH and ports 80 and 443 will be used for Nginx proxy configuration in the next section. If you do not plan to use Nginx or do not require access through these ports, you can skip allowing them through the firewall.

In order to ensure that the firewall settings we have added are applied and in effect, we need to enable ufw:

sudo ufw enable

At the end of this section, we have a MinIO storage ready to accept traffic and admin dashboard can be reach out by going to your_server_ip:9000.

We can login by using access_key and secret_key to watch service details, create buckets or modify accesses.

At the end of this section, we have a MinIO storage ready to accept traffic, and the admin dashboard can be accessed by navigating to your_server_ip:9000.

To log in and access service details, create buckets, or modify access, you will need to use the some_access_key and some_secret_key.

* Using MinIO Object Storage With SSL

In this section we will use Nginx as a proxy and SSL to access object storage with a more secure setup. (You can use HAProxy as well)

Because we want to have SSL certification we need to install some tools like certbot and common-tools.

To install Nginx as well as certbot and common-tools, which are useful for managing SSL certificates, use the following commands:

sudo apt install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot

After adding desired repositories and installing certbot, run below command to install Nginx:

sudo apt install nginx python3-certbot-nginx

Now for getting a free SSL we can run:

sudo certbot certonly --standalone -d minio.your_domain_name

We result should be:

Output

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

Press ENTER and we will add our email.

Certbot will then ask us to register with Let’s Encrypt:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel:

Press ENTER and type A to agree.

After that we will be asked for your consent:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

Once we type answer Y or N, the public and private keys will be generated and saved in the /etc/letsencrypt/live/minio-server.your_domain_name directory.

Now, we should copy these two files (privkey.pem and fullchain.pem) into the certs directory under Minio’s configuration folder, which is /etc/minio.

Use the following to copy privkey.pem and rename the file private.key:

sudo cp /etc/letsencrypt/live/minio-server.your_domain_name/privkey.pem /etc/minio/certs/private.key

After that, repeat the same step with fullchain.pem:

sudo cp /etc/letsencrypt/live/minio-server.your_domain_name/fullchain.pem /etc/minio/certs/public.crt

Let’s change the ownership of the files to miniouser:

sudo chown minio-user:minio-user /etc/minio/certs/private.key
sudo chown minio-user:minio-user /etc/minio/certs/public.crt

Then, restart the MinIO server to start using HTTPS:

sudo systemctl restart minio

We can connect to the Minio web interface through https://minio.your_domain_name:9000 or http://your_server_ip:9000.

We can see the login screen of the Minio server:

* Configure NGINX Proxy for MinIO Server (Optional)

The following set up will configure Nginx to proxy requests to MinIO.

Prerequisites

  • An existing NGINX deployment
  • An existing MinIO deployment

Setting up a proxy is pretty simple and after creating a soft link for site-available and site-enabled on /etc/nginx just add the following lines to the config file:

upstream minio {
least_conn;
server minio.your_domain_name.com;
}

server {
listen 80;
listen [::]:80;
server_name minio.example.net;

# Allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# Disable buffering
proxy_buffering off;
proxy_request_buffering off;

location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;

proxy_pass http://minio:9000; # This uses the upstream directive definition to load balance
}
}

server {

listen 80;
listen [::]:80;
server_name console.example.net;

# Allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# Disable buffering
proxy_buffering off;
proxy_request_buffering off;

location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;

# This is necessary to pass the correct IP to be hashed
real_ip_header X-Real-IP;

proxy_connect_timeout 300;

# To support websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

chunked_transfer_encoding off;

proxy_pass http://minio:9001; # This uses the upstream directive definition to load balance and assumes a static Console port of 9001
}
}

From now on Nginx will respond to our request by acting as a proxy.

That’s it. If you have any problem, please leave a comment below and I’ll be happy to help.

READ MORE:

--

--