A diminutive Docker image to relieve static web sites

A diminutive Docker image to relieve static web sites

Welcome to my private web situation.

I’m a Ruby developer with a devops background and management ride.
I even absorb a private curiosity in languages savor Crystal and Rust.
It is likely you’ll additionally accept me right here: GitHub / Twitter / LinkedIn / Electronic mail.

↞ Assist

Till now not too long ago, I passe to think that serving static web sites from Docker would be a raze of bandwith and storage. Bundling nginx or diversified more than just a few heavy runtimes inner a Docker image for the sole real cause of serving static files didn’t seem savor the most easy belief – Netlify or Github Pages can tackle this seriously better. However my pastime server used to be unhappy and cried digital tears.

A recent HackerNews post about redbean, a single-binary, trim diminutive, static file server purchased me pondering. So begins my lumber to search out the most time/storage efficient Docker image to relieve a static web situation.

After evaluating just a few static file servers with the same specs, I settled for thttpd, which comes with a the same puny footprint nonetheless seems exceptional more fight-examined.

Working thttpd goes savor this:

thttpd -D -h -p 3000 -d /static-web situation -u static-particular person -l - -M 60

This could initiating the server in foreground (-D), listening on host (-h) and port 3000 (-p), serving all files inner /static-web situation (-d) which would perhaps be accessible to static-particular person (-u). This could print to find admission to logs to STDOUT (-l -) and place of residing the Cache-Administration header to 60 seconds (-M). There are just a few more than just a few tidy formulation, savor general auth, throttling and digital hosts, which it is likely you’ll study about within the documentation.

My first attempt uses the puny alpine image, which already packages thttpd:

FROM alpine:3.13.2

# Set up thttpd
RUN apk add thttpd

# Salvage a non-root particular person to bear the files and bustle our server
RUN adduser -D static
USER static
WORKDIR /home/static

# Reproduction the static web situation
# Use the .dockerignore file to manipulate what finally ends up all via the image!
COPY . .

# Urge thttpd
CMD ["thttpd", "-D", "-h", "", "-p", "3000", "-d", "/home/static", "-u", "static", "-l", "-", "-M", "60"]

It is likely you’ll bear and bustle the image by calling:

docker bear -t static:most recent .
docker bustle -it --rm -p 3000: 3000 static:most recent

…then browse to http://localhost: 3000.

The image builds hasty and, at 7.77MB, in all equity puny:

> docker photos | grep static
static              most recent              cb1750e32562        About an hour ago    7.77MB

We are capable of crimson meat up additional by the use of Docker scratch, which is generally a no-op image, gentle as vacuum. The predicament with scratch is it is likely you’ll’t genuinely possess exceptional inner: it is likely you’ll’t produce recent customers, there could be now not this form of thing as a kit supervisor or any executable for that matter – apart from the ones you copied over yourself.

Using the scratch image generally requires a multi-stage design. We originate from alpine, obtain and assemble thttpd as a static binary, produce a particular person, then reproduction these assets over to scratch and add our static files to the mix:

FROM alpine:3.13.2 AS builder


# Set up all dependencies required for compiling thttpd
RUN apk add gcc musl-dev fabricate

# Win thttpd sources
RUN wget http://www.acme.com/instrument/thttpd/thttpd-${THTTPD_VERSION}.tar.gz 
  && tar xzf thttpd-${THTTPD_VERSION}.tar.gz 
  && mv /thttpd-${THTTPD_VERSION} /thttpd

# Bring together thttpd to a static binary which we are capable of reproduction spherical
RUN cd /thttpd 
  && ./configure 
  && fabricate CCOPT='-O2 -s -static' thttpd

# Salvage a non-root particular person to bear the files and bustle our server
RUN adduser -D static

# Switch to the scratch image
FROM scratch


# Reproduction over the actual person
COPY --from=builder /and loads others/passwd /and loads others/passwd

# Reproduction the thttpd static binary
COPY --from=builder /thttpd/thttpd /

# Use our non-root particular person
USER static
WORKDIR /home/static

# Reproduction the static web situation
# Use the .dockerignore file to manipulate what finally ends up all via the image!
COPY . .

# Urge thttpd
CMD ["/thttpd", "-D", "-h", "", "-p", "3000", "-d", "/home/static", "-u", "static", "-l", "-", "-M", "60"]

Let’s absorb one other scrutinize at those numbers:

> docker photos | grep static
static              most recent              ab0699ed2690        About a minute ago   186kB


The 186KB we’re left with correspond to the scale of the thttpd static binary and the static files that had been copied over, which in my case used to be factual one file containing the textual converse material hi there world. Expose that the alpine step of the multi-stage bear is generally pretty immense in dimension (~130MB), on the change hand it is far at probability of be reused across builds and doesn’t to find pushed to the registry.

At this level, it is likely you’ll convert the image we constructed to this point precise into a erroneous image for all of your static web sites and push it to a registry, so it is likely you’ll skip the alpine step utterly. Otherwise it is likely you’ll merely use my Docker Hub bear:

FROM lipanski/docker-static-web situation:most recent

COPY . .

This produces a single-layer image of 186KB + no matter the scale of your static web situation and nothing else. Whereas you absorb got got to configure thttpd in a more than just a few blueprint, it is likely you’ll factual override the CMD line:

FROM lipanski/docker-static-web situation:most recent

COPY . .

CMD ["/thttpd", "-D", "-h", "", "-p", "3000", "-d", "/home/static", "-u", "static", "-l", "-", "-M", "60"]

To quit, Docker can be passe efficiently to kit and relieve static web sites.

The code is on hand at https://github.com/lipanski/docker-static-web situation.

Whereas you loved my weblog post, please unfold the news:

Read More
Portion this on knowasiak.com to consult with with of us on this topicSignal in on Knowasiak.com now while you will be now not registered but.

Related Articles

What’s recent in Emacs 28.1?

By Mickey Petersen It’s that time again: there’s a new major version of Emacs and, with it, a treasure trove of new features and changes.Notable features include the formal inclusion of native compilation, a technique that will greatly speed up your Emacs experience.A critical issue surrounding the use of ligatures also fixed; without it, you…

Replace about const generics in Rust

A year has passed and we’re finally stabilizing the next feature related to const generics: ✨ feature(const_generics_defaults) ✨ With this, I am going to once again summarize the progress made here. This summary was written by @lcnr and therefore overrepresents parts I have been involved with while not giving other areas the focus they deserve.…

Windows 11 Guide

A guide on setting up your Windows 11 Desktop with all the essential Applications, Tools, and Games to make your experience with Windows 11 great! Note: You can easily convert this markdown file to a PDF in VSCode using this handy extension Markdown PDF. Getting Started Windows 11 Desktop Bypass Windows 11’s TPM, CPU and…