Skip to content

Current Infrastructure

Purpose: Single source of truth for all hosted services. Audience: GFSC team, coordinators, volunteers with infrastructure access.

Living document. If you change something, update it here. [INPUT NEEDED: x] marks gaps to fill in.

Service Index

Service Host URL Status Deploy
Mastodon / Hometown shaw social.gfsc.studio ✅ Running Co-op Cloud
Mailman shaw lists.gfsc.community 🔴 Broken Co-op Cloud
HedgeDoc shaw pad.gfsc.studio ✅ Running Co-op Cloud
n8n shaw Deprecated Co-op Cloud
Listmonk shaw Deprecated Co-op Cloud
donna-bot misc-hetzner ✅ Running Kamal
musicwall misc-hetzner musicwall.club ✅ Running Kamal
PlaceCal (production) placecal-production placecal.org ✅ Running Kamal
PlaceCal (staging) placecal-staging placecal-staging.org ✅ Running Kamal
Ghost blog Digital Ocean gfsc.community ✅ Running Manual
Handbook GitHub Pages handbook.gfsc.community ✅ Running Git push

Infrastructure Map

graph TD

    subgraph DO["Digital Ocean"]
        Ghost["Ghost blog\ngfsc.community\n✅ Running"]
    end

    subgraph Shaw["Hetzner — shaw (community services)"]
        Mastodon["Mastodon / Hometown\nsocial.gfsc.studio\n✅ Running"]
        HedgeDoc["HedgeDoc\npad.gfsc.studio\n✅ Running"]
        Mailman["Mailman\nlists.gfsc.studio\n✅ Running"]
        n8n["n8n\n❓ Status unknown"]
        Listmonk["Listmonk\n❓ Status unknown"]
    end

    subgraph Prod["Hetzner — PlaceCal production"]
        PlaceCalP["PlaceCal\nplacecal.org\n ✅ Running"]
        DjP["Delayed Job\n(background jobs)"]
        PgP["PostgreSQL"]
    end

    subgraph Staging2["Hetzner — PlaceCal staging"]
        PlaceCalS["PlaceCal staging\n✅ Running"]
        DjS["Delayed Job\n(background jobs)"]
        PgS["PostgreSQL"]
    end

    subgraph KamalBox["Hetzner — Kamal box"]
        DonnaBot["donna-bot\n✅ Running"]
        Musicwall["musicwall\n✅ Running"]
    end

DNS: Cloudflare (some domains) + Namecheap (coordinator's account) Code: github.com/geeksforsocialchange + git.coopcloud.tech (Co-op Cloud config) Monitoring: AppSignal (PlaceCal application only)

Hosting Providers

Hetzner

  • Account holder: Kim / GFSC
  • Dashboard: cloud.hetzner.com
  • Known servers:
  • PlaceCal production — [INPUT NEEDED: confirm monthly cost from invoice]
  • PlaceCal staging — [INPUT NEEDED: confirm monthly cost from invoice]
  • Kamal box (donna-bot + musicwall) — [INPUT NEEDED: spec and cost]
  • Co-op Cloud box (shaw) — [INPUT NEEDED: who owns this account / what is the billing arrangement?][INPUT NEEDED: confirm exact monthly cost]
  • Total Hetzner: [INPUT NEEDED: actual monthly invoice]

Co-op Cloud (shaw)

  • What it is: Docker Swarm on Hetzner. Config lives on git.coopcloud.tech (Gitea).
  • Billing: [INPUT NEEDED: who owns the Hetzner account for shaw — GFSC, Autonomic, or individual? What is the billing arrangement?]
  • Monthly cost: [INPUT NEEDED: confirm exact monthly cost]
  • Management: [INPUT NEEDED: who currently manages shaw and what is the arrangement?]
  • Support contact: [INPUT NEEDED: who to contact for OS/infrastructure issues on shaw?]
  • git.coopcloud.tech repo: [INPUT NEEDED: URL]

Digital Ocean

  • Account holder: Kim / GFSC
  • Services: Ghost blog only
  • Monthly cost: $12/mo (~£10)

Cloudflare (DNS)

  • Account holder: Kim / GFSC
  • Manages: GFSC domains where applicable (some domains are on Namecheap — see DNS section)
  • Cost: Free tier

Known Managed Services (not self-hosted)

Service Provider Purpose Cost
Transactional email [INPUT NEEDED: verify — Mailersend?] PlaceCal sends event emails [INPUT NEEDED: verify]
App monitoring AppSignal PlaceCal errors + performance Free (open source plan)
Container registry GitHub Container Registry PlaceCal Docker images Free
Ghost email Mailgun Ghost blog transactional email £12/mo

Note

PlaceCal's transactional email provider needs verification — check the PlaceCal repo config. A higher-tier Mailgun account may also be needed for PlaceCal soon.

Services — Detail

Mastodon / Hometown

What it is: Federated social network (Hometown fork — adds local-only posting to Mastodon). Community perk for subscribers. URL: https://social.gfsc.studio Host: Co-op Cloud / Hetzner (shaw) Status: ✅ Running

Access - Admin: https://social.gfsc.studio/admin [INPUT NEEDED: confirm path, who has login] - SSH: [INPUT NEEDED: direct access to shaw, or via someone else?] - Credentials held by: [INPUT NEEDED]

Deploy / Update - Managed via Co-op Cloud on git.coopcloud.tech - Updates: [INPUT NEEDED: automated or manual pull request?] - [INPUT NEEDED: who handles OS layer on shaw and what is the current arrangement?]

When it breaks 1. Check domain: dig social.gfsc.studio — does it resolve? 2. Check TLS: curl -I https://social.gfsc.studio — cert valid? 3. Common issue: TLS renewal failure — check Traefik + Let's Encrypt logs 4. If container issue: [INPUT NEEDED: who to contact and how?] 5. If DNS issue: Cloudflare/Namecheap dashboard → check A record

Mailman

What it is: Mailing list manager URL: https://lists.gfsc.community Host: Co-op Cloud / Hetzner (shaw) Status: 🔴 Not currently responding

Active lists: [INPUT NEEDED: how many lists, how active?]

Access - Admin: [INPUT NEEDED] - Credentials held by: [INPUT NEEDED]

When it breaks 1. Check: curl -I https://lists.gfsc.community to see current state 2. If container-level: [INPUT NEEDED: who to contact and how?]

HedgeDoc

What it is: Real-time collaborative markdown editor URL: https://pad.gfsc.studio Host: Co-op Cloud / Hetzner (shaw) Status: ✅ Running — confirmed live, HTTP 200 Note: HedgeDoc 1.x is in maintenance mode upstream (security fixes only, no new features). 2.x is a separate rewrite, not a drop-in upgrade. Backend: Express.js

Usage: [INPUT NEEDED: who uses this, how often, for what?]

Access - Login: [INPUT NEEDED: local accounts or SSO?] - Credentials held by: [INPUT NEEDED]

When it breaks 1. Check: curl -I https://pad.gfsc.studio — confirmed returns 200 2. Check: PostgreSQL container healthy (HedgeDoc 1.x has a DB dependency) 3. If container-level: [INPUT NEEDED: who to contact and how?]

n8n

What it is: Workflow automation Host: Co-op Cloud / Hetzner (shaw) Status: [INPUT NEEDED: confirm currently running?]

Access - [INPUT NEEDED: admin URL, credentials, who holds them]

Active workflows: [INPUT NEEDED: are any workflows currently running? Who set them up?]

Listmonk

What it is: Newsletter / mailing list platform Host: Co-op Cloud / Hetzner (shaw) Status: [INPUT NEEDED: confirm currently running?]

Access - [INPUT NEEDED: admin URL, credentials, who holds them]

Active lists/campaigns: [INPUT NEEDED: any active subscriber lists or campaigns?]

donna-bot

What it is: [INPUT NEEDED: what does this do? Discord bot?] Host: Kamal / Hetzner (separate box from shaw and PlaceCal) Status: ✅ Running

Access - SSH: [INPUT NEEDED: which box, which user] - Credentials held by: [INPUT NEEDED] - Repo: [INPUT NEEDED: GitHub or Codeberg URL]

Deploy / Update

kamal deploy   # from repo root

When it breaks

docker ps | grep donna              # is it running?
docker logs [container] --tail 100  # what's it saying?
docker restart [container]          # quick restart
kamal deploy                        # full redeploy

musicwall

What it is: [INPUT NEEDED: what is this?] Host: Kamal / Hetzner (same box as donna-bot) Status: ✅ Running

Access - SSH: [INPUT NEEDED] - Repo: [INPUT NEEDED]

When it breaks

docker ps | grep musicwall
docker logs [container] --tail 100
docker restart [container]

PlaceCal (Production)

What it is: GFSC's flagship community event aggregator. Ruby on Rails. Serves 600+ organisations. URL: https://placecal.org Host: Hetzner (production server) Status: ✅ Running Monitoring: AppSignal (errors + performance — already set up, free on open source plan) Email: [INPUT NEEDED: verify provider — Mailersend or other?]

Current resource usage: [INPUT NEEDED: confirm from live monitoring once in place]

Access - SSH: [INPUT NEEDED: which user, key location] - Credentials held by: [INPUT NEEDED] - Rails admin: [INPUT NEEDED: URL path]

Deploy / Update

# From the PlaceCal repo root:
kamal deploy -d production        # deploy
kamal app logs -d production      # view logs
kamal rollback -d production      # rollback if needed
Repo: github.com/geeksforsocialchange/PlaceCal

When it breaks

docker ps | grep placecal                        # containers running?
docker logs [web-container] --tail 100           # app errors?
docker exec [web-container] bin/rails db:migrate # missed migration?
docker exec -it [db-container] psql -U [user]    # DB alive?
AppSignal will surface most app-level errors before you need to SSH in.

PlaceCal (Staging)

What it is: Preview/test environment for PlaceCal Host: Hetzner (staging server) Status: ✅ Running

Deploy: Same as production, different Kamal target (-d staging) When it breaks: Same steps as production — lower urgency

Ghost Blog

What it is: GFSC community blog URL: https://gfsc.community Host: Digital Ocean droplet Status: ✅ Running

Access - Admin: https://gfsc.community/ghost - Credentials held by: [INPUT NEEDED] - Digital Ocean droplet: [INPUT NEEDED: droplet name/ID]

When it breaks

# SSH to Digital Ocean droplet
ghost status
ghost restart

Handbook

What it is: GFSC operational documentation URL: https://handbook.gfsc.community Generator: Zensical — MkDocs Material-based static site tool Source repo: github.com/geeksforsocialchange/PlaceCal-Handbook Status: ✅ Running

Deploy: Git push → GitHub Actions builds with Zensical → [INPUT NEEDED: Cloudflare Pages or GitHub Pages?] When it breaks: Check GitHub Actions build log in the PlaceCal-Handbook repo. Static site — no server, no database, nothing to crash.

DNS

Providers: Cloudflare + Namecheap (coordinator's account) Account holder: [INPUT NEEDED]

Domain Points to Notes
placecal.org Hetzner (production)
social.gfsc.studio Hetzner (shaw)
lists.gfsc.community Hetzner (shaw)
pad.gfsc.studio Hetzner (shaw)
gfsc.community Digital Ocean
handbook.gfsc.community [INPUT NEEDED: Cloudflare Pages / other?]

Backups

This section records what backup arrangements are in place. [INPUT NEEDED] throughout — this is a critical gap to fill.

Service Data at risk Backup method Location Retention Who verifies
PlaceCal production PostgreSQL database [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED]
PlaceCal production Uploaded assets / media [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED]
PlaceCal staging PostgreSQL database [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED]
Mastodon (shaw) PostgreSQL database [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED]
Mastodon (shaw) Media store [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED]
HedgeDoc (shaw) PostgreSQL database [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED]
Ghost blog Database + content [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED]

Warning

No confirmed backup arrangements are currently documented.

Credentials & Access Audit

Passwords and keys are NOT stored here. This records who holds what, so we know who to contact.

System Primary holder Secondary Notes
Hetzner account [INPUT NEEDED] [INPUT NEEDED]
shaw (Co-op Cloud box) [INPUT NEEDED] [INPUT NEEDED] [INPUT NEEDED: who manages and what is the arrangement?]
Digital Ocean [INPUT NEEDED] [INPUT NEEDED]
Cloudflare / DNS [INPUT NEEDED] [INPUT NEEDED]
Namecheap / DNS Primary coordinator [INPUT NEEDED]
GitHub (geeksforsocialchange org) [INPUT NEEDED] [INPUT NEEDED]
git.coopcloud.tech [INPUT NEEDED] [INPUT NEEDED]
AppSignal [INPUT NEEDED] [INPUT NEEDED]
Mailgun [INPUT NEEDED] [INPUT NEEDED] Ghost email
Shared credential store [INPUT NEEDED: 1Password? Vaultwarden? Bitwarden? Nothing?] Critical gap