github rss
Host a static website on Backblaze B2
Dec 12, 2017

Backblaze B2 doesn’t currently have a way of hosting a static website on it, and as I use it for other things I figured I could try to host this blog on it.

To accomplish this I am using the following technologies (although you could use other technologies to acheive the same result):

  • Minio, an object storage server that has an Amazon S3 compatible API, and can act as a gateway for other object storage services such as B2.
  • Caddy, a golang based webserver which has automatic HTTPS

Now assuming both of those are installed, let’s get started.

First you’ll need to give minio your B2 keys, and run the gateway. As minio runs in the foreground, if you CTRL-C out of the minio command below, or close the terminal then the command will exit. Replace the access key and secret key with the ones that Backblaze gives you.

export MINIO_ACCESS_KEY=0123
export MINIO_SECRET_KEY=abcd1234
minio gateway b2

As the gateway is now running you’ll need to open up a new terminal window and run the following. In the first line you’ll need to substitute the REPLACE_WITH_* wariables with their appropriate content that is found in the Backblaze control panel. The second and third command you’ll need to replace site-example-com with the name of the bucket you want, it can be anything (alphanumeric, and also dashes) but has to be unique within the entire B2 platform, so I recommend using the domain you’ll be hosting at, but switch all the .s to -s.

mc config host add myb2 http://127.0.0.1:9000 REPLACE_WITH_MINIO_ACCESS_KEY REPLACE_WITH_MINIO_SECRET_KEY
mc mb myb2/site-example-com
mc policy download myb2/site-example-com

Now that minio is up and running it is time to get started on configuring Caddy.As Caddy has automatic HTTPS, the first part of my Caddyfile is to set up a redirect so all of your traffic will we served as HTTPS. In the below Caddyfile snippets you’ll need to replace site.example.com with your domain name, and site-example-com with the name of your B2 bucket created above.

http://site.example.com {
	redir https://site.example.com{uri}
}

The second part of the caddy file will have the webserver logic for interacting with the bucket, and serving it to the public. The first section of this config is to rewrite the request so that it will serve an index.html file if just the directory is requested, and if the directory doesn’t have an index.html file then the default 404.html file will be served. The next section is another rewrite, and it says that if the path doesn’t exist then serve the default 404 file. Once all the URL rewriting is done the requests will need to be proxied to Minio. Last, we tell Caddy to drop the two headers from Minio that could leak data.

https://site.example.com {
	rewrite / {
		r (.*\/$)
		to {1}index.html /404.html
	}
	rewrite {
		to {path} /404.html
	}
	proxy / 127.0.0.1:9000/site-example-com {
		transparent
	}
	header / -Server
	header / -X-Amz-Request-Id
}

A note about the above config, you’ll need to have a 404.html file in the root of your B2 bucket so that a custom 404 page can be served, otherwise it’llbe the default Caddy 404 page. Also, because the 404.html file is a sucess in being able to serve it, Caddy will serve this as a sucessful HTTP 200 which means that browsers and search engine crawlers won’t know that the page is a 404. If this is not suitable for you then you can store your custom 404 page along side your Caddyfile and change the configuration to use that instead, so that Caddy will serve the correct headers.

Start up Caddy with caddy -conf /path/to/Caddyfile, and it’ll fetch certs for you and run serve your blog.

I use docker to have these services run in the background, however I will leave this as an exercise for the reader.


Back to posts