close

DEV Community

genuineswe
genuineswe

Posted on

My New Developer Spent 2 Hours on Our README. Docker Fixed It in 5 Minutes.

Last month, a new developer joined our team.
I pointed them to the project README.
It had 15 steps to set up the environment.
By lunch, they were still stuck on step 4.

Their Node version was 20.
The project needed Node 16.
They had a Windows machine.
I was on a Mac.
The "Standard Setup" was a myth.


The Wrong Approach

For months, I tried to solve this with documentation.
I added more "Note:" sections to the README.
I shared my .nvmrc file.
I even wrote a setup script in Bash.

But documentation is what The Pragmatic Programmer calls Knowledge that Rots.
Every time we updated a package, the README broke.
The principle of "Don't Repeat Yourself" applies to setups too.
I was repeating the same manual fixes for every new hire.

Method Effort Result
Writing long READMEs High Quickly outdated
Custom Bash scripts Medium OS-dependent issues
Screen-sharing walkthroughs High Total time sink

The Realization

I realized that a README is just a wish list.
It hopes the developer has the right tools.
I needed to provide the actual environment.

In The Pragmatic Programmer, Hunt and Thomas call this Orthogonality — reducing hidden dependencies between components.
My application code was tied too closely to my global OS.
If I updated my system, I broke my app.
I needed a boundary.


The Correct Approach

I replaced the 15-step README with one Dockerfile.
This file defines the operating system, Node version, and dependencies.
It is the single source of truth for the environment.

First, a .dockerignore file to keep the image clean:

# .dockerignore
node_modules
dist
.git
.env
Enter fullscreen mode Exit fullscreen mode

This works like .gitignore — it prevents Docker from copying unnecessary files into your image. Without it, your 50MB project becomes a 500MB image.

Then the Dockerfile itself:

FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev", "--", "--host"]
Enter fullscreen mode Exit fullscreen mode

The --host flag is critical. Vite's dev server binds to localhost by default, which is unreachable from outside the container. Adding --host binds it to 0.0.0.0, making it accessible on your machine at localhost:5173.

For full-stack features, I used Docker Compose.
Instead of telling devs to "install Redis locally," I just added it to the config.

services:
  web:
    build: .
    ports:
      - "5173:5173"
    volumes:
      - .:/app
      - /app/node_modules
  cache:
    image: redis:alpine
Enter fullscreen mode Exit fullscreen mode

The volumes section syncs your local code to the container in real time. Edit a file in VS Code and Vite hot-reloads instantly — no rebuild needed. The second volume (/app/node_modules) prevents your local node_modules from overwriting the container's.


The Results

I asked that same new developer to try the Docker setup instead.
They ran docker compose up.
The environment was ready in minutes.

Metric Before Docker After Docker
First install 2 hours 5 minutes
Local OS pollution High (Global DBs) Zero
Environment drift Constant None

Reflection

Consistency is a feature.
We spend too much time on "Incidental Complexity" — problems we accidentally create for ourselves.
Setting up a dev environment shouldn't be a test of patience.
Docker is just a better way to communicate requirements.

John Ousterhout writes in A Philosophy of Software Design that the best way to deal with complexity is to eliminate it, not manage it.
A 15-step README manages the complexity. A Dockerfile eliminates it.

It isn't about being a DevOps expert.
It is about being a professional who values their time.
Keep your laptop clean.
Containers are the modern README.


Your Next Step

Check your project's README today.
Count how many steps are just environment setup.
Try to move the first three steps into a Dockerfile.
Run it locally and see if you can delete those lines from your documentation.

Have you replaced documentation with Docker in your workflow? I'd love to hear what worked (or didn't) in the comments below.

Top comments (0)