Initial commit
This commit is contained in:
753
skills/docker-platform-guide.md
Normal file
753
skills/docker-platform-guide.md
Normal file
@@ -0,0 +1,753 @@
|
||||
---
|
||||
name: docker-platform-guide
|
||||
description: Platform-specific Docker considerations for Windows, Linux, and macOS
|
||||
---
|
||||
|
||||
## 🚨 CRITICAL GUIDELINES
|
||||
|
||||
### Windows File Path Requirements
|
||||
|
||||
**MANDATORY: Always Use Backslashes on Windows for File Paths**
|
||||
|
||||
When using Edit or Write tools on Windows, you MUST use backslashes (`\`) in file paths, NOT forward slashes (`/`).
|
||||
|
||||
**Examples:**
|
||||
- ❌ WRONG: `D:/repos/project/file.tsx`
|
||||
- ✅ CORRECT: `D:\repos\project\file.tsx`
|
||||
|
||||
This applies to:
|
||||
- Edit tool file_path parameter
|
||||
- Write tool file_path parameter
|
||||
- All file operations on Windows systems
|
||||
|
||||
|
||||
### Documentation Guidelines
|
||||
|
||||
**NEVER create new documentation files unless explicitly requested by the user.**
|
||||
|
||||
- **Priority**: Update existing README.md files rather than creating new documentation
|
||||
- **Repository cleanliness**: Keep repository root clean - only README.md unless user requests otherwise
|
||||
- **Style**: Documentation should be concise, direct, and professional - avoid AI-generated tone
|
||||
- **User preference**: Only create additional .md files when user specifically asks for documentation
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Docker Platform-Specific Guide
|
||||
|
||||
This skill provides detailed guidance on Docker differences, considerations, and optimizations for Windows, Linux, and macOS platforms.
|
||||
|
||||
## Linux
|
||||
|
||||
### Advantages
|
||||
|
||||
- **Native containers:** No virtualization layer overhead
|
||||
- **Best performance:** Direct kernel features (cgroups, namespaces)
|
||||
- **Full feature set:** All Docker features available
|
||||
- **Production standard:** Most production deployments run on Linux
|
||||
- **Flexibility:** Multiple distributions supported
|
||||
|
||||
### Platform Features
|
||||
|
||||
**Container Technologies:**
|
||||
- Namespaces: PID, network, IPC, mount, UTS, user
|
||||
- cgroups v1 and v2 for resource control
|
||||
- Overlay2 storage driver (recommended)
|
||||
- SELinux and AppArmor for mandatory access control
|
||||
|
||||
**Storage Drivers:**
|
||||
```bash
|
||||
# Check current driver
|
||||
docker info | grep "Storage Driver"
|
||||
|
||||
# Recommended: overlay2
|
||||
# /etc/docker/daemon.json
|
||||
{
|
||||
"storage-driver": "overlay2"
|
||||
}
|
||||
```
|
||||
|
||||
### Linux-Specific Configuration
|
||||
|
||||
**Daemon Configuration** (`/etc/docker/daemon.json`):
|
||||
```json
|
||||
{
|
||||
"storage-driver": "overlay2",
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "10m",
|
||||
"max-file": "3"
|
||||
},
|
||||
"live-restore": true,
|
||||
"userland-proxy": false,
|
||||
"userns-remap": "default",
|
||||
"icc": false,
|
||||
"default-ulimits": {
|
||||
"nofile": {
|
||||
"Name": "nofile",
|
||||
"Hard": 64000,
|
||||
"Soft": 64000
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**User Namespace Remapping:**
|
||||
```bash
|
||||
# Enable in daemon.json
|
||||
{
|
||||
"userns-remap": "default"
|
||||
}
|
||||
|
||||
# Restart Docker
|
||||
sudo systemctl restart docker
|
||||
|
||||
# Result: root in container = unprivileged user on host
|
||||
```
|
||||
|
||||
### SELinux Integration
|
||||
|
||||
```bash
|
||||
# Check SELinux status
|
||||
sestatus
|
||||
|
||||
# Run container with SELinux enabled
|
||||
docker run --security-opt label=type:svirt_sandbox_file_t myimage
|
||||
|
||||
# Volume labels
|
||||
docker run -v /host/path:/container/path:z myimage # Private label
|
||||
docker run -v /host/path:/container/path:Z myimage # Shared label
|
||||
```
|
||||
|
||||
### AppArmor Integration
|
||||
|
||||
```bash
|
||||
# Check AppArmor status
|
||||
sudo aa-status
|
||||
|
||||
# Run with default Docker profile
|
||||
docker run --security-opt apparmor=docker-default myimage
|
||||
|
||||
# Create custom profile
|
||||
sudo aa-genprof docker run myimage
|
||||
```
|
||||
|
||||
### Systemd Integration
|
||||
|
||||
```bash
|
||||
# Check Docker service status
|
||||
sudo systemctl status docker
|
||||
|
||||
# Enable on boot
|
||||
sudo systemctl enable docker
|
||||
|
||||
# Restart Docker
|
||||
sudo systemctl restart docker
|
||||
|
||||
# View logs
|
||||
sudo journalctl -u docker -f
|
||||
|
||||
# Configure service
|
||||
sudo systemctl edit docker
|
||||
```
|
||||
|
||||
### cgroup v1 vs v2
|
||||
|
||||
```bash
|
||||
# Check cgroup version
|
||||
stat -fc %T /sys/fs/cgroup/
|
||||
|
||||
# If using cgroup v2, ensure Docker version >= 20.10
|
||||
|
||||
# /etc/docker/daemon.json
|
||||
{
|
||||
"exec-opts": ["native.cgroupdriver=systemd"]
|
||||
}
|
||||
```
|
||||
|
||||
### Linux Distribution Specifics
|
||||
|
||||
**Ubuntu/Debian:**
|
||||
```bash
|
||||
# Install Docker
|
||||
sudo apt-get update
|
||||
sudo apt-get install ca-certificates curl
|
||||
sudo install -m 0755 -d /etc/apt/keyrings
|
||||
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||||
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install docker-ce docker-ce-cli containerd.io
|
||||
|
||||
# Non-root user
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
**RHEL/CentOS/Fedora:**
|
||||
```bash
|
||||
# Install Docker
|
||||
sudo dnf -y install dnf-plugins-core
|
||||
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
|
||||
sudo dnf install docker-ce docker-ce-cli containerd.io
|
||||
|
||||
# Start Docker
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
|
||||
# Non-root user
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
**Alpine:**
|
||||
```bash
|
||||
# Install Docker
|
||||
apk add docker docker-compose
|
||||
|
||||
# Start Docker
|
||||
rc-update add docker boot
|
||||
service docker start
|
||||
```
|
||||
|
||||
## macOS
|
||||
|
||||
### Architecture
|
||||
|
||||
- **Docker Desktop:** Required (no native Docker on macOS)
|
||||
- **Virtualization:** Uses HyperKit (Intel) or Virtualization.framework (Apple Silicon)
|
||||
- **Linux VM:** Containers run in lightweight Linux VM
|
||||
- **File sharing:** osxfs or VirtioFS for bind mounts
|
||||
|
||||
### macOS-Specific Considerations
|
||||
|
||||
**Resource Allocation:**
|
||||
```
|
||||
Docker Desktop → Preferences → Resources → Advanced
|
||||
- CPUs: Allocate based on workload (default: half available)
|
||||
- Memory: Allocate generously (default: 2GB, recommend 4-8GB)
|
||||
- Swap: 1GB minimum
|
||||
- Disk image size: 60GB+ for development
|
||||
```
|
||||
|
||||
**File Sharing Performance:**
|
||||
|
||||
Traditional osxfs is slow. Improvements:
|
||||
1. **VirtioFS:** Enable in Docker Desktop settings (faster)
|
||||
2. **Delegated/Cached mounts:**
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
# Host writes delayed (best for source code)
|
||||
- ./src:/app/src:delegated
|
||||
|
||||
# Container writes cached (best for build outputs)
|
||||
- ./build:/app/build:cached
|
||||
|
||||
# Default consistency (slowest but safest)
|
||||
- ./data:/app/data:consistent
|
||||
```
|
||||
|
||||
**Network Access:**
|
||||
|
||||
```bash
|
||||
# Access host from container
|
||||
host.docker.internal
|
||||
|
||||
# Example: Connect to host PostgreSQL
|
||||
docker run -e DATABASE_URL=postgresql://host.docker.internal:5432/db myapp
|
||||
```
|
||||
|
||||
### Apple Silicon (M1/M2/M3) Specifics
|
||||
|
||||
**Architecture Considerations:**
|
||||
```bash
|
||||
# Check image architecture
|
||||
docker image inspect node:20-alpine | grep Architecture
|
||||
|
||||
# M-series Macs are ARM64
|
||||
# Some images only available for AMD64
|
||||
|
||||
# Build multi-platform
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t myapp .
|
||||
|
||||
# Run AMD64 image on ARM (via emulation)
|
||||
docker run --platform linux/amd64 myimage # Slower
|
||||
```
|
||||
|
||||
**Rosetta 2 Integration:**
|
||||
```
|
||||
Docker Desktop → Features in development → Use Rosetta for x86/amd64 emulation
|
||||
```
|
||||
Faster AMD64 emulation on Apple Silicon.
|
||||
|
||||
### macOS Docker Desktop Settings
|
||||
|
||||
**General:**
|
||||
- ✅ Start Docker Desktop when you log in
|
||||
- ✅ Use VirtioFS (better performance)
|
||||
- ✅ Use Virtualization framework (Apple Silicon)
|
||||
|
||||
**Resources:**
|
||||
```
|
||||
CPUs: 4-6 (for development)
|
||||
Memory: 6-8 GB (for development)
|
||||
Swap: 1-2 GB
|
||||
Disk image size: 100+ GB (grows dynamically)
|
||||
```
|
||||
|
||||
**Docker Engine:**
|
||||
```json
|
||||
{
|
||||
"builder": {
|
||||
"gc": {
|
||||
"enabled": true,
|
||||
"defaultKeepStorage": "20GB"
|
||||
}
|
||||
},
|
||||
"experimental": false,
|
||||
"features": {
|
||||
"buildkit": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### macOS File Permissions
|
||||
|
||||
```bash
|
||||
# macOS user ID and group ID
|
||||
id -u # Usually 501
|
||||
id -g # Usually 20
|
||||
|
||||
# Match in container
|
||||
docker run --user 501:20 myimage
|
||||
|
||||
# Or in Dockerfile
|
||||
RUN adduser -u 501 -g 20 appuser
|
||||
USER appuser
|
||||
```
|
||||
|
||||
### macOS Development Workflow
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml for development
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
volumes:
|
||||
# Source code with delegated (better performance)
|
||||
- ./src:/app/src:delegated
|
||||
# node_modules in volume (much faster than bind mount)
|
||||
- node_modules:/app/node_modules
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
|
||||
volumes:
|
||||
node_modules:
|
||||
```
|
||||
|
||||
### Common macOS Issues
|
||||
|
||||
**Problem:** Slow file sync
|
||||
**Solution:**
|
||||
- Use VirtioFS
|
||||
- Use delegated/cached mounts
|
||||
- Store dependencies in volumes (not bind mounts)
|
||||
|
||||
**Problem:** High CPU usage
|
||||
**Solution:**
|
||||
- Reduce file watching
|
||||
- Exclude large directories from file sharing
|
||||
- Allocate more resources
|
||||
|
||||
**Problem:** Port already in use
|
||||
**Solution:**
|
||||
```bash
|
||||
# Find process using port
|
||||
lsof -i :PORT
|
||||
kill -9 PID
|
||||
```
|
||||
|
||||
## Windows
|
||||
|
||||
### Windows Container Types
|
||||
|
||||
**1. Linux Containers on Windows (LCOW):**
|
||||
- Most common for development
|
||||
- Uses WSL2 or Hyper-V backend
|
||||
- Runs Linux containers
|
||||
- Good compatibility
|
||||
|
||||
**2. Windows Containers:**
|
||||
- Native Windows containers
|
||||
- For Windows-specific workloads
|
||||
- Requires Windows Server base images
|
||||
- Less common in development
|
||||
|
||||
### Windows Backend Options
|
||||
|
||||
**WSL2 Backend (Recommended):**
|
||||
- Faster
|
||||
- Better resource usage
|
||||
- Native Linux kernel
|
||||
- Requires Windows 10/11 (recent versions)
|
||||
|
||||
**Hyper-V Backend:**
|
||||
- Older option
|
||||
- More resource intensive
|
||||
- Works on older Windows versions
|
||||
|
||||
### WSL2 Configuration
|
||||
|
||||
**Enable WSL2:**
|
||||
```powershell
|
||||
# Run as Administrator
|
||||
wsl --install
|
||||
|
||||
# Or manually
|
||||
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
|
||||
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
|
||||
|
||||
# Set WSL2 as default
|
||||
wsl --set-default-version 2
|
||||
|
||||
# Install Ubuntu (or other distro)
|
||||
wsl --install -d Ubuntu
|
||||
```
|
||||
|
||||
**Docker Desktop Integration:**
|
||||
```
|
||||
Settings → Resources → WSL Integration
|
||||
- Enable integration with default distro
|
||||
- Select additional distros
|
||||
```
|
||||
|
||||
### Windows Path Considerations
|
||||
|
||||
**Path Formats:**
|
||||
```bash
|
||||
# Forward slashes (recommended, works everywhere)
|
||||
docker run -v C:/Users/name/project:/app myimage
|
||||
|
||||
# Backslashes (need escaping in some contexts)
|
||||
docker run -v C:\Users\name\project:/app myimage
|
||||
|
||||
# In docker-compose.yml (forward slashes)
|
||||
volumes:
|
||||
- C:/Users/name/project:/app
|
||||
|
||||
# Or relative paths
|
||||
volumes:
|
||||
- ./src:/app/src
|
||||
```
|
||||
|
||||
### Git Bash / MINGW Path Conversion Issues
|
||||
|
||||
**CRITICAL ISSUE:** When using Docker in Git Bash (MINGW) on Windows, automatic path conversion breaks volume mounts.
|
||||
|
||||
**The Problem:**
|
||||
```bash
|
||||
# What you type in Git Bash:
|
||||
docker run -v $(pwd):/app myimage
|
||||
|
||||
# What Git Bash converts it to (BROKEN):
|
||||
docker run -v C:\Program Files\Git\d\repos\project:/app myimage
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
|
||||
**1. MSYS_NO_PATHCONV (Recommended):**
|
||||
```bash
|
||||
# Per-command fix
|
||||
MSYS_NO_PATHCONV=1 docker run -v $(pwd):/app myimage
|
||||
|
||||
# Session-wide fix (add to ~/.bashrc)
|
||||
export MSYS_NO_PATHCONV=1
|
||||
|
||||
# Function wrapper (automatic for all Docker commands)
|
||||
docker() {
|
||||
(export MSYS_NO_PATHCONV=1; command docker.exe "$@")
|
||||
}
|
||||
export -f docker
|
||||
```
|
||||
|
||||
**2. Double Slash Workaround:**
|
||||
```bash
|
||||
# Use double leading slash to prevent conversion
|
||||
docker run -v //c/Users/project:/app myimage
|
||||
|
||||
# Works with $(pwd) too
|
||||
docker run -v //$(pwd):/app myimage
|
||||
```
|
||||
|
||||
**3. Named Volumes (No Path Issues):**
|
||||
```bash
|
||||
# Named volumes work without any fixes
|
||||
docker run -v my-data:/data myimage
|
||||
```
|
||||
|
||||
**What Works Without Modification:**
|
||||
- Docker Compose YAML files with relative paths
|
||||
- Named volumes
|
||||
- Network and image commands
|
||||
- Container commands without volumes
|
||||
|
||||
**What Needs MSYS_NO_PATHCONV:**
|
||||
- Bind mounts with `$(pwd)`
|
||||
- Bind mounts with absolute Unix-style paths
|
||||
- Volume mounts specified on command line
|
||||
|
||||
**Shell Detection:**
|
||||
```bash
|
||||
# Detect Git Bash/MINGW and auto-configure
|
||||
if [ -n "$MSYSTEM" ] || [[ "$(uname -s)" == MINGW* ]]; then
|
||||
export MSYS_NO_PATHCONV=1
|
||||
echo "Git Bash detected - Docker path conversion fix enabled"
|
||||
fi
|
||||
```
|
||||
|
||||
**Recommended ~/.bashrc Configuration:**
|
||||
```bash
|
||||
# Docker on Git Bash fix
|
||||
if [ -n "$MSYSTEM" ]; then
|
||||
export MSYS_NO_PATHCONV=1
|
||||
fi
|
||||
```
|
||||
|
||||
See the `docker-git-bash-guide` skill for comprehensive path conversion documentation, troubleshooting, and examples.
|
||||
|
||||
### Windows File Sharing
|
||||
|
||||
**Configure Shared Drives:**
|
||||
```
|
||||
Docker Desktop → Settings → Resources → File Sharing
|
||||
Add: C:\, D:\, etc.
|
||||
```
|
||||
|
||||
**Performance Considerations:**
|
||||
- File sharing is slower than Linux/Mac
|
||||
- Use WSL2 backend for better performance
|
||||
- Store frequently accessed files in WSL2 filesystem
|
||||
|
||||
### Windows Line Endings
|
||||
|
||||
**Problem:** CRLF vs LF line endings
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Git configuration
|
||||
git config --global core.autocrlf input
|
||||
|
||||
# Or per-repo (.gitattributes)
|
||||
* text=auto
|
||||
*.sh text eol=lf
|
||||
*.bat text eol=crlf
|
||||
```
|
||||
|
||||
```dockerfile
|
||||
# In Dockerfile for scripts
|
||||
FROM alpine
|
||||
COPY --chmod=755 script.sh /
|
||||
# Ensure LF endings
|
||||
RUN dos2unix /script.sh || sed -i 's/\r$//' /script.sh
|
||||
```
|
||||
|
||||
### Windows Firewall
|
||||
|
||||
```powershell
|
||||
# Allow Docker Desktop
|
||||
New-NetFirewallRule -DisplayName "Docker Desktop" -Direction Inbound -Program "C:\Program Files\Docker\Docker\Docker Desktop.exe" -Action Allow
|
||||
|
||||
# Check blocked ports
|
||||
netstat -ano | findstr :PORT
|
||||
```
|
||||
|
||||
### Windows-Specific Docker Commands
|
||||
|
||||
```powershell
|
||||
# Run PowerShell in container
|
||||
docker run -it mcr.microsoft.com/powershell:lts-7.4-windowsservercore-ltsc2022
|
||||
|
||||
# Windows container example
|
||||
docker run -it mcr.microsoft.com/windows/servercore:ltsc2022 cmd
|
||||
|
||||
# Check container type
|
||||
docker info | Select-String "OSType"
|
||||
```
|
||||
|
||||
### WSL2 Disk Management
|
||||
|
||||
**Problem:** WSL2 VHDX grows but doesn't shrink
|
||||
|
||||
**Solution:**
|
||||
```powershell
|
||||
# Stop Docker Desktop and WSL
|
||||
wsl --shutdown
|
||||
|
||||
# Compact disk image (run as Administrator)
|
||||
# Method 1: Optimize-VHD (requires Hyper-V tools)
|
||||
Optimize-VHD -Path "$env:LOCALAPPDATA\Docker\wsl\data\ext4.vhdx" -Mode Full
|
||||
|
||||
# Method 2: diskpart
|
||||
diskpart
|
||||
# In diskpart:
|
||||
select vdisk file="C:\Users\YourName\AppData\Local\Docker\wsl\data\ext4.vhdx"
|
||||
attach vdisk readonly
|
||||
compact vdisk
|
||||
detach vdisk
|
||||
exit
|
||||
```
|
||||
|
||||
### Windows Development Workflow
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml for Windows
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
volumes:
|
||||
# Use forward slashes
|
||||
- ./src:/app/src
|
||||
# Named volumes for better performance
|
||||
- node_modules:/app/node_modules
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
# Windows-specific: ensure proper line endings
|
||||
command: sh -c "dos2unix /app/scripts/*.sh && npm start"
|
||||
|
||||
volumes:
|
||||
node_modules:
|
||||
```
|
||||
|
||||
### Common Windows Issues
|
||||
|
||||
**Problem:** Permission denied errors
|
||||
**Solution:**
|
||||
```powershell
|
||||
# Run Docker Desktop as Administrator
|
||||
# Or grant permissions to Docker Desktop
|
||||
icacls "C:\ProgramData\DockerDesktop" /grant Users:F /T
|
||||
```
|
||||
|
||||
**Problem:** Slow performance
|
||||
**Solution:**
|
||||
- Use WSL2 backend
|
||||
- Store project in WSL2 filesystem (`\\wsl$\Ubuntu\home\user\project`)
|
||||
- Use named volumes for node_modules, etc.
|
||||
|
||||
**Problem:** Path not found
|
||||
**Solution:**
|
||||
- Use forward slashes
|
||||
- Ensure drive is shared in Docker Desktop
|
||||
- Use absolute paths or `${PWD}`
|
||||
|
||||
## Platform Comparison
|
||||
|
||||
| Feature | Linux | macOS | Windows |
|
||||
|---------|-------|-------|---------|
|
||||
| **Performance** | Excellent (native) | Good (VM overhead) | Good (WSL2) to Fair (Hyper-V) |
|
||||
| **File sharing** | Native | Slow (improving with VirtioFS) | Slow (better in WSL2) |
|
||||
| **Resource efficiency** | Best | Good | Good (WSL2) |
|
||||
| **Feature set** | Complete | Complete | Complete (LCOW) |
|
||||
| **Production** | Standard | Dev only | Dev only (LCOW) |
|
||||
| **Ease of use** | Moderate | Easy (Docker Desktop) | Easy (Docker Desktop) |
|
||||
| **Cost** | Free | Free (Docker Desktop Personal) | Free (Docker Desktop Personal) |
|
||||
|
||||
## Cross-Platform Best Practices
|
||||
|
||||
### Multi-Platform Images
|
||||
|
||||
```bash
|
||||
# Create buildx builder
|
||||
docker buildx create --name multiplatform --driver docker-container --use
|
||||
|
||||
# Build for multiple platforms
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64,linux/arm/v7 \
|
||||
-t myimage:latest \
|
||||
--push \
|
||||
.
|
||||
```
|
||||
|
||||
### Platform-Agnostic Dockerfiles
|
||||
|
||||
```dockerfile
|
||||
# Works on all platforms
|
||||
FROM node:20-alpine
|
||||
|
||||
# Use COPY with --chmod (not RUN chmod, which is slower)
|
||||
COPY --chmod=755 script.sh /usr/local/bin/
|
||||
|
||||
# Use environment variables for paths
|
||||
ENV APP_HOME=/app
|
||||
WORKDIR ${APP_HOME}
|
||||
|
||||
# Use exec form for CMD/ENTRYPOINT (works on Windows containers too)
|
||||
CMD ["node", "server.js"]
|
||||
```
|
||||
|
||||
### Cross-Platform Compose Files
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
volumes:
|
||||
# Relative paths work everywhere
|
||||
- ./src:/app/src
|
||||
# Named volumes (platform-agnostic)
|
||||
- data:/app/data
|
||||
environment:
|
||||
# Use environment variables
|
||||
- NODE_ENV=${NODE_ENV:-development}
|
||||
|
||||
volumes:
|
||||
data:
|
||||
```
|
||||
|
||||
### Testing Across Platforms
|
||||
|
||||
```bash
|
||||
# Test on different platforms with buildx
|
||||
docker buildx build --platform linux/amd64 -t myapp:amd64 --load .
|
||||
docker run --rm myapp:amd64
|
||||
|
||||
docker buildx build --platform linux/arm64 -t myapp:arm64 --load .
|
||||
docker run --rm myapp:arm64
|
||||
```
|
||||
|
||||
## Platform Selection Guide
|
||||
|
||||
**Choose Linux for:**
|
||||
- Production deployments
|
||||
- Maximum performance
|
||||
- Full Docker feature set
|
||||
- Minimal overhead
|
||||
- CI/CD pipelines
|
||||
|
||||
**Choose macOS for:**
|
||||
- Development on Mac hardware
|
||||
- When you need macOS tools
|
||||
- Docker Desktop ease of use
|
||||
- M1/M2/M3 development
|
||||
|
||||
**Choose Windows for:**
|
||||
- Development on Windows hardware
|
||||
- Windows-specific applications
|
||||
- When team uses Windows
|
||||
- WSL2 for better Linux container support
|
||||
|
||||
This platform guide covers the major differences. Always test on your target deployment platform before going to production.
|
||||
Reference in New Issue
Block a user