Docker images
The toolchain is also available as images on ubuntu:24.04 (glibc 2.39; the release needs 2.38+). Two flavours:
| tag | contents |
|---|---|
ghcr.io/descaldnd/oxl:1.0.0-beta, :latest (full) | the toolchain in /opt/oxl-<version> (symlinks in /usr/local/bin), clang-18 as the link driver, lld-18, the runtime libraries and their -dev packages, lldb-18 and lldb-dap-18, git, the documentation and oxl-docs |
ghcr.io/descaldnd/oxl:1.0.0-beta-slim, :slim (slim) | the toolchain without documentation, clang-18, lld-18 and the runtime libraries; no debugger, no -dev packages, no git |
Both have a user oxl (uid 1000), working directory /work, the cache OXL_HOME=/home/oxl/.oxl, a UTF-8 locale and ca-certificates. The images expose no port by default.
Run#
docker run --rm -v "$PWD:/work" ghcr.io/descaldnd/oxl oxl run .
docker run --rm -v "$PWD:/work" ghcr.io/descaldnd/oxl oxl test
docker run --rm -v "$PWD:/work" -v oxl-cache:/home/oxl/.oxl ghcr.io/descaldnd/oxl:slim oxl build -o app # a cache volume between runs
docker run --rm ghcr.io/descaldnd/oxl oxl doctor # the environment inside the containerThe files are created as uid 1000; on a Linux host whose user has another id add --user "$(id -u):$(id -g)" (then set -e OXL_HOME=/tmp/oxl).
A multi-stage build of an application#
A built program is an ordinary dynamic ELF: it needs the C++ runtime and the system libraries the program reaches (--as-needed; ldd app lists them). Build in the slim image and copy the binary into a plain ubuntu:24.04:
FROM ghcr.io/descaldnd/oxl:slim AS build
WORKDIR /work
COPY --chown=oxl:oxl . .
RUN oxl build -o /tmp/app
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y --no-install-recommends libstdc++6 liburing2 libsqlite3-0 libssl3t64 libnghttp2-14 ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /tmp/app /usr/local/bin/app
USER 1000
ENTRYPOINT ["app"]Even a hello world links liburing, libsqlite3, libssl/libcrypto, libnghttp2 and libstdc++ (checked with ldd in the image); libpq5 (with its Kerberos / LDAP dependencies) is added by programs that use PostgreSQL. The runtime packages for the libraries of the runtime are liburing2, libsqlite3-0, libpq5, libssl3t64, libnghttp2-14, libpcre2-8-0, zlib1g; install what ldd of your program shows (ca-certificates for TLS clients).
Dev container#
docker/devcontainer/devcontainer.json of the repository is a template: copy it to <project>/.devcontainer/devcontainer.json and choose "Reopen in Container" in VS Code. It uses the full image, mounts the project at /work and the volume oxl-cache for the cache, passes --cap-add=SYS_PTRACE --security-opt seccomp=unconfined and asks for the extension oxwaldlink.oxl-lang. The release archive carries the extension as share/oxl/vscode/oxl-lang-<version>.vsix; the image links it to /usr/local/share/oxl/oxl-lang.vsix. Dev containers install extensions by id, so if it is not in your Marketplace, install it once in the container terminal: code --install-extension /usr/local/share/oxl/oxl-lang.vsix.
Debugging#
oxl dap is a proxy over lldb-dap-18 (the full image). lldb needs ptrace:
docker run -it --rm -v "$PWD:/work" --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ghcr.io/descaldnd/oxl bashFor remote debugging from VS Code on the host run the adapter on a TCP port (oxl dap --listen [host:]port, see oxl dap --help) and publish the port:
docker run -it --rm -p 127.0.0.1:4711:4711 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v "$PWD:/work" \
ghcr.io/descaldnd/oxl oxl dap --listen 0.0.0.0:4711The launch configuration on the host: {"type": "oxl", "request": "launch", "name": "Container", "connect": {"host": "127.0.0.1", "port": 4711}, "program": "/work/app"} ("debugServer": 4711 is the short form); program and other paths are paths inside the container. --once makes the adapter exit after the first session. See VS Code.
A debug adapter starts programs: publish the port on 127.0.0.1 or inside a trusted network only.
io_uring, seccomp, limits#
- The runtime uses
io_uringwhen the kernel allows it. The default seccomp profile of Docker 25+ andkernel.io_uring_disabled=1|2makeio_uring_setupfail withEPERM; the runtime then falls back to its blocking thread pool (everything works, I/O is slower).oxl doctorshows it as the warningio-uring; allow it with--security-opt seccomp=unconfinedor a profile that permitsio_uring_setup,io_uring_enterandio_uring_register. - The runtime starts one worker per CPU the process may use; it does not read the CFS quota of
--cpus. On a large host with--cpus=2use--cpuset-cpus=0-1or-e OXL_WORKERS=2(oxl doctor:cpu-quota). - Compiling needs 1-2 GiB of memory: do not run the container with
-mbelow1g(oxl doctor:memory-limit). vm.max_map_countis a setting of the host kernel; every task stack uses two mappings (oxl doctor:max-map-count).
Build the images yourself#
The images are built from the release archive; nothing is downloaded:
scripts/package_release.sh 1.0.0-beta # dist/oxl-1.0.0-beta-linux-x86_64.tar.xz (--no-docs --no-pdf --no-vsix: quick)
scripts/docker_build.sh dist/oxl-1.0.0-beta-linux-x86_64.tar.xz --tag-prefix ghcr.io/descaldnd/oxlThe script builds both targets of docker/Dockerfile, runs scripts/docker_test.sh (oxl --version, oxl doctor, oxl new and oxl test, a built program, a sqlite program and a service that link, lldb-dap and the oxl dap handshake) in each image and prints the sizes. Nothing is pushed.