Here I show you the easiest way to start your own blog. Make sure you have a domain and a virtual server with docker behind.

We will deploy all needed software as Docker containers. Here is a code snippet that contains a specification for docker-compose:

version: '3'

services:

  traefik:
    image: traefik:v2.2
    container_name: traefik
    networks:
      - web
    command:
      
      - --log.level=DEBUG
      - --global.sendanonymoususage=false
      - --api.insecure=true
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443

      #Enable https
      - --certificatesresolvers.mychallenge.acme.httpchallenge=true
      - --certificatesresolvers.mychallenge.acme.httpchallenge.entrypoint=web
      - --certificatesresolvers.mychallenge.acme.email=your@email
      - --certificatesresolvers.mychallenge.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.mychallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory

    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./shared/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:

      # middleware redirect
      - traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)
      - traefik.http.routers.http-catchall.entrypoints=web
      - traefik.http.routers.http-catchall.middlewares=redirect-to-https

      - traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
      
      - traefik.enable=true
      - traefik.http.routers.traefik.rule=Host(`traefik.localhost`)
      - traefik.http.routers.traefik.entrypoints=websecure
      - traefik.http.services.traefik.loadbalancer.server.port=8080
      - traefik.http.routers.traefik.tls.certresolver=mychallenge
    restart: unless-stopped


  ghost:
    image: ghost:3.11
    container_name: ghost
    networks:
      - web
    environment:
      - url=https://localhost
    labels:
      - traefik.enable=true
      - traefik.http.routers.ghost.rule=Host(`localhost`)
      - traefik.http.routers.ghost.entrypoints=websecure
      - traefik.http.services.ghost.loadbalancer.server.port=2368
      - traefik.http.routers.ghost.tls.certresolver=mychallenge
    volumes:
      - ./shared/ghost:/var/lib/ghost/content


networks:
  web:

This specification is ready to run on a local Docker instance. Just paste it in a docker-compose.yaml and execute docker compose up.

This specification deploys 2 containers. The first container runs Traefik, a powerful reverse proxy, which routes traffic to a target service. You can access the Traefik dashboard at https://traefik.localhost. Ghost, a blog platform, is served by the second container. It is accessible at https://localhost.

As you might notice, the URLs contain https. When you follow the links, you browser should complain about invalid certificates and will recommend not to proceed to the websites. (Although it is completely safe to proceed in this example). Later we will learn how to generate valid certificates for your domain.

Traefik helps us to redirect our requests to the blog. You might type http://localhost as well and you would end-up at https. Besides redirection, Traefik takes care of certificate generation. Additional information on enabling HTTPS can be found here: https://docs.traefik.io/https/overview/.

The next item on the agenda is to schedule back-ups. The idea is to be able to archive the content of the blog and take the archive out of the system. The easiest way is to use existing popular version control systems such as Gitlab and Github.

An example that depicts all the discussed concepts are packed in a template, that you can download here (2 KB). The template has to be adapted to your infrastructure before use.

In this post, I showed you how to set up your own blog using available open-source tools. The setup requires a domain, a host and a git server for backups. The blog is one use-case of the Docker containerisation technology. In the upcoming posts, I will show how else you can use Docker to address some common needs.