Skip to content

The eProsima DDS stack, in the CI image - #15

Merged
kzangeli merged 2 commits into
mainfrom
feature/dds-in-ci-image
Sep 22, 2026
Merged

kzangeli merged 2 commits into
mainfrom
feature/dds-in-ci-image

Conversation

@kzangeli

Copy link
Copy Markdown
Collaborator

The DDS stack moves into the CI image, so that coraine can carry the DDS
bridge without any image build ever compiling Fast DDS again.

Why here. Section 3 of Dockerfile.ci says the image exists because two
dependencies are packaged by no distribution and have to be compiled, and that
baking them once turns every job's setup into a pull. The eProsima stack is the
third and by far the most expensive: mongoc and libmicrohttpd are a couple of
minutes, this is eight — and until now it was paid by every build of the
coraine-dds image, every night.

A DDS base image of its own was the alternative. This file's own argument
against it: "a third environment in the middle is where environment-sensitive
bugs hide"
. One was hiding there already — the stack was built on 24.04 and
shipped into a 26.04 broker image, and tinyxml2 carries its soname in the
package name, so the runtime stage could not name a package that existed.

Verified on 26.04, which it had never been built on: 13 packages, no
changes needed. And end to end — a broker image built against this one does a
real DDS round trip with ROS 2 nodes, a talker's samples in and a PATCHed
attribute out.

What it costs: the CI image goes 1.44 GB → 1.65 GB. The broker image that
copies /opt/dds/lib out of it grows by 26 MB.

The versions are not named here. corDdsBridge/ddsenabler-pinned.repos is
the single source of truth — the relationship klib-pins has with the k-libs —
so the repos file is fetched rather than restated.

/opt/dds/{lib,include} is that stack staged for other images to copy, so a
Dockerfile that has no business knowing there are nine libraries does not have
to name all nine.

⚠ cp -a, not cp: libfastdds.so, .so.3.6 and .so.3.6.2.0 are one
16 MiB library and two links to it, and a copy that follows the links writes it
three times — which is how 21 MiB of libraries became 63 MiB of image and read
as the price of DDS.

Merges before the coraine side, which needs the tag this publishes.

🤖 Generated with Claude Code

kzangeli and others added 2 commits September 22, 2026 20:19
Section 3a, next to the two the file already says are the reason it exists.
The DDS stack is the third, and by far the most expensive: mongoc and
libmicrohttpd are a couple of minutes, this is eight - and it was being paid by
every build of the coraine-dds image, every night.

⭐ WHY HERE AND NOT IN A DDS BASE IMAGE OF ITS OWN: the reason this file gives
for ubuntu in the first place. A third environment in the middle is where
environment-sensitive bugs hide, and the one that was hiding there is concrete
- the stack was built on 24.04 and shipped into a 26.04 broker image, so
tinyxml2 carried a different soname in its package NAME on each side and the
runtime stage could not name a package that existed. One base, one toolchain.

Verified on 26.04, which it had never been built on: 13 packages, no changes
needed.

THE VERSIONS ARE NOT NAMED HERE. corDdsBridge/ddsenabler-pinned.repos is the
single source of truth for which eProsima releases the bridge is built against
- the relationship klib-pins has with the k-libs - so it is fetched rather than
restated.

/opt/dds/{lib,include} is the same stack again, staged: 25 MB of libraries and
5.6 MB of headers in an image of 1.65 GB. /usr/local is where it has to be
INSTALLED, because that is where everything compiling against eProsima looks;
but the SHIPPED broker image needs those libraries without the toolchain that
built them, and picking them back out of /usr/local means a Dockerfile that has
no business knowing there are nine of them naming all nine. So the stack says
what it consists of once, here.

⚠ cp -a, not cp. libfastdds.so, .so.3.6 and .so.3.6.2.0 are one 16 MiB library
and two links to it, and a copy that follows the links writes it three times -
which is how 21 MiB of libraries became 63 MiB of image and read as the price
of DDS.

foonathan_memory is in neither directory: it comes out STATIC here, so it is
already inside the libraries that use it, and no public Fast DDS header
includes it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…pt it

The post-publish check exists because a CACHED build may not re-run the
Dockerfile's own assert layer. That is exactly the case in which a missing
/opt/dds would reach a consumer - and the consumer is now the broker image,
which would build its broker fine and then fail on a missing
/opt/dds/include. So the check covers the DDS stack too, and prints what
it found.

And the summary told the reader to set the tag "in .github/workflows/
{ci,nightly}.yml", which is no longer all of it: docker/Dockerfile's CI_IMAGE
arg is where the DDS stack is copied from, and a tag from before this PR builds
the broker and then fails. Three places, named.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kzangeli
kzangeli merged commit f5a4eb4 into main Sep 22, 2026
1 check passed
@kzangeli
kzangeli deleted the feature/dds-in-ci-image branch September 22, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant