Friday 16 February 2024

Container Size Matters

I have an issue

I have 2 containers and I need them to talk, sounds easy right
But these containers only have ports for "listening" on and so cannot be setup directly to talk to one another. The normal got here is to use NetCat. I good and can you can pipe data between the to apps.

The problem comes when you want to put it into a container. NetCat requires a full OS to work so you start with a base container of some description, maybe alpine, maybe Ubuntu or my favourite of Rocky Linux. But this gives you a 100Mb image at best, or worse 500Mb.

I just not going to cut it.

The solution is easier that you think, native golang

But why golang

Golang has the ability to compile to native executable code.

take a look at this Dockerfile

FROM golang:1.20.0 as exporter
ENV GO111MODULE=on
WORKDIR /app
COPY . .
RUN go get ./
RUN CGO_ENABLED=0 GOOS=linux go build -o bin/dump1090-netcat ./

FROM scratch
COPY --from=exporter /app/bin/dump1090-netcat /usr/local/bin/
CMD ["/usr/local/bin/dump1090-netcat"]
First we start off with a full "fat" container for doing the build in
When the executable is built you need to make sure it builds with the "CGO_ENABLE=0" flag so that it will not try to link to any libs in the container. Without this the final stage wont work

The last part is "FROM scratch", this tells docker that there is no file structure nor is there a base image for here on out
Then we copy in the binary from the exporter stage and set it as the command

The resulting image is only as big as the executable but has all the functionality
In this case I pass in several environment options to the container indicating source IP and port and then the destination IP and port and it connects to the source and send to the destination.

No pipes required 
(code) (container)

No comments:

Post a Comment