Docker Development Guide
This guide explains how to use Docker for local Jekyll development, matching the exact Ruby 3.1 environment used by GitHub Actions.
Why Docker?
- Consistency: Same Ruby 3.1 environment as GitHub Actions
- No local Ruby setup: Works regardless of your system’s Ruby version
- Clean environment: No conflicts with other Ruby projects
- Fast setup: One command to get started
Prerequisites
- Docker Desktop installed (download here)
- Docker Compose (included with Docker Desktop)
Quick Start
1. Start the Development Server
docker-compose up
This will:
- Build the Docker image (first time only, ~2-3 minutes)
- Install all Ruby dependencies
- Start Jekyll with LiveReload
- Watch for file changes
Your site will be available at:
- Main site: http://localhost:4000
- LiveReload: Automatic browser refresh on changes
2. Stop the Server
Press Ctrl+C in the terminal, or run:
docker-compose down
Common Tasks
Build Site (No Server)
docker-compose run --rm jekyll bundle exec jekyll build
Output will be in _site/ directory.
Serve Without LiveReload
docker-compose run --rm -p 4000:4000 jekyll bundle exec jekyll serve --host 0.0.0.0
Rebuild After Gemfile Changes
If you modify Gemfile:
docker-compose up --build
This rebuilds the image with updated dependencies.
Run Shell Inside Container
docker-compose run --rm jekyll bash
Useful for debugging or running commands inside the container.
Install New Gem
- Add gem to
Gemfile - Rebuild:
docker-compose up --build
File Structure
.
├── Dockerfile # Container definition (Ruby 3.1)
├── docker-compose.yml # Service configuration
├── .dockerignore # Files excluded from Docker build
└── Gemfile # Ruby dependencies
Troubleshooting
Port 4000 Already in Use
If port 4000 is busy, change the port in docker-compose.yml:
ports:
- "4001:4000" # Use localhost:4001 instead
Changes Not Reflecting
- Check that LiveReload is enabled (default with
docker-compose up) - Some files require full rebuild (
_config.yml, Sass partials) - Hard refresh browser:
Cmd+Shift+R(Mac) orCtrl+Shift+R(Windows/Linux)
Container Won’t Start
- Check Docker Desktop is running
- Verify no port conflicts:
lsof -i :4000 - Remove old containers:
docker-compose down -v - Rebuild:
docker-compose up --build
Build Fails
If bundle install fails:
# Remove bundle cache and rebuild
docker-compose down -v
docker-compose up --build
Performance Notes
First Build
- Takes 2-3 minutes to download Ruby base image and install dependencies
- Subsequent builds use cached layers (much faster)
Volume Caching
- Bundle dependencies are cached in a Docker volume (
bundle_cache) - Speeds up subsequent
docker-compose upcommands
File Watching
- Docker Desktop for Mac/Windows uses file sharing
- Large projects may have slower file watching than native
- Performance is acceptable for this site size
Comparison: Docker vs Native Ruby
| Aspect | Docker | Native Ruby 3.1+ |
|---|---|---|
| Setup time | 2-3 min (first time) | 15-30 min (rbenv/rvm setup) |
| Consistency | ✅ Exact GitHub Actions env | ⚠️ Depends on local Ruby version |
| Ruby 2.6 compatible | ✅ Yes | ❌ No (can’t install gems) |
| File watching | ⚠️ Slightly slower | ✅ Fastest |
| Isolation | ✅ No conflicts | ⚠️ Shared gem environment |
| Disk usage | ~500MB Docker image | ~200MB rbenv/gems |
What’s Inside the Container?
- Base:
ruby:3.1-slim(Debian Bookworm) - Installed: build-essential, git, bundler, github-pages gem
- Working dir:
/site(your project root mounted here) - Exposed ports: 4000 (Jekyll), 35729 (LiveReload)
Docker Commands Reference
# Start server with LiveReload
docker-compose up
# Start in background (detached)
docker-compose up -d
# View logs
docker-compose logs -f
# Stop server
docker-compose down
# Build only (no server)
docker-compose run --rm jekyll bundle exec jekyll build
# Clean build (remove _site/)
docker-compose run --rm jekyll bundle exec jekyll clean
# Check Jekyll version
docker-compose run --rm jekyll bundle exec jekyll --version
# Update dependencies
docker-compose run --rm jekyll bundle update
# Rebuild image from scratch
docker-compose build --no-cache
Integration with CI/CD
This Docker setup mirrors your GitHub Actions environment:
Local (Docker):
- Ruby 3.1
- Bundler cache
- github-pages gem
GitHub Actions:
- Ruby 3.1 (
.github/workflows/jekyll.yml) - Bundler cache enabled
- github-pages gem
Changes that work locally in Docker will work in CI/CD.
Next Steps
- Start developing:
docker-compose up - Make changes: Edit files, see instant updates
- Commit: Changes tested in production-like environment
- Push: Confident that GitHub Actions will build successfully