@openinc/dhi-bootstrap
v1.0.6
Published
Route setup and privilege dropping bootstrap for Docker Hardened Images (dhi.io)
Downloads
460
Keywords
Readme
dhi-bootstrap
Route setup and privilege dropping bootstrap for Docker Hardened Images (dhi.io)
Why this is needed
Docker Hardened Images (dhi.io) are stripped-down base images designed to run applications as a non-root user. This is good for security, but it creates a problem: some container-startup tasks — like adding a network route to reach an internal VPN or private subnet — require root privileges and must happen before the application starts.
The standard workaround is to run the whole container as root, which defeats the purpose of a hardened image. dhi-bootstrap solves this by acting as a minimal init process that:
- Starts as root (via
USER rootor the default container user) - Performs the privileged setup (route configuration via
NET_ADMIN) - Immediately drops to an unprivileged user
- Hands off to your application
The result is that your application process never runs as root, and the attack surface of the privileged phase is kept as small as possible.
What it does
dhi-bootstrap is a lightweight init process for Docker containers that runs as root, optionally configures network routes, drops privileges to an unprivileged user, then exec's your application. It ships as both a CLI tool and a programmatic Node.js API.
Docker usage
Use the published image as a base and set dhi-bootstrap as the entrypoint:
FROM openinc/dhi-bootstrap AS bootstrap
FROM node:24-alpine
COPY --from=bootstrap /app/bootstrap.mjs /usr/local/bin/dhi-bootstrap
ENTRYPOINT ["node", "/usr/local/bin/dhi-bootstrap"]
CMD ["node", "server.js"]Or reference it directly in a docker-compose.yml:
services:
app:
image: my-app
entrypoint: ["node", "/usr/local/bin/dhi-bootstrap", "node", "server.js"]
environment:
ROUTE_DESTINATION: 10.0.0.0/8
ROUTE_GATEWAY: 172.17.0.1
DROP_TO_USER: node
cap_add:
- NET_ADMINEnvironment variables
| Variable | Default | Description |
|---|---|---|
| ROUTE_DESTINATION | — | Destination network (e.g. 10.0.0.0/8). Route setup is skipped if unset. |
| ROUTE_GATEWAY | — | Gateway IP for the route (e.g. 172.17.0.1). Route setup is skipped if unset. |
| DROP_TO_USER | node | Unix user/group to drop privileges to before spawning the child process. |
CLI
dhi-bootstrap <command> [args...]The bootstrap process:
- Adds the configured route via
/sbin/ip route replace(requiresNET_ADMINcapability) - Drops process uid/gid to
DROP_TO_USER - Spawns
<command>and forwardsSIGTERM/SIGINTto it
Programmatic API
import { setupRoute, dropPrivileges } from "@openinc/dhi-bootstrap";
setupRoute({ destination: "10.0.0.0/8", gateway: "172.17.0.1" });
dropPrivileges("node");setupRoute(options?)
Configures a network route. Falls back to ROUTE_DESTINATION / ROUTE_GATEWAY env vars if options are omitted. Exits the process if the ip route command fails.
dropPrivileges(user?)
Calls process.setgid and process.setuid to drop to the given user. Falls back to DROP_TO_USER env var, then "node". Logs a warning (but does not exit) if the call fails.
