🐳 Docker Basics cho n8n
Docker là nền tảng để self-host n8n. Bài này covers core concepts bạn cần biết trước khi deploy.
Docker Concepts
What is Docker?
Text
1TRADITIONAL SERVER DOCKER2───────────────── ──────3┌─────────────────┐ ┌─────────────────┐4│ App 1 │ App 2 │ │ Container 1 │5├─────────────────┤ │ ┌───────────┐ │6│ Dependencies │ │ │App+Deps │ │7│ (shared!) │ │ └───────────┘ │8├─────────────────┤ │ Container 2 │9│ Host OS │ │ ┌───────────┐ │10├─────────────────┤ │ │App+Deps │ │11│ Hardware │ │ └───────────┘ │12└─────────────────┘ ├─────────────────┤13 │ Docker Engine │14❌ Dependency conflicts ├─────────────────┤15❌ Hard to replicate │ Host OS │16 ├─────────────────┤17 │ Hardware │18 └─────────────────┘19 20 ✅ Isolated21 ✅ ReproducibleCore Concepts:
Text
1IMAGE: Blueprint (read-only)2├── Dockerfile defines it3├── Downloaded from registry4└── Versioned with tags5 6CONTAINER: Running instance7├── Created from image8├── Has its own filesystem9└── Can be started/stopped10 11VOLUME: Persistent storage12├── Data survives restarts13├── Shared between containers14└── Lives on host filesystem15 16NETWORK: Communication17├── Containers can talk18├── Isolated by default19└── Custom networks possibleInstalling Docker
Ubuntu/Debian:
Bash
1# Update packages2sudo apt update3 4# Install prerequisites5sudo apt install -y \6 ca-certificates \7 curl \8 gnupg \9 lsb-release10 11# Add Docker GPG key12curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \13 sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg14 15# Add repository16echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \17 https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \18 sudo tee /etc/apt/sources.list.d/docker.list > /dev/null19 20# Install Docker21sudo apt update22sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin23 24# Add user to docker group (no sudo needed)25sudo usermod -aG docker $USER26 27# Log out and back in, then verify28docker --version29docker compose versionmacOS/Windows:
Text
1Download Docker Desktop:2https://www.docker.com/products/docker-desktop/3 4Install and run.5Docker Desktop includes:6• Docker Engine7• Docker Compose8• Docker CLIVerify Installation:
Bash
1# Test Docker2docker run hello-world3 4# Expected output:5# Hello from Docker!6# This message shows that your installation...Docker Commands
Essential Commands:
Bash
1# IMAGES2docker pull n8nio/n8n # Download image3docker images # List images4docker rmi n8nio/n8n # Remove image5 6# CONTAINERS7docker run n8nio/n8n # Create & start8docker ps # List running9docker ps -a # List all10docker stop <container> # Stop11docker start <container> # Start again12docker rm <container> # Remove13 14# LOGS & DEBUG15docker logs <container> # View logs16docker logs -f <container> # Follow logs17docker exec -it <container> sh # Shell into container18 19# CLEANUP20docker system prune # Remove unused21docker volume prune # Remove unused volumesRunning n8n with Docker
Simple Run (Testing):
Bash
1docker run -it --rm \2 --name n8n \3 -p 5678:5678 \4 n8nio/n8n5 6# Options explained:7# -it : Interactive mode8# --rm : Remove when stopped9# --name : Container name10# -p : Port mapping (host:container)With Persistent Data:
Bash
1# Create volume2docker volume create n8n_data3 4# Run with volume5docker run -d \6 --name n8n \7 -p 5678:5678 \8 -v n8n_data:/home/node/.n8n \9 n8nio/n8n10 11# -d : Detached (background)12# -v : Mount volumeWith Environment Variables:
Bash
1docker run -d \2 --name n8n \3 -p 5678:5678 \4 -e N8N_BASIC_AUTH_ACTIVE=true \5 -e N8N_BASIC_AUTH_USER=admin \6 -e N8N_BASIC_AUTH_PASSWORD=secret \7 -e GENERIC_TIMEZONE=Asia/Ho_Chi_Minh \8 -v n8n_data:/home/node/.n8n \9 n8nio/n8nDocker Volumes Deep Dive
Types of Storage:
Text
1VOLUME TYPES2────────────3 41. NAMED VOLUME (Recommended)5 docker volume create mydata6 -v mydata:/path/in/container7 8 ✅ Docker manages location9 ✅ Easy backup/restore10 ✅ Works on all platforms11 122. BIND MOUNT13 -v /host/path:/container/path14 15 ✅ Direct file access16 ⚠️ Platform-specific17 ⚠️ Permission issues18 193. TMPFS (Memory)20 --tmpfs /path21 22 ✅ Fast, ephemeral23 ❌ Lost on restartn8n Data Structure:
Text
1/home/node/.n8n/2├── config # Settings3├── database.sqlite # Workflows, creds (SQLite mode)4├── .n8n/ 5│ ├── crash.journal6│ └── ssh/ # SSH keys7└── custom/ # Custom nodesVolume Commands:
Bash
1# Create2docker volume create n8n_data3 4# List5docker volume ls6 7# Inspect8docker volume inspect n8n_data9 10# Backup (copy to host)11docker run --rm \12 -v n8n_data:/source \13 -v $(pwd):/backup \14 alpine tar cvf /backup/n8n_backup.tar /source15 16# Restore17docker run --rm \18 -v n8n_data:/target \19 -v $(pwd):/backup \20 alpine sh -c "cd /target && tar xvf /backup/n8n_backup.tar --strip 1"Docker Networks
Network Types:
Text
1BRIDGE (default)2└── Containers can reach each other by IP3└── Need port mapping to reach from host4 5HOST6└── No isolation from host7└── Container uses host's network8└── No port mapping needed9 10CUSTOM BRIDGE (Recommended)11└── Containers reach by name12└── Isolated from other networksCreate Custom Network:
Bash
1# Create network2docker network create n8n-network3 4# Run containers on same network5docker run -d \6 --name postgres \7 --network n8n-network \8 -e POSTGRES_PASSWORD=secret \9 postgres:1510 11docker run -d \12 --name n8n \13 --network n8n-network \14 -p 5678:5678 \15 -e DB_TYPE=postgresdb \16 -e DB_POSTGRESDB_HOST=postgres \17 n8nio/n8n18 19# n8n can reach postgres by hostname "postgres"Dockerfile (Reference)
n8n's Dockerfile (simplified):
dockerfile
1FROM node:18-alpine2 3# Install dependencies4RUN apk add --update graphicsmagick tzdata git5 6# Set user (not root)7USER node8 9# Set working directory10WORKDIR /home/node11 12# Install n8n13RUN npm install n8n14 15# Expose port16EXPOSE 567817 18# Start command19CMD ["n8n", "start"]Building Custom Image:
dockerfile
1# Dockerfile.custom2FROM n8nio/n8n3 4# Install custom node5RUN npm install n8n-nodes-custom6 7# Or add files8COPY ./custom-nodes /home/node/.n8n/customBash
1# Build2docker build -t my-n8n -f Dockerfile.custom .3 4# Run5docker run -d --name n8n -p 5678:5678 my-n8nCommon Issues
Port Already in Use:
Bash
1# Error: port 5678 already in use2 3# Find what's using it4sudo lsof -i :56785# or6sudo netstat -tulpn | grep 56787 8# Kill or change port9docker run -p 5679:5678 n8nio/n8nPermission Issues:
Bash
1# Error: permission denied2 3# Check volume permissions4docker exec n8n ls -la /home/node/.n8n5 6# Fix ownership7docker exec -u root n8n chown -R node:node /home/node/.n8nContainer Won't Start:
Bash
1# Check logs2docker logs n8n3 4# Common issues:5# - Port conflict6# - Volume mount error7# - Environment variable typo8# - Missing dependenciesPractice Exercise
Hands-On Practice
Complete these steps:
- Install Docker on your machine
- Pull n8n image:
Bash1docker pull n8nio/n8n
- Run n8n locally:
Bash1docker run -p 5678:5678 n8nio/n8n
- Access http://localhost:5678
- Create a simple workflow
- Stop and restart container
- Notice workflow is gone (no volume!)
- Run with volume:
Bash1docker volume create n8n_data2docker run -p 5678:5678 -v n8n_data:/home/node/.n8n n8nio/n8n
- Verify workflow persists after restart
You now understand Docker basics! 🐳
Key Takeaways
Remember
- 🐳 Images are blueprints, containers are running instances
- 💾 Volumes persist data across restarts (essential!)
- 🔗 Networks let containers communicate
- 🔒 Don't run as root in production
- 📝 Always check logs when debugging
Tiếp Theo
Bài tiếp theo: Docker Compose - Orchestrate n8n với database và reverse proxy trong một file config.
