Small toy web server with a few features to test and debug several HTTP- and web-related festures. Main purpose is to test CI/CD workflows (builds, deployments, …) and tools (Docker, Kubernetes, …) and services.
- no build step
- relatively small footprint (less than 2MB in prod)
- larger dev-dependencies (typescript, eslint, prettier, >100MB), usefull to compare build sizes of dev vs prod
- CSS styles as static assets, to check proper routing/serving.
Run, then open http://localhost:8080 or open http://localhost:$PORT
.
Install node.js. Needs NODE v22.7.0 or later for experimental native support of TypeScript.
Clone this repository and run the app:
export PORT=8080
npm ci --prod
npm start
Clone this repository and run the app:
export PORT=8080
pnpm run build
npx .
export PORT=8080
npx hello-world-web
export PORT=8080
npx https://github.com/eins78/hello-world-web
Use a prebuilt image, or build one locally with Docker either directly or using buildpacks.
IMG=ghcr.io/eins78/hello-world-web:main
docker pull $IMG
IMG=hello-world-web
docker buildx build --load -t $IMG .
# or with a different base image:
docker buildx build --build-arg BASEIMAGE=node:slim --load -t $IMG .
Builds in a docker "builder" Docker container and outputs a "runner" Docker image.
- see
buildpacks.io
- images published (manually) on dockerhub: https://hub.docker.com/r/eins78/hello-world-web-buildpacks
brew install buildpacks/tap/pack
app_version="$(node -p 'require("./package.json").version')"
IMG="eins78/hello-world-web-buildpacks:${app_version}.0"
PACK_BUILDER="paketobuildpacks/builder:base"
pack build "$IMG" --builder "$PACK_BUILDER"
# to publish: docker push "$IMG"
export PORT=8080
export "APP_TITLE=Hello ${USER}@$(hostname -s)"!
docker run --rm -it -e APP_TITLE -e PORT -p $PORT:$PORT $IMG
export PORT=8080
cp .env-default .env
docker compose up --build
install systemd config and service:
curl -fsSL https://raw.githubusercontent.com/eins78/hello-world-web/main/deploy/systemd/hello-world-web.conf | sudo tee /etc/hello-world-web.conf
curl -fsSL https://raw.githubusercontent.com/eins78/hello-world-web/main/deploy/systemd/hello-world-web-docker.service | sudo tee /etc/systemd/system/hello-world-web.service
sudo systemctl daemon-reload
sudo systemctl enable hello-world-web
sudo systemctl restart hello-world-web
sudo systemctl status hello-world-web
sudo journalctl -efu hello-world-web
Install node.js, see nodesource/distributions. Debian/Ubuntu example:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && \
sudo apt-get install -y nodejs
install app code, config and systemd service:
sudo git clone https://github.com/eins78/hello-world-web.git /opt/hello-world-web
sudo cp /opt/hello-world-web/deploy/systemd/hello-world-web.conf /etc/hello-world-web.conf
sudo cp /opt/hello-world-web/deploy/systemd/hello-world-web.service /etc/systemd/system/hello-world-web.service
sudo mkdir -p /var/www/
sudo chown -R www-data /var/www /opt/hello-world-web /etc/hello-world-web.conf
sudo systemctl daemon-reload
sudo systemctl enable hello-world-web
sudo systemctl restart hello-world-web
sudo systemctl status hello-world-web
sudo journalctl -efu hello-world-web
All examples assume that port 8080
will be configured, but this port is nowhere used as a default so any misconfiguration will be spotted.
A different default port is used for every way that it can be configured,
so its easy to see from the resolved value which configuration was applied.
This table also shows the order of precendence (last wins, if applicable).
config | port |
---|---|
webserver | 9999 |
.env file |
4444 |
Dockerfile |
7777 |
docker-compose.yaml |
3333 |
PORT env var |
8080 |
There is a healthcheck script that checks if the homepage is served with a non-error status.
Note that the query parameter ?healthcheck
is used, but not handled specifically by the server,
it just helps to identifiy the healthcheck requests in logs.
-
GET https://localhost:${PORT}/api/time?healthcheck
-
Node.js script:
bin/healthcheck.mjs
-
with
docker
anddocker-compose
, seectr=hello-world-web-webserver-1 docker inspect $ctr | jq '.[0].State.Health'
pnpm i
pnpm dev
See https://direnv.net/#basic-installation.
brew install direnv || apt install direnv
echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
direnv allow .
See https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html.
- https://nodejs.org/en/learn/typescript/run-natively#running-typescript-natively
- https://nodejs.org/docs/latest/api/typescript.html#typescript-features
the following commands will run all tests like in CI (Github Actions), but locally:
pnpm run ci
The Renovate bot is configured to update dependencies and create PRs.
Non-Major updates are automatically merged after the CI checks pass.
When updating the renovate config (renovate.json5
), the branch should be prefixed with renovate/
so that the bot will validate the changes when a PR is created.