chore: add Infisical migration deploy script and compose files
Three new Infisical-wired compose files (one per Postiz space) plus a single migrate-to-infisical.sh script that handles the full switchover: extract existing POSTGRES_PASSWORD, backup old files, install new compose, create minimal .env, restart, verify health. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f6481d99e3
commit
19d79b7eb6
|
|
@ -0,0 +1,156 @@
|
|||
services:
|
||||
postiz-bcrg:
|
||||
image: ghcr.io/gitroomhq/postiz-app:latest
|
||||
container_name: postiz-bcrg
|
||||
restart: unless-stopped
|
||||
entrypoint: ["/infisical-entrypoint.sh"]
|
||||
command: ["docker-entrypoint.sh", "sh", "-c", "nginx && pnpm run pm2"]
|
||||
environment:
|
||||
# === Infisical secret injection ===
|
||||
INFISICAL_CLIENT_ID: "${INFISICAL_CLIENT_ID}"
|
||||
INFISICAL_CLIENT_SECRET: "${INFISICAL_CLIENT_SECRET}"
|
||||
INFISICAL_PROJECT_SLUG: "postiz-bondingcurve"
|
||||
INFISICAL_ENV: "prod"
|
||||
INFISICAL_URL: "http://infisical:8080"
|
||||
# === Config (not secrets) ===
|
||||
MAIN_URL: "https://bondingcurve.rsocials.online"
|
||||
FRONTEND_URL: "https://bondingcurve.rsocials.online"
|
||||
NEXT_PUBLIC_BACKEND_URL: "https://bondingcurve.rsocials.online/api"
|
||||
DATABASE_URL: "postgresql://postiz:${POSTGRES_PASSWORD}@postiz-bcrg-postgres:5432/postiz"
|
||||
REDIS_URL: "redis://postiz-bcrg-redis:6379"
|
||||
BACKEND_INTERNAL_URL: "http://localhost:3000"
|
||||
TEMPORAL_ADDRESS: "postiz-bcrg-temporal:7233"
|
||||
IS_GENERAL: "true"
|
||||
DISABLE_REGISTRATION: "false"
|
||||
STORAGE_PROVIDER: "local"
|
||||
UPLOAD_DIRECTORY: "/uploads"
|
||||
NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads"
|
||||
# === OAuth config (client_id/secret come from Infisical) ===
|
||||
POSTIZ_GENERIC_OAUTH: "true"
|
||||
NEXT_PUBLIC_POSTIZ_OAUTH_DISPLAY_NAME: "Pocket ID"
|
||||
NEXT_PUBLIC_POSTIZ_OAUTH_LOGO_URL: "https://raw.githubusercontent.com/pocket-id/pocket-id/refs/heads/main/frontend/static/img/static-logo.svg"
|
||||
POSTIZ_OAUTH_URL: "https://auth.jeffemmett.com"
|
||||
POSTIZ_OAUTH_AUTH_URL: "https://auth.jeffemmett.com/authorize"
|
||||
POSTIZ_OAUTH_TOKEN_URL: "https://auth.jeffemmett.com/api/oidc/token"
|
||||
POSTIZ_OAUTH_USERINFO_URL: "https://auth.jeffemmett.com/api/oidc/userinfo"
|
||||
# === Email config (EMAIL_PASS comes from Infisical) ===
|
||||
EMAIL_PROVIDER: "nodemailer"
|
||||
EMAIL_FROM_NAME: "Bonding Curve Research"
|
||||
EMAIL_FROM_ADDRESS: "noreply@rmail.online"
|
||||
EMAIL_HOST: "mailcowdockerized-postfix-mailcow-1"
|
||||
EMAIL_PORT: "587"
|
||||
EMAIL_SECURE: "false"
|
||||
EMAIL_USER: "noreply@rmail.online"
|
||||
NODE_TLS_REJECT_UNAUTHORIZED: "0"
|
||||
API_LIMIT: 30
|
||||
NX_ADD_PLUGINS: false
|
||||
volumes:
|
||||
- postiz-bcrg-config:/config/
|
||||
- postiz-bcrg-uploads:/uploads/
|
||||
- /opt/infisical/entrypoint-wrapper.sh:/infisical-entrypoint.sh:ro
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-bcrg"
|
||||
- "traefik.http.routers.postiz-bcrg.rule=Host(`bondingcurve.rsocials.online`) || Host(`socials.bondingcurve.tech`)"
|
||||
- "traefik.http.routers.postiz-bcrg.entrypoints=web,websecure"
|
||||
- "traefik.http.services.postiz-bcrg.loadbalancer.server.port=5000"
|
||||
networks:
|
||||
- traefik-public
|
||||
- postiz-bcrg-internal
|
||||
- mailcow-network
|
||||
depends_on:
|
||||
postiz-bcrg-postgres:
|
||||
condition: service_healthy
|
||||
postiz-bcrg-redis:
|
||||
condition: service_healthy
|
||||
postiz-bcrg-temporal:
|
||||
condition: service_started
|
||||
|
||||
postiz-bcrg-postgres:
|
||||
image: postgres:17-alpine
|
||||
container_name: postiz-bcrg-postgres
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-bcrg"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||
POSTGRES_USER: postiz
|
||||
POSTGRES_DB: postiz
|
||||
volumes:
|
||||
- postiz-bcrg-postgres-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- postiz-bcrg-internal
|
||||
healthcheck:
|
||||
test: pg_isready -U postiz -d postiz
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
|
||||
postiz-bcrg-redis:
|
||||
image: redis:7.2
|
||||
container_name: postiz-bcrg-redis
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-bcrg"
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: redis-cli ping
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
volumes:
|
||||
- postiz-bcrg-redis-data:/data
|
||||
networks:
|
||||
- postiz-bcrg-internal
|
||||
|
||||
postiz-bcrg-temporal-postgres:
|
||||
image: postgres:16
|
||||
container_name: postiz-bcrg-temporal-postgres
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-bcrg"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: temporal
|
||||
POSTGRES_USER: temporal
|
||||
networks:
|
||||
- postiz-bcrg-internal
|
||||
volumes:
|
||||
- postiz-bcrg-temporal-postgres-data:/var/lib/postgresql/data
|
||||
|
||||
postiz-bcrg-temporal:
|
||||
image: temporalio/auto-setup:1.28.1
|
||||
container_name: postiz-bcrg-temporal
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-bcrg"
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- postiz-bcrg-temporal-postgres
|
||||
environment:
|
||||
- DB=postgres12
|
||||
- DB_PORT=5432
|
||||
- POSTGRES_USER=temporal
|
||||
- POSTGRES_PWD=temporal
|
||||
- POSTGRES_SEEDS=postiz-bcrg-temporal-postgres
|
||||
- TEMPORAL_NAMESPACE=default
|
||||
networks:
|
||||
- postiz-bcrg-internal
|
||||
|
||||
volumes:
|
||||
postiz-bcrg-postgres-data:
|
||||
postiz-bcrg-redis-data:
|
||||
postiz-bcrg-config:
|
||||
postiz-bcrg-uploads:
|
||||
postiz-bcrg-temporal-postgres-data:
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
postiz-bcrg-internal:
|
||||
driver: bridge
|
||||
mailcow-network:
|
||||
external: true
|
||||
name: mailcowdockerized_mailcow-network
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
services:
|
||||
postiz-cc:
|
||||
image: ghcr.io/gitroomhq/postiz-app:latest
|
||||
container_name: postiz-cc
|
||||
restart: unless-stopped
|
||||
entrypoint: ["/infisical-entrypoint.sh"]
|
||||
command: ["docker-entrypoint.sh", "sh", "-c", "nginx && pnpm run pm2"]
|
||||
environment:
|
||||
# === Infisical secret injection ===
|
||||
INFISICAL_CLIENT_ID: "${INFISICAL_CLIENT_ID}"
|
||||
INFISICAL_CLIENT_SECRET: "${INFISICAL_CLIENT_SECRET}"
|
||||
INFISICAL_PROJECT_SLUG: "postiz-crypto-commons"
|
||||
INFISICAL_ENV: "prod"
|
||||
INFISICAL_URL: "http://infisical:8080"
|
||||
# === Config (not secrets) ===
|
||||
MAIN_URL: "https://socials.crypto-commons.org"
|
||||
FRONTEND_URL: "https://socials.crypto-commons.org"
|
||||
NEXT_PUBLIC_BACKEND_URL: "https://socials.crypto-commons.org/api"
|
||||
DATABASE_URL: "postgresql://postiz:${POSTGRES_PASSWORD}@postiz-cc-postgres:5432/postiz"
|
||||
REDIS_URL: "redis://postiz-cc-redis:6379"
|
||||
BACKEND_INTERNAL_URL: "http://localhost:3000"
|
||||
TEMPORAL_ADDRESS: "postiz-cc-temporal:7233"
|
||||
IS_GENERAL: "true"
|
||||
DISABLE_REGISTRATION: "true"
|
||||
STORAGE_PROVIDER: "local"
|
||||
UPLOAD_DIRECTORY: "/uploads"
|
||||
NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads"
|
||||
# === OAuth config (client_id/secret come from Infisical) ===
|
||||
POSTIZ_GENERIC_OAUTH: "true"
|
||||
NEXT_PUBLIC_POSTIZ_OAUTH_DISPLAY_NAME: "Pocket ID"
|
||||
NEXT_PUBLIC_POSTIZ_OAUTH_LOGO_URL: "https://raw.githubusercontent.com/pocket-id/pocket-id/refs/heads/main/frontend/static/img/static-logo.svg"
|
||||
POSTIZ_OAUTH_URL: "https://auth.jeffemmett.com"
|
||||
POSTIZ_OAUTH_AUTH_URL: "https://auth.jeffemmett.com/authorize"
|
||||
POSTIZ_OAUTH_TOKEN_URL: "https://auth.jeffemmett.com/api/oidc/token"
|
||||
POSTIZ_OAUTH_USERINFO_URL: "https://auth.jeffemmett.com/api/oidc/userinfo"
|
||||
# === Email config (EMAIL_PASS comes from Infisical) ===
|
||||
EMAIL_PROVIDER: "nodemailer"
|
||||
EMAIL_FROM_NAME: "Crypto Commons"
|
||||
EMAIL_FROM_ADDRESS: "noreply@rmail.online"
|
||||
EMAIL_HOST: "mailcowdockerized-postfix-mailcow-1"
|
||||
EMAIL_PORT: "587"
|
||||
EMAIL_SECURE: "false"
|
||||
EMAIL_USER: "noreply@rmail.online"
|
||||
NODE_TLS_REJECT_UNAUTHORIZED: "0"
|
||||
API_LIMIT: 30
|
||||
NX_ADD_PLUGINS: false
|
||||
volumes:
|
||||
- postiz-cc-config:/config/
|
||||
- postiz-cc-uploads:/uploads/
|
||||
- /opt/infisical/entrypoint-wrapper.sh:/infisical-entrypoint.sh:ro
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-cc"
|
||||
- "traefik.http.routers.postiz-cc.rule=Host(`socials.crypto-commons.org`) || Host(`socials.valleyofthecommons.com`)"
|
||||
- "traefik.http.routers.postiz-cc.entrypoints=web,websecure"
|
||||
- "traefik.http.services.postiz-cc.loadbalancer.server.port=5000"
|
||||
networks:
|
||||
- traefik-public
|
||||
- postiz-cc-internal
|
||||
- mailcow-network
|
||||
depends_on:
|
||||
postiz-cc-postgres:
|
||||
condition: service_healthy
|
||||
postiz-cc-redis:
|
||||
condition: service_healthy
|
||||
postiz-cc-temporal:
|
||||
condition: service_started
|
||||
|
||||
postiz-cc-postgres:
|
||||
image: postgres:17-alpine
|
||||
container_name: postiz-cc-postgres
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-cc"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||
POSTGRES_USER: postiz
|
||||
POSTGRES_DB: postiz
|
||||
volumes:
|
||||
- postiz-cc-postgres-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- postiz-cc-internal
|
||||
healthcheck:
|
||||
test: pg_isready -U postiz -d postiz
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
|
||||
postiz-cc-redis:
|
||||
image: redis:7.2
|
||||
container_name: postiz-cc-redis
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-cc"
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: redis-cli ping
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
volumes:
|
||||
- postiz-cc-redis-data:/data
|
||||
networks:
|
||||
- postiz-cc-internal
|
||||
|
||||
postiz-cc-elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.24
|
||||
container_name: postiz-cc-elasticsearch
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-cc"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- xpack.security.enabled=false
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
volumes:
|
||||
- postiz-cc-elasticsearch-data:/usr/share/elasticsearch/data
|
||||
networks:
|
||||
- postiz-cc-internal
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
postiz-cc-temporal-postgres:
|
||||
image: postgres:16
|
||||
container_name: postiz-cc-temporal-postgres
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-cc"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: temporal
|
||||
POSTGRES_USER: temporal
|
||||
networks:
|
||||
- postiz-cc-internal
|
||||
volumes:
|
||||
- postiz-cc-temporal-postgres-data:/var/lib/postgresql/data
|
||||
|
||||
postiz-cc-temporal:
|
||||
image: temporalio/auto-setup:1.28.1
|
||||
container_name: postiz-cc-temporal
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-cc"
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- postiz-cc-temporal-postgres
|
||||
- postiz-cc-elasticsearch
|
||||
environment:
|
||||
- DB=postgres12
|
||||
- DB_PORT=5432
|
||||
- POSTGRES_USER=temporal
|
||||
- POSTGRES_PWD=temporal
|
||||
- POSTGRES_SEEDS=postiz-cc-temporal-postgres
|
||||
- ENABLE_ES=true
|
||||
- ES_SEEDS=postiz-cc-elasticsearch
|
||||
- ES_VERSION=v7
|
||||
- TEMPORAL_NAMESPACE=default
|
||||
networks:
|
||||
- postiz-cc-internal
|
||||
|
||||
volumes:
|
||||
postiz-cc-postgres-data:
|
||||
postiz-cc-redis-data:
|
||||
postiz-cc-config:
|
||||
postiz-cc-uploads:
|
||||
postiz-cc-temporal-postgres-data:
|
||||
postiz-cc-elasticsearch-data:
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
postiz-cc-internal:
|
||||
driver: bridge
|
||||
mailcow-network:
|
||||
external: true
|
||||
name: mailcowdockerized_mailcow-network
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
services:
|
||||
postiz-p2pf:
|
||||
image: ghcr.io/gitroomhq/postiz-app:latest
|
||||
container_name: postiz-p2pf
|
||||
restart: unless-stopped
|
||||
entrypoint: ["/infisical-entrypoint.sh"]
|
||||
command: ["docker-entrypoint.sh", "sh", "-c", "nginx && pnpm run pm2"]
|
||||
environment:
|
||||
# === Infisical secret injection ===
|
||||
INFISICAL_CLIENT_ID: "${INFISICAL_CLIENT_ID}"
|
||||
INFISICAL_CLIENT_SECRET: "${INFISICAL_CLIENT_SECRET}"
|
||||
INFISICAL_PROJECT_SLUG: "postiz-p2pfoundation"
|
||||
INFISICAL_ENV: "prod"
|
||||
INFISICAL_URL: "http://infisical:8080"
|
||||
# === Config (not secrets) ===
|
||||
MAIN_URL: "https://p2pf.rsocials.online"
|
||||
FRONTEND_URL: "https://p2pf.rsocials.online"
|
||||
NEXT_PUBLIC_BACKEND_URL: "https://p2pf.rsocials.online/api"
|
||||
DATABASE_URL: "postgresql://postiz:${POSTGRES_PASSWORD}@postiz-p2pf-postgres:5432/postiz"
|
||||
REDIS_URL: "redis://postiz-p2pf-redis:6379"
|
||||
BACKEND_INTERNAL_URL: "http://localhost:3000"
|
||||
TEMPORAL_ADDRESS: "postiz-p2pf-temporal:7233"
|
||||
IS_GENERAL: "true"
|
||||
DISABLE_REGISTRATION: "false"
|
||||
STORAGE_PROVIDER: "local"
|
||||
UPLOAD_DIRECTORY: "/uploads"
|
||||
NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads"
|
||||
# === OAuth config (client_id/secret come from Infisical) ===
|
||||
POSTIZ_GENERIC_OAUTH: "true"
|
||||
NEXT_PUBLIC_POSTIZ_OAUTH_DISPLAY_NAME: "Pocket ID"
|
||||
NEXT_PUBLIC_POSTIZ_OAUTH_LOGO_URL: "https://raw.githubusercontent.com/pocket-id/pocket-id/refs/heads/main/frontend/static/img/static-logo.svg"
|
||||
POSTIZ_OAUTH_URL: "https://auth.jeffemmett.com"
|
||||
POSTIZ_OAUTH_AUTH_URL: "https://auth.jeffemmett.com/authorize"
|
||||
POSTIZ_OAUTH_TOKEN_URL: "https://auth.jeffemmett.com/api/oidc/token"
|
||||
POSTIZ_OAUTH_USERINFO_URL: "https://auth.jeffemmett.com/api/oidc/userinfo"
|
||||
# === Email config (EMAIL_PASS comes from Infisical) ===
|
||||
EMAIL_PROVIDER: "nodemailer"
|
||||
EMAIL_FROM_NAME: "P2P Foundation Socials"
|
||||
EMAIL_FROM_ADDRESS: "noreply@rmail.online"
|
||||
EMAIL_HOST: "mailcowdockerized-postfix-mailcow-1"
|
||||
EMAIL_PORT: "587"
|
||||
EMAIL_SECURE: "false"
|
||||
EMAIL_USER: "noreply@rmail.online"
|
||||
NODE_TLS_REJECT_UNAUTHORIZED: "0"
|
||||
API_LIMIT: 30
|
||||
NX_ADD_PLUGINS: false
|
||||
volumes:
|
||||
- postiz-p2pf-config:/config/
|
||||
- postiz-p2pf-uploads:/uploads/
|
||||
- /opt/infisical/entrypoint-wrapper.sh:/infisical-entrypoint.sh:ro
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-p2pf"
|
||||
- "traefik.http.routers.postiz-p2pf.rule=Host(`p2pf.rsocials.online`) || Host(`socials.p2pfoundation.net`)"
|
||||
- "traefik.http.routers.postiz-p2pf.entrypoints=web,websecure"
|
||||
- "traefik.http.services.postiz-p2pf.loadbalancer.server.port=5000"
|
||||
networks:
|
||||
- traefik-public
|
||||
- postiz-p2pf-internal
|
||||
- mailcow-network
|
||||
depends_on:
|
||||
postiz-p2pf-postgres:
|
||||
condition: service_healthy
|
||||
postiz-p2pf-redis:
|
||||
condition: service_healthy
|
||||
postiz-p2pf-temporal:
|
||||
condition: service_started
|
||||
|
||||
postiz-p2pf-postgres:
|
||||
image: postgres:17-alpine
|
||||
container_name: postiz-p2pf-postgres
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-p2pf"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||
POSTGRES_USER: postiz
|
||||
POSTGRES_DB: postiz
|
||||
volumes:
|
||||
- postiz-p2pf-postgres-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- postiz-p2pf-internal
|
||||
healthcheck:
|
||||
test: pg_isready -U postiz -d postiz
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
|
||||
postiz-p2pf-redis:
|
||||
image: redis:7.2
|
||||
container_name: postiz-p2pf-redis
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-p2pf"
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: redis-cli ping
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
volumes:
|
||||
- postiz-p2pf-redis-data:/data
|
||||
networks:
|
||||
- postiz-p2pf-internal
|
||||
|
||||
postiz-p2pf-temporal-postgres:
|
||||
image: postgres:16
|
||||
container_name: postiz-p2pf-temporal-postgres
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-p2pf"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: temporal
|
||||
POSTGRES_USER: temporal
|
||||
networks:
|
||||
- postiz-p2pf-internal
|
||||
volumes:
|
||||
- postiz-p2pf-temporal-postgres-data:/var/lib/postgresql/data
|
||||
|
||||
postiz-p2pf-temporal:
|
||||
image: temporalio/auto-setup:1.28.1
|
||||
container_name: postiz-p2pf-temporal
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=postiz-p2pf"
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- postiz-p2pf-temporal-postgres
|
||||
environment:
|
||||
- DB=postgres12
|
||||
- DB_PORT=5432
|
||||
- POSTGRES_USER=temporal
|
||||
- POSTGRES_PWD=temporal
|
||||
- POSTGRES_SEEDS=postiz-p2pf-temporal-postgres
|
||||
- TEMPORAL_NAMESPACE=default
|
||||
networks:
|
||||
- postiz-p2pf-internal
|
||||
|
||||
volumes:
|
||||
postiz-p2pf-postgres-data:
|
||||
postiz-p2pf-redis-data:
|
||||
postiz-p2pf-config:
|
||||
postiz-p2pf-uploads:
|
||||
postiz-p2pf-temporal-postgres-data:
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
postiz-p2pf-internal:
|
||||
driver: bridge
|
||||
mailcow-network:
|
||||
external: true
|
||||
name: mailcowdockerized_mailcow-network
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# Migrate Postiz spaces from plaintext .env to Infisical secret injection
|
||||
# =============================================================================
|
||||
#
|
||||
# Run this ON the Netcup server as root:
|
||||
# ssh netcup-full
|
||||
# bash /path/to/migrate-to-infisical.sh
|
||||
#
|
||||
# What it does:
|
||||
# 1. Extracts POSTGRES_PASSWORD from each existing .env
|
||||
# 2. Backs up old docker-compose.yml and .env
|
||||
# 3. Copies new Infisical-wired compose files into place
|
||||
# 4. Creates minimal .env (INFISICAL_CLIENT_ID/SECRET + POSTGRES_PASSWORD)
|
||||
# 5. Restarts each space one at a time
|
||||
# 6. Verifies containers come up healthy
|
||||
# 7. Moves old .env to .env.removed (you delete after confirming)
|
||||
#
|
||||
# Prerequisites:
|
||||
# - Machine identities created in Infisical for each project
|
||||
# - /opt/infisical/entrypoint-wrapper.sh exists
|
||||
# - This script is in the same directory as docker-compose.{cc,p2pf,bcrg}.yml
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
POSTIZ_BASE="/opt/postiz"
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
# Color output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${CYAN}[migrate]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}[ OK ]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[ WARN ]${NC} $*"; }
|
||||
err() { echo -e "${RED}[ERROR ]${NC} $*"; }
|
||||
|
||||
# ── Preflight checks ──────────────────────────────────────────────────────────
|
||||
|
||||
log "Preflight checks..."
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
err "Must run as root (ssh netcup-full)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f /opt/infisical/entrypoint-wrapper.sh ]; then
|
||||
err "Infisical entrypoint wrapper not found at /opt/infisical/entrypoint-wrapper.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for slug in cc p2pf bcrg; do
|
||||
if [ ! -f "$SCRIPT_DIR/docker-compose.${slug}.yml" ]; then
|
||||
err "Missing $SCRIPT_DIR/docker-compose.${slug}.yml"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
ok "Preflight passed"
|
||||
|
||||
# ── Space definitions ─────────────────────────────────────────────────────────
|
||||
|
||||
declare -A SPACE_DIR
|
||||
SPACE_DIR[cc]="crypto-commons"
|
||||
SPACE_DIR[p2pf]="p2pfoundation"
|
||||
SPACE_DIR[bcrg]="bondingcurve"
|
||||
|
||||
declare -A SPACE_INFISICAL_SLUG
|
||||
SPACE_INFISICAL_SLUG[cc]="postiz-crypto-commons"
|
||||
SPACE_INFISICAL_SLUG[p2pf]="postiz-p2pfoundation"
|
||||
SPACE_INFISICAL_SLUG[bcrg]="postiz-bondingcurve"
|
||||
|
||||
# ── Collect Infisical credentials ─────────────────────────────────────────────
|
||||
# You can either enter them interactively or set them as env vars before running:
|
||||
# export INFISICAL_CC_CLIENT_ID=... INFISICAL_CC_CLIENT_SECRET=...
|
||||
# export INFISICAL_P2PF_CLIENT_ID=... INFISICAL_P2PF_CLIENT_SECRET=...
|
||||
# export INFISICAL_BCRG_CLIENT_ID=... INFISICAL_BCRG_CLIENT_SECRET=...
|
||||
|
||||
declare -A INF_CLIENT_ID
|
||||
declare -A INF_CLIENT_SECRET
|
||||
|
||||
for slug in cc p2pf bcrg; do
|
||||
upper=$(echo "$slug" | tr '[:lower:]' '[:upper:]')
|
||||
id_var="INFISICAL_${upper}_CLIENT_ID"
|
||||
secret_var="INFISICAL_${upper}_CLIENT_SECRET"
|
||||
|
||||
if [ -n "${!id_var:-}" ] && [ -n "${!secret_var:-}" ]; then
|
||||
INF_CLIENT_ID[$slug]="${!id_var}"
|
||||
INF_CLIENT_SECRET[$slug]="${!secret_var}"
|
||||
ok "Using env var credentials for ${SPACE_DIR[$slug]}"
|
||||
else
|
||||
echo ""
|
||||
log "Enter Infisical machine identity for ${SPACE_DIR[$slug]} (${SPACE_INFISICAL_SLUG[$slug]}):"
|
||||
read -rp " Client ID: " INF_CLIENT_ID[$slug]
|
||||
read -rp " Client Secret: " INF_CLIENT_SECRET[$slug]
|
||||
if [ -z "${INF_CLIENT_ID[$slug]}" ] || [ -z "${INF_CLIENT_SECRET[$slug]}" ]; then
|
||||
err "Missing credentials for ${SPACE_DIR[$slug]}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
log "Starting migration..."
|
||||
echo ""
|
||||
|
||||
# ── Migrate each space ────────────────────────────────────────────────────────
|
||||
|
||||
for slug in cc p2pf bcrg; do
|
||||
dir="${POSTIZ_BASE}/${SPACE_DIR[$slug]}"
|
||||
log "━━━ Migrating ${SPACE_DIR[$slug]} (postiz-${slug}) ━━━"
|
||||
|
||||
# 1. Extract POSTGRES_PASSWORD from existing .env
|
||||
if [ -f "$dir/.env" ]; then
|
||||
PG_PASS=$(grep '^POSTGRES_PASSWORD=' "$dir/.env" | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
||||
if [ -z "$PG_PASS" ]; then
|
||||
err "Could not extract POSTGRES_PASSWORD from $dir/.env"
|
||||
err "Check the file manually and set it in the new .env"
|
||||
exit 1
|
||||
fi
|
||||
ok "Extracted POSTGRES_PASSWORD from existing .env"
|
||||
else
|
||||
err "No .env found at $dir/.env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. Backup old files
|
||||
log "Backing up old files..."
|
||||
cp "$dir/docker-compose.yml" "$dir/docker-compose.yml.pre-infisical-${TIMESTAMP}"
|
||||
cp "$dir/.env" "$dir/.env.pre-infisical-${TIMESTAMP}"
|
||||
ok "Backed up to *.pre-infisical-${TIMESTAMP}"
|
||||
|
||||
# 3. Copy new compose file
|
||||
log "Installing new Infisical-wired compose..."
|
||||
cp "$SCRIPT_DIR/docker-compose.${slug}.yml" "$dir/docker-compose.yml"
|
||||
ok "Installed new docker-compose.yml"
|
||||
|
||||
# 4. Create minimal .env
|
||||
log "Creating minimal .env (3 values only)..."
|
||||
cat > "$dir/.env" << ENVEOF
|
||||
# Infisical machine identity (fetches all other secrets at container start)
|
||||
INFISICAL_CLIENT_ID=${INF_CLIENT_ID[$slug]}
|
||||
INFISICAL_CLIENT_SECRET=${INF_CLIENT_SECRET[$slug]}
|
||||
|
||||
# Postgres password (needed at compose interpolation time for DB containers)
|
||||
POSTGRES_PASSWORD=${PG_PASS}
|
||||
ENVEOF
|
||||
chmod 600 "$dir/.env"
|
||||
ok "Created minimal .env (600 perms)"
|
||||
|
||||
# 5. Restart containers
|
||||
log "Restarting ${SPACE_DIR[$slug]}..."
|
||||
cd "$dir"
|
||||
docker compose down 2>&1 | sed 's/^/ /'
|
||||
docker compose up -d 2>&1 | sed 's/^/ /'
|
||||
|
||||
# 6. Wait for health
|
||||
log "Waiting for postiz-${slug} to be healthy (up to 90s)..."
|
||||
healthy=false
|
||||
for i in $(seq 1 18); do
|
||||
sleep 5
|
||||
state=$(docker inspect --format='{{.State.Running}}' "postiz-${slug}" 2>/dev/null || echo "false")
|
||||
if [ "$state" = "true" ]; then
|
||||
# Check if the entrypoint wrapper ran successfully by looking at logs
|
||||
if docker logs "postiz-${slug}" 2>&1 | grep -q "\[infisical-wrapper\] Fetching secrets"; then
|
||||
healthy=true
|
||||
break
|
||||
fi
|
||||
fi
|
||||
echo -n "."
|
||||
done
|
||||
echo ""
|
||||
|
||||
if $healthy; then
|
||||
ok "postiz-${slug} is running with Infisical secrets"
|
||||
else
|
||||
warn "postiz-${slug} may not be healthy yet. Check logs:"
|
||||
warn " docker logs postiz-${slug} 2>&1 | head -30"
|
||||
warn "Continuing with next space..."
|
||||
fi
|
||||
|
||||
# 7. Move old .env backup to .removed
|
||||
mv "$dir/.env.pre-infisical-${TIMESTAMP}" "$dir/.env.REMOVED-${TIMESTAMP}"
|
||||
ok "Old .env renamed to .env.REMOVED-${TIMESTAMP}"
|
||||
echo ""
|
||||
done
|
||||
|
||||
# ── Summary ───────────────────────────────────────────────────────────────────
|
||||
|
||||
echo ""
|
||||
log "━━━ Migration Complete ━━━"
|
||||
echo ""
|
||||
log "Verify each space is working:"
|
||||
echo " curl -s https://socials.crypto-commons.org | head -5"
|
||||
echo " curl -s https://p2pf.rsocials.online | head -5"
|
||||
echo " curl -s https://bondingcurve.rsocials.online | head -5"
|
||||
echo ""
|
||||
log "Check container logs:"
|
||||
echo " docker logs postiz-cc 2>&1 | grep infisical"
|
||||
echo " docker logs postiz-p2pf 2>&1 | grep infisical"
|
||||
echo " docker logs postiz-bcrg 2>&1 | grep infisical"
|
||||
echo ""
|
||||
log "Once confirmed working, delete the old .env backups:"
|
||||
echo " rm /opt/postiz/crypto-commons/.env.REMOVED-*"
|
||||
echo " rm /opt/postiz/p2pfoundation/.env.REMOVED-*"
|
||||
echo " rm /opt/postiz/bondingcurve/.env.REMOVED-*"
|
||||
echo " rm /opt/postiz/*/docker-compose.yml.pre-infisical-*"
|
||||
echo ""
|
||||
ok "Done! Secrets are now managed by Infisical."
|
||||
Loading…
Reference in New Issue