Skip to content
The 31 guidesFREN中文
Guides
Part 2 · guide 6 of 6 Level: Intermediate Reading time: 16 min Platforms: Linux

Docker: isolate your projects

Every project in its own watertight bubble. Docker keeps your projects from stepping on each other, contains the damage when the agent experiments, and makes your deployments reproducible. For beginners and experts alike.

In this guide
  1. 01Why it changes your life (especially with an agent)
  2. 02Installing Docker
  3. 03Level 1, run something existing (beginner)
  4. 04Level 2, a mini-project with several services (Docker Compose)
  5. 05Level 3, packaging YOUR project (the Dockerfile)
  6. 06Expert level, hardening the isolation
  7. 07Frequently asked questions

In short

Docker puts each project in a container, a lightweight box that carries its own version of Node or Python and its dependencies: projects stop stepping on each other, deploy identically and contain the damage when an agent experiments. Install it with the official script (curl -fsSL https://get.docker.com | sudo sh), run ready-made images with docker run, describe a multi-service project in a compose.yml, then package your own code with a Dockerfile. For an exposed service, harden it: non-root user, capped resources, only the ports you really need published.

Do this first: Git, GitHub & backups

You’re going to run several projects on this machine. One is stuck on Node 20, another wants Node 24. This one needs an old version of a library, that one the latest. Installed “loosely” on the system, they end up stepping on each other, and you hit the classic: “but it worked before.” Docker fixes this once and for all: every project lives in its own watertight bubble.

Why it changes your life (especially with an agent)

Three reasons, and the third is underrated:

  • No more version conflicts. Each project carries its exact environment. Node 20 here, Node 24 there, no interference. You no longer install anything “globally” that risks breaking another project.
  • Reproducible deployments. The container that runs on your machine is identical to the one that’ll run online. “It works on my machine” disappears: your machine is the container. It hugely simplifies going live (see Cloudflare Tunnel).
  • The damage stays in the box. This is the key point for anyone working with an agent. An agent that experiments, a sketchy dependency, a script that goes off the rails: locked inside a container, they can’t wreck the whole machine. It’s the level of isolation above the “project folder”, a real sandbox per project (tie this back to Securing access).

Installing Docker

# The official method, in one command
curl -fsSL https://get.docker.com | sudo sh
# Allow your user to drive Docker without sudo (log out/in afterward)
sudo usermod -aG docker $USER

Check: docker run hello-world should download a tiny image and print a welcome message. If you see it, you’re ready.

Level 1, run something existing (beginner)

The best thing about Docker at the start is that you benefit from other people’s work. Tens of thousands of applications are already “boxed up,” ready to launch. Need a PostgreSQL database for a project? No laborious installation:

# Launch an isolated PostgreSQL database, in one line
docker run -d --name ma-db -e POSTGRES_PASSWORD=secret -p 5432:5432 postgres:16
docker ps              # see what's running
docker logs ma-db      # see the logs
docker stop ma-db      # stop it (docker start ma-db to restart)
docker rm ma-db        # delete the container (the box vanishes cleanly)

Level 2, a mini-project with several services (Docker Compose)

Most projects are several pieces: an app + a database, for example. Docker Compose describes all of that in a single compose.yml file, and launches the whole thing with one command.

# compose.yml, a small web app + its database, isolated together
services:
  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - db-data:/var/lib/postgresql/data   # the data survives restarts
volumes:
  db-data:
docker compose up -d      # everything starts, in the background
docker compose logs -f    # follow what's happening
docker compose down       # stop everything and clean up

Level 3, packaging YOUR project (the Dockerfile)

To box up your own code, you write a Dockerfile: the recipe that says how to build your project’s image.

# Dockerfile, the recipe for your box
# (a Docker comment sits on its own line: a # at the end of a line would be read as an argument)
# Start from an official, lightweight Node image
FROM node:24-slim
WORKDIR /app
COPY package*.json ./
# Install the dependencies INSIDE the box
RUN npm ci
COPY . .
EXPOSE 8080
# The command that starts the app
CMD ["node", "server.js"]
docker build -t mon-app .   # build the image from the Dockerfile
docker run -d -p 8080:8080 mon-app

From now on, your project and its environment are one. You can run it on any machine that has Docker, identically.

Expert level, hardening the isolation

The container already isolates a lot, but by default it doesn’t stop where it could. When you host an exposed service, or you confine an agent, tighten the bolts:

  • Don’t run as root inside the container: add an unprivileged user (USER node) in your Dockerfile. If someone escapes the app, they aren’t root.
  • Read-only filesystem: docker run --read-only stops the container from writing where it shouldn’t.
  • Limit resources: --memory=512m --cpus=1 stops a runaway container from choking the whole machine.
  • Reduce privileges: --cap-drop=ALL removes useless Linux capabilities; you only add back what you need.
  • Isolate the network: only publish (-p) the ports that are actually needed; the rest stays invisible. And what you publish to the outside goes through Cloudflare Tunnel or stays on Tailscale, never in the clear on the Internet.

Frequently asked questions

What is the difference between a Docker container and a virtual machine?

A container is much lighter: it shares the host's Linux kernel instead of shipping its own, so you can run ten side by side without them getting in each other's way. The trade-off is weaker isolation. To confine truly risky code, a virtual machine, which no longer shares the host's kernel, offers the strongest separation.

How do you use Docker without typing sudo for every command?

Add your user to the docker group with sudo usermod -aG docker $USER, then log out and back in. The command docker run hello-world should then download a tiny image and print a welcome message: that means everything is ready.

Does Docker fully protect the machine from an AI agent?

It greatly reduces what can break: an experimenting agent or a runaway script stays locked inside the container. But a container shares the host's kernel and is not an escape-proof prison. For an agent running unsupervised, run the Docker daemon rootless with non-root containers, or even put everything inside virtual machines.

What are Portainer and Dokploy for?

Portainer is a web dashboard for Docker: you see all your containers, their logs and resource use, and start, stop or redeploy them in two clicks. Dokploy goes further: it is a self-hosted deployment platform that builds and publishes your projects from a Git repository, with domains and certificates. It is best to learn the basics on the command line first.

Does a Docker database keep its data across restarts?

Yes, if you give it a volume. In a compose.yml, a named volume linked to PostgreSQL's data folder keeps the data from one restart to the next. Without a volume, a deleted container disappears without a trace.

Terms in this guide: DockerContainerAgentLinux

Spotted a mistake?

A command stopped working, a price changed?

Tools change every month. Tell me what is wrong in this chapter and I will fix it and update its date.

Only the page, your message and the optional contact are kept. Nothing else.

Guide 14 of 31 · part 2 no guides read yet Open the list of guides