> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trymondo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> This document defines how to work with MOPS infrastructure across environments (dev, staging, prod) using Docker, Portainer, and Git. It ensures Jordan and Joe operate with the same brain and adhere to expert standards.

## Folder Structure

```
MOPS/
├── environments/
│   ├── dev/
│   │   ├── n8n/
│   │   │   ├── .env
│   │   │   └── docker-compose.yml
│   │   └── traefik/
│   ├── staging/
│   │   ├── n8n/
│   │   └── traefik/
│   └── prod/
│       ├── n8n/
│       └── traefik/
├── shared/              # Reserved for shared future config fragments
└── README.md
```

***

## Stack Naming (Portainer)

* Format: `[env]-[service]-stack`
* Examples:
  * `dev-n8n-stack`
  * `prod-n8n-stack`
  * `staging-traefik-stack`

All container, volume, and network names follow the same prefixing rule.

***

## Environments

### `dev/`

* Used for experiments, rapid iteration, test credentials only.
* Safe to break.
* Only accessible to internal team.

### `staging/`

* Used for internal QA.
* Should mirror `prod` config and infrastructure 1:1 as closely as possible.
* Uses *real integration endpoints* (e.g., SMTP, OAuth), but **not production data**.

### `prod/`

* Production-only.
* Zero downtime expectation.
* Code and config **`must flow from staging`**, not directly from `dev`.

***

## Workflow Summary

1. **`Develop in dev/`**
   * Work with live containers locally or via Portainer Stack.
   * Debug, test new features, iterate quickly.
2. **`Promote to staging/`**
   * Use `rsync` or `git` to copy the working config.
   * Replace test `.env` values with real sandbox/QA credentials.
   * Run end-to-end test flows.
3. **`Promote to prod/`**
   * Only after staging passes.
   * Tag commit (`v1.2.0-prod`), deploy via CI/CD or Portainer Git Stack.
   * Document changes and review logs post-deploy.

***

## Secrets Management

### Current State

`.env` files are stored in Git — this is **not secure**.

### Immediate Fix

* Move `.env` values to Portainer **Secrets** (per environment).
* Reference them in `docker-compose.yml` like this:

```yaml theme={null}
env_file:
  - /run/secrets/n8n_api_key
```

### Near-Future Upgrade Path

* Use [dotenv-vault](https://www.dotenv.org/) or \[SOPS + Git-crypt] for OSS secret encryption.
* Alternative: GitHub Actions + \[secrets manager] for automated secure injection.

***

## CI/CD Plan

### Goals

* Push to `environments/prod/**` requires PR approval and triggers deploy to `prod`
* Push to `environments¸/staging/**` triggers deploy to `staging`

### Tool: GitHub Actions

```yaml theme={null}
on:
  push:
    paths:
      - 'environments/staging/**'
    branches:
      - main

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to Staging
        run: |
          ssh user@server 'cd /docker && docker compose -f environments/staging/n8n/docker-compose.yml up -d'
```

Add manual approval + backup steps for `prod`.

***

## Backup & Rollback Plan

### For PostgreSQL (n8n, mautic):

* Use `pg_dump` and `pg_restore`.
* Set up nightly cron-based backup containers.

### For Volumes:

* Use \[bind mounts] to make data externally accessible.
* Snapshot `/var/lib/docker/volumes` regularly using rsync or Btrfs/ZFS snapshots.

***

## Best Practices

* Never deploy to `prod` directly.
* Never store `.env` with secrets in Git.
* Always test in `staging` before production.
* Always prefix stacks/networks/containers with `[env]-[service]`.
* Always document new services in their `README.md`.
* Avoid floating Docker image tags in `prod` (e.g., use `n8nio/n8n:1.27.1` not `:latest`).

***

## Future Improvements

* Central secrets manager
* Automated rollback script
* Infra diagram / dependency map
* Multi-server orchestration (Docker Swarm or K8s)
* Terraform/Ansible for provisioning VPSes

***

> Questions? Ping Jordan or Joe. Otherwise: build, test, promote. Stay sharp.
> git config --global pull.rebase true
