Friday, July 4, 2025

Changelog #1: Container Registry & Custom Domains

Mikael Knutsson
Mikael Knutsson
Jonathan Grahl
Jonathan Grahl
5 min read

A short while ago we set a goal: move our public websites to Molnett. Today, this blog post deployed through our pipeline, lives in our registry, and serves from our infrastructure.

Today we are launching the two missing pieces that made that possible: Container Registry and Custom Domains. Here's what we built and why it matters.


📦 Container Registry: See What You've Built

We needed a registry that integrated directly with our platform. We evaluated Harbor - it's an excellent, fully-featured registry with built-in UI, authentication, authorization, scanning, and replication. But here's the thing: we already have our own authentication system that handles all of Molnett, and we wanted to use it consistently across everything.

Harbor is designed to run as a standalone service. We needed something that could hook directly into our API and auth system, using repository URLs like oci.se-ume.mltt.art/PROJECT-ID/name. So we built on CNCF's Distribution directly.

Container Registry Overview

Each Project gets its own registry namespace, included and free. Push images from your CI/CD pipeline or local development - authentication works exactly like the rest of Molnett, using the same tokens and permissions you already have.

molnctl auth login && molnctl auth docker
docker buildx build . -t $(molnctl svcs image-name) --push

Full visibility into your images

With this in place, you can actually see what you've pushed. Browse your repositories, check storage usage, and remove tags and repositories you don't need anymore. We're working on automated garbage collection and retention policies that will be aware of what's actually running in your services - so you'll never accidentally delete an image that's in use.

You can explore each repository in detail - every tag, every layer, every digest. The metadata we attach to images also enables searching and filtering that wasn't possible before.

OCI Image drilldown

Multi-Platform Support Done Right

We standardize all images as OCI Image Indexes, whether you push single or multi-platform builds. This might seem like a small detail, but it solves a real problem. When you push images for different architectures (amd64, arm64, or anything else), we automatically detect the platform and organize your images accordingly.

Here's a common one: you build on your M1 MacBook, push to the registry, deploy, and... nothing works. Turns out you pushed an arm64 image to an amd64 server. By standardizing on OCI Image Indexes, we catch this at pull time with a clear error message, not as confusing logs when your container won't start.


🌐 Custom Domains: Actually Ship to Customers

You've built your service, it's running perfectly. Now you need to put it on app.yourcompany.com. This is where many platforms make things unnecessarily complex.

We chose CNAME records for subdomains and ANAME records for root domains because they let you prepare everything before you switch.

Custom Domains overview

Zero-downtime migration, built in

With A records, you switch DNS and hope for the best. Your domain points to us, but we need to verify domain ownership through your web server to get certificates. Depending on DNS propagation, you could be looking at 10-15 minutes before everything works properly.

Our approach validates ownership through DNS records instead:

  1. Enter your domain
  2. Select your target service
  3. Add the CNAME or ANAME record we provide
  4. We provision SSL certificates automatically
  5. Test everything while your production traffic still goes to your current provider
  6. Switch when you're ready

No downtime. No stressed customers. No emergency rollbacks.

Custom Domain setup

Every domain gets:

  • Free SSL certificates via Let's Encrypt
  • Automatic renewal (no more 3am pages about expired certs)
  • Real-time status monitoring
  • Clear error messages if something needs attention

How we built this:

Behind the scenes, we use Cert Manager with its webhook system. We store the validation records directly in our DNS provider (Gandi), and Cert Manager handles the Let's Encrypt domain verification through DNS. We utilize a Kubernetes operator that reconciles and tracks the progress of each custom domain, updating the status in real-time so you know exactly what's happening.

We even maintain our own Gandi cert-manager webhook. The original was archived, and we needed support for storing validation records on a different domain than where your traffic goes. So we forked it, added the features we needed, and now it supports this scenario perfectly.


What's coming next

The registry will soon get garbage collection and retention policies that understand your running services. No more manually cleaning up old images or worrying about deleting something important.

We're also building managed PostgreSQL powered by Neon. The exciting part? You'll be able to fork your entire database instantly - like branching code but for your data. Test that risky migration on real production data without touching production, and it takes seconds, not hours.

This combination of managed PostgreSQL and instant environment forking, together with the usage metering and billing system we're building, will let us open Molnett to everyone.

Thank you for being with us on this journey. If you want to follow along as we build, apply for early access below.

Apply for Early Access →