Synopsis #
Docker images assume an OCI runtime and Linux kernel interfaces. OpenBSD does not provide a native Docker Engine or a base-system OCI container runtime, and a Linux container image cannot run directly as an OpenBSD process. Before migrating, identify which parts of the application depend on Linux or the container runtime.
OpenBSD packages, base-system daemons, pledge(2) , unveil(2) , filesystem chroots, and vmm(4) solve different problems. None is a drop-in Docker replacement. This guide helps choose a deployment method and identify workloads that should remain on Linux.
Identify Application Requirements #
Record the container definition and its external behavior before selecting a target:
- application source and supported operating systems;
- required Linux kernel APIs, devices, capabilities, and filesystems;
- published ports and network dependencies;
- persistent volumes and ownership expectations;
- environment variables, secrets, and generated configuration;
- health checks, startup order, and restart policy;
- image build steps and native dependencies;
- backup, restore, update, and rollback procedures;
- CPU, memory, storage, and architecture requirements.
A Compose file is an orchestration description, not a portable system specification. Image layers can contain Linux executables and libraries even when the application language itself is portable.
Select the Deployment Model #
| Requirement | Appropriate OpenBSD direction |
|---|---|
| The application has a maintained OpenBSD package | Install the package and use its package README and rc.d service |
| A base-system daemon provides the required protocol | Configure the base daemon and preserve its privilege-separated design |
| The application can be ported and maintained on OpenBSD | Build or update a port, then install the resulting package |
| The application itself supports pledge or unveil | Add restrictions in the application and test every required operation |
| A legacy process needs a restricted filesystem view | Consider a purpose-built chroot with explicit limitations |
| The workload requires Linux or an OCI runtime | Run it on a maintained Linux host or, where suitable, a Linux virtual machine |
| The workload requires unsupported devices, graphics, or virtualization features | Keep it on infrastructure that supports those requirements |
These options provide different levels of isolation and need different update and recovery procedures.
Prefer Packages and Service Accounts for Portable Applications #
Search the current package repository before rebuilding an application manually:
pkg_info -Q APPLICATION_NAME
When a package exists, install it with pkg_add(1)
, read its file under /usr/local/share/doc/pkg-readmes/, and manage a packaged daemon with rcctl(8)
. Preserve the package’s service account, directories, file ownership, login class, and startup script.
Store mutable data outside program directories, protect secrets with restrictive ownership and modes, and expose only required network addresses. This lets the application run as an OpenBSD service without recreating the container filesystem.
Managing Software: Packages and Ports and Build Third-Party Software from Ports cover package installation and local builds.
Understand Application Restrictions #
pledge(2) limits the system-call capabilities retained by a process. unveil(2) limits the filesystem paths visible to a process. Applications normally call these interfaces in their own code, and packaged software can carry maintained policy.
They do not create an OCI image, virtual network, resource namespace, writable layer, or orchestration API. Do not guess which promises or paths an application needs. When porting an application, add restrictions incrementally, test all lifecycle operations, and preserve diagnostics for denied operations.
Treat chroot as a Filesystem Tool #
chroot(2) changes a process’s apparent root directory. Several OpenBSD daemons use a chroot as one layer within a broader privilege-separated design.
A manually constructed chroot is not a complete container security boundary. It does not by itself provide a separate kernel, virtual network, resource accounting, image lifecycle, or safe orchestration. It can also require copied libraries, devices, users, configuration, and update procedures that become an additional maintenance burden.
Use a chroot only when the application’s documentation and threat model require a restricted filesystem view. Combine it with a dedicated unprivileged account, minimal files, explicit device policy, network controls, and a complete update procedure. Do not copy a Linux root filesystem into a chroot and expect its binaries to run.
Use a Linux Virtual Machine When Linux Is Required #
OpenBSD’s vmd(8)
manages virtual machines on supported amd64 hardware. Supported guests are OpenBSD and Linux systems with serial consoles. OpenBSD 8.0 supports up to 64 virtual CPUs per guest, with one CPU by default. Graphics, snapshots, hardware passthrough, and live migration are unavailable.
A Linux guest supplies the kernel needed to run Docker or another OCI runtime. The guest must be maintained as a separate operating system:
- patch and monitor both host and guest;
- restrict the guest network with PF and guest policy;
- protect virtual disk images and configuration;
- use application-consistent backups rather than assuming disk-image copying is safe;
- plan console recovery and clean shutdown;
- confirm capacity and unsupported vmm features before migration.
Create and Network Virtual Machines with vmm provides the host procedure. Use a separate Linux host or another hypervisor when the workload needs features that vmm does not provide.
Translate Common Container Features #
| Container concept | Migration question |
|---|---|
| Image | Which package, source revision, configuration, and data schema must be reproduced? |
| Volume | Which OpenBSD filesystem path owns persistent data, with which user and backup policy? |
| Published port | Which daemon address and PF rule expose the service, and to whom? |
| Environment secret | Which protected configuration or credentials mechanism owns the secret? |
| Restart policy | Which rc.d service and failure-monitoring policy manages the process? |
| Health check | Which protocol-level or process-level check proves useful service? |
| Resource limit | Which login-class or VM resource limits does the application need? |
| Compose dependency | Which explicit service dependency and recovery order must be documented? |
This translation makes hidden runtime assumptions visible. It also shows when a Linux container platform remains the simpler and safer operational choice.
Validate the Migration #
Build the target in a non-production environment and test:
- clean installation from documented inputs;
- startup after reboot without an interactive shell;
- network access from permitted and denied sources;
- secret and file permissions;
- application data backup and full restore;
- package or guest update and rollback;
- failure of each external dependency;
- log delivery, health checks, and capacity alerts;
- complete removal without deleting unrelated data.
Retain the original workload until the restored target passes functional and recovery tests. If the application depends on undocumented Linux behavior or cannot be maintained through OpenBSD packages, ports, or a supported guest, record that constraint and keep it on Linux rather than weakening the OpenBSD host.