# Getting Started with Production Deployment **Audience**: Junior DevOps Engineers, Infrastructure Team **Time to Complete**: 10-15 minutes (one-time setup) **Prerequisites**: - Basic Linux command line knowledge - DigitalOcean account with billing enabled - SSH access to your local machine --- ## Overview This guide prepares your local machine for deploying Maple Open Technologies infrastructure to DigitalOcean **from scratch**. You'll set up your workspace and prepare to create servers (droplets), databases, and networking—all through command-line tools. **What you'll accomplish:** - Set up your local workspace - Prepare the `.env` configuration file - Understand how to store and use infrastructure details as you create them - Get ready to run deployment scripts that create resources on DigitalOcean **What you WON'T need:** Existing secrets or passwords (you'll generate these as you go) --- ## Table of Contents 1. [Prerequisites Check](#prerequisites-check) 2. [Setting Up Your Local Workspace](#setting-up-your-local-workspace) 3. [Understanding the `.env` File](#understanding-the-env-file) 4. [Next Steps](#next-steps) --- ## Prerequisites Check Before starting, verify you have: ### 1. DigitalOcean Account ```bash # You should be able to log in to DigitalOcean # Visit: https://cloud.digitalocean.com/ ``` **Need an account?** Sign up at https://www.digitalocean.com/ ### 2. DigitalOcean API Token You'll need a Personal Access Token to create resources from command line. **Create one:** 1. Log into DigitalOcean: https://cloud.digitalocean.com/ 2. Click **API** in left sidebar 3. Click **Generate New Token** 4. Name: "Production Deployment" 5. Scopes: Check **Read** and **Write** 6. Click **Generate Token** 7. **COPY THE TOKEN IMMEDIATELY** (you can't see it again) Save this token somewhere safe - you'll add it to `.env` shortly. ### 3. SSH Key Pair You need SSH keys to access the servers you'll create. **Check if you already have keys:** ```bash ls -la ~/.ssh/id_rsa.pub # If you see the file, you're good! Skip to next section. ``` **Don't have keys? Create them:** ```bash # Generate new SSH key pair ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # Press Enter to accept default location # Enter a passphrase (optional but recommended) # Verify creation ls -la ~/.ssh/id_rsa.pub # Should show the file exists ``` **Add SSH key to DigitalOcean:** 1. Copy your public key: ```bash cat ~/.ssh/id_rsa.pub # Copy the entire output ``` 2. Go to DigitalOcean: https://cloud.digitalocean.com/ 3. Click **Settings** → **Security** 4. Click **Add SSH Key** 5. Paste your public key 6. Name it: "My Local Machine" 7. Click **Add SSH Key** ### 4. Command Line Tools Verify you have these installed: ```bash # Check git git --version # Should show: git version 2.x.x # Check ssh ssh -V # Should show: OpenSSH_x.x # Check curl curl --version # Should show: curl 7.x.x or 8.x.x ``` **Missing tools?** Install them: - **macOS**: Tools should be pre-installed or install via `brew install git` - **Linux**: `sudo apt install git curl openssh-client` (Ubuntu/Debian) - **Windows**: Use WSL2 (Windows Subsystem for Linux) --- ## Setting Up Your Local Workspace ### Step 1: Clone the Repository ```bash # Navigate to where you keep code projects cd ~/Projects # or wherever you prefer # Clone the monorepo git clone https://codeberg.org/mapleopentech/monorepo.git # Navigate to infrastructure directory cd monorepo/cloud/infrastructure/production # Verify you're in the right place pwd # Should show: /Users/yourname/Projects/monorepo/cloud/infrastructure/production ``` ### Step 2: Create Your `.env` File from Template The repository includes a `.env.template` file with all configuration variables you'll need. Your actual `.env` file (with real values) is gitignored and will never be committed to the repository. ```bash # Copy the template to create your .env file cp .env.template .env # The .env file is automatically gitignored (safe from accidental commits) # Verify it was created ls -la .env # Should show: -rw-r--r-- ... .env # Also verify .env is gitignored git check-ignore -v .env # Should show: .gitignore:2:.env .env ``` **What's the difference?** - `.env.template` = Safe to commit, contains `CHANGEME` placeholders - `.env` = Your private file, contains real IPs/passwords/tokens, NEVER commit! ### Step 3: Set Secure File Permissions **Important**: This file will contain sensitive information. ```bash # Make it readable/writable only by you chmod 600 .env # Verify permissions changed ls -la .env # Should show: -rw------- 1 youruser youruser ... .env ``` ### Step 4: Add Your DigitalOcean API Token ```bash # Open .env file in your editor nano .env # Or: vim .env # Or: code .env ``` **Find this line:** ```bash DIGITALOCEAN_TOKEN=CHANGEME ``` **Replace with your token:** ```bash DIGITALOCEAN_TOKEN=dop_v1_abc123xyz789yourtoken ``` **Save and close** the file (in nano: `Ctrl+X`, then `Y`, then `Enter`) ### Step 5: Verify Gitignore Protection **Critical**: Verify `.env` won't be committed to Git: ```bash # Check if .env is ignored git check-ignore -v .env # Expected output: # .gitignore:XX:.env .env # Also verify git status doesn't show .env git status # .env should NOT appear in untracked files ``` ✅ If `.env` appears in git status, STOP and check your `.gitignore` file --- ## Understanding the `.env` File ### What is the `.env` File For? The `.env` file is your **infrastructure notebook**. As you create resources (servers, databases, etc.) on DigitalOcean, you'll record important details here: - IP addresses of servers you create - Passwords you generate - API keys and tokens - Configuration values **Think of it like a worksheet**: You start with `CHANGEME` placeholders and fill them in as you build your infrastructure. ### What is "source .env"? **Simple explanation**: The `source` command reads your `.env` file and loads all values into your current terminal session so deployment scripts can use them. **Analogy**: It's like loading ingredients onto your kitchen counter before cooking. The `.env` file is your pantry (storage), and `source` puts everything on the counter (active memory). **Example**: ```bash # BEFORE running "source .env" echo $DIGITALOCEAN_TOKEN # Output: (blank - doesn't exist yet) # AFTER running "source .env" source .env echo $DIGITALOCEAN_TOKEN # Output: dop_v1_abc123... (the value from your .env file) ``` **Important**: You need to run `source .env` in EVERY new terminal window before running deployment commands. ### The `.env` File Structure Your `.env` file looks like this: ```bash # Each line is: VARIABLE_NAME=value DIGITALOCEAN_TOKEN=dop_v1_abc123xyz CASSANDRA_NODE1_IP=CHANGEME CASSANDRA_ADMIN_PASSWORD=CHANGEME # Lines starting with # are comments (ignored) # Blank lines are also ignored ``` **Initial state**: Most values are `CHANGEME` **As you deploy**: You'll replace `CHANGEME` with actual values **Final state**: All `CHANGEME` values replaced with real infrastructure details ### How You'll Use It During Deployment Here's the workflow you'll follow in the next guides: 1. **Create a resource** (e.g., create a database server on DigitalOcean) 2. **Note important details** (e.g., IP address: 10.137.0.11, password: abc123) 3. **Update `.env` file** (replace `CASSANDRA_NODE1_IP=CHANGEME` with `CASSANDRA_NODE1_IP=10.137.0.11`) 4. **Load the values** (run `source .env`) 5. **Run next deployment script** (which uses those values) ### Using Environment Variables Every time you start a new terminal for deployment work: ```bash # Step 1: Go to infrastructure directory cd ~/monorepo/cloud/infrastructure/production # Step 2: Load all values from .env into this terminal session source .env # Step 3: Verify it worked (check one variable) echo "DigitalOcean Token: ${DIGITALOCEAN_TOKEN:0:15}..." # Should show: DigitalOcean Token: dop_v1_abc123... ``` ### Quick Verification Test that your DigitalOcean token loaded correctly: ```bash # Make sure you ran "source .env" first! # Check the token (shows first 20 characters only) echo "DIGITALOCEAN_TOKEN: ${DIGITALOCEAN_TOKEN:0:20}..." # Expected output: # DIGITALOCEAN_TOKEN: dop_v1_abc123xyz789... ``` **If you see blank output:** 1. Did you run `source .env`? (run it now) 2. Did you add your token to `.env`? (check Step 4 above) 3. Did you save the file after editing? ### Variable Naming Convention We use consistent prefixes to organize variables: | Prefix | Purpose | Example | |--------|---------|---------| | `CASSANDRA_*` | Cassandra database | `CASSANDRA_NODE1_IP` | | `REDIS_*` | Redis cache | `REDIS_PASSWORD` | | `AWS_*` | Cloud storage | `AWS_ACCESS_KEY_ID` | | `BACKEND_*` | Application backend | `BACKEND_ADMIN_HMAC_SECRET` | | `*_MAILGUN_*` | Email services | `MAPLEFILE_MAILGUN_API_KEY` | --- ## Common Mistakes to Avoid ### ❌ Mistake 1: Committing .env File ```bash # NEVER DO THIS! git add .env git commit -m "Add environment variables" # Always check before committing git status git diff --cached ``` ### ❌ Mistake 2: Forgetting to Load Variables **Symptom**: Scripts fail with errors like "variable not set" or blank values ```bash # ❌ Wrong - running script without loading .env first ./scripts/create-droplet.sh # Error: DIGITALOCEAN_TOKEN: variable not set # ✅ Correct - load .env first, then run script source .env ./scripts/create-droplet.sh # ✅ Also correct - load and run in one line (source .env && ./scripts/create-droplet.sh) ``` **Remember**: Each new terminal needs `source .env` run again! ### ❌ Mistake 3: Using Wrong Permissions ```bash # Too permissive - others can read your secrets! chmod 644 .env # ❌ Wrong # Correct - only you can read/write chmod 600 .env # ✅ Correct ``` ### ❌ Mistake 4: Leaving CHANGEME Values ```bash # ❌ Wrong - still has placeholder CASSANDRA_NODE1_IP=CHANGEME # ✅ Correct - replaced with actual value after creating server CASSANDRA_NODE1_IP=10.137.0.11 ``` --- ## Troubleshooting ### Problem: "Permission denied" when reading .env **Cause**: File permissions too restrictive or wrong owner **Solution**: ```bash # Check current permissions and owner ls -la .env # Fix permissions chmod 600 .env # If you're not the owner, fix ownership sudo chown $(whoami):$(whoami) .env ``` ### Problem: Variables not loading **Symptoms**: Scripts fail with "variable not set" errors or echo commands show blank **Solution - Check each step**: ```bash # Step 1: Verify .env file exists in current directory ls -la .env # Should show: -rw------- 1 youruser youruser ... .env # Step 2: Check it has content (not empty) head .env # Should show lines like: DIGITALOCEAN_TOKEN=dop_v1_abc123... # Step 3: Load variables into current terminal source .env # (no output is normal - silence means success) # Step 4: Verify loading worked by printing a variable echo "DIGITALOCEAN_TOKEN is: ${DIGITALOCEAN_TOKEN:0:20}..." # Should print: DIGITALOCEAN_TOKEN is: dop_v1_abc123xyz789... # NOT: DIGITALOCEAN_TOKEN is: (blank) ``` **Still not working?** Check these: - Are you in the correct directory? Run `pwd` to verify - Is the `.env` file formatted correctly? No spaces around `=` sign - Did you save the file after editing? - Did you replace `CHANGEME` with actual values? ### Problem: Git showing .env file **Symptoms**: `git status` shows `.env` as untracked or modified **Solution**: ```bash # Verify gitignore is working git check-ignore -v .env # If not ignored, check .gitignore exists cat .gitignore | grep "\.env" # If needed, manually add to gitignore echo ".env" >> .gitignore ``` ### Problem: Accidentally committed secrets **⚠️ CRITICAL - Act immediately!** **If not yet pushed**: ```bash # Remove from staging git reset HEAD .env # Or undo last commit git reset --soft HEAD~1 ``` **If already pushed**: 1. **DO NOT PANIC** - but act quickly 2. Immediately contact team lead 3. All secrets in that file must be rotated (changed) 4. Team lead will help remove from Git history --- ## Quick Reference Commands ### Daily Workflow (Copy-Paste Template) Every time you open a new terminal for deployment work, run these commands in order: ```bash # Step 1: Go to the infrastructure directory cd ~/monorepo/cloud/infrastructure/production # Step 2: Load configuration into this terminal session source .env # Step 3: Verify token loaded correctly echo "Token loaded: ${DIGITALOCEAN_TOKEN:0:15}..." # Step 4: Now you can run deployment commands # (You'll use these in the next guides) ``` **Why these steps?** - Step 1: Ensures you're in the right folder where `.env` exists - Step 2: Loads your DigitalOcean token and other config values - Step 3: Confirms everything loaded correctly - Step 4: Ready to create infrastructure! ### One-time Setup Summary ```bash # Clone repository git clone https://codeberg.org/mapleopentech/monorepo.git cd monorepo/cloud/infrastructure/production # Create .env file cp .env.template .env # Add your DigitalOcean token nano .env # Set permissions chmod 600 .env # Verify gitignored git check-ignore -v .env # Load and verify source .env echo "Token: ${DIGITALOCEAN_TOKEN:0:15}..." ``` --- ## Next Steps ✅ **You've completed:** - Local workspace setup - `.env` file creation - DigitalOcean API token configuration - Understanding of how to use environment variables **Next, you'll create infrastructure on DigitalOcean:** 1. **[Initialize Docker Swarm](01_init_docker_swarm.md)** - Create Docker Swarm cluster 2. **[Deploy Cassandra](02_cassandra.md)** - Set up Cassandra database cluster 3. **[Deploy Redis](03_redis.md)** - Set up Redis cache server 4. **[Deploy Meilisearch](04_meilisearch.md)** - Set up Meilisearch search engine 5. **[Configure Spaces](04.5_spaces.md)** - Set up DigitalOcean Spaces object storage 6. **[Deploy Backend](05_maplepress_backend.md)** - Deploy backend application 7. **[Setup Caddy](06_maplepress_caddy.md)** - Configure automatic SSL/TLS with Caddy --- ## Important Notes ### You're Building From Scratch - **No existing infrastructure**: You'll create everything step by step - **Generate secrets as needed**: Each guide will tell you when to create passwords/keys - **Update `.env` as you go**: After creating each resource, add details to `.env` - **Keep notes**: Write down IPs, passwords as you create them ### The `.env` File Will Grow **Right now:** Only has `DIGITALOCEAN_TOKEN` **After creating droplets:** Will have server IP addresses **After setting up databases:** Will have passwords and connection strings **At the end:** Will have all infrastructure details documented --- ## Security Reminders 🔒 **Always**: - Verify `.env` is gitignored (check this NOW: `git check-ignore -v .env`) - Use `chmod 600` for `.env` files - Run `source .env` before running deployment scripts - Keep `.env` file backed up securely (encrypted backup) 🚫 **Never**: - Commit `.env` files to Git - Share `.env` via email or Slack - Use permissive file permissions (644, 777) - Leave `CHANGEME` values in production --- ## Quick Pre-flight Check Before continuing to the next guide, verify: ```bash # 1. You're in the right directory pwd # Should show: .../monorepo/cloud/infrastructure/production # 2. .env file exists with correct permissions ls -la .env # Should show: -rw------- ... .env # 3. Your token is loaded source .env echo "Token: ${DIGITALOCEAN_TOKEN:0:15}..." # Should show: Token: dop_v1_abc123... # 4. Git won't commit .env git check-ignore -v .env # Should show: .gitignore:XX:.env .env ``` ✅ **All checks passed?** Continue to [Create DigitalOcean Droplets](01-create-droplets.md) --- **Document Version**: 2.0 (From-Scratch Edition) **Last Updated**: November 3, 2025 **Maintained By**: Infrastructure Team