Skip to content
Bytearium

No ads or affiliate links active

Cloud & development

Docker Compose: define a stack in one file

Docker Compose describes services, networks and volumes in one YAML file and starts everything with one command. Structure, pitfalls, Minecraft example.

This entry is still below our minimum bar for the search index (length and number of sources) and is being reworked. It is therefore not listed in search engines.

Eight docker run commands in your shell history are a memory test. One Compose file is a document.

The short answer

Docker Compose is a tool for defining and running multi-container applications from a single YAML file, the Compose file [1]. You describe services, networks and volumes once, and one command creates and starts all of them [1][2]. Why use it? The file is a readable, versionable record of how your setup is built. Our assessment: for a homelab with more than one container, Compose is the first tool to learn before anything bigger.

How it works

  1. The file. The default Compose file is compose.yaml (preferred) or compose.yml in the working directory; the older names docker-compose.yaml and docker-compose.yml still work [2]. The file follows the Compose Specification [2].
  2. Services. A service is an abstract description implemented by running the same container image and configuration one or more times [2]. A web app and its database are two services.
  3. Networks. Services talk to each other over networks, which establish an IP route between containers [2]. Our assessment: inside one Compose project, services can usually reach each other by service name, so you rarely type addresses.
  4. Volumes. Services store and share persistent data in volumes [2]. This matters because a container is disposable: docker compose down removes containers and networks, but anonymous volumes are not removed by default, and they are not automatically mounted by a later up. Docker's advice is to use explicit paths as bind mounts or named volumes for data that must persist [4].
  5. Configs and secrets. The specification also has configs, mounted into containers as files, and secrets, a variant for sensitive data [2]. Our assessment: keep real passwords out of the Compose file you commit.
  6. Projects. A project is one deployment of the application. Its name groups the resources and isolates them from other installations, so the same file can run twice under different names [2].
  7. Check before you start. docker compose config merges your files, resolves variables and prints the resulting model, and --quiet only validates it [3]. docker compose down stops and removes the containers and networks of the project, and with -v it also removes named volumes declared in the file [4]. Read that option twice before you use it.
  8. Published ports. A ports entry makes a container reachable on the host. Our assessment: write 127.0.0.1:8080:80 when the service should be reachable only from the host itself, and put a reverse proxy in front for everything else.

A homelab example

The Bytearium homelab runs rack servers (HPE ProLiant DL360 Gen9 and DL380 Gen10) and a QNAP NAS, as of 14 to 18 Oct 2026. We have not recorded which containers run there, so we say nothing about that. A general example for a Minecraft Java server with the community image itzg/minecraft-server, whose documentation shows port 25565, the /data directory for persistent data and the setting EULA=TRUE [5]:

services:
  mc:
    image: itzg/minecraft-server
    ports:
      - "25565:25565"
    environment:
      EULA: "TRUE"
    volumes:
      - mc-data:/data
volumes:
  mc-data:

With EULA: "TRUE" you accept Mojang's end user licence agreement, so read it first; that decision is yours [5]. We have not pinned an image tag here and the right tag depends on your version needs (unverified). Run docker compose config --quiet, then docker compose up -d.

Checklist

  • Put the Compose file in its own folder with a clear project name.
  • Run docker compose config --quiet before every first start [3].
  • Store persistent data in named volumes or bind mounts [4].
  • Pin image tags once the setup works, instead of floating on the default.
  • Keep passwords and tokens out of the committed file.
  • Publish only the ports that need to be reachable, and bind local-only ones to 127.0.0.1.
  • Read docker compose down -v as "delete my named volumes" [4].
  • Keep a backup of the volumes, not only of the file.

Primary sources

These sources are the basis of this page. That does not mean every claim was checked individually; whether a review record exists is shown above under “Status”. The interpretation and checklist are our own work.

There is no documented review record for this version yet. The text relies on the sources listed.

How this page was made: Bytearium creates these pages with the help of AI and is responsible for publishing them. AI can be wrong, so we show our sources and review status openly.

  1. DockerDocker Compose
  2. DockerHow Compose works
  3. Dockerdocker compose config
  4. Dockerdocker compose down
  5. itzgDocker Minecraft Server, Intro

This page has no ads and no affiliate links.