Running static sites from minio
One aspect of S3-like stores that I have found useful is the ability to serve static websites. Unlike S3 and Ceph RGW, doing this in minio requires some additional tooling. This website is hosted on my minio cluster and these are the steps that I took to make that happen.
- Create the bucket in minio
-
Create a user that only has permissions to this bucket. (This isn't strictly required but, I like having a user per bucket).
-
Create a policy for the user, I give full permissions on the bucket (you can simply replace
gnuherder.how
with the name of your bucket):{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:GetBucketPolicyStatus", "s3:GetEncryptionConfiguration", "s3:GetLifecycleConfiguration", "s3:PutObject", "s3:DeleteObjectVersion", "s3:GetBucketLocation", "s3:GetBucketNotification", "s3:GetObjectVersion", "s3:GetObjectVersionTagging", "s3:ListBucket", "s3:ListBucketVersions", "s3:ReplicateObject", "s3:GetBucketObjectLockConfiguration", "s3:GetBucketPolicy", "s3:GetBucketVersioning", "s3:ListBucketMultipartUploads", "s3:DeleteObject", "s3:GetObjectRetention", "s3:GetObjectTagging", "s3:GetObjectVersionForReplication", "s3:ListMultipartUploadParts", "s3:PutObjectRetention", "s3:AbortMultipartUpload", "s3:GetBucketTagging", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::gnuherder.how", "arn:aws:s3:::gnuherder.how/*" ] } ] }
-
Create the user and assign them to the group with this policy
-
-
Install the
mc
utility - Add an alias for your minio cluster
mc alias set minio {{url to minio cluster}} {{username}} '{{password}}'
- Set the bucket policy to download to allow public downloads
mc policy set download minio/gnuherder.how
(again, replacinggnuherder.how
with the name of your bucket) - Upload the content to the bucket. I use the the aws cli to do so but, I'm not going to cover how to configure. I run
AWS_PROFILE=rgw aws --endpoint-url http://minio.tobolaski.lan:9000 s3 sync --delete public/ s3://gnuherder.how/
where theAWS_PROFILE
is the name of the profile I have configured with the minio credentials,--endpoint-url
is the host where my minio cluster is running,public/
is the source directory of the content ands3://gnuherder.how/
is the bucket to put the content into. -
Now you'll need to have a reverse proxy in order to serve the content at the public dns address, i.e. gnuherder.how. I use nginx for this, this is my configuration:
server { listen 0.0.0.0:443 http2 ssl ; listen [::0]:443 http2 ssl ; server_name gnuherder.how ; # Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx) # We use ^~ here, so that we don't check any regexes (which could # otherwise easily override this intended match accidentally). location ^~ /.well-known/acme-challenge/ { root /var/lib/acme/acme-challenge; auth_basic off; } ssl_certificate /var/lib/acme/gnuherder.how/fullchain.pem; ssl_certificate_key /var/lib/acme/gnuherder.how/key.pem; ssl_trusted_certificate /var/lib/acme/gnuherder.how/chain.pem; location / { rewrite ^/$ /index.html last; rewrite ^(.*)/$ $1/index.html last; proxy_set_header HOST object-store.net.tobolaski.com; proxy_set_header CONNECTION ''; proxy_set_header AUTHORIZATION ''; proxy_hide_header Set-Cookie; proxy_hide_header 'Access-Control-Allow-Origin'; proxy_hide_header 'Access-Control-Allow-Methods'; proxy_hide_header 'Access-Control-Allow-Headers'; proxy_hide_header x-amz-id-2; proxy_hide_header x-amz-request-id; proxy_hide_header x-amz-meta-server-side-encryption; proxy_hide_header x-amz-server-side-encryption; proxy_hide_header x-amz-bucket-region; proxy_hide_header x-amzn-requestid; proxy_ignore_headers Set-Cookie; proxy_pass https://object-store.net.tobolaski.com:9001/gnuherder.how/; } proxy_buffering off; }
The rewrite line is to handle going from url that end with
/
to/index.html
which is how the files are stored in minio. It also removes a number of cookies that minio will add to the response which are not required for people to use the site. Be sure to do annginx -t
in order to test the configuration and then asystemd reload nginx
to make the server active.One gotcha that I ran into was that nginx does not use the system's dns settings. In order to resolve a hostname to proxy to, you need to have
resolver x.x.x.x;
(wherex.x.x.x
is an ip address) set in a block. I have it set in thehttp
block as I want it to be used for everything.
Note 2023-06-12
This site is no longer a static site running out of Minio. This was the last configuration I used before switching. It will likely work for quite a while but, eventually, some configuration option will change and it will stop working.