Granola CLI Deployment Guide
Guides deploying a CLI tool with Docker Compose for development and production, including Make commands and security hardening.
What this file does
Guides deploying a CLI tool with Docker Compose for development and production, including Make commands and security hardening.
When to use it
- You need a repeatable Docker-based deployment for a CLI tool
- You want separate dev and production Docker Compose setups
- You require security features like non-root user and read-only mounts
- You want health checks and logging built into the deployment
Assumes this stack
Granola CLI Deployment Guide
Overview
This guide covers deploying the Granola CLI using Docker Compose for both development and production environments. It emphasizes secure, reproducible workflows and leverages Make commands for convenience.
For authentication setup, see AUTHENTICATION.md. For project overview and CLI usage, see README.md.
Quick Start
Development Deployment
- Clone and setup:
git clone <repository-url> cd granola-cli cp .env.example .env - Configure environment (optional):
Edit
.envto customize paths. - Start development container:
make up - Run CLI commands:
make folders make notes - Stop container:
make down
Production Deployment
- Clone and setup:
git clone <repository-url> cd granola-cli cp .env.example .env - Configure environment (optional):
Edit
.envto customize config paths. - Build and start production container:
make prod-up - Run CLI commands:
make prod-folders make prod-notes - Stop container:
make prod-down
Docker Compose Workflows
Development Environment
- Uses
docker-compose.ymlanddocker-compose.override.yml(auto-loaded). - Source code is mounted for live reload.
- Config directory is mounted read-only from host:
volumes: - "${HOME}/Library/Application Support/Granola:/granola-config:ro" - .:/app:cached - Health checks and logs available via Make commands.
Production Environment
- Uses
docker-compose.yml+docker-compose.prod.yml. - Optimized, secure multi-stage build (
Dockerfile.prod). - Config directory mounted read-only:
volumes: - "${GRANOLA_CONFIG_PATH:-${HOME}/Library/Application Support/Granola}:/granola-config:ro" - Runs as non-root user, with resource limits and security hardening.
- Health checks, logging, and resource monitoring enabled.
Configuration
-
Environment variables:
Variable Description Default NODE_ENVNode environment productionGRANOLA_CONFIG_PATHCustom config path Auto-detected DEBUGDebug logging Disabled -
Resource limits:
- Development: 256MB memory, 0.5 CPU
- Production: 128MB memory, 0.25 CPU
Docker Commands Reference
| Command | Description |
|---|---|
docker compose --profile development up --build | Start development container |
docker compose --profile production up --build -d | Start production container |
docker compose down | Stop containers |
docker compose logs -f | View logs |
docker compose exec granola-cli-dev sh | Access development shell |
docker compose exec granola-cli-prod sh | Access production shell |
docker compose exec granola-cli-dev granola folders | List folders (development) |
docker compose exec granola-cli-prod granola folders | List folders (production) |
docker compose exec granola-cli-dev granola notes | List notes (development) |
docker compose exec granola-cli-prod granola notes | List notes (production) |
docker compose ps | Check container status |
NPM Script Shortcuts
| Command | Description |
|---|---|
npm run docker:dev | Start development container |
npm run docker:prod | Start production container |
npm run docker:stop | Stop containers |
npm run docker:logs | View logs |
npm run docker:shell | Access container shell |
Container Configuration
Security Features
- Runs as non-root user (
granola, UID 1001) - Read-only filesystem and config mounts
- Dropped capabilities, no new privileges
- Resource limits (memory, CPU)
- Proper signal handling (
dumb-init) - Isolated bridge network, no exposed ports
Performance Optimizations
- Multi-stage builds for small images
- Layer caching for fast rebuilds
- Alpine Linux base for minimal attack surface
- Health checks and log rotation
Resource Management
- Monitor with
docker stats granola-cli-prod - Adjust limits in
docker-compose.ymlproduction profile as needed
Monitoring & Maintenance
Health Checks
- Built-in health checks (interval: 60s, timeout: 10s, retries: 2)
- Test:
granola --version - Check status:
make health # Development make prod-health # Production
Logging
- Driver: json-file
- Max size: 10MB (dev), 5MB (prod)
- Max files: 3 (dev), 2 (prod)
- View logs:
make logs # Development make prod-logs # Production
Resource Usage
- Monitor:
docker stats granola-cli-prod
Updates
-
Pull latest code and rebuild:
git pull origin main make prod-down make prod-build make prod-up -
Clean unused Docker resources:
docker system prune -f
Troubleshooting
Common Issues
-
Authentication fails:
- Check config mount in container:
make shell # Dev make prod-shell # Prod ls -la /granola-config/ - Verify host config permissions:
ls -la "$HOME/Library/Application Support/Granola/" - See
AUTHENTICATION.mdfor details.
- Check config mount in container:
-
Build fails:
- Clean and rebuild:
make clean make build export DOCKER_BUILDKIT=1
- Clean and rebuild:
-
Container won't start:
- Check logs:
make logs # Dev make prod-logs # Prod - Check health:
make health make prod-health
- Check logs:
-
Resource issues:
- Monitor usage:
docker stats granola-cli-prod - Adjust limits in compose files.
- Monitor usage:
Best Practices
Development
- Use override files for environment-specific config
- Mount source code for hot reloading
- Enable debug logging when troubleshooting
- Use Make commands for consistency
Production
- Use production Dockerfile for optimized builds
- Set resource limits to prevent exhaustion
- Enable health checks for monitoring
- Use read-only mounts for security
- Monitor logs regularly
Security
- Never run as root in production
- Use read-only filesystems when possible
- Limit capabilities to minimum required
- Mount volumes read-only when possible
- Regularly update base images
For more details, see README.md, AUTHENTICATION.md, and CLI_SETUP.md.
What's inside
5 sections: Quick Start, Docker Compose Workflows, Commands Reference, Container Configuration, Monitoring & Maintenance, Troubleshooting, Best Practices.
Change this for your project
- Replace
granola-cliwith your project name in all commands and paths - Replace
granolauser and UID1001with your own non-root user - Replace
$HOME/Library/Application Support/Granolawith your config directory path - Replace
granola --versionhealth check with your own CLI command
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Using Make commands to wrap Docker Compose operations for consistency
- Separating dev and production compose files with profiles
- Mounting config directories read-only for security
Related Documents
๐ GitHub MCP Server - Feature Showcase
Showcases eight GitHub MCP server tools with example inputs, outputs, and real-world use cases for AI agents.
OpenCode Agents
Provides a collection of specialised Markdown agent files for OpenCode, each with a distinct role and thinking algorithm.
Chloe ้จ็ฝฒๆๆกฃ
Guides you through deploying an enhanced SillyTavern fork with direct, Docker, and reverse-proxy setups, plus security hardening and troubleshooting.
msitarzewski/agency-agents
Curates a directory of 100+ specialised AI agent personalities for software engineering, design, marketing, sales, and more, each with identity, workflows, and deliverables.