m13253 / dns-over-https

High performance DNS over HTTPS client & server
https://developers.google.com/speed/public-dns/docs/dns-over-https
MIT License
1.99k stars 221 forks source link

Build the docker image from scratch, for a lighter docker image? #151

Closed Gontier-Julien closed 3 months ago

Gontier-Julien commented 1 year ago

It just a proposal for now, but it being working perfectly, and i run it everyday with my own docker image.

Currently the docker image is build like this:

FROM golang:alpine AS build-env

RUN apk add --no-cache git make

WORKDIR /src
ADD . /src
RUN make doh-server/doh-server

FROM alpine:latest

COPY --from=build-env /src/doh-server/doh-server /doh-server

ADD doh-server/doh-server.conf /doh-server.conf

RUN sed -i '$!N;s/"127.0.0.1:8053",\s*"\[::1\]:8053",/":8053",/;P;D' /doh-server.conf

EXPOSE 8053

ENTRYPOINT ["/doh-server"]
CMD ["-conf", "/doh-server.conf"]

My proposition. To build the final image from 'scratch':

FROM golang:alpine AS build-env

RUN apk add --no-cache git make

WORKDIR /src
ADD . /src
RUN make doh-server/doh-server

FROM scratch

COPY --from=build-env /src/doh-server/doh-server /doh-server

ADD doh-server/doh-server.conf /doh-server.conf //Comment. this can also be changed to a COPY instead of a ADD

RUN sed -i '$!N;s/"127.0.0.1:8053",\s*"\[::1\]:8053",/":8053",/;P;D' /doh-server.conf

COPY --from=build-env /etc/passwd /etc/passwd
COPY --from=build-env /etc/group /etc/group
# run as non-privileged user
USER nobody:nobody

EXPOSE 8053

ENTRYPOINT ["/doh-server"]
CMD ["-conf", "/doh-server.conf"]

Advantage:

Disadvantage:

The image could be also made smaller by adding '-s -w' to the 'ldflags' like this:

CGO_ENABLED=0 GOOS=linux go build -ldflags "-s -w"

I can make a pull request if your okay with those changes, but i just wanted to discuss it with you first ^^ I've been running my image for 9month straight with no issues on my side You can check my current docker image and GitHub for it.

Gontier-Julien commented 1 year ago

Adfditional comment on what the ldflags do:

-s    disable symbol table
-w    disable DWARF generation
Jamesits commented 1 year ago

-ldflags "-s -w"

I'm perfectly fine with this. Just make a PR and I'll be happy to merge it.

If you have strong space requirements you can even UPX the executables to trade cold start time for some (usually 50%) additional space savings (but I don't recommend doing this for everyone).

Disabling CGO

Disabling CGO is usually fine for most web applications in the wild, but this is a DNS server, and disabling CGO slightly changes how the DNS client in netgo behaves (from directly calling into the libc to mimicking the behavior in pure Go). This change has been causing unexpected problems all the time and I really don't recommend doing this.

And there will not be any libc version incompatibilities because we invented Docker to solve exactly this problem.

Starting from scratch

This is another popular thing that I don't recommend. 3 reasons:

Starting from scratch will save you at most a few megabytes, plus base image layers will be shared between images, so I personally feel it has more cons than pros.

Running as nobody

While running as non-root comes with some security defaults that makes the system slightly more secure, there are multiple problems:

There are modern ways to achieve the same security enhancements. Recommended:

Gontier-Julien commented 1 year ago

I'll make a pr now for the ldflags 👍🏻

Also other question since we at it, is the latest tag based on commit or latest stable version ?

Jamesits commented 1 year ago

Currently based on master, since the automated build is set up like 2 days ago and we don't have a tag newer than that yet. (Plus we don't have the correct GitHub workflow for a Git tag...)

Gontier-Julien commented 1 year ago

Alright so when a new version will be up the will be a tag for it then? ^^

Jamesits commented 3 months ago

I guess this can be safely closed for now.