9 · Atlas Cloud
Objective — make one explicit end-of-phase Atlas Cloud adoption decision. If the project has an active Atlas Cloud license and adopts it now, register the selected non-production schema for versioned, team-visible migration tracking: open the SSH tunnel, build a baseline migration, push it to Atlas Cloud, apply the baseline, and wire up GitHub CI. If not, record N/A — no Atlas Cloud license/adoption and keep the page-5 schema dump + diff as the free baseline.
Steps at a glance:
- Open the SSH tunnel — Tunnel the selected non-production MySQL port to localhost so Atlas can reach it.
- Create the schema baseline — Export the live selected target schema and generate a baseline migration from it.
- Push to Atlas Cloud — Publish the baseline migration directory to Atlas Cloud.
- Apply the baseline to the selected target — Register the selected target against the pushed baseline and confirm it’s synced.
- Wire up GitHub CI — Gate future schema changes through CI by registering a cloud token and the cloud environments.
Background
Section titled “Background”Atlas Cloud is a paid/hosted layer. Default to skip unless the project already has an active license and intentionally adopts it for this app.
Whether to do this page at all:
flowchart LR Tunnel[SSH tunnel to non-production DB] --> Baseline[Register baseline migration] Baseline --> Atlas[Atlas Cloud ERD] Change[Future schema change] --> CI[CI migration gate] CI --> Atlas1. Open the SSH tunnel
Section titled “1. Open the SSH tunnel”Tunnel the selected non-production MySQL port to localhost so Atlas can reach it. Use the environment row from Zaj-PROJECT.md (staging-primary, qa, uat, client-demo, etc.); staging is only the common example.
-
Open the tunnel and confirm the non-production URL is set.
Terminal window NON_PROD_SSH_ALIAS="<alias-from-Zaj-PROJECT.md>"ssh -L 3307:127.0.0.1:3306 "$NON_PROD_SSH_ALIAS" -N &ps aux | grep "ssh -L"echo "Non-production URL: $ATLAS_NON_PROD_URL" # if empty, run `direnv allow` in the project root# Expected: the tunnel process is running; $ATLAS_NON_PROD_URL is non-empty- ✅ The tunnel is up and
$ATLAS_NON_PROD_URLresolves.
- ✅ The tunnel is up and
2. Create the schema baseline
Section titled “2. Create the schema baseline”Export the live selected non-production schema and generate a baseline migration from it.
-
Inspect, diff, and mark the baseline applied locally.
Terminal window # Backup existing migrations before rebuild (never blind rm)ATLAS_MIG_DIR=packages/ZajModules/Database/Atlas/migrationsif [ -d "$ATLAS_MIG_DIR" ] && [ "$(ls -A "$ATLAS_MIG_DIR" 2>/dev/null)" ]; thenmv "$ATLAS_MIG_DIR" "${ATLAS_MIG_DIR}.bak.$(date +%Y%m%d-%H%M%S)"fimkdir -p "$ATLAS_MIG_DIR"# Export the live selected target schemaatlas schema inspect -u "$ATLAS_NON_PROD_URL" --format '{{ sql . }}' \> packages/ZajModules/Database/Atlas/schema/current.sqlgrep -c "CREATE TABLE" packages/ZajModules/Database/Atlas/schema/current.sql # sanity-check table count# Generate the baseline migrationatlas migrate diff baseline \--dir "file://packages/ZajModules/Database/Atlas/migrations" \--to "file://packages/ZajModules/Database/Atlas/schema/current.sql" \--dev-url "docker://mysql/8/dev"# Mark it applied locally (substitute the generated timestamp)atlas migrate apply \--dir "file://packages/ZajModules/Database/Atlas/migrations" \--url "$ATLAS_LOCAL_URL" \--baseline "YOUR_TIMESTAMP"# Expected: a baseline migration generated and marked applied against the local URL- ✅ A baseline migration is generated from the selected target schema and marked applied locally.
3. Push to Atlas Cloud
Section titled “3. Push to Atlas Cloud”Publish the baseline migration directory to Atlas Cloud.
-
Push the migrations directory.
Terminal window atlas migrate push YOUR_PROJECT_NAME \--dir "file://packages/ZajModules/Database/Atlas/migrations" \--dev-url "docker://mysql/8/dev"# Expected: a project URL is returned; the ERD tab shows your tables- ✅ The push returns a URL and the ERD tab shows your tables.
Open the returned URL — the ERD tab should show your tables.
4. Apply the baseline to the selected target
Section titled “4. Apply the baseline to the selected target”Register the selected target against the pushed baseline and confirm it’s synced.
-
Apply the baseline and check status.
Terminal window atlas migrate apply \--dir "file://packages/ZajModules/Database/Atlas/migrations" \--url "$ATLAS_NON_PROD_URL" \--baseline "YOUR_TIMESTAMP"atlas migrate status \--dir "file://packages/ZajModules/Database/Atlas/migrations" \--url "$ATLAS_NON_PROD_URL"# expect: Migration Status: OK- ✅
Migration Status: OK— the selected target is registered and synced.
- ✅
5. Wire up GitHub CI
Section titled “5. Wire up GitHub CI”Gate future schema changes through CI by registering a cloud token and the cloud environments.
-
Copy the token, set the secret, and register the databases.
-
Atlas Cloud → Set Up CI → GitHub → CLI → copy the token (
aci_…). -
Store the secret without putting the token in shell history:
Terminal window printf '%s' 'aci_…' | gh secret set ATLAS_CLOUD_TOKEN --repo OWNER/REPO# Or: gh secret set ATLAS_CLOUD_TOKEN < /path/to/token-file -
Add the cloud environments to
atlas.hcl. -
Register databases:
atlas migrate apply --env cloud-staging --baseline "YOUR_TIMESTAMP"(example environment name; use the Atlas env name mapped toENV_KEY).
- ✅ The CI token is stored as
ATLAS_CLOUD_TOKEN, cloud envs are inatlas.hcl, and databases are registered.
-
Checklist
Section titled “Checklist”Do not mark this step done until every box below is checked.
- 🤖 Baseline created — baseline migration created from the selected target schema.
- 🤖 Pushed to Atlas Cloud — ERD renders correctly.
- 🤖 Target synced — selected target registered and showing “Synced” (
migrate status: OK). - 🔀 CI configured — GitHub CI token configured (
ATLAS_CLOUD_TOKEN) (👤 copy token from Atlas Cloud). - 🔵 Or N/A recorded — if Atlas Cloud is not adopted, the run records
N/Awith the license/adoption reason and relies on the page-5 schema dump + diff baseline.
That closes the optional non-production tracks. Continue to Phase 6 · SuperAdmin setup — brand and configure the app on the selected non-production target.