Split databases and Redis — prepare infrastructure for per-domain isolation
Redis: per-app DB index (0-5) with shared auth DB 15 for SSO keys; flushdb replaces flushall so deploys don't wipe cross-app auth state. Postgres: drop 13 cross-domain FK constraints (migration v2t0p8q9r0), remove dead ORM relationships, add explicit joins for 4 live ones. Multi-engine sessions (account + federation) ready for per-domain DBs via DATABASE_URL_ACCOUNT / DATABASE_URL_FEDERATION env vars. All URLs initially point to the same appdb — zero behaviour change until split-databases.sh is run to migrate data to per-domain DBs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
12
_config/init-databases.sql
Normal file
12
_config/init-databases.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
-- Per-domain databases for the coop stack.
|
||||
-- Run once on fresh deployments (not needed for existing single-DB setups
|
||||
-- that use the split-databases.sh migration script instead).
|
||||
--
|
||||
-- Usage: psql -U postgres -f init-databases.sql
|
||||
|
||||
CREATE DATABASE db_account;
|
||||
CREATE DATABASE db_blog;
|
||||
CREATE DATABASE db_market;
|
||||
CREATE DATABASE db_cart;
|
||||
CREATE DATABASE db_events;
|
||||
CREATE DATABASE db_federation;
|
||||
153
_config/split-databases.sh
Executable file
153
_config/split-databases.sh
Executable file
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# split-databases.sh — Migrate from single appdb to per-domain databases.
|
||||
#
|
||||
# Prerequisites:
|
||||
# - All apps stopped (5-min maintenance window)
|
||||
# - init-databases.sql already run (CREATE DATABASE db_*)
|
||||
# - Run from a host that can reach the Postgres container
|
||||
#
|
||||
# Usage:
|
||||
# PGHOST=db PGUSER=postgres PGPASSWORD=change-me bash split-databases.sh
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SOURCE_DB="${SOURCE_DB:-appdb}"
|
||||
|
||||
# ── Table → database mapping ───────────────────────────────────────────────
|
||||
|
||||
declare -A DB_TABLES
|
||||
|
||||
DB_TABLES[db_account]="
|
||||
users
|
||||
magic_links
|
||||
oauth_codes
|
||||
oauth_grants
|
||||
ghost_labels
|
||||
user_labels
|
||||
ghost_newsletters
|
||||
user_newsletters
|
||||
ghost_tiers
|
||||
ghost_subscriptions
|
||||
kv
|
||||
"
|
||||
|
||||
DB_TABLES[db_blog]="
|
||||
authors
|
||||
tags
|
||||
posts
|
||||
post_authors
|
||||
post_tags
|
||||
post_likes
|
||||
menu_items
|
||||
menu_nodes
|
||||
container_relations
|
||||
"
|
||||
|
||||
DB_TABLES[db_market]="
|
||||
products
|
||||
product_images
|
||||
product_sections
|
||||
product_labels
|
||||
product_stickers
|
||||
product_attributes
|
||||
product_nutrition
|
||||
product_allergens
|
||||
product_likes
|
||||
product_logs
|
||||
market_places
|
||||
nav_tops
|
||||
nav_subs
|
||||
listings
|
||||
listing_items
|
||||
link_errors
|
||||
link_externals
|
||||
subcategory_redirects
|
||||
"
|
||||
|
||||
DB_TABLES[db_cart]="
|
||||
cart_items
|
||||
orders
|
||||
order_items
|
||||
"
|
||||
|
||||
DB_TABLES[db_events]="
|
||||
calendars
|
||||
calendar_slots
|
||||
calendar_entries
|
||||
calendar_entry_posts
|
||||
ticket_types
|
||||
tickets
|
||||
page_configs
|
||||
"
|
||||
|
||||
DB_TABLES[db_federation]="
|
||||
ap_anchors
|
||||
ap_actor_profiles
|
||||
ap_activities
|
||||
ap_followers
|
||||
ap_inbox_items
|
||||
ap_remote_actors
|
||||
ap_following
|
||||
ap_remote_posts
|
||||
ap_local_posts
|
||||
ap_interactions
|
||||
ap_notifications
|
||||
ap_delivery_log
|
||||
ipfs_pins
|
||||
"
|
||||
|
||||
# ── Migrate each domain ────────────────────────────────────────────────────
|
||||
|
||||
for target_db in db_account db_blog db_market db_cart db_events db_federation; do
|
||||
tables="${DB_TABLES[$target_db]}"
|
||||
table_list=""
|
||||
for t in $tables; do
|
||||
table_list="$table_list --table=$t"
|
||||
done
|
||||
|
||||
echo "=== Migrating $target_db ==="
|
||||
echo " Tables: $(echo $tables | tr '\n' ' ')"
|
||||
|
||||
# Dump schema + data for these tables from the source DB
|
||||
pg_dump "$SOURCE_DB" $table_list --no-owner --no-privileges \
|
||||
| psql -q "$target_db"
|
||||
|
||||
echo " Done."
|
||||
done
|
||||
|
||||
# ── Stamp Alembic head in each domain DB ──────────────────────────────────
|
||||
|
||||
echo ""
|
||||
echo "=== Stamping Alembic head in each DB ==="
|
||||
for target_db in db_account db_blog db_market db_cart db_events db_federation; do
|
||||
# Create alembic_version table and stamp current head
|
||||
psql -q "$target_db" <<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS alembic_version (
|
||||
version_num VARCHAR(32) NOT NULL,
|
||||
CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num)
|
||||
);
|
||||
DELETE FROM alembic_version;
|
||||
INSERT INTO alembic_version (version_num) VALUES ('v2t0p8q9r0');
|
||||
SQL
|
||||
echo " $target_db stamped at v2t0p8q9r0"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Migration complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Update docker-compose.yml — set per-app DATABASE_URL to the new DBs"
|
||||
echo " 2. Remove schema_sql config (no longer needed)"
|
||||
echo " 3. Redeploy all services"
|
||||
echo ""
|
||||
echo "Per-app DATABASE_URL values:"
|
||||
echo " blog: postgresql+asyncpg://postgres:change-me@db:5432/db_blog"
|
||||
echo " market: postgresql+asyncpg://postgres:change-me@db:5432/db_market"
|
||||
echo " cart: postgresql+asyncpg://postgres:change-me@db:5432/db_cart"
|
||||
echo " events: postgresql+asyncpg://postgres:change-me@db:5432/db_events"
|
||||
echo " federation: postgresql+asyncpg://postgres:change-me@db:5432/db_federation"
|
||||
echo " account: postgresql+asyncpg://postgres:change-me@db:5432/db_account"
|
||||
echo ""
|
||||
echo " DATABASE_URL_ACCOUNT: postgresql+asyncpg://postgres:change-me@db:5432/db_account"
|
||||
echo " DATABASE_URL_FEDERATION: postgresql+asyncpg://postgres:change-me@db:5432/db_federation"
|
||||
Reference in New Issue
Block a user