This domain is 8 minutes old
hey, I'm Wojtek :)
My name is Wojtek Sychut and I do DevOps work. Among other duties, I design architectures, create Infrastructure as Code definitions and automate things.
I have registered this domain name - WojtekSychut.com - roughly 8 minutes ago. And you should be able to read this post by now.
This is a self-hosted blog, which means that I am "hosting" it by myself or - in other words - managing almost everything underneath this website in a way that makes it accessible to viewers.
The physical server is leased from a company called Hetzner and they take care of power, hardware and internet connection. I do the rest: operating system setup, configuration, various security-related tasks, updates, choosing, provisioning and configuration of software, logging, benchmarking, tuning, backups - all the usual responsibilities of a hosting provider.
This blog is not hidden behind a proxy like Cloudflare's, but I'm fairly certain that this post should be reachable even under a heavy load of connections from life- and nolife-forms.
It is not designed to withstand a big, fat DDoS attack on me or my dedicated server provider (there are limits to overkill, too) but I'll mention steps taken to ease the disaster recovery in such case.
stored in Git
This blog resides in two Git repositories. One contains Hugo (an SSG - Static Site Generator) with a 3rd party hugo-clarity theme as a submodule. The other repository is for posts only. I can edit or add a post from my smartphone, using Git client - local or web-hosted. Jenkins would get an information about the change via webhook, pull both repositories and build the site.
It would then, based on preconfigured exceptions, publish the post or show it to me as a draft and wait for the decision to go online with it. I'll get to the CI/CD workflow in a little bit.
domain DNS setup
Immediately after leasing the domain name, I ran IaC code configuring initial records. Terraform accepted the domain name as a parameter and ran IaC definition based on previously crafted template. It configured all records with two separate DNS parkings. As backup - only one providers' addresses are configured in domain's WHOIS.
no email for now
Freshly after leasing the domain name, I have no mail configured for it yet. This is already reflected in domain's configuration.
DMARC record informs other mail systems not to accept emails originating from this domain nor any of its subdomains:
1> dig txt _dmarc.wojteksychut.com +short 2"v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s;"
Empty DKIM entries were created for all key names:
1> dig txt whatever._domainkey.wojteksychut.com +short 2"v=DKIM1; p="
A "null MX" record was created
1> dig mx wojteksychut.com +short 20 .
A TXT record instructing SPF-capable mail systems not to accept messages originating from this domain:
1> dig txt wojteksychut.com +short 2"v=spf1 -all"
A single "A" record was added, pointing at web server's IPv4 address.
The pipeline is executed every time new content is pushed to the posts repository. The publishing process is fully automated if everything goes well. If some tests return errors, the pipeline would not publish the website automatically, but instead notify me asking for a manual review.
The workflow is fairly straight-forward:
initial agent environment and similar checks are run during the init stage
Git repositories with SSG and posts are cloned
posts are linted - Markdown syntax is checked with markdownlint
directory structure is prepared
in the build stage, Hugo is executed twice, preparing two versions of this website:
- public (this one)
- private, which includes drafts
Several Jenkins agents or a multi-threaded agent is used to ensure speedy simultanous build.
the pre-pub tests stage runs first batch of content checks
website files are published to separate locations in paralell during the publish stage:
in main step, files are transferred to where the site is usually available from if main version was built and doesn't require auditing
If no manual audit is required, public files land on the remote system which serves the website. The version available publicly until this build is not yet replaced with new content.
backup step copies those files to a system located with another provider to ensure the acceleration of the disaster recovery process
Backup system doesn't have a web server publicly open and the website is only exposed to certain proxy/CDN provider(s). It is done this way to ensure that threat actors attacking the website would not know the origin server's address if I decide to enable proxy-based DDoS protecion
preview env step creates a preview environment where drafts are available
Preview environment is created even when linters and some other checks fail. Email detailing stuff that needs reviewing is sent to me. In addition to email, two ChatOps methods can be quickly enabled
final pre-release tests are carried out in the post-pub stage. There are own and 3rd-party content checks carried out, TLS certificate is validated along with expiration time, offered ciphers etc. If these and other tests are super green, new version is released
OK, 8 minutes from domain registration to content availability. I did not wrote this post in minutes. A machine learning "chat bot" could create this content in no time, but I don't intend to use this tech for purposes of this blog.
T minus 10 minutes
This post was finished 10 minutes before I leased the domain name. It was residing in a Git repository and a second repository contained already configured static site generator. At this point, the post had a placeholder string everywhere the number of minutes will be. Web server had no website files yet, nor was configured to serve the website.
The domain was registered at 15:01 UTC,
At the same time, Ansible was instructed to provision website's configuration and reload nginx.
The pipeline was started as well, to build website files and propagate them on main and backup systems. Final checks would fail at this point, as domain's DNS zone is not provisioned yet.
Finally, the Terraform was executed, to provision DNS records in fresh domain's zone.
As soon as the A record was pointing at web server's IP address, a script was executed to obtain a TLS certificate from Let's Encrypt. Certificate was issued at 15:07 UTC - 6 minutes from domain registration.
1> openssl s_client -connect wojteksychut.com:443 | openssl x509 -noout -dates 2notBefore=Feb 9 14:07:51 2023 GMT 3notAfter=May 10 14:07:50 2023 GMT
The publishing pipeline was initiated again, with a dedicated variable replacing all placeholder strings with the final value: 8 minutes! (there was a placeholder here, too)
Since domain name registration, all other actions were carried out by a CI/CD pipeline, too. Automation is fun!