S3 Speicher mit Minio und nginx - Tutorial (ohne Docker)

Ich persönlich finde S3 Speicher sehr angenehm und versuche ihn für verschiedene Anwendungsbereiche zu verwenden. Heute habe ich mir wieder einen extra Server installiert und möchte den Prozess hiermit quasi dokumentieren. Mit dieser Anleitung installieren wir Minio auf einem Debian 12 (Bookworm) System. Dazu verwenden wir direkt nginx als Reverse Proxy und sichern das mittels Let’s encrypt Zertifikaten ab, sodass immer eine gesicherte Verbindung aufgebaut werden kann.

Was ist S3 Speicher?

S3-Speicher bezieht sich auf Amazon Simple Storage Service, kurz Amazon S3. Es handelt sich dabei um einen skalierbaren Cloud-Speicherdienst von Amazon Web Services (AWS). S3 ermöglicht es Benutzern, große Datenmengen sicher und kostengünstig in der Cloud zu speichern. Ein Objektspeicher ist eine Art von Datenspeicher, der darauf ausgelegt ist, große Mengen unstrukturierter Daten in Form von Objekten zu speichern. Jedes Objekt besteht aus Daten, Metadaten und einem eindeutigen Identifikator. Im Fall von S3 werden diese Objekte in sogenannten “Buckets” organisiert, die als virtuelle Container dienen, um die Objekte zu gruppieren.

Installation von Minio

Anlegen des Nutzers und Gruppe

Mittlerweile gibt es extra Paket für Debian und Ubuntu sodass sich die Installation etwas mehr vereinfacht. Minio sollte natürlich nicht im Kontext des root-Nutzers laufen. Best practise ist hier, sich einen eigenen Nutzer anzulegen. Du kannst natürlich auch gerne schon einen vorhanden verwenden.

groupadd -r minio-user
useradd -M -r -g minio-user minio-user

Wie geschrieben kannst du die Parameter auch entsprechend anpassen. Bedenke aber, dass die Anleitung davon ausgeht, dass du die Nutzer und Gruppe genau so genannt wurden.

Datenverzeichnis vorbereiten

Als nächstes solltest du dir noch Gedanken machen wohin auf deinem System die Daten abgelegt werden sollen. In meinem Fall lege dich diese nach /opt ab. Zuerst wird das Verzeichnis angelegt und anschließend bekommt unser Minio Nutzer minio-user das Verzeichnis als Besitzer zugeordnet.

mkdir -p /opt/minio
chown minio-user:minio-user /opt/minio

Minio Paket installieren

Glücklicherweise gibt es Minio mittlerweile auch als fertiges Paket, sodass wir uns um diverse Dinge keine Gedanken machen müssen. Dies beinhaltet nämlich mittlerweile auch einen systemd Skript um das Programm sauber darüber starte und stoppen zu können. Zuerst laden wir uns das Paket erst einmal runter. Sehr wahrscheinlich ist die verlinkte Version schon veraltet wenn du dieses Tutorial liest. Schaue als bitter mal hier welche die aktuelle Version ist und ersetze die Versionnummer.

wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio_20240217011557.0.0_amd64.deb -O minio.deb

Sollte dein System aus irgendwelchen Gründen den Befehl wget nicht kennen kannst du den mittels

apt install wget -y

installieren.

Nun brauchen wir nur noch Minio zu installieren und haben schon einen großen Teil erledigt.

dpkg -i minio.deb

Nach ein paar Sekunden ist das ganze auch schon fertig und wir können anfangen das Programm zu konfigurieren.

Standardkonfiguration für Minio anlegen

Wir nutzen in diesem Tutorial eine recht einfache Konfiguration. Diese kannst du natürlich immer noch nach weiterem belieben erweitern wenn du möchtest. Wir legen uns also die Default Konfiguration an

touch /etc/default/minio

und bearbeiten diese. Ich verwende immer vim als Editor. Du kannst natürlich auch gerne nano verwenden wenn dir das lieber ist.

vim /etc/default/minio

Darin kopieren wir jetzt folgende Zeilen

# Definition des Admin Accounts
MINIO_ROOT_USER=myminioadmin
MINIO_ROOT_PASSWORD=minio-secret-key-change-me

# MINIO_VOLUMES setzt das Verzeichnis in dem unsere Daten gespeichert werden

MINIO_VOLUMES="/opt/minio"

# Damit wir auch die Konsole bzw. Webfrontend verwenden können, müssen wir das natürlich noch setzen
MINIO_OPTS="--console-address :9001"

Bitte pass entsprechend MINIO_ROOT_USER und MINIO_ROOT_PASSWORD an und lasse die Werte nicht auf default setzen. Auch wenn du das System nicht nach außen hin veröffentlichst, sollten niemals Standardzugangsdaten verwendet werden.

Minio starten und Login

Nun starten wir Minio erst einmal um zu sehen ob alles funktioniert. Zudem sollten wir uns auch einmal anmelden um auch das gegengetestet zu haben.

systemctl enable minio
systemctl start minio

Nun öffnen wir einen Browser und navigieren zu {HOSTIP}:9001 und sollten anschließend so ein Bild sehen. Startseite des S3 Servers Minio Bitte anschließend einmal einloggen um zu sehen, dass auch deine Zugangsdaten korrekt funktionieren.

nginx als Rervse Proxy mit Zertifkat einrichten

Ich verwende in dem Tutorial Cerbot zum generieren des Let’s encrypt Zertifikates. Zudem wird mein öffentliches DNS meiner Domain von Cloudflare betrieben. Entsprechend verwende ich hier die dns-challenge mit Cloudflare und API Token.

Cloudflare API Token generieren

Auf der Cloudflare Profilseite gibt es den Punkt API Tokens (Generischer Link dorthin). Dort legen wir uns rechts oben ein neuen Token an und verwenden das Template Edit Zone DNS. Du solltest nun ungefähr dieses Bild hier sehen. Cloudflare API Token Template Den Bereich Permissions lassen wir so wie er ist. Im Bereich Zone Resources müssen wir im letzten drop down Feld in der Reihe nur noch die entsprechende Domain auswählen. Den Rest können wir mit Continue to summary ebenfalls auslassen. Auf der nächsten Seite bestätigen wir mit Create Token und nun wird uns unser Token angezeigt. Ich empfehle diesen sicher abzuspeichern falls du den später noch mal für andere Dinge verwenden möchtest.

Pakete installieren

Nun zurück zu unserer Linux Maschine. Wir können hier nun endlich alle benötigten Pakete installieren die wir brauchen.

apt install nginx certbot python3-certbot-dns-cloudflare

Dies benötigt ein paar Sekunden und wir können weiter machen uns unser Zertifikat zu besorgen.

Let’s encrypt Zertifikat mit Certbot beantragen

Zuerst richten wir noch die Punkte für die DNS Challenge zu Cloudflare ein. Dazu erstellen wir uns ein Verzeichnis

mkdir -p /etc/certbot

und legen uns dort eine Datei an

touch /etc/certbot/credentials

in diese kommt nun unser Cloudflare Token. Also editieren wir die Datei

vim /etc/certbot/credentials

und kopieren folgendes dort rein

dns_cloudflare_api_token={DEIN_CLOUDFLARE_API_TOKEN}

Damit die Datei nicht von jedem Nutzer auf dem System gelesen werden kann, passen wir noch die Berechtigungen mittels

chmod 600 /etc/certbot/credentials

an. Nun haben wir den Grundstock gelegt um das Zertifikat beantragen zu können. Beachte jetzt, dass du die Domain entsprechend an deine Domain anpassen musst.

certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/certbot/credentials -d minio.example.com -d s3.example.com
Aus irgendwelchen Gründen funktioniert das bei mir beim ersten mal nicht immer zuverlässig. Solltest du auf den Fehler stoßen, dass man überprüfen soll, ob der DNS Eintrag gesetzt ist, warte noch kurz und führe den Befehl erneut aus.

nginx einrichten

Nun können wir uns mit dem Thema nginx als reverse proxy für minio beschäftigen. Die Software wurde bereits oben schon installiert, also können wir direkt mit der Konfiguration der Seite beginnen. Dazu wechseln wir in das Konfigurationsverzeichnis für die Webseiten

cd /etc/nginx/sites-available

Dort legen wir dann die Seitenkonfiguration an

touch minio.conf

und können dann auch diese im Anschluss bearbeiten

vim minio.conf

Dort kannst du dann folgendes rein kopieren:

## API End Point
server
{
	# Listen
	listen 80;
	listen [::]:80;
	listen 443 ssl http2;
	listen [::]:443 ssl http2;

	# Directory & Server Naming
	server_name s3.example.com;

	# HTTP to HTTPS redirection
	if ($scheme != "https")
	{
		return 301 https://$host$request_uri;
	}

	# SSL
	ssl_certificate /etc/letsencrypt/live/minio.example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/minio.example.com/privkey.pem;

	# Disable Hidden FIle Access Except Lets Encrypt Verification
	location ~ /\.well-known
	{
		allow all;
	}

	# 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://127.0.0.1:9000;
	}

	# Nginx Logging
	access_log /var/log/nginx/s3.example.com-access.log;
	error_log /var/log/nginx/s3.example.com-error.log warn;
}

###################### Console ######################

server
{
	# Listen
	listen 80;
	listen [::]:80;
	listen 443 ssl http2;
	listen [::]:443 ssl http2;

	# Directory & Server Naming
	server_name minio.example.com;

	# HTTP to HTTPS redirection
	if ($scheme != "https")
	{
		return 301 https://$host$request_uri;
	}

	# SSL
	ssl_certificate /etc/letsencrypt/live/minio.example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/minio.example.com/privkey.pem;

	# Disable Hidden FIle Access Except Lets Encrypt Verification
	location ~ /\.well-known
	{
		allow all;
	}

	# 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;
		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://127.0.0.1:9001;
	}

	# Nginx Logging
	access_log /var/log/nginx/minio.example.com-access.log;
	error_log /var/log/nginx/minio.example.com-error.log warn;
}

Bitte beachte, dass du überall das example.com durch deine eigene Domain austauschst. Die Konfiguration habe ich von hier übernommen und ein wenig angepasst.

Jetzt legen wir noch den symlink an

ln /etc/nginx/site-available/minio.conf /etc/nginx/site-enabled/

und sollten testen ob wir auch kein Fehler gemacht haben. Das können wir am einfachsten mittels

nginx -t

Hier sollte keine Ausgabe erscheinen. Andernfalls müstest du die angezeigten Fehler noch verbessern. Zu guter letzt können wir nginx neu starten

systemctl restart nginx

Jetzt kannst du auch Minio über https über deine Domainnamen erreichen. Solltest du Minio nur im lokalen Netzwerk verwenden, denk daran, dass noch im DNS entsprechend zu hinterlegen.

Optional: Minio Admin Cli installieren

Gegebenenfalls brauchst du zu einem späteren Zeitpunkt mal die Admin CLI von Minio. Also solltest du diese direkt mit installieren. Diese ist ein einfaches binary das wir nur auf das System kopieren müssen.

curl https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/sbin/mc

Allerdings wird es ohne Execute Rechte nicht ausgeführt werden können, also fügen wir diese noch hinzu

chmod +x /usr/local/sbin/mc

Anschließend könntest du mittels mc den Minio Server auch via CLI administrieren.

Fazit

In meinem Kubernetes Cluster verwende ich Minio um darauf Backups abzulegen die mittels volsync erstellt wurden. Ebenso verwendet Thanos den S3 Speicher als Langzeitspeicher um die Prometheus Daten lange aufzuheben.

Solltest du Fragen zu dem Tutorial haben, kannst du mich gerne über eine der im Blog angegebenen Netzwerke erreichen.