Introduction
In this guide, I will show you how to easily and affordably create S3 hosting on your own server. π₯οΈ
We will use the MinIO application on a VPS, and while you can choose any provider that suits your needs (such as Hetzner, AWS, Azure, or OVH),
I personally will use a low-cost 1GB RAM Ubuntu VPS from mikr.us.
With an additional hard drive, my total cost will be 110 PLN per year (approximately $26.5)
VPS Hardening
Before diving into the tutorial, I recommend performing an initial configuration of your new VPS. This includes setting up an A record in your DNS zone, configuring a root password, creating a new user, and disabling password-based SSH login. This process, known as VPS Hardening πͺͺ, significantly enhances your serverβs security. There are numerous resources online covering this topic, so I encourage you to do some research.
Let’s get started. π₯
Creating a Dedicated User and Group for MinIO
To enhance security and ensure proper isolation of services, we will create a dedicated user and group specifically for running MinIO. This prevents the application from operating under the root user, reducing potential risks. π
Start by executing the following commands on your Ubuntu server:
sudo groupadd minio
sudo useradd -r -g minio -s /usr/sbin/nologin minio
This user will later be responsible for running the MinIO service, ensuring that it operates with minimal privileges, adhering to best security practices.
Creating a Storage Directory for MinIO and Setting Permissions
Next, we need to create a dedicated storage directory for MinIO and assign the correct permissions to ensure the minio
user has full control over it. This will serve as the location where MinIO stores data. π
Run the following commands on your Ubuntu server:
sudo mkdir -p /storage/minio
sudo chown minio:minio /storage/minio
sudo chmod 750 /storage/minio
Setting Up MinIO Storage and Downloading the MinIO Binary
Now that we have created the storage directory for MinIO, the next step is to create a data
folder inside it and download the MinIO binary. This prepares the environment for running the MinIO service. βοΈ
Follow these commands to proceed:
sudo mkdir -p /storage/minio/data
cd /storage/minio
sudo wget https://dl.min.io/server/minio/release/linux-amd64/minio
sudo chown -R minio:minio /storage/minio
sudo chmod 750 /storage/minio
sudo chmod +x /storage/minio/minio
sudo chown -R minio:minio /storage/minio/data
sudo chmod u+rxw /storage/minio/data
Creating and Configuring a Systemd Service for MinIO
To ensure MinIO starts automatically and runs as a managed service, we will create a new systemd
service. This service will launch MinIO with the necessary environment variables for API, CLI, and web console access. π οΈ
Step 1: Create the Systemd Service File
First, run the following command: sudo nano /etc/systemd/system/minio.service
and add the following configuration to the file:
[Unit]
Description=MinIO Object Storage
After=network.target
[Service]
User=minio
Group=minio
ExecStart=/storage/minio/minio server /storage/minio/data \
--address :9000 \
--console-address :40288
Environment="MINIO_ROOT_USER=admin"
Environment="MINIO_ROOT_PASSWORD=strongpassword123"
Restart=always
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
ExecStart
β Runs MinIO with the specified storage path and binds the API/CLI to port 9000
and the web console to 40288
. In my case I use TCP ports requested in mikr.us dashboardEnvironment
β Defines the root user and password for MinIO. Replace admin
and strongpassword123
with secure credentials.Restart=always
β Ensures MinIO restarts if it crashes or the server reboots.
Step 2: Enable and Start the MinIO Service βΆοΈ
Save and exit the file, then reload the systemd daemon to apply the changes:
sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
Step 3: Verify the Service Status and Logs π
To confirm that MinIO is running correctly, check its status and view the logs:
sudo systemctl status minio
sudo journalctl -u minio
At this point, MinIO should be accessible via the API at http://<your-server-ip>:9000
and through the web console at http://<your-server-ip>:44935
.
Creating a Bucket and Access Key
The last step is to create a bucket and generate an access key for it. Let’s navigate to the “Buckets” panel and click on “Create Bucket”. I will name my bucket tutorial-bucket
. πͺ£
Now let’s create a new access key. Open the “Access Keys” panel and click “Create Access Key”. I will name it tutorial-bucket-rw
, indicating that this key has read and write permissions for the tutorial-bucket
. π
Make sure to save the secret somewhere safe, as you wonβt be able to view it again later.
The final step in the configuration process is to assign the appropriate permissions to our access key. π
Click the pencil icon next to your new Access Key and paste the following text into the Access Key Policy field:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::tutorial-bucket/*"
]
}
]
}
This policy grants the key permissions to list, read, write, and delete objects within the tutorial-bucket
, ensuring it has full access to manage the contents.
For testing purposes, I configured one of the WordPress plugins to upload a backup to our new S3 bucket. As you can see, I entered our credentials and also disabled SSL verification in the plugin settings.
Everything is working correctly. β
Configuring SSL for MinIO with Certbot and Automated Certificate Synchronization
To ensure basic security standards, we need to configure SSL for our MinIO instance π. We’ll achieve this by using Certbot and creating a service that automatically synchronizes certificates to the appropriate directory.
Step 1: Certbot Configuration
First, you need to configure Certbot. I wonβt duplicate commonly available information, so simply follow the guide below to complete the setup:
π How to Acquire a Letβs Encrypt Certificate Using DNS Validation with ACME-DNS and Certbot on Ubuntu 18.04
After running the command:
sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d <YOUR_DOMAIN>
The certificates privkey.pem
and cert.pem
will be generated in the directory: /etc/letsencrypt/live/<YOUR_DOMAIN>/
Step 2: Create the Service π οΈ
Once this is done, we can proceed with creating our service.
Create a new directory with the following commands:
sudo mkdir -p /home/minio/.minio/certs
sudo chown -R minio:minio /home/minio
sudo chmod u+rxw -R /home/minio
Next, create a script file at sudo nano /usr/local/bin/minio_sync_certs.sh
with the following content: (dont forget to replace <YOUR_DOMAIN>)
#!/bin/bash
CERT_SRC="/etc/letsencrypt/live/<YOUR_DOMAIN>/fullchain.pem"
KEY_SRC="/etc/letsencrypt/live/<YOUR_DOMAIN>/privkey.pem"
CERT_DST="/home/minio/.minio/certs/public.crt"
KEY_DST="/home/minio/.minio/certs/private.key"
cp "$CERT_SRC" "$CERT_DST"
cp "$KEY_SRC" "$KEY_DST"
chmod 600 "$KEY_DST"
chmod 644 "$CERT_DST"
chown -R minio:minio "$KEY_DST"
chown -R minio:minio "$CERT_DST"
Now, grant execution permissions to the script via sudo chmod +x /usr/local/bin/minio_sync_certs.sh
After it create service file in sudo nano /etc/systemd/system/minio-sync-certs.service
with the following content:
[Unit]
Description=Sync Lets Encrypt certificate to MinIO directory
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/minio_sync_certs.sh
[Install]
WantedBy=multi-user.target
Step 3: Create the Service Timer β
Next, set up a timer to automate certificate synchronization. Create the file sudo nano /etc/systemd/system/minio-sync-certs.timer
with the following content:
[Unit]
Description=Timer to synchronize Let's Encrypt certificates
[Timer]
OnBootSec=1min
OnUnitActiveSec=12h
Persistent=true
[Install]
WantedBy=timers.target
Finally, enable and start the timer:
sudo systemctl daemon-reload
sudo systemctl enable minio-sync-certs.timer
sudo systemctl start minio-sync-certs.timer
Now, when we execute the command: systemctl restart minio
. We should notice that the red padlock in the browser disappears, indicating that our connection is now secure and encrypted using TLS. ππ
Wrapping Up
Congratulations! You’ve successfully set up a secure and cost-effective S3-compatible storage solution using MinIO. From configuring a VPS to enabling SSL encryption. With your MinIO instance ready, you can now confidently use it for backups, media storage, or any other cloud storage needs.
Happy hosting! π₯
Pingback: Installing and Configuring WordPress with MySQL on Coolify – hasto