Skip to main content

Command Palette

Search for a command to run...

From Procrastination to Containers: My Messy Docker Journey on Windows 10

Published
7 min read
From Procrastination to Containers: My Messy Docker Journey on Windows 10

"Make sure you have Node 16, not 17. Install Python 3.9, not 3.10. Oh, and PostgreSQL needs to be version 13 with these specific extensions..."

I was getting tired of saying this every time someone new joined our team. We were building an application with a React frontend, FastAPI backend, and PostgreSQL database, and onboarding was a nightmare. Every time a new developer joined the team, we'd spend half a day getting their environment set up with the exact right versions. Dependencies broke constantly, and I'd become the unofficial "why won't this run on my machine?" support person.

I knew Docker could solve this, but every time I tried to learn it, the tutorials felt overwhelming. They assumed I knew things I didn't, or jumped straight into complex orchestration setups. So I kept putting it off, telling myself I'd figure it out when I had more time.

After the third developer couldn't get our project running because of some Python version conflict, I decided to start simple. I'd learn Docker basics with something I could actually understand – serving a basic HTML page from a container.

Why I Finally Stopped Avoiding Docker

The dependency management problems at work were getting worse, but I needed to understand Docker fundamentals before I could tackle our complex application stack. Starting with a simple HTML container seemed like the right approach – I could focus on learning the core concepts without getting lost in the specifics of React builds or database configurations.

Getting Docker Running on Windows 10

I'm on Windows 10 Pro 22H2. Getting Docker to work meant enabling Hyper-V and setting up WSL2, which required a restart. My laptop wasn't happy about it, but eventually Docker Desktop started up.

I opened Ubuntu through WSL and poked around the terminal for a bit. Everything seemed to be working, so I decided to try something simple first.

The Hello World Test

I started with the basic test everyone mentions:

docker run hello-world

It worked immediately. The container downloaded, ran, and showed me a message explaining what just happened.

Seeing Docker actually do something concrete helped. It wasn't some abstract concept anymore – it was a thing that could download and run code on my machine.

Apache: Where I Hit My First Real Problem

Next, I tried running Apache:

docker run httpd

The container started without any errors. I opened my browser and went to localhost... nothing. Just a blank page.

The container was running fine according to Docker, but I couldn't see the website. This is where I realized I didn't understand how containers actually connect to the outside world.

Learning About Ports and Container Management

I needed to figure out Docker's command-line flags. Turns out they're not optional extras – they're how you make containers actually useful.

Port mapping was the first thing I needed:

-p 8081:80

This connects port 8081 on my laptop to port 80 inside the container, where Apache runs. After adding this flag, I could finally see Apache's default page at localhost:8081.

Detached mode solved another problem:

docker run -d -p 8081:80 httpd

Without the -d flag, the container would take over my terminal. I'd have to open a new tab every time I wanted to run another command. With -d, the container runs in the background and gives me my terminal back.

Naming containers made everything easier to manage:

--name apache_container

Instead of dealing with random names like "cranky_tesla" or "boring_lovelace," I could give my container a name that made sense to me. This made stopping and starting it much simpler.

Volume Mounts: My Most Frustrating Hour

I wanted to serve my own HTML files instead of Apache's default page. This meant mounting my local folder inside the container. My first attempt didn't work:

-v $pwd:/usr/local/apache2/htdocs

Docker gave me error messages I didn't understand. After some googling and trial and error, I figured out two problems:

  1. Bash needs $(pwd) instead of $pwd

  2. There can't be spaces around the colon

The working version:

-v $(pwd):/usr/local/apache2/htdocs

When this finally worked, I could edit files on my Windows machine and see the changes immediately in the browser. That felt pretty satisfying.

Creating My First HTML File (And Messing It Up)

I tried to create a simple HTML file from the command line:

echo"<h1>Hello World</h1>" index.html

Bash threw an error because I forgot the space after echo. Fixed:

echo "<h1>Hello, this is my first Docker-served page!</h1>" > index.html

Small mistake, but it reminded me that command-line syntax matters more than I usually pay attention to.

Writing a Script to Automate Everything

I kept running the same commands: stop the container, remove it, start it again with the right flags. After doing this about ten times, I wrote a script:

#!/bin/bash
docker stop apache_container || true
docker rm apache_container || true
docker run -d -p 8081:80 --name apache_container -v $(pwd):/usr/local/apache2/htdocs httpd
echo "✅ Apache is running. Open http://localhost:8081 in your browser."

Made it executable:

chmod +x run_apache.sh

Now I could just run ./run_apache.sh and my website would be live. Much better than typing out that long docker command every time.

Debugging When Things Went Wrong

When containers didn't work (which happened more than I'd like to admit), I learned to check the logs:

docker logs apache_container

This showed me what Apache was actually doing inside the container. Instead of guessing why something wasn't working, I could see the actual error messages.

Putting Everything on GitHub

After I got the setup working reliably, I wanted to document it. Partly for other people, but mostly so I wouldn't forget how I did it.

I initialized a git repo:

cd ~/my_website
git init
git add .
git commit -m "Initial commit with website and Docker script"

Created a README that explained what each piece does:

# My Website (Apache + Docker)

## How to use this

1. Make sure Docker is installed and running
2. Run the script: `./run_apache.sh`
3. Open http://localhost:8081 in your browser

## What the flags do

- `-d` runs the container in the background
- `-p` connects your computer's port to the container's port
- `--name` lets you give the container a memorable name
- Volume mounting makes your file changes show up immediately

Then pushed it to GitHub:

git remote add origin https://github.com/yourusername/my_website.git
git branch -M main
git push -u origin main

Now anyone can clone it and have a working setup in a few seconds.

What I Actually Learned

This whole process taught me that Docker isn't as complicated as I made it out to be. The core concepts are straightforward once you get past the initial confusion about how containers work.

The main things I learned:

  • Start with something simple and build from there

  • Docker error messages are usually helpful if you actually read them

  • Document your setup while it's fresh in your mind

  • If you're running the same commands repeatedly, write a script

  • Pay attention to syntax – Docker cares about spaces, parentheses, and colons

The End Result

What started as a simple HTML exercise turned into a solid understanding of Docker fundamentals. I have a working Apache container, a script that makes restarting it easy, and documentation that explains the whole process.

This simple HTML project built the foundation for containerizing more complex work applications. Once I understood ports, volumes, and container management through this basic example, tackling our React-FastAPI-PostgreSQL stack became much more approachable. No more "works on my machine" problems or spending hours debugging someone's Python version conflicts.

Docker doesn't intimidate me anymore. When people mention containerizing applications, I actually understand what they're talking about instead of just nodding along.

The whole experience taught me that breaking down intimidating technologies into small, concrete steps makes them much more approachable. Starting with a simple HTML page was exactly what I needed to build confidence before tackling our actual work problems.