Why bother
A single run command is fine for one container. But a real project is at least an application and a database, often with a cache and helper services besides.
Starting them one by one, remembering every flag and the right order, is tiresome. A description file solves it: all services in one place, one command to start.
A side benefit: that file is a ready set of instructions. Anyone opening your repository sees the architecture immediately.
A minimal file
A service description file at the project root:
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: notes
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
app:
build: .
depends_on:
- db
environment:
DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/notes
ports:
- "8000:8000"
volumes:
pgdata:
What matters here
Addressing by service name. The application connects to the database at "db", not at a numeric address. Inside the shared network, containers find each other by name — the least obvious thing for beginners.
Persistent storage. The volumes section exists so the database survives the container being recreated. Without it everything vanishes on shutdown — a classic loss of practice data.
Passwords from the environment. Values come from a variables file that doesn't enter the repository. No passwords belong in the description itself.
Startup dependency. Declaring that the app starts after the database. A caveat: this guarantees start order, not that the database is ready to accept connections. Fine for a learning project; production needs a readiness check.
Commands
Start everything:
docker compose up
In the background:
docker compose up -d
Rebuild the application image:
docker compose up --build
Watch the logs:
docker compose logs -f app
Stop:
docker compose down
Stop and delete the data:
docker compose down -v
That last command wipes storage. Handy when you want a clean database, dangerous when you don't.
Common mistakes
A password in the description file. The file is in the repository, so the password is exposed.
Forgetting persistent storage. Restart and the data is gone.
Port already in use. If a database is already installed on the machine, the standard port is taken. Expose a different one externally.
The app can't see the database. Almost always because the connection string names a local address instead of the service name.
What it adds to a portfolio
A project that starts with one command is a pleasure to open. It shows you thought about more than the code — you thought about how it gets used.
And in team work such a file saves hours: a new participant doesn't lose a day to environment setup but starts everything with one command and gets to work.
Хватит читать — пора делать
На CohortX можно найти команду под пет-проект и получить тот самый опыт, о котором спрашивают на собеседовании.
Похожие статьи
- Поднять базу и приложение вместе: знакомство с ComposeКак описать несколько служб одним файлом, запустить всё одной командой и не хранить пароли в коде.
- Docker for beginners: what it's forWhat a container is in plain terms, which problem it solves, the first commands, and a minimal build file.
- Docker для начинающих: зачем он нуженЧто такое контейнер простыми словами, какую проблему решает, первые команды и минимальный файл описания.