Docker forandrade hur vi bygger, levererar och kor programvara. Istallet for "det fungerar pa min maskin" garanterar Docker att din applikation kor pa samma satt overallt - pa din laptop, pa en kollegas maskin, i CI/CD och i produktion. I denna guide gar vi fran noll till att deploya en riktig applikation.
Vad ar Docker?
Docker ar en plattform som paketerar din applikation och alla dess beroenden i en standardiserad enhet som kallas en container. En container ar en isolerad, lattvidig process som delar vardens OS-karna men har sitt eget filsystem, natverk och processutrymme.
Containrar vs Virtuella Maskiner
| Aspekt | Containrar | Virtuella Maskiner |
|---|---|---|
| Start | Sekunder | Minuter |
| Storlek | MB | GB |
| OS | Delar vardkarna | Fullstandigt gast-OS |
| Isolering | Processniva | Hardvaruniva |
| Prestanda | Nastan nativ | Overhead fran hypervisor |
| Tathet | Hundratals per vard | Tiotal per vard |
Installera Docker
# macOS brew install --cask docker # Ubuntu/Debian curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # Verify installation docker --version docker run hello-world
Grundlaggande Koncept
Images
En image ar en skrivskyddad mall med instruktioner for att skapa en container. Tank pa den som en ogonblicksbild av din applikation och dess miljo.
# Pull an image from Docker Hub docker pull node:20-alpine # List local images docker images # Remove an image docker rmi node:20-alpine
Containrar
En container ar en korande instans av en image. Du kan skapa, starta, stoppa och ta bort containrar.
# Run a container docker run -d --name my-app -p 3000:3000 node:20-alpine # List running containers docker ps # List all containers (including stopped) docker ps -a # Stop a container docker stop my-app # Remove a container docker rm my-app # View logs docker logs my-app # Execute a command inside a running container docker exec -it my-app sh
Skriva en Dockerfile
En Dockerfile ar en textfil med instruktioner for att bygga en image. Varje instruktion skapar ett lager.
Grundlaggande Dockerfile for en Node.js-App
# Use an official Node.js runtime as base image FROM node:20-alpine # Set working directory WORKDIR /app # Copy package files first (better caching) COPY package.json package-lock.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose the port the app runs on EXPOSE 3000 # Command to run the application CMD ["node", "server.js"]
Bygga och Kora
# Build the image docker build -t my-node-app . # Run the container docker run -d -p 3000:3000 my-node-app # Visit http://localhost:3000
Flerstegsbyggen
Flerstegsbyggen haller dina produktionsimages sma genom att separera byggmiljon fran korskorstiden.
# Stage 1: Build FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Production FROM node:20-alpine AS runner WORKDIR /app COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"]
Detta producerar en image med bara den kompilerade utdatan och produktionsberoenden - ingen kallkod, inga utvecklingsberoenden, inga byggverktyg.
Next.js Flerstegsexempel
FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci FROM node:20-alpine AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static EXPOSE 3000 CMD ["node", "server.js"]
Volymer: Bestande Data
Som standard forsvinner data inuti en container nar containern tas bort. Volymer loser detta.
# Create a named volume docker volume create my-data # Run with a volume docker run -d -v my-data:/app/data my-app # Bind mount (map host directory to container) docker run -d -v $(pwd)/data:/app/data my-app # List volumes docker volume ls
Natverk
Docker skapar isolerade natverk for containrar att kommunicera.
# Create a custom network docker network create my-network # Run containers on the same network docker run -d --name api --network my-network my-api docker run -d --name db --network my-network postgres:16 # Containers can reach each other by name # From "api" container: postgres://db:5432
Docker Compose
Docker Compose later dig definiera och kora multi-container-applikationer med en enda YAML-fil.
docker-compose.yml
services: api: build: ./api ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb depends_on: - db db: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=mydb volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" redis: image: redis:7-alpine ports: - "6379:6379" volumes: pgdata:
Kommandon
# Start all services docker compose up -d # View logs docker compose logs -f # Stop all services docker compose down # Rebuild and restart docker compose up -d --build # Scale a service docker compose up -d --scale api=3
.dockerignore
Precis som .gitignore forhindrar denna fil att onodiga filer kopieras in i imagen.
node_modules .git .env *.md .next dist coverage
Basta Praxis for Produktion
1. Anvand Sma Basimages
# Bad: 1GB+ FROM node:20 # Good: ~180MB FROM node:20-alpine
2. Kor Inte som Root
FROM node:20-alpine RUN addgroup -S app && adduser -S app -G app USER app WORKDIR /home/app COPY . .
3. Anvand Specifika Image-Taggar
# Bad: can change unexpectedly FROM node:latest # Good: pinned version FROM node:20.11-alpine3.19
4. Utnyttja Byggcachen
Ordna dina Dockerfile-instruktioner fran minst till mest frekvent andrade:
FROM node:20-alpine WORKDIR /app # These change rarely - cached COPY package.json package-lock.json ./ RUN npm ci --only=production # This changes often - not cached COPY . .
5. Halsokontroller
HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1
6. Anvand Miljovariabler
ENV NODE_ENV=production ENV PORT=3000
Fuskblad for Vanliga Docker-Kommandon
# Images docker build -t name:tag . # Build image docker images # List images docker rmi image_name # Remove image docker image prune # Remove unused images # Containers docker run -d -p 3000:3000 image # Run detached docker ps # List running docker stop container_name # Stop docker rm container_name # Remove docker logs -f container_name # Follow logs docker exec -it container sh # Shell into container # Compose docker compose up -d # Start services docker compose down # Stop services docker compose logs -f # Follow all logs docker compose ps # List services # Cleanup docker system prune -a # Remove everything unused
Fran Docker till Kubernetes
Docker hanterar enskilda containrar. Nar du behover orkestrera hundratals containrar over flera servrar behover du Kubernetes. Docker och Kubernetes kompletterar varandra:
- Docker: bygger och kor containrar
- Kubernetes: orkestrerar containrar i stor skala (schemalagning, skalning, sjalvlakande)
Om du ar intresserad av nasta steg, kolla in min artikel om Introduktion till Kubernetes.
Slutsats
Docker ar en grundlaggande fardighet for moderna utvecklare. Det eliminerar miljoinkonsekvenser, forenklar deployment och ar grunden for containerorkestrering med Kubernetes. Borja med en enkel Dockerfile, ga over till Docker Compose for multi-service-appar och adoptera flerstegsbyggen och sakerhets-best practices allteftersom du vaxer.
Det basta sattet att lara sig Docker ar att containerisera ett projekt du redan arbetar pa. Borja idag.