{"id":45939062,"url":"https://github.com/mac9sb/configuration","last_synced_at":"2026-02-28T10:19:56.644Z","repository":{"id":337257660,"uuid":"1152515674","full_name":"mac9sb/configuration","owner":"mac9sb","description":"Root configuration for developer tooling, sites and services on macOS","archived":false,"fork":false,"pushed_at":"2026-02-20T13:52:07.000Z","size":285,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-20T17:56:45.891Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mac9sb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-08T01:39:34.000Z","updated_at":"2026-02-20T13:52:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mac9sb/configuration","commit_stats":null,"previous_names":["mac9sb/configuration"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mac9sb/configuration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mac9sb%2Fconfiguration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mac9sb%2Fconfiguration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mac9sb%2Fconfiguration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mac9sb%2Fconfiguration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mac9sb","download_url":"https://codeload.github.com/mac9sb/configuration/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mac9sb%2Fconfiguration/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29930233,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T09:58:13.507Z","status":"ssl_error","status_checked_at":"2026-02-28T09:57:57.047Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-28T10:19:56.056Z","updated_at":"2026-02-28T10:19:56.628Z","avatar_url":"https://github.com/mac9sb.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Server\n\nPersonal macOS development environment — manages sites, tooling, and infrastructure as a single repository with git submodules.\n\n## Todo\nasdfasdf\n- [ ] Look into creating cron jobs where codex will analyze repo and submodules for clean up tasks and create PR's\n\n## Structure\n\n```\n~/Developer/\n├── setup.sh                 # Main setup script\n├── uninstall.sh             # Teardown script\n├── .env.example             # R2 credentials template (tracked)\n├── .env.local               # R2 credentials (gitignored)\n├── utilities/\n│   ├── dotfiles/            # Symlinked to ~/.*\n│   └── githooks/            # Installed to .git/hooks/ during setup\n├── tooling/\n│   ├── orchestrator/\n│   │   └── Sources/OrchestratorCLI/Resources/\n│   │       ├── cloudflared/ # Tunnel + primary domain config template\n│   │       ├── launchd/     # Launchd plist templates\n│   │       ├── newsyslog/   # Log rotation config template\n│   │       └── scripts/     # Runtime scripts\n│   └── \u003cother tools\u003e/       # CLI tool submodules\n└── sites/                   # Website submodules\n```\n\n## Quick Start\n\n```sh\ngit clone --recursive https://github.com/mac9sb/server.git ~/Developer\ncd ~/Developer\ncp .env.example .env.local   # fill in R2 credentials\n./setup.sh                   # prompts for sudo during Phase A\n```\n\n\u003e [!NOTE]\n\u003e Setup uses the repo `Brewfile` (Homebrew + mas) to install tools, casks, and App Store apps.\n\u003e Sign into the App Store first if you want MAS installs to succeed.\n\n## Architecture\n\n```\nInternet → Cloudflare Tunnel (maclong) → Apache :80 → VirtualHost routing\n                                            │\n              ┌─────────────────────────────┼──────────────────────────────┐\n              │                             │                              │\n        maclong.dev                  api.maclong.dev                cool-app.com\n       (VirtualHost →              (VirtualHost →                (VirtualHost →\n        static from                 proxy → :8001)                proxy → :8002)\n        .output)\n                         localhost/site-name/  ← path-based dev access for all\n```\n\n- **Primary domain**: set in `tooling/orchestrator/Sources/OrchestratorCLI/Resources/cloudflared/config.yml` via `# primary-domain: maclong.dev`\n- **Domain sites**: directory name contains a dot → custom domain VirtualHost (e.g. `sites/cool-app.com/`)\n- **Subdomain sites**: directory name has no dot → subdomain of primary domain (e.g. `sites/api/` → `api.maclong.dev`)\n- **Local dev**: every site is also accessible at `http://localhost/site-name/` via path-based routing\n- **Static sites**: `.output/` directory → Apache serves via `DocumentRoot` or `Alias`\n- **Server apps**: `.build/release/Application` (or `.build/\u003ctriple\u003e/release/Application`) → reverse-proxied via `mod_proxy`\n- **State**: single SQLite dasdfasdfatabase (WAL mode) at `~/Library/Application Support/com.mac9sb/state.db`\n\n## Submodules\n\nSubmodules are the source of truth for what repos exist; orchestrator derives Apache and cloudflared routing directly from the filesystem. Adding or removing a submodule is all you need to do for routing — custom domains still require a DNS route to the tunnel (see below).\n\n### Adding\n\n```sh\ncd ~/Developer\n\n# Primary domain site (directory name = domain)\ngit submodule add https://github.com/mac9sb/portfolio.git sites/maclong.dev\n\n# Subdomain site (no dot → becomes api.maclong.dev)\ngit submodule add https://github.com/mac9sb/api.git sites/api\n\n# Custom domain site (dot in name → becomes cool-app.com)\ngit submodule add https://github.com/mac9sb/cool-app.git sites/cool-app.com\n\n# Tooling\ngit submodule add https://github.com/mac9sb/\u003crepo\u003e.git tooling/\u003crepo\u003e\n\ngit commit -m \"Add \u003crepo\u003e suasdfsadfbmodule\"\n```\n\nThe orchestrator daemon auto-detects new sites and configures Apache + process supervision.\n\n### Updating\n\n```sh\ngit submodule update --remote --merge\ngit add sites/\u003cname\u003e\ngit commit -m \"Update \u003cname\u003e submodule\"\n```\n\n\u003e [!WARNING]\n\u003e **Do NOT use `git -C sites/\u003cname\u003e pull`** — this bypasses submodule tracking. The pre-push hook will block inconsistent pushes.\n\n## Domain Routing\n\nApache routing is derived entirely from site directory names and the primary domain configured in `tooling/orchestrator/Sources/OrchestratorCLI/Resources/cloudflared/config.yml` (ingress entries are auto-managed by orchestrator):\n\n```\n# primary-domain: maclong.dev\n```\n\n| Directory name | VirtualHost `ServerName` | How it works |\n|---|---|---|\n| `sites/maclong.dev/` | `maclong.dev` | Dot in name → custom domain (also the primary) |\n| `sites/api/` | `api.maclong.dev` | No dot → subdomain of primary domain |\n| `sites/cool-app.com/` | `cool-app.com` | Dot in name → custom domain |\n\nEvery site also gets a path-based entry in the default VirtualHost for local development at `http://localhost/site-name/`.\n\n### Adding a Subdomain Site\n\nSubdomain DNS is already covered by the `*.maclong.dev` wildcard — just add the submodule:\n\n```sh\ngit submodule add https://github.com/mac9sb/api.git sites/api\ngit commit -m \"Add api submodule\"\n# → automatically served at api.maclong.dev\n```\n\n### Adding a Custom Domain Site\n\nCustom domains need a DNS route to the tunnel; the cloudflared ingress entry is auto-managed:\n\n1. Add the submodule (directory name = the domain):\n\n   ```sh\n   git submodule add https://github.com/mac9sb/cool-app.git sites/cool-app.com\n   ```\n\n2. Orchestrator automatically updates `tooling/orchestrator/Sources/OrchestratorCLI/Resources/cloudflared/config.yml` (no manual edits needed).\n\n3. Route DNS to the tunnel:\n\n   ```sh\n   cloudflared tunnel route dns maclong cool-app.com\n   ```\n\n4. Orchestrator picks up the change, regenerating Apache config and ingress entries automatically.\n\n### Renaming / Changing Domains\n\n```sh\ngit mv sites/old-name sites/new-name.com\ngit commit -m \"Move to new-name.com\"\n```\n\n## Cloudflare Tunnel\n\nThe tunnel config at `tooling/orchestrator/Sources/OrchestratorCLI/Resources/cloudflared/config.yml` is version-controlled (no credentials) and rendered to `~/.cloudflared/config.yml` during setup. It contains:\n\n- The **primary domain** as a parseable comment (`# primary-domain: maclong.dev`)\n- **Ingress rules** for the primary domain and all discovered site hostnames\n- All ingress rules forward to Apache on `:80` — Apache handles per-site routing via VirtualHosts\n\nSee the comments in `tooling/orchestrator/Sources/OrchestratorCLI/Resources/cloudflared/config.yml` for full details.\n\n### First-Time Setup\n\n```sh\nsudo ./setup.sh    # renders config, installs agents\ncloudflared tunnel login\ncloudflared tunnel create maclong --credentials-file ~/.cloudflared/maclong.json\ncloudflared tunnel route dns maclong maclong.dev\ncloudflared tunnel route dns maclong \"*.maclong.dev\"\n```\n\n### With Existing Tunnel\n\nIf the tunnel already exists (e.g., created on another machine or a previous install), fetch the credentials and add DNS routes:\n\n```sh\n# Authenticate with Cloudflare (creates ~/.cloudflared/cert.pem)\ncloudflared tunnel login\n\n# Fetch credentials for the existing tunnel\ncloudflared tunnel token --cred-file ~/.cloudflared/maclong.json maclong\n\n# Add DNS routes (creates CNAME records pointing to the tunnel)\ncloudflared tunnel route dns maclong maclong.dev\ncloudflared tunnel route dns maclong \"*.maclong.dev\"\n\n# Use -f / --overwrite-dns to replace existing DNS records\ncloudflared tunnel route dns -f maclong \"*.maclong.dev\"\n```\n\n## Daily Backups\n\nA daily backup script runs at 03:00 via launchd, snapshots all SQLite databases, packages them into tarballs, and uploads to Cloudflare R2 using pure `curl` + S3v4 signing (no AWS CLI needed). Local backups are retained for 7 days.\n\nSee `tooling/orchestrator/Sources/OrchestratorCLI/Resources/scripts/backup.sh` for the full process. Copy `.env.example` to `.env.local` and fill in your R2 credentials:\n\n```sh\ncp .env.example .env.local\n```\n\n## Useful Commands\n\n```sh\n# Apache\nsudo apachectl configtest \u0026\u0026 sudo apachectl restart\n\n# Launchd agents\nlaunchctl list | grep mac9sb\n\n# Restart a specific server\norchestrator restart \u003cserver-name\u003e\n\n# Logs\ntail -f ~/Library/Logs/com.mac9sb/\u003csite\u003e.log\ntail -f ~/Library/Logs/com.mac9sb/orchestrator-*.log\ntail -f /var/log/apache2/sites/\u003csite\u003e-error.log\n\n# Submodules\ngit submodule status\ngit submodule update --remote --merge\n\n# Manual backup\n~/Developer/tooling/orchestrator/Sources/OrchestratorCLI/Resources/scripts/backup.sh\n\n# Rebuild a site\ncd ~/Developer/sites/\u003cname\u003e \u0026\u0026 swift build -c release\n\n# Tunnel\ncloudflared tunnel info maclong\ncloudflared tunnel list\n```\n\n## Teardown\n\n```sh\nsudo ./uninstall.sh          # standard (preserves CLI tools, SSH keys, credentials)\nsudo ./uninstall.sh --all    # full (also removes cloudflared)\n```\n\nSee `uninstall.sh` for exactly what gets removed and what's preserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmac9sb%2Fconfiguration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmac9sb%2Fconfiguration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmac9sb%2Fconfiguration/lists"}