monorepo/cloud/infrastructure/production/setup/00-getting-started.md

16 KiB

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
  2. Setting Up Your Local Workspace
  3. Understanding the .env File
  4. Next Steps

Prerequisites Check

Before starting, verify you have:

1. DigitalOcean Account

# 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:

ls -la ~/.ssh/id_rsa.pub
# If you see the file, you're good! Skip to next section.

Don't have keys? Create them:

# 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:

    cat ~/.ssh/id_rsa.pub
    # Copy the entire output
    
  2. Go to DigitalOcean: https://cloud.digitalocean.com/

  3. Click SettingsSecurity

  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:

# 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

# 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.

# 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.

# 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

# Open .env file in your editor
nano .env
# Or: vim .env
# Or: code .env

Find this line:

DIGITALOCEAN_TOKEN=CHANGEME

Replace with your token:

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:

# 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:

# 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:

# 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:

# 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:

# 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

# 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

# ❌ 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

# 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

# ❌ 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:

# 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:

# 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:

# 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:

# 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:

# 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

# 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 - Create Docker Swarm cluster
  2. Deploy Cassandra - Set up Cassandra database cluster
  3. Deploy Redis - Set up Redis cache server
  4. Deploy Meilisearch - Set up Meilisearch search engine
  5. Configure Spaces - Set up DigitalOcean Spaces object storage
  6. Deploy Backend - Deploy backend application
  7. Setup Caddy - 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:

# 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


Document Version: 2.0 (From-Scratch Edition) Last Updated: November 3, 2025 Maintained By: Infrastructure Team