If anyone is interested in running basic-webserver in a docker container. I've managed to get the following working using my apple silicon machine. I'm definitely no docker expert, but fumbled through some guides to get this working.
Sharing as other may find this useful, or have suggestions on how I could improve this.
# Dockerfile
# Builder state using the roclang/nightly-ubuntu-latest image
FROM roclang/nightly-debian-bookworm as builder
# Copy the source code
COPY ./main.roc /src/main.roc
# Build the roc app
RUN ["roc", "build", "/src/main.roc"]
# Check if the binary is present
RUN ["ls", "/src/main"]
# Use a smaller image for running the app
FROM bitnami/minideb:bookworm as final
# Copy the binary from the builder container
COPY --from=builder /src/main .
# Run the app binary
CMD ["./main"]
#!/bin/bash
# This script is used to build and run the server locally using Docker for
# testing purposes prior to pushing to a Container Registry
# Load environment variables from the .env file
set -a
source .env
set +a
# Read the version from the command line argument or default to "dev"
version="${1:-dev}"
# Build docker image for deployment
docker buildx build \
--build-arg VERSION="$version" \
-f Dockerfile \
--platform linux/amd64 \
--tag "server:$version" .
# Run the docker image to test locally
docker run \
--rm \
--platform linux/amd64 \
-p 9090:9090 \
--env ROC_BASIC_WEBSERVER_HOST=0.0.0.0 \
--env ROC_BASIC_WEBSERVER_PORT=9090 \
server:$version
The final container size is 128MB
, while the binary is only 7MB
. I'd love to get that smaller if possible, but the bitnami/minideb:bookworm
is the smallest container I've found that works. From my investigation I think we need glibc and so can't use the alpine containers which are built with musl.
I think in the base roclang containers, we could do something like the following (i.e., adding the last 2 lines for cleanup):
...
RUN apt-get update && \
apt-get install -y package1 package2 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
I've used this simple trick before and it has been effective in my use-cases.
Would it be possible for roc to build a static binary? Then the second/final docker stage could be FROM scratch
and would contain nothing else.
I think this is possible, though I'm not sure how practical for basic-webserver. Needs investigation to see what system libraries may be required. I hope we could know this at compile time.
I'd be interested to know if @Folkert de Vries has thought about these ideas for nea?
for nea I think this should be fine. libc should be available and just behave the same, there should be no other dependencies at runtime
In general I think databases are usually loaded as dynamic libraries? though in the rust ecosystem, maybe not and you can compile them in statically?
I haven't had a look in detail, but ziglibc might be potentially of interest:
on linux musl should do roughly the same thing. but I'm not sure that really matters, but if it does we have options
Last updated: Jul 06 2025 at 12:14 UTC