Catalypt LogoCatalypt.ai

Industry Focus

Developer Options

Resources

Back to Blog

AI Built a Docker Image That Was Larger Than My Hard Drive

March 18, 2024 Josh Butler DevOps

"Just containerize the app," they said. "Docker makes everything easier," they said. Then AI created a Dockerfile that tried to download the entire internet, and my laptop filed a restraining order against me.

This is the story of how a simple web app became a 47GB monster that included a full Ubuntu desktop environment "just in case we need to debug with GUI tools."

The Innocent Beginning

Me: "Create a Dockerfile for a Node.js Express app"

AI: "I'll create a production-ready, fully-featured container!'

# AI's Dockerfile
FROM ubuntu:latest

# "Let's install everything for maximum compatibility"
RUN apt-get update && apt-get install -y     nodejs     npm     python3     python3-pip     ruby     golang     rust     java-11-jdk     php     perl     r-base     postgresql     mysql-server     mongodb     redis     nginx     apache2     docker.io     kubernetes     terraform     ansible     git     vim     emacs     vscode     chromium-browser     firefox     libreoffice     gimp     vlc     steam     && rm -rf /var/lib/apt/lists/*

# Just a Node.js app btw

The Layer Cake of Doom

# AI creating a new layer for everything
FROM node:18

# Layer 1: Copy package.json
COPY package.json .

# Layer 2: Copy package-lock.json
COPY package-lock.json .

# Layer 3: Copy .npmrc
COPY .npmrc .

# Layer 4: Copy each dependency individually
COPY node_modules/express node_modules/express
COPY node_modules/react node_modules/react
# ... 847 more COPY commands ...

# Layer 851: Copy source files one by one
COPY src/index.js src/index.js
COPY src/app.js src/app.js
# ... 200 more files ...

# Final image: 1,052 layers
# Docker: "I'm tired, boss'

The Multi-Stage Disaster

# AI heard multi-stage builds are good
FROM node:18 AS base
FROM python:3.9 AS python-deps
FROM golang:1.19 AS go-deps
FROM rust:latest AS rust-deps
FROM maven:3.8 AS java-deps

# Stage 2: Combine everything
FROM ubuntu:latest AS builder
COPY --from=base / /node
COPY --from=python-deps / /python
COPY --from=go-deps / /go
COPY --from=rust-deps / /rust
COPY --from=java-deps / /java

# Stage 3: The "slim" production image
FROM ubuntu:latest
COPY --from=builder / /
# Congrats, you now have 5 operating systems in one container

Real AI Docker Disasters

The Secret Exposer

# AI's helpful environment setup
ENV DATABASE_URL=postgresql://admin:[email protected]/maindb
ENV API_KEY=sk-1234567890abcdef
ENV AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCY
ENV CREDIT_CARD_ENCRYPTION_KEY=ThisIsNotSecureAtAll

# "I've set up all your environment variables!"
# Now they're in the image layers forever

The Recursive Docker

FROM docker:dind

# Install Docker inside Docker
RUN apk add --no-cache docker docker-compose

# Install Kubernetes
RUN curl -LO https://dl.k8s.io/release/v1.26.0/bin/linux/amd64/kubectl

# Install Docker inside the Docker that's inside Docker
RUN docker run -d --name inner-docker docker:dind

# "For maximum containerization"

The Permission Nightmare

# AI's solution to permission issues
USER root
RUN chmod -R 777 /
RUN chown -R nobody:nogroup /
USER nobody
USER root  # Changed its mind
RUN chmod -R 000 /important-files  # "For security"
USER www-data
RUN su root  # This doesn't work in Dockerfile
USER 0  # Just use root by ID
RUN echo "ALL ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

# Security level: Yes

The Build Optimization

# AI optimizing build time
# "I'll download dependencies in parallel!"

RUN npm install &     pip install -r requirements.txt &     go mod download &     cargo build &     mvn install &     wait

# Guess what happens when they all try to write to disk simultaneously?
# Corruption. Corruption happens.

The Volume Mount Madness

# AI's docker-compose.yml
version: '3.8'
services:
  app:
    volumes:
      - ./src:/app/src
      - ./node_modules:/app/node_modules
      - /:/host-root  # "For debugging"
      - /var/run/docker.sock:/var/run/docker.sock
      - ~/.ssh:/root/.ssh  # "For git"
      - ~/.aws:/root/.aws  # "For AWS"
      - /etc/passwd:/etc/passwd  # "For user mapping"
      - C:WindowsSystem32:/windows  # "Cross-platform support"
    
    # Congratulations, the container owns your computer now

The Health Check Horror

# AI's comprehensive health check
HEALTHCHECK --interval=1s --timeout=30s --start-period=0s --retries=1000   CMD curl -f http://localhost:3000/health ||       wget -q --spider http://localhost:3000/health ||       nc -z localhost 3000 ||       telnet localhost 3000 ||       ping -c 1 localhost ||       ps aux | grep node ||       echo "I'm probably fine" ||       exit 1

# Checks every second
# Docker spends more time checking health than running the app

The .dockerignore Ignorance

# AI's .dockerignore
*
!*
*.log
!*.log
node_modules
!node_modules/important-module
**/*
!**/*
.git
!.git/hooks  # "Might need these"
*.tmp
!*.tmp.important

# Schrodinger's dockerignore: everything is both ignored and not ignored

The Port Expose Explosion

# AI making sure no port is left behind
EXPOSE 80
EXPOSE 443
EXPOSE 3000
EXPOSE 3001
EXPOSE 3002
# ... 65,532 more EXPOSE commands ...
EXPOSE 65535

# "Maximum flexibility for port binding!"
# Also maximum security scanner alerts

How to Guide AI Docker Generation

"Create a minimal Dockerfile for Node.js with these constraints:
- Use specific version (node:18-alpine)
- Only install production dependencies
- No root user in production
- Single RUN command for apt/apk
- Use .dockerignore
- No secrets in ENV
- Maximum 10 layers
- Final image under 200MB"

The Correct Approach

# What we actually needed
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
USER node
EXPOSE 3000
CMD ["node", "index.js"]

# 8 lines. 95MB. Done.

Lessons Learned

  1. Alpine > Ubuntu for most apps
  2. Fewer layers = smaller image
  3. Multi-stage !== multi-everything
  4. Don't install tools you won't use
  5. Root user is not the solution
  6. Secrets don't belong in Dockerfiles
  7. apt-get clean isn't magic

The Final Image Size

# docker images
REPOSITORY          TAG       SIZE
my-simple-app       ai-made   47.3GB
my-simple-app       human     94.2MB

# Efficiency improvement: -50,000%

My Favorite AI Docker Quote

"I've included a full development environment in the production image for easier debugging. Also installed Wine so you can run Windows applications if needed."

It was a React app.

AI creating Dockerfiles is like packing for vacation by bringing your entire house - technically you have everything you might need, but good luck fitting it in the overhead compartment. The beauty of containers is their simplicity and isolation. When AI turns your 50MB app into a 50GB behemoth that includes three databases and a desktop environment, it's missing the point harder than a stormtrooper misses a protagonist. Remember: if your Docker image is larger than a DVD, you're doing it wrong.

Get Started