๐ณ Docker
Containerize your hackathon project for consistent, portable deployments.
Docker packages your app and its dependencies into containers that run the same everywhere. Perfect for hackathons when you need to deploy fast and avoid โworks on my machineโ issues.
๐ฏ Why Docker for Hackathons?
โ Common Problems
- โ โIt works on my laptop but not on Railway/Renderโ
- โ Environment differences between dev/prod
- โ Dependency conflicts (โNode 18 vs 20โ)
- โ Database connection issues
- โ Time wasted debugging deployment issues
โ Docker Solves
- โ โWorks on my machineโ โ Works everywhere
- โ Consistent environments (same OS, same dependencies)
- โ Easy deployment (Railway, Render, Fly.io all support Docker)
- โ Isolated services (frontend, backend, database in containers)
- โ
One command to run everything (
docker-compose up)
๐ก Pro tip: Docker isnโt just for production. Use it to ensure your entire team has identical dev environments.
๐ Quick Start
Install Docker
macOS / Windows:
- Download Docker Desktopย
- Install and restart your computer
Linux:
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.shVerify Installation
docker --version
docker-compose --version๐ป Dockerfile Examples
Node.js / Next.js App
# Dockerfile
FROM node:20-alpine AS base
# Install dependencies only when needed
FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
CMD ["node", "server.js"]Note: For Next.js, enable standalone output in next.config.js:
// next.config.js
module.exports = {
output: 'standalone',
}Python / FastAPI Backend
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY . .
# Expose port
EXPOSE 8000
# Run application
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]Simple Node.js Server
# Dockerfile
FROM node:20-alpine
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy app files
COPY . .
# Expose port
EXPOSE 3000
# Run app
CMD ["node", "server.js"]๐ Docker Compose (Full Stack)
Perfect for hackathons: run your entire stack with one command.
# docker-compose.yml
version: '3.8'
services:
# Frontend (Next.js)
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}
- NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
- NEXT_PUBLIC_RPC_URL=${RPC_URL}
depends_on:
- backend
# Backend (Node.js API)
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "8000:8000"
environment:
- DATABASE_URL=${DATABASE_URL}
- PRIVATE_KEY=${PRIVATE_KEY}
- RPC_URL=${RPC_URL}
env_file:
- .env
# Database (PostgreSQL)
postgres:
image: postgres:15-alpine
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=hackathon
volumes:
- postgres_data:/var/lib/postgresql/data
# Redis (for caching/sessions)
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:Running Docker Compose
# Start everything
docker-compose up
# Start in background
docker-compose up -d
# View logs
docker-compose logs -f
# Stop everything
docker-compose down
# Rebuild after changes
docker-compose up --build๐ Environment Variables with Docker
Option 1: .env file (Recommended)
# .env
SUPABASE_URL=https://xxxxx.supabase.co
PRIVATE_KEY=0xabc123...
RPC_URL=https://eth-sepolia.g.alchemy.com/v2/...Docker Compose automatically loads .env:
services:
backend:
environment:
- PRIVATE_KEY=${PRIVATE_KEY}Option 2: Direct in docker-compose.yml
services:
backend:
environment:
- PRIVATE_KEY=0xabc123... # โ ๏ธ Not recommended for productionOption 3: Docker secrets (Advanced)
echo "my-secret" | docker secret create private_key -๐ข Deploying Docker Containers
Railway
- Connect your GitHub repo
- Railway auto-detects Docker
- Add environment variables in dashboard
- Deploy!
Or use railway.toml:
[build]
builder = "DOCKERFILE"
dockerfilePath = "Dockerfile"
[deploy]
startCommand = "node server.js"Render
- Create new Web Service
- Connect GitHub repo
- Set Dockerfile path
- Add environment variables
- Deploy!
Fly.io
# Install flyctl
curl -L https://fly.io/install.sh | sh
# Launch app
fly launch
# Deploy
fly deployVercel (Docker support in beta)
Currently, Vercel primarily supports serverless. For Docker containers, use Railway or Render.
๐ ๏ธ Common Commands
# Build an image
docker build -t my-app .
# Run a container
docker run -p 3000:3000 my-app
# Run with environment variables
docker run -p 3000:3000 -e PRIVATE_KEY=0x123 my-app
# List running containers
docker ps
# View logs
docker logs <container-id>
# Stop container
docker stop <container-id>
# Remove container
docker rm <container-id>
# Remove image
docker rmi my-app
# Clean up everything (โ ๏ธ careful!)
docker system prune -a๐ .dockerignore (Important!)
Create a .dockerignore to exclude unnecessary files:
# .dockerignore
node_modules
.next
.git
.env
.env.local
*.log
README.md
.dockerignore
Dockerfile
docker-compose.ymlThis makes builds faster and images smaller.
๐จ Multi-Stage Builds (Optimization)
Use multi-stage builds to create smaller images:
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]๐ Debugging
Enter a Running Container
docker exec -it <container-id> shView Container Logs
docker logs -f <container-id>Inspect Environment Variables
docker exec <container-id> envCheck if Port is Exposed
docker port <container-id>๐ Resources
- ๐ Official Docs: https://docs.docker.comย
- ๐ Docker Compose Docs: https://docs.docker.com/composeย
- ๐ Railway Docs: https://docs.railway.appย
- ๐จ Render Docs: https://render.com/docsย
- ๐ชฐ Fly.io Docs: https://fly.io/docsย
โ Checklist for Hackathons
- Create
Dockerfilefor each service - Add
.dockerignore(faster builds) - Create
docker-compose.ymlfor local dev - Test locally:
docker-compose up - Set environment variables in deployment platform
- Deploy to Railway/Render/Fly.io
- Verify everything works in production
๐จ Common Mistakes
โ Donโt
- โ Copy
.envinto image (use environment variables) - โ Run as root (use non-root user)
- โ Install dev dependencies in production image
- โ Expose unnecessary ports
- โ Forget
.dockerignore(huge images)
โ Do
- โ Use multi-stage builds (smaller images)
- โ
Use specific base image versions (
node:20-alpine, notnode:latest) - โ Run as non-root user
- โ Use environment variables, not hardcoded secrets
- โ Test locally before deploying
Remember: Docker ensures your hackathon project runs the same everywhere. Deploy with confidence! ๐ณ๐