How to Set S3 Hosting on Your Own Server

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 dashboard
Environment – 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! πŸ”₯

1 thought on “How to Set S3 Hosting on Your Own Server”

  1. Pingback: Installing and Configuring WordPress with MySQL on Coolify – hasto

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top