How to run multiple MinIO servers with Træfɪk
Træfɪk is a modern reverse proxy also written in Go. It
supports multiple ways to get configured, this cookbook will explain how you
can setup multiple MinIO instances via Docker which you can access on different
sub-domains through Træfɪk.
1. Prerequisites
You have Docker installed and running, if not follow install instructions.
2. Steps
Fetch, configure and launch Træfɪk
First of all you should create a configuration file for Træfɪk to enable Let's
Encrypt and to configure the Docker backend. Incoming traffic via HTTP gets
automatically redirected to HTTPS and the certificates are getting created on
demand by the integrated Let's Encrypt support.
cat << EOF > traefik.toml
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[acme]
email = "[email protected]"
storageFile = "/etc/traefik/acme.json"
entryPoint = "https"
onDemand = true
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "example.com"
watch = true
EOF
Beside the configuration we should also touch the acme.json
file, this file
is the storage for the generated certificates. This file will also store the
private keys, so you should set proper permissions to make sure not everybody
can read the configuration.
touch acme.json
chmod 640 acme.json
With those steps we are prepared to launch a Træfɪk container which proxies the
incoming traffic.
docker run -d \
--restart always \
--name traefik \
--publish 80:80 \
--publish 443:443 \
--volume $(pwd)/traefik.toml:/etc/traefik/traefik.toml \
--volume $(pwd)/acme.json:/etc/traefik/acme.json \
--volume /var/run/docker.sock:/var/run/docker.sock \
traefik
Fetch, configure and launch MinIO
Now it's time to prepare multiple instances of MinIO to demonstrate a
multi-tenant solution. That way you are able to launch multiple MinIO instances
with different credentials that get routed automatically by Træfɪk.
We will launch the MinIO instances with volume mounts from the host system. If
you prefer data containers please take a look at the MinIO Docker quickstart guide.
for i in $(seq 1 5); do
mkdir -p $(pwd)/minio${i}/{export,config}
docker run -d \
--restart always \
--name minio-${i} \
--volume $(pwd)/minio${i}/config:/root/.minio \
--volume $(pwd)/minio${i}/export:/export \
minio/minio
done
Test launched instances
To test the launched instances you can take curl, that way you can verify that
the instances are really launched correctly.
curl -H Host:minio-1.example.com http://127.0.0.1
This call will result in the following output because the request had been
unauthenticated, but you can see that it finally have been correctly launched.
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied.</Message><Key></Key><BucketName></BucketName><Resource>/</Resource><RequestId>3L137</RequestId><HostId>3L137</HostId></Error>
Now you can reach all the launched MinIO instances via https://minio-{1,2,3,4,5}.example.com
As a final note I would like to mention that you should start the Docker
containers with the init system of your operating system. As an example you can
see an example for a systemd service file how I'm launching new MinIO
instances. Just store this file as /etc/systemd/system/[email protected]
and
start new instances with systemctl start minio@server1
,
systemctl start minio@server2
, systemctl start minio@server3
and the
instances will be available at server1.example.com
and so on.
[Unit]
Description=MinIO: %i
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStop=/bin/sh -c '/usr/bin/docker ps | /usr/bin/grep %p-%i 1> /dev/null && /usr/bin/docker stop %p-%i || true'
ExecStartPre=/bin/sh -c '/usr/bin/docker ps | /usr/bin/grep %p-%i 1> /dev/null && /usr/bin/docker kill %p-%i || true'
ExecStartPre=/bin/sh -c '/usr/bin/docker ps -a | /usr/bin/grep %p-%i 1> /dev/null && /usr/bin/docker rm %p-%i || true'
ExecStartPre=/usr/bin/docker pull minio/minio:latest
ExecStart=/usr/bin/docker run --rm \
--name %p-%i \
--volume /storage/%p/%i/files:/export \
--volume /storage/%p/%i/config:/root/.minio \
--label traefik.frontend.rule=Host:%i.example.com \
--label traefik.frontend.passHostHeader=true \
minio/minio:latest
[Install]
WantedBy=multi-user.target