Introduction

While browsing Twitter during my free time, I came across tweets about OrbStack. After looking at the benchmark comparisons, I decided to install it and give it a try. Indeed, the foreign developers did not disappoint!

Upon entering the OrbStack official website, the first slogan that caught my eye was: Say goodbye to slow, clunky containers and VMs.

Features

  • Native UI
  • Support for Linux VMs management
  • Support for ARM and Intel (using Rosetta translation on ARM)
  • VirtioFS file sharing
  • Complete CLI integration
  • Kubernetes integration
  • Higher network throughput
  • Support for eBPF
  • Optimized for Apple Silicon
  • Support for binding domains to containers

Architectural design:

Arch

For more information, please visit the official documentation:

Installation

brew install orbstack

Domains

This is a feature I find quite practical. OrbStack binds domains by default to Docker compose services and containers. We can visit http://orb.local to view all accessible services!

OrbStack Service list

For example, if we start an Nginx container named web in OrbStack, it will be bound to a domain called web.orb.local. OrbStack uses mDNS to resolve domain names to IPs. We can use the following command to check the IP resolution for a domain:

dns-sd -Q web.orb.local
DATE: ---Sun 17 Sep 2023---
17:33:11.494  ...STARTING...
Timestamp     A/R  Flags         IF  Name                        Type   Class  Rdata
17:33:11.495  Add  40000002      24  web.orb.local.              Addr   IN     192.168.215.2

Of course, we can also register manually. You can refer to the dns-sd help manual:

dns-sd --help
dns-sd -E                          (Enumerate recommended registration domains)
dns-sd -F                          (Enumerate recommended browsing     domains)
dns-sd -R <Name> <Type> <Domain> <Port> [<TXT>...]         (Register a service)
dns-sd -P <Name> <Type> <Domain> <Port> <Host> <IP> [<TXT>...] (Register Proxy)
dns-sd -B        <Type> <Domain>                 (Browse for service instances)
dns-sd -Z        <Type> <Domain>           (Output results in Zone File format)
dns-sd -L <Name> <Type> <Domain>        (Resolve ('lookup') a service instance)
dns-sd -Q <name> <rrtype> <rrclass>         (Generic query for any record type)
dns-sd -q <name> <rrtype> <rrclass>     (Generic query, using SuppressUnusable)
dns-sd -G v4/v6/v4v6 <hostname>          (Get address information for hostname)
dns-sd -X udp/tcp/udptcp <IntPort> <ExtPort> <TTL>           (NAT Port Mapping)
dns-sd -H                               (Print usage for complete command list)
dns-sd -V            (Get version of currently running daemon / system service)
dns-sd -O [-compress|-stdout](Dump the state of mDNSResponder to file / STDOUT)

However, mDNS has one limitation: it only works for the .local TLD. This is why OrbStack mentions in its official documentation that it only supports the local TLD!

For containers started with Docker Compose, the Docker Compose project name is used as the middle part of the domain name. As shown in the image above, for the series of services I started for outline, the domain names are as follows:

  • cockroachdb.outline.orb.local
  • outline.outline.orb.local
  • zitadel.outline.orb.local
  • minio.outline.orb.local
  • postgres.outline.orb.local
  • redis.outline.orb.local
  • nginx.outline.orb.local

Of course, in addition to the default bound domains, we can also manually specify domains by configuring the label item for a service in the docker-compose.yaml file:

services:
  nginx:
    image: nginx
    labels:
      - dev.orbstack.domains=foo.local,bar.local

With the above configuration, we can access the Nginx container by visiting foo.local and bar.local!

Conclusion

OrbStack is powerful and elegant, both in terms of UI and design philosophy. It’s said that the developer of this project is still a college student. All I can say is that effort is worthless in the face of talent…

I hope this is helpful, Happy hacking…