back to twinlog

gemserv as an 8.8MB docker container

EDIT 2020-06-23: I've switched to running a static binary as a systemd service because of CGI experiments. Gemserv compiles nicely with rust-musl-builder.

My requirements for my server setup were:

1. provisioning happens fully with a single command, given an empty Debian server

2. updating software also happens with a single command

3. uploading new content takes a ton of manual work---just kidding

Oh, and I also obviously rented the cheapest possible VPS from Hetzner, so compiling is slooooow.

Long story short, I decided I had to wrap `gemserv` in a docker container, and to make it as small as possible. (The container only contains the single static binary.)

In case anyone else has use for it, here's the Dockerfile:

---

FROM rust:buster as builder

ENV OPENSSL_VER=1.1.1g

# MUSL build: see https://gitlab.com/rust_musl_docker/image/-/blob/master/BaseDockerfile.template

ENV MUSL_PREFIX=/musl
RUN mkdir /workdir && mkdir $MUSL_PREFIX
WORKDIR /libworkdir

RUN apt-get update && \
  apt-get install -y \
  musl-dev \
  musl-tools \
  --no-install-recommends && \
  rm -rf /var/lib/apt/lists/*

RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/x86_64-linux-musl/asm && \
    ln -s /usr/include/asm-generic /usr/include/x86_64-linux-musl/asm-generic && \
    ln -s /usr/include/linux /usr/include/x86_64-linux-musl/linux

RUN curl -sL http://www.openssl.org/source/openssl-${OPENSSL_VER}.tar.gz | tar xz
RUN cd openssl-${OPENSSL_VER} && \
    CC="musl-gcc -fPIE -pie" LDFLAGS="-L/musl/lib/" CFLAGS="-I/musl/include" ./Configure no-shared no-async --prefix=$MUSL_PREFIX --openssldir=$MUSL_PREFIX/ssl linux-x86_64 && \
    make depend && make -j$(nproc) && make install

RUN rustup target add x86_64-unknown-linux-musl

ENV PATH=$MUSL_PREFIX/bin:$PATH \
    PKG_CONFIG_ALLOW_CROSS=1 \
    OPENSSL_STATIC=true \
    OPENSSL_DIR=$MUSL_PREFIX \
    SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
    SSL_CERT_DIR=/etc/ssl/certs


## gemserv build
WORKDIR /workdir
RUN git clone git://80h.dev/gemserv.git
RUN cd gemserv && cargo install --path . --target=x86_64-unknown-linux-musl


## Second stage: single-binary container
FROM scratch
COPY --from=builder /usr/local/cargo/bin/gemserv /bin/gemserv
ENTRYPOINT ["/bin/gemserv"]
CMD ["/etc/gemserv/config.toml"]