A journey static assets web server: Part 2

Few weeks ago, I was write about A journey static assets web server: Part 1 and this is second post about the journey

Honestly I have been running my old school CDN (Content Delivery Network) since December 2021 (Sometimes so lazy to write it down :)) ). Few weeks back when I was feel to write some post here, I was discovered checked my server and it’s look so weird because the RAM usage always show ~750MB++ that’s so costly usage while my server only had 1GB RAM.

I don’t take seriously before but since it’s make me bizarre then combine with my vision it’s keep simple stup*** as fu** so no need for metrics analytics (read: no cool observability there) or deep analysis with eBPF things :)) only trust htop ROFL.


Because I remembered that the majority of my server consists of containers, so the next was checked with docker stats (Yes, another simple htop (again)).

CONTAINER ID   NAME                            CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O        PIDS
692e51e216b2   cedeen_webz_1                   0.01%     185.5MiB / 969.4MiB   18.10%    1.57kB / 0B      38.2MB / 0B      43

Yes, my old static assets server takes ~180MiB of memory and sometimes it’s almost 200MiB so I was thinking about replace that.

Deep Surf (again)

When I was surfing and reading a few blogs from Hacker News or lobste.rs , I found that there are blogs it’s same theme like my blog (using etch theme). Then digging in found some blogs like monotux.tech and echorand.me after reading some posts, found that monotux.tech - Flying with this blog was using Dockerfile with sws (sounds like Rust things again).

Enter sws

Okay, it’s time to read what’s static web server (sws). It’s similiar to typical static site server and is written with Rust, for more features and documentation can read directly in here .

I have no idea, so I just went ahead and tried it out. Here is a snippet of my sws configuration:

host = "::"
port = 8787
root = "./public"
log-level = "info"
# cache-control-headers = true
compression = true
page404 = "./public/404.html"
page50x = "./public/50x.html"
# Lets nginx handle it
#security-headers = true

# #### CORS
# cors-allow-origins = ""
# cors-allow-headers = ""

#### Grace period after a graceful shutdown
grace-period = 3
log-remote-address = true

#### Redirect to trailing slash in the requested directory uri
redirect-trailing-slash = false

#### Check for existing pre-compressed files
compression-static = true

Below is another example of my docker-compose.yaml for running it.

version: "3"
    image: joseluisq/static-web-server:2.14.2-alpine
    hostname: cdn-sws
    restart: always
    read_only: true
    mem_limit: 64m
      - ./config.toml:/etc/config.toml
      - <your directory mount>
      - 8787:8787
      - SERVER_CONFIG_FILE=/etc/config.toml

Afterwards, I attempted to inspect the memory usage of SWS without any fancy observability tools by using docker stats.

CONTAINER ID   NAME                            CPU %     MEM USAGE / LIMIT   MEM %     NET I/O           BLOCK I/O         PIDS
b9ee396d14da   cedeen-v2-sws_cdn-sws_1         0.01%     14.55MiB / 64MiB    22.73%    3.88kB / 90.8kB   7.64MB / 0B       59

Well done! It only consumes around~14MiB of memory and has been pretty stable and cool so far.

Closing thoughts

So the conclusion so far for my DIY CDN (not really distributed) is using sws as the final journey (not really meh) to serving my static content. and looking forward trying to serve large or high-quality images in my next tinkering, as well as serving some .md and .txt files. But i want to leave my TODO’s like:

Thank You!