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
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
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
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?
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
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 |