Run Code Anywhere: A Modern Guide to Docker


Run Code Anywhere: A Modern Guide to Docker

Imagine a world where your code runs flawlessly across any environment – from your laptop to production servers – without the dreaded "but it works on my machine" syndrome.

That's the promise of containers, and they've revolutionized how we develop, test, and deploy applications.

Containers emerged as a solution to the chaos of maintaining traditional servers, where applications would conflict with each other and overwrite data.

Using Linux namespaces, containers create isolated environments that efficiently allocate resources without interfering with neighboring processes. Which is a fancy way to say you can split CPU and memory without starving other process on the host.

This technology has evolved from virtual machines to the containerization we know today, making development more consistent and deployment more reliable, but most importantly, more resource efficient.

What's the Problem?

Back in the day (10-20 years ago), companies used to hold in-house massive servers in their basements.

These servers ran multiple applications that frequently conlicting with each other – requiring different versions of utilities, fighting over disk space and memory, and as a result sometimes overwriting each other's data.

It was a maintenance nightmare (although at the time, it was just "IT life").

Virtual Machines Changed Everything

The tech world's first attempt at solving this was virtual machines – completely isolated environments with their own operating systems.

While this worked, it was resource-intensive and inefficient.
Don't get me wrong, this technology was born in the seventies, and was the go-to approach for about three decades, but we're here to talk about modern days.

Virtual machines essentially duplicate entire operating systems, consuming significant resources.

The Container Approach: Lightweight Isolation

Containers emerged based on Linux namespaces, creating efficient isolation without the overhead.

They allow different applications to run side-by-side without conflict, sharing the same underlying system while maintaining separation.

This means you can:

  1. Run multiple applications without conflicts
  2. Ensure consistent environments from development to production
  3. Use minimal resources compared to virtual machines
  4. Package applications with all their dependencies

“With Docker, you can spin up a new container in seconds, which is significantly faster than provisioning a full virtual machine, leading to faster development cycles and improved agility.”

- The Docker documentation

Essential Container Commands

Basic Commands:

  • podman/docker ps - List running containers
  • podman/docker ps -a - List all containers (including stopped ones)
  • podman/docker images - View stored container images
  • podman/docker pull [image] - Download container images
  • podman/docker run [image] - Start a container
  • podman/docker run -it [image] sh - Start a container with interactive shell
  • podman/docker run -d [image] - Run container in detached mode
  • podman/docker run -p [host:container] - Map ports between host and container
  • podman/docker run -P - Map random ports
  • podman/docker stop [container] - Stop a running container
  • podman/docker container prune - Remove all stopped containers

Build and Management:

  • podman/docker build -t [name] . - Build a container from Dockerfile
  • podman/docker tag [id] [name] - Add a name to an existing image
  • podman/docker exec -it [container] sh - Get a shell in a running container

Compose Commands:

  • podman/docker compose up - Start multi-container environment
  • podman/docker compose down - Stop and remove multi-container environment
  • podman/docker compose logs - View logs from compose environment
  • podman/docker compose stop [service] - Stop specific service in compose
  • podman/docker compose start [service] - Start specific service in compose

Building Efficient Containers

Building containers is rather easy, and while there are tools to help with that, here's a simple Golang image:

FROM golang:alpine
WORKDIR /app
COPY . .
RUN go build
EXPOSE 8080
CMD ["./main"]

Run `docker build -f my-container.Dockerfile .` (can skip the -f

A pro tip is the multi-stage build approach.

This dramatically reduces container size by using one container to build the application and another minimal container to run it (basically implementing a CI pipeline into your container build process):

FROM golang:alpine AS builder
WORKDIR /app
COPY . .
RUN go build

FROM scratch
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]

What we did here is to build the app as usual, then take only the binary artifact into a distro-less image!

This approach reduced the container size from 340MB to just 7MB!!!


Development Workflow Enhancement

For development, mounting your local directory to the container creates a powerful workflow:

services:
app:
image: myapp
volumes:
- ./:/app
command: tail -f /dev/null

This setup lets you make code changes on your local machine and see them instantly reflected in the container, streamlining the development-test cycle.

All that's left is to `docker exec -it

Containers have transformed development workflows from frustrating environment mismatches to seamless, consistent experiences.

Whether you're a solo developer or part of a large team, mastering containers is now an essential skill that will make your code run smoothly anywhere, and makes team work, open source, or just life-long projects because infinitely easier to maintain and work on!


Thank you for reading.
Feel free to reply directly with any question or feedback.
Have a great weekend!

ESPRESSO FRIDAYS

Every once in a while I send hand picked things I've learned. Kind of like your filter to the tech internet. No spam, I promise!

Read more from ESPRESSO FRIDAYS

I Was DEFINITELY Using The Wrong VPS Setup When was the last time you thought up running something on a server? It doesn't have to be something fancy. A side project. A utility. An open source that you always wanted to run on your own but just too lazy to get it off the ground so you. I certainly have. Even when I needed a local server, my immediate thought was "sure, I can just setup and K8s cluster on my raspberry pie an put whatever I want there" 🤦 After years of advocating for complex...

Stop Using Redis. Use Open Source Instead. This issue is brought to you by: Level Up Your Security Skills With Snyk! Join security expert John Hammond for Fetch the Flag CTF - a 12-hour capture-the-flag event hosted by Snyk. Level up your security skills and compete for awesome prizes. Register now here! Redis, the cache system and in-memory DB we all love, started as a small passion project by an Italian developer name Salvatore Sanfilippo. Since it was open source and free to use, a small...

Kubernetes - Does It Live Up to the Hype? Twelve years ago, I landed my first DevOps role. I was a junior engineer, responsible for infrastructure and security at a startup (yeah, not the best call on their behalf), that would later become a unicorn. One evening, our CEO landed the first huge client, and we had 24 hours to prepare. I panicked. I spun up extra servers, scaled out load balancers, and froze every scale-down rule I could find to make sure we overkill this and that I'm not the...