How I Built an IoT Tea Tracker with Flask, SSL, and Apache on AWS

Intro

Last week, I set out to solve a fun and simple problem: track how many cups of tea I drink with a single tap from my smartphone. While this might sound trivial, it turned into a great opportunity to learn more about hosting Flask applications, securing them with SSL, and integrating them cleanly with my existing WordPress site hosted on AWS Lightsail.

In this post, I’ll walk through how I set up a dedicated Flask microservice at iot.eedude.com, configured SSL with Let’s Encrypt, and set up an Apache reverse proxy to serve it securely.


πŸ› οΈ The Idea

I wanted to create a small API endpoint that would increment a counter every time I pressed a shortcut from my phone. The endpoint should be publicly accessible (with HTTPS), lightweight, and easily extendable for other IoT-style hacks later.


πŸ”§ Infrastructure Setup

I already had a Bitnami WordPress stack running on an AWS Lightsail instance. Rather than setting up a separate server, I:

  • Added a new A record in my domain DNS for iot.eedude.com
  • Created a new Flask app inside a folder (~/tea_tracker)
  • Installed Python3 virtualenv and Flask:
sudo apt update
sudo apt install python3-venv -y
python3 -m venv venv
source venv/bin/activate
pip install flask

🐍 Writing the Flask App

The app is dead simple. It:

  • Increments a number stored in a JSON file every time /tea is hit
  • Exposes /tea/status to check how many cups have been logged
  • Has a homepage (/) that just renders a simple HTML button

Here’s a snippet:

@app.route('/tea')
def increment_tea():
    count = load_count() + 1
    save_count(count)
    return jsonify(message="Cup of tea logged!", total_cups=count)

πŸ” Configuring Apache as a Reverse Proxy

Bitnami uses a custom Apache stack, so I created a new virtual host:

<VirtualHost *:443>
  ServerName iot.eedude.com

  SSLEngine on
  SSLCertificateFile "/opt/bitnami/apache/conf/bitnami/certs/server.crt"
  SSLCertificateKeyFile "/opt/bitnami/apache/conf/bitnami/certs/server.key"

  ProxyPreserveHost On
  ProxyPass / http://127.0.0.1:5000/
  ProxyPassReverse / http://127.0.0.1:5000/
</VirtualHost>

Don’t forget to enable vhost includes in httpd.conf:

Include conf/vhosts/*.conf

πŸ” Setting Up SSL

The Bitnami stack makes this really easy:

sudo /opt/bitnami/bncert-tool

I added both eedude.com and iot.eedude.com and Let’s Encrypt issued a valid cert for both. I confirmed it worked by running:

echo | openssl s_client -connect localhost:443 -servername iot.eedude.com | openssl x509 -noout -text | grep DNS

πŸ“± Creating a Mobile Shortcut

Using Chrome on Android, I visited https://iot.eedude.com/tea and added the page to my home screen. Now, I just tap an icon labeled “Tea Button β˜•” whenever I have a cuppa. It hits the endpoint and logs it!


βœ… Results

  • βœ… SSL-protected Flask app
  • βœ… Running under Apache on same server as WordPress
  • βœ… Instant tea-tracking from my phone

This little project helped me integrate Flask into a production environment, work with Apache VHosts, and configure domain/subdomain SSL certs.

Posted in Mini-Projects | Tagged | Leave a comment

Adventures in finding a truly minimalist blogging platform

So I’ve started a new blog.

Having ran a self-hosted wordpress blog before, I was keen to investigate more lightweight alternatives. I came across Hugo in my travels.

Hugo is an open source static site generator written in Go. What really interested me about it was its simplicity relative to something like WordPress.

I spun up an Amazon Web Services (AWS) lightsail server , ssh’d into it and installed hugo by downloading the release from https://github.com/gohugoio/hugo/releases

Then I just had to move the extracted folder to

/usr/local/bin/ 

where it was on my PATH and from there I could just run this command to make a new site

hugo new site mysite

From there it generates a folder structure that looks like this:

So if I want to make a new blog post for example, I add it to the content folder following a certain sub-folder structure

So in this post which is named my-first-hugo-post there is an index.md file which is a markdown file, and there is also an image.


+++
title = "My first post using hugo!"
date = "2024-12-08T17:32:13Z"

#
# description is optional
#
# description = "An optional description for SEO. If not provided, an automatically created summary will be used."

tags = []
+++



A truly momentous occasion. I can hardly believe it.


This is my first time experimenting with markdown so I'm hoping this will be a useful recipe that makes it easy for me to make and maintain a minimalist blog site.



Lets see where this goes.



Here is a test list: 

- Thing 1
- Thing 2



This is an image upload test:



![image-20241208172319453](image-20241208172319453.png)

There is a header section which hugo uses to add metadata about the post. Under that is the actual post text.

Once I have the index.md file and the image added to the content folder I can then run

hugo

Which will then take the markdown files and generate a set of corresponding html files in the public folder. From there I can serve these files using “hugo server” or set up a web server like apache and get it to serve the contents of that folder.

Another fantastic addition to this workflow was the markdown editor Typora

This allows me to write in markdown but to actually see how it will look in real time. I can also just copy paste in images and it will generate the markdown for me and also add the image to the same folder. Here is a screengrab from Typora:

So I set up a git repo where I could use Typora on my local windows machine to generate a blog post and then once done I could push to github.com and from there I could go onto the aws server and pull that down and run hugo to generate the html files.

This is around the time that I realised that minimalism comes at the cost of complexity in a weird way. I quickly realised that if I had to do this flow every time I wanted to write a blog post there is no way I would be bothered. I’m sure I could have automated it to make it less paunful but even then it was too involved to interest me.

And so I spun up a WordPress instance on aws which very handily had an option to auto-set up an ssl cert for me.

Sorry Hugo, I’m sticking with WordPress.

Posted in Thoughts | Tagged , , | Leave a comment