- Full grant strategy framework for renewable energy & green hydrogen - AI-powered grant studio, partner outreach, financial modeling - Umami analytics with data-performance tracking - Live Degelas metrics connected to solar.degelas.be - Trilingual (EN/FR/AR) with i18n support - Dockerized with Nginx frontend + Express API proxy
12 KiB
Atlas Green Morocco — Docker Deployment Guide
Production-Ready Containerization & Deployment
Overview
This guide covers deploying Atlas Green Morocco using Docker and Docker Compose. The setup includes:
- Multi-stage Dockerfile: Efficient Node.js → Alpine build pipeline
- Nginx Configuration: High-performance serving with gzip, security headers, and SPA routing
- Docker Compose: One-command local and production deployment
- Optimized Images: Final production image is <25MB
Prerequisites
Before deploying, ensure you have:
-
Docker installed (v20.10+)
docker --version -
Docker Compose installed (v2.0+)
docker compose version -
Git (to clone the project)
git clone https://github.com/your-repo/atlas-green-morocco.git cd atlas-green-morocco
Quick Start: Local Deployment (1 Minute)
1. Build and Run with Docker Compose
docker compose up -d --build
This command:
- Builds the Docker image from the Dockerfile
- Starts a container mapping port 80 to your localhost
- Runs Nginx in the foreground (production-ready)
2. Access the Application
Open your browser and go to:
http://localhost
You should see the Atlas Green Morocco playbook website live.
3. Check Container Logs
docker compose logs -f atlas-green-app
4. Stop the Container
docker compose down
Production Deployment Guide
Option 1: Deploy to a VPS (DigitalOcean, Linode, Vultr, AWS EC2, etc.)
Step 1: SSH into Your Server
ssh root@your_server_ip
Step 2: Install Docker & Docker Compose
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to docker group
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
docker compose version
Step 3: Clone the Repository
git clone https://github.com/your-repo/atlas-green-morocco.git
cd atlas-green-morocco
Step 4: Deploy with Docker Compose
docker compose up -d --build
Step 5: Verify Deployment
docker compose ps
You should see:
CONTAINER ID IMAGE STATUS
abc123def456 atlas-green-morocco:latest Up 2 minutes
Step 6: Access Your Application
Visit:
http://your_server_ip
Option 2: Deploy to Heroku (with Heroku Container Registry)
Step 1: Install Heroku CLI
curl https://cli.heroku.com/install.sh | sh
heroku login
Step 2: Create Heroku App
heroku create atlas-green-morocco
Step 3: Deploy Docker Image
heroku container:push web -a atlas-green-morocco
heroku container:release web -a atlas-green-morocco
Step 4: View Application
heroku open -a atlas-green-morocco
Option 3: Deploy to AWS ECS (Elastic Container Service)
Step 1: Create ECR Repository
aws ecr create-repository --repository-name atlas-green-morocco --region us-east-1
Step 2: Build and Push Image
# Get AWS credentials
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
# Build image
docker build -t atlas-green-morocco .
# Tag image for ECR
docker tag atlas-green-morocco:latest YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/atlas-green-morocco:latest
# Push to ECR
docker push YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/atlas-green-morocco:latest
Step 3: Create ECS Task Definition
Use the AWS Console or CLI to create a task definition pointing to your ECR image on port 80.
Step 4: Create ECS Service & Launch
Use AWS ECS Console to create a service from the task definition and launch on your cluster.
Option 4: Deploy to DigitalOcean App Platform (Easiest)
Step 1: Connect Your GitHub Repository
Go to DigitalOcean App Platform > Create App > Select your GitHub repository.
Step 2: Configure Build Settings
- Buildpack: Docker (automatic detection from Dockerfile)
- Port: 80
- Environment: Production
Step 3: Deploy
Click "Deploy" and DigitalOcean will:
- Build your Docker image
- Push to their registry
- Deploy to a container
- Assign a public URL
Docker Image Architecture
Dockerfile Explanation
# Stage 1: Builder (Node.js 20 Alpine)
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci # Clean install (faster, more reliable)
COPY . .
RUN npm run build # Build Vite app → dist/
# Stage 2: Runtime (Nginx Alpine)
FROM nginx:alpine AS runner
RUN rm -rf /usr/share/nginx/html/* # Remove default nginx content
COPY nginx.conf /etc/nginx/conf.d/default.conf # Custom config
COPY --from=builder /app/dist /usr/share/nginx/html # Copy build output
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] # Run Nginx in foreground
Why Multi-Stage?
- Stage 1 (Node.js): Only used for building
- Stage 2 (Nginx): Only used for running
- Final image: <25MB (no Node.js bloat)
Nginx Configuration Highlights
# Gzip compression (text, CSS, JS, SVG)
gzip on;
gzip_min_length 1024;
gzip_types text/plain text/css application/javascript;
# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
# SPA routing support
location / {
try_files $uri $uri/ /index.html;
}
# Static asset caching (6 months for fingerprinted files)
location ~* \.(?:ico|css|js|gif|jpe?g|png|svg)$ {
expires 6M;
add_header Cache-Control "public, max-age=15552000, immutable";
}
Docker Compose Configuration
docker-compose.yml Explained
version: '3.8'
services:
atlas-green-app:
build:
context: . # Build from current directory
dockerfile: Dockerfile # Use our multi-stage Dockerfile
image: atlas-green-morocco:latest
container_name: atlas-green-production
ports:
- "80:80" # Map port 80 (HTTP) to container
restart: unless-stopped # Auto-restart on crash
environment:
- NODE_ENV=production # Production environment
Common Docker Compose Commands
# Start containers in background
docker compose up -d
# Build and start
docker compose up -d --build
# View logs
docker compose logs -f
# Stop containers
docker compose down
# Remove images too
docker compose down --rmi all
# View running containers
docker compose ps
# Execute command in container
docker compose exec atlas-green-app /bin/sh
# Restart service
docker compose restart atlas-green-app
Environment Variables & Customization
Build-Time Variables
To pass custom variables during build, update docker-compose.yml:
services:
atlas-green-app:
build:
context: .
dockerfile: Dockerfile
args:
NODE_ENV: production
Runtime Variables
To set runtime environment variables for Nginx:
services:
atlas-green-app:
environment:
- NODE_ENV=production
- CUSTOM_DOMAIN=atlasgreenmorocco.com # Add your domain
Health Checks & Monitoring
Add Health Check to docker-compose.yml
services:
atlas-green-app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
Monitor Logs
# Real-time logs
docker compose logs -f
# Last 100 lines
docker compose logs --tail 100
# Specific service logs
docker compose logs atlas-green-app
Scaling & Performance Tips
1. Use a Reverse Proxy (Nginx, Traefik)
If running multiple containers, use a load balancer:
docker network create atlas-network
# Add to docker-compose.yml:
networks:
- atlas-network
2. Enable Resource Limits
services:
atlas-green-app:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
3. Use a CDN (CloudFlare, AWS CloudFront)
- Cache static assets globally
- Reduce origin server load
- Improve page load times globally
4. Enable Gzip in Nginx (Already Done)
The provided nginx.conf includes gzip compression for:
- Text, CSS, JavaScript
- SVG, JSON
- Reduces bandwidth by ~60%
Troubleshooting
Container Won't Start
# Check logs
docker compose logs atlas-green-app
# Common issues:
# 1. Port 80 already in use → change docker-compose.yml
# 2. Disk space → docker system prune
# 3. Out of memory → increase Docker memory limit
Nginx Returning 404
Check that dist/ folder exists:
ls dist/
# Should show: index.html, and assets
If missing, rebuild:
docker compose down
docker compose up -d --build
High Memory Usage
Check container stats:
docker stats atlas-green-app
Nginx is very lightweight. If memory is high:
- Clear Docker cache:
docker system prune - Check for background processes:
docker exec atlas-green-app ps aux
HTTPS / SSL Setup
To add SSL (required for production):
- Use Let's Encrypt with Traefik (easiest for Docker)
- Use AWS ALB (if on AWS)
- Use Cloudflare (free SSL + CDN)
Example with Traefik:
services:
traefik:
image: traefik:latest
# Configure automatic SSL from Let's Encrypt
# Point your domain to server IP
Security Best Practices
✅ Do:
- Keep Docker and images updated
- Run containers as non-root user (Nginx does this by default)
- Use
.dockerignoreto exclude sensitive files - Implement environment-based configuration
- Use health checks
- Set resource limits
❌ Don't:
- Run containers as root
- Commit credentials to Dockerfile
- Use
:latesttag in production (use specific versions) - Skip security headers (we've included them in nginx.conf)
Cost Optimization
| Platform | Cost | Notes |
|---|---|---|
| VPS (DigitalOcean) | $5–20/mo | Simplest for small teams |
| DigitalOcean App Platform | $12–100/mo | Managed, auto-scaling |
| Heroku | $7–500/mo | Easy, but pricier at scale |
| AWS ECS | $0–100+/mo | Most flexible, steepest learning curve |
| Your own hardware | $0 | For tech-savvy founders (risky) |
Recommendation for MVP: Start with DigitalOcean VPS ($5–10/mo) or DigitalOcean App Platform ($12/mo for managed container).
Backup & Data Persistence
Since Atlas Green is a static website (no database), backups are simple:
# Backup your git repository (that's your backup!)
git push origin main
# For database (if you add one later)
docker compose exec postgres pg_dump -U postgres mydb > backup.sql
Final Checklist: Ready to Deploy?
Before going live to production:
.dockerignorecreated (excludes node_modules, .git, etc.)Dockerfiletested locally (docker build .)nginx.confin root directorydocker-compose.ymlcustomized with your domain/envnpm run buildworks locallydist/index.htmlcontains your compiled app- Health checks configured (optional but recommended)
- Monitoring / alerting set up (optional)
- Backup strategy defined
- DNS pointing to your server
- SSL certificate ready (if HTTPS required)
One-Line Production Deploy
Once everything is tested:
ssh root@your_server && \
git clone https://github.com/your-repo/atlas-green-morocco.git && \
cd atlas-green-morocco && \
docker compose up -d --build
That's it. Your application is live.
Support & Resources
- Docker Docs: https://docs.docker.com/
- Docker Compose Docs: https://docs.docker.com/compose/
- Nginx Docs: https://nginx.org/en/docs/
- Our GitHub: https://github.com/your-repo/atlas-green-morocco
Last Updated: January 2026
Production Ready: ✅ Yes
For questions or issues, open an issue on GitHub or email hello@atlasgreenmorocco.com