How I hosted this website online


In this post I’ll describe the steps I took to get this website hosted online. This is a follow-up post to this one which describes how I built this site from scratch using Flask.

The first thing I had to do was decide what platform to use to host my site. This includes deciding whether I would host it as a dynamic web app or as static pages. My website does not require any dynamic server responses to requests from users, so I had the choice to do it either way. I also had to choose whether or not I would be willing to pay for hosting. I looked at three different options: Google Cloud, Heroku, and GitHub Pages.

Google Cloud
With Google Cloud you can use App Engine for dynamic apps or Cloud Storage for static websites. When you create a Google Cloud account you get $300 in free credits that must be used within 90 days, after which you are charged for use of the platform. For a small site like mine I’m sure the cost would be low, but it’s not free.

Heroku
Heroku is a platform for hosting dynamic applications. It has a free tier that, unlike Google Cloud, remains free regardless of how long you use it. The catch is that your app goes into a sleep mode if it remains inactive for 30 minutes or longer and it takes a bit of time to wake-up when a user accesses it.

GitHub Pages
GitHub Pages is a platform within GitHub that you can use to host static websites directly from a repository. It’s free to use for a public repository but you need to upgrade if you want to use a private repository.

I considered these options and chose to use GitHub Pages to host my site. There was no reason really to host it as a dynamic app, and for a static website the hosting is free without any hitches like slow loading. And, being a GitHub user already made the choice even easier. If I do make some dynamic apps in the future for things like data dashboards I think I will try Heroku since the loading time is less of a concern for an individual dashboard than it is for a website.

Once I had decided to use GitHub Pages for hosting I turned my attention to producing the static pages for my site from my Flask application. Developed as is, a Flask application produces pages dynamically from the server. To produce static pages for hosting, you need to use a package called Frozen-Flask. This package turns your Flask application into a static pages generator. When the necessary code is added to your application and you run it, a “build” folder is created in your project folder and the files for your static website are generated inside it.

I referred to the code in this blog post by Kaustubh Vaghmare when adding the Frozen-Flask related code I needed to produce my static pages.

After adding the necessary code to my app, I created a new GitHub repository for hosting my site, following the steps outlined on this GitHub docs page.

Then, I ran my application in “build” mode to produce the static pages and added them to the repository.

At this point I was finally ready to see my website up live online. So I typed the URL into the browser window… drumroll…. hit enter… and… it didn’t work.


Tough Problem: Pages not being generated as html by Frozen-Flask

This was the only tough problem I encountered getting my site up and running online. When I ran my flask app in build mode to produce the static pages via frozen-flask only the index (home) page was being generated as html. All the other pages for the site were being produced without any file extensions on them. So when I visited the live site and tried to move from the home page to another page just a "Save file as" window would appear. I Googled to try and find a solution but didn't find much help on this.

Eventually however I did find this Reddit post and a comment explaining that you "need to put .html extensions at the end of your routes". There was also an edit to the comment saying that Frozen-Flask could handle adding the extensions automatically "as long as you include the trailing slash in your route".

I first tried adding trailing slashes to my routes but this ended up creating additional subfolders in my build folder with a new index page for each one. This seemed to actually work to generate the pages with extensions, but it also seemed like a kind of messy solution, so I didn't go with this method. Instead I did as originally suggested in the comment and added .html extensions to all my routes, with the exception of the home route, as shown below in the one for my "About" page.

@app.route("/about.html")
def  about():
return render_template('about.html', title='About')

This worked and all my pages were generated as html.


Below is all the code I added to my app to get Frozen-Flask to work:

# Added to imports
from flask_frozen import Freezer
import sys

# Initialize freezer
freezer = Freezer(app)

# Tell freezer about pages that use variables to produce URLs
# This code should be placed after you routes and before "if  __name__  ==  '__main__':"
# In my case I had two to add: one for my site posts and one for my references
@freezer.register_generator
def pagelist():
    for page in flatpages:
        yield url_for('post', name=page['post_name'])

    for ref in ref_dict:
        yield url_for('reference', ref_name=ref)

# Use an optional "build" command line argument to run "freezer.freeze"
if  __name__  ==  '__main__':
    if  len(sys.argv) >  1  and sys.argv[1] ==  'build':
        freezer.freeze()
    else:
        app.run(debug=True)

Once all the code needed to generate my static pages was added, and the .html extension problem was solved, I was able to run my app in build mode to generate my static pages and add them to my GitHub repository. And it worked! 🥳

The last thing to do was to add my custom domain name. This, of course, is entirely optional but I wanted to give it a try. I'm in Korea, and when I went to try and register a domain through one of the more common providers, like Google Domains, I found that Korea was not among the countries in which the service is available. So I decided to use a local Korean provider called 반값도메인/Ban-gap Domain. It was actually pretty easy, and inexpensive, to get my domain through this service and it was cheaper to use a .kr domain so that's what I chose. Finally, I followed the instructions in this blog post (Korean) to create a CNAME record with my domain provider that points to the default GitHub pages site, and the instructions on this GitHub docs page to set up my custom domain.

And that's it. Website built, and now up and running on my own custom domain! 😄

I hope you found this post helpful and thanks for reading.