As my first technical post, I would like to share how I’m hosting my blog. I’ve decided to use Microsoft Azure, a technology I’m using since its initial release in 2008. In Azure, I could have used many different technologies, but I’ve decided to use Virtual Machines. I think VMs will give me more flexibility, while keeping the costs low. Since this is a personal blog, low cost is probably the most important component.
First thing I wanted to check was the estimated monthly cost for the blog. I used Azure Pricing Calculator to get the estimation and it would cost me $11.81/month to host my blog. Details below:
- VM Standard B1s (1 vcpus, 1 GiB memory): $7.59
- Standard HDD S4 32GB: $1.54
- I’m using this for both the OS disk and keep my blog content. I don’t expect needing a dedicated data disk on the short term for my blog
- Storage transactions: $0.05
- I’m assuming the suggested value by the calculator
- Static IP Address: $2.63
- The initial static IPs are cheaper than dynamic IPs
- Bandwidth: $0.00
- I’m not expecting to exceed the initial bandwidth quota
I used Ubuntu 20.04 as the OS for my VM. To create a VM, you can follow this step-by-step Quickstart: Create a Linux virtual machine in the Azure portal, just skip the web server steps, since we are going to host WordPress on it.
With the VM running, the next step was to install software to host the blog. I’m using WordPress with MySQL, both running on Docker containers.
As a good practice, update the environment running:
sudo apt-get update
Then, install Docker and Docker Compose.
Create folders to store WordPress and MySQL files, like /rgland/blog/vol/wordpress and /rgland/blog/vol/db.
Create a .env (dot env) file with environment variables for Docker Compose:
MYSQL_ROOT_PASSWORD=<Add your value here>
MYSQL_DATABASE=<Add your value here>
MYSQL_USER=<Add your value here>
MYSQL_PASSWORD=<Add your value here>
VOL_ROOT=<Add your value here>
Then, a docker-compose.yml file with the following content:
version: "3.9"
services:
db:
image: hsheth2/mysql-low-memory:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
deploy:
resources:
limits:
cpus: '0.25'
memory: 128M
environment:
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
MYSQL_DATABASE: $MYSQL_DATABASE
MYSQL_USER: $MYSQL_USER
MYSQL_PASSWORD: $MYSQL_PASSWORD
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- "80:80"
restart: always
deploy:
resources:
limits:
cpus: '0.25'
memory: 128M
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: $MYSQL_USER
WORDPRESS_DB_PASSWORD: $MYSQL_PASSWORD
WORDPRESS_DB_NAME: $MYSQL_DATABASE
volumes:
db_data:
driver: local
driver_opts:
o: bind
type: none
device: $VOL_ROOT/db
wordpress_data:
driver: local
driver_opts:
o: bind
type: none
device: $VOL_ROOT/wordpress
To test, run:
docker-compose up -d
Go the the browser and try to access your WordPress. You should see the WordPress instalation wizard.
To stop, run:
docker-compose down
In case of a VM restart or redeploy, very possible to happen in a cloud environment, we need to make sure the blog starts as the VM starts. For this, create /lib/systemd/system/rgland.service with the following content:
[Unit]
Description=rg.land blog
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/rgland/blog
ExecStart=bash /rgland/blog/start.sh # or docker-compose up -d
ExecStop=bash /rgland/blog/stop.sh # or docker-compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
Then, run to install and enable our service:
systemctl enable docker-compose-app
It’s also a good idea to disable access to SSH (port 22) in the VM Network Security Group, allowing just HTTP/HTTPS(ports 80/443).
You can find all the yml files and scripts above in GitHub.
Pingback: Cheap Static Websites Hosting – rg.land