Skip to content

Latest commit

 

History

History
101 lines (82 loc) · 4.84 KB

devcontainer.rst

File metadata and controls

101 lines (82 loc) · 4.84 KB

Development container

anyhttp is developed and tested in a devcontainer. The same image runs the CI jobs in :src:`.github/workflows/release.yml`, so a build that works in the container is the build CI does.

There are three image layers. Only the last one is built locally when you open the project:

Image Built from Contents
psedoc/cpp-devcontainer pgit/cpp-devcontainer generic C++ toolchain and libraries
psedoc/anyhttp :src:`.devcontainer/base/Dockerfile` the HTTP/2 and HTTP/3 stack anyhttp needs
(local, per checkout) :src:`.devcontainer/Dockerfile` interactive tools, shell settings, what makes this documentation

psedoc/anyhttp changes rarely and takes a while to build, so it is built once and pushed to Docker Hub. Opening the project (or a codespace) then only pulls it and adds the thin top layer.

What cpp-devcontainer provides

See its repository for details. In short: a Debian trixie image with GCC, a current clang from apt.llvm.org, CMake, Ninja, gdb, and gtest-parallel. The C++ libraries are built twice, once for each standard library, because a C++ library built against libstdc++ cannot be linked into a libc++ program or vice versa:

Prefix Standard library Libraries
/usr/local libstdc++ (GCC) Boost, GTest/GMock, fmt, spdlog
/opt/libc++ libc++ (clang) the same set

With clang, anyhttp builds against libc++ and must pick up the libraries from /opt/libc++; with GCC it uses libstdc++ and the ones in /usr/local. USE_LIBCXX in the top level :src:`CMakeLists.txt` selects which (default: on for clang), and LIBCXX_ROOT (default: /opt/libc++) where the libc++ builds are.

What anyhttp adds

:src:`.devcontainer/base/Dockerfile` adds the protocol stack. All of it is C, so a single build in /usr/local serves both standard libraries.

  • AWS-LC in /opt/boringssl, static libraries only. It is API-compatible with BoringSSL, which is what ngtcp2 calls it. It is deliberately kept out of /usr/local so it does not shadow the system OpenSSL; see "One TLS library per process" in :src:`CLAUDE.md`.
  • nghttp3 (lib only) in /usr/local.
  • ngtcp2 in /usr/local, with both crypto backends: ngtcp2_crypto_boringssl (what anyhttp links by default) and ngtcp2_crypto_ossl (with -DTLS_LIBRARY=OpenSSL). Its OpenSSL example programs are installed as osslclient and osslserver for interop tests.
  • urlparse (from ngtcp2's third-party tree).
  • nghttp2 with HTTP/3 support, built against the OpenSSL variant: the library for the HTTP/2 backend, plus nghttp, nghttpd, nghttpx and h2load for testing and benchmarking. libbpf is built first so that nghttpx can use it for QUIC connection steering.
  • curl from git master with nghttp2, ngtcp2 and nghttp3 over OpenSSL, so curl --http3 works. The apt package is removed so the tests cannot pick up an older curl.
  • libev (needed by the nghttp2 and ngtcp2 tools) and golang-cfssl (used to generate the test PKI in pki/).
  • The Debian libnghttp2-dev / libnghttp3-dev packages are removed, so CMake and pkg-config cannot find a stale system copy instead of the one in /usr/local.
  • gdb helpers for the vscode user: libc++ pretty printers and Asio's debugger extensions (backtraces across co_await), both registered in ~/.gdbinit.

The top layer, :src:`.devcontainer/Dockerfile`, adds things for interactive use: tmux, btop, valgrind, ping, persistent bash history (a volume mounted at /commandhistory), and the aliases in .devcontainer/.bash_aliases. It also has Doxygen, Sphinx and Breathe, for this documentation. :src:`.devcontainer/devcontainer.json` adds the VS Code extensions (clangd, CMake Tools, TestMate, CodeLLDB, ...), SYS_PTRACE for debuggers and sanitizers, and bind-mounts ~/.claude from the host.

Updating the images

Bump a dependency by changing its ARG ..._VERSION in the base Dockerfile, then:

cd .devcontainer/base
docker build -t psedoc/anyhttp:testing .

.devcontainer/Dockerfile builds FROM that tag, so rebuilding the devcontainer ("Dev Containers: Rebuild Container" in VS Code) picks it up. Once the tests pass in it, tag and push a numbered version and point both .devcontainer/Dockerfile and the image: entries in .github/workflows/release.yml at it. Keep the psedoc/anyhttp and psedoc/cpp-devcontainer version numbers in step, so it is clear which base a given anyhttp image was built on.