Back to path
SmallWeekend build ~6h· 4 milestones

Containerize an app and put it behind CI

A team ships by running scripts on their laptops, and "works on my machine" is a daily phrase. You give them a reproducible image and a pipeline that proves every change before it merges.

DockerMulti-stage buildsCI pipelinesAutomated testingContainer registriesContainer health checksCost awareness

What you'll build

A lean, multi-stage Docker image and a CI pipeline that builds, tests, and publishes it on every push, red builds block merges.

See how we teach, before you sign up

You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:

src/server.jsjs
const http = require('http');

const server = http.createServer((req, res) => {
  if (req.url === '/healthz') {
    res.writeHead(200, { 'content-type': 'application/json' });
    return res.end(JSON.stringify({ status: 'ok' }));
  }
  res.writeHead(200, { 'content-type': 'text/plain' });
  res.end('hello from the container');
});

const port = process.env.PORT || 3000;
server.listen(port, () => {
  // One structured startup line so logs are greppable.
  console.log(JSON.stringify({ level: 'info', msg: 'listening', port }));
});

module.exports = server;

Reading this file

  • req.url === '/healthz'A health endpoint. Load balancers and the Docker HEALTHCHECK hit this to ask "are you alive?" before sending real traffic.
  • process.env.PORT || 3000Read the port from the environment, never hard-code it. The platform tells the container which port to use.
  • console.log(JSON.stringify(...))Log one structured JSON line, not free text. Machines can parse it, so later you can search and alert on your logs.

A minimal service with the /healthz endpoint the HEALTHCHECK and milestone 4 depend on.

That's 1 of 8 explained code blocks in this single project.

The build, milestone by milestone

  1. 1

    Write a real Dockerfile

    6 guided steps

    A bloated image with the whole build toolchain inside it is slow to pull, slow to start, and a bigger attack surface. Multi-stage builds ship only what runs.

  2. 2

    Build the CI

    6 guided steps

    CI is the contract that "main is always shippable." If tests are green and the image builds, anyone can trust the branch.

  3. 3

    Publish it

    5 guided steps

    An image only on the CI runner is gone when the job ends. Publishing to a registry makes a specific, immutable build deployable anywhere.

  4. 4

    Prove it runs healthy and costs little

    5 guided steps

    An image that builds but has no signal of "alive vs wedged" is undeployable, and a registry/CI bill that nobody has ever looked at is how a weekend project quietly becomes a recurring charge.

What's inside when you start

4 starter files, ready to clone
4 guided milestones
4 full reference solutions
8 code blocks explained line-by-line
4 "is it working?" checks
4 interview questions it prepares you for

You'll walk away with

A repo with a Dockerfile and a working CI pipeline
A published, commit-tagged image in a registry
A health-checked container that reports `healthy` via `docker ps`
A short README noting the image-size reduction, a cost note (image size, registry storage, CI minutes), and how to pull and run it

This is portfolio-grade. Build it free.

Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.

Start building