Purpose: Centralized hub for all @StPeteMusic brand tools, automation, and infrastructure. Houses n8n workflows, documentation, and supporting tools for managing social media, events, and community engagement in St. Petersburg, FL.
Live n8n instance: https://n8n-stpetemusic.duckdns.org
/
├── README.md # This file
├── CLAUDE.md # Claude Code guidance
├── AWS_SETUP.md # AWS infrastructure quick reference
├── .env.example # Environment variable template (commit this)
├── .env # Local secrets (DO NOT COMMIT)
├── .gitignore
│
├── infrastructure/ # Terraform IaC (manages all AWS resources)
│ ├── main.tf # Provider config + S3 remote backend
│ ├── variables.tf # Input variables
│ ├── outputs.tf # Output values (IP, URLs, SG ID)
│ ├── ec2.tf # EC2 instance, Elastic IP, Security Group
│ ├── backup.tf # S3 backup bucket (disabled, ready to enable)
│ ├── database.tf # RDS PostgreSQL (disabled, ready to enable)
│ └── terraform.tfvars.example # Example variable values (no secrets)
│
├── .github/
│ └── workflows/
│ ├── terraform-plan.yml # Runs terraform plan on PRs
│ └── terraform-apply.yml # Runs terraform apply on merge to main
│
├── database/ # PostgreSQL schema and seed data
│ ├── schema.sql # Full table definitions + pgcrypto encryption
│ └── seed.sql # Initial data from CSV contacts + templates
│
├── n8n/ # n8n automation engine
│ ├── CLAUDE.md # n8n-specific Claude guidance
│ ├── docker-compose.yaml # Local development setup
│ ├── docker-compose.prod.yaml # Production (AWS EC2) setup
│ ├── local-files/ # Read/write files for workflows (CSV, MD)
│ └── workflows/
│ └── StPeteMusic/ # Active workflows (source of truth)
│ ├── obsidian-post-creator.json
│ ├── obsidian-to-youtube-posting.json
│ ├── youtube-shorts-tracker-creator.json
│ └── system-prompt.md # AI agent instructions
│
├── data/ # Data archives (gitignored)
│
└── docs/ # Project documentation
├── AWS_DEPLOYMENT.md # Step-by-step AWS deployment guide
├── OBSIDIAN_DATAVIEW_QUERIES.md
└── YOUTUBE_SHORTS_*.md
n8n runs on AWS EC2 (t3.micro, free tier) with HTTPS via Let's Encrypt. All infrastructure is managed with Terraform — see infrastructure/.
| Resource | Value |
|---|---|
| n8n URL | https://n8n-stpetemusic.duckdns.org |
| Server | AWS EC2 t3.micro, us-east-1 |
| SSH Key | ~/.ssh/stpetemusic-n8n.pem |
| DNS | DuckDNS free subdomain |
| SSL | Let's Encrypt (auto-renews) |
Quick reference:
AWS_SETUP.md| Step-by-step from scratch:docs/AWS_DEPLOYMENT.md
All resources are in us-east-1 (N. Virginia).
| Resource | ID | Console Link |
|---|---|---|
| EC2 Instance | i-03874197d725b0455 |
Open in Console |
| Elastic IP | 54.235.171.182 |
Open in Console |
| Security Group | sg-03a69e68cf7077cf3 |
Open in Console |
| EBS Volume (20GB gp3) | — | EC2 → Volumes |
| Free Tier Usage | — | Billing → Free Tier |
| Billing Budgets | — | Billing → Budgets |
| IAM User | maylortaylor |
IAM → Users |
Terraform remote state is stored in S3, locked via DynamoDB. Never edit AWS resources manually — always go through Terraform.
| Resource | ID | Console Link |
|---|---|---|
| S3 State Bucket | stpetemusic-terraform-state |
Open in Console |
| DynamoDB Lock Table | stpetemusic-terraform-locks |
Open in Console |
| GitHub Actions | — | Actions → Runs |
Terraform workflow:
cd infrastructure
terraform plan # preview changes (also runs automatically on PRs)
terraform apply # apply changes (also runs automatically on merge to main)Import existing resources (already done — documented here for reference):
terraform import aws_security_group.n8n sg-03a69e68cf7077cf3
terraform import aws_instance.n8n i-03874197d725b0455
terraform import aws_eip.n8n eipalloc-0a2ebbeef75ce8009Only workflows in n8n/workflows/StPeteMusic/ are considered active. All others are legacy/reference.
| Workflow | Purpose | AI |
|---|---|---|
obsidian-post-creator.json |
Chat agent → generates YouTube post metadata → writes draft to Obsidian | Claude (default) |
obsidian-to-youtube-posting.json |
Publishes Obsidian drafts to YouTube | Claude (default) |
youtube-shorts-tracker-creator.json |
Tracks and creates YouTube Shorts | Gemini (backup) |
AI Configuration:
- Default: Anthropic Claude (
CLAUDE_API_KEY_N8N_STPETEMUSIC) - Backup: Google Gemini (
N8N_GEMINI_API_KEY)
For local testing before pushing changes to production.
- Docker + Docker Compose
- All credentials in
.env(copy from.env.example)
# 1. Copy environment template
cp .env.example .env
# Fill in your credentials
# 2. Start n8n
cd n8n
docker-compose up -d
# 3. Open n8n UI
open http://localhost:5678
# 4. Import workflows from n8n/workflows/StPeteMusic/cd n8n
docker-compose down# SSH into server
ssh -i ~/.ssh/stpetemusic-n8n.pem [email protected]
# View n8n logs
docker logs -f n8n
# Restart n8n
docker restart n8n
# Update n8n to latest version
docker pull n8nio/n8n:latest
cd ~/stpetemusic/n8n
docker-compose -f docker-compose.prod.yaml --env-file ../.env up -dSee AWS_SETUP.md for full production reference.
| Variable | Purpose | Required |
|---|---|---|
N8N_ENCRYPTION_KEY |
n8n data encryption | Yes |
CLAUDE_API_KEY_N8N_STPETEMUSIC |
Anthropic Claude (default AI) | Yes |
GROQ_API_KEY |
Groq LLM | Optional |
N8N_GEMINI_API_KEY |
Google Gemini (backup AI) | Optional |
IG_USER_ID |
Instagram Business account ID | For IG workflows |
IG_ACCESS_TOKEN |
Instagram access token (60-day expiry) | For IG workflows |
FB_PAGE_ID |
Facebook Page ID | For FB workflows |
FB_ACCESS_TOKEN |
Facebook access token | For FB workflows |
YOUTUBE_CLIENT_ID |
YouTube OAuth client ID | For YT workflows |
YOUTUBE_CLIENT_SECRET |
YouTube OAuth client secret | For YT workflows |
YOUTUBE_API_KEY |
YouTube Data API key | For YT workflows |
Never commit
.env— it's gitignored. See.env.examplefor the full template.
| Token | Expiry | How to Refresh |
|---|---|---|
| Instagram/Facebook | 60 days | curl "https://graph.instagram.com/access_token?grant_type=ig_refresh_token&access_token=YOUR_TOKEN" |
| YouTube | Managed by OAuth | Re-authenticate in n8n Credentials UI |
When setting up OAuth credentials (YouTube, Instagram, Facebook) in n8n or Google/Meta Developer portals, use this callback URL:
https://n8n-stpetemusic.duckdns.org/rest/oauth2-credential/callback
Status: Changes committed, awaiting Terraform apply and server reboot
Completed:
-
✅ n8n Workflow: obsidian-to-youtube-posting.json
- Updated "Build Updated Content" Code node with smart tag merging logic
- Now changes
status: ready→status: published - Auto-generates default tags:
#stpetemusic,#suiteestudios,#bandname,#publishedyt - Smart merge: detects existing "## Tags" section, merges tags without duplicates
- If no tags section exists, creates new one at end of file
- Tags tracked for platform status:
#publishedYT,#publishedIG, etc.
-
✅ Terraform: EC2 Auto Recovery
- Added
maintenance_options { auto_recovery = "on" }toinfrastructure/ec2.tf - Instance will auto-restart if it becomes unresponsive due to hardware/system issues
- Works alongside Docker's
restart: unless-stoppedpolicy (handles app crashes)
- Added
Pending (Tomorrow):
-
⏳ Terraform apply
- Fix AWS credential chain issue (file path error in credential helper)
- Run
terraform planandterraform applyto enable auto-recovery - Issue:
/Users/matttaylor/Documents/_dev/amver-hub/aws_tokenfile missing (likely PSD config bleed)
-
⏳ Reboot EC2 instance
- Instance is currently hung (n8n crashed during YouTube upload, won't respond to SSH)
- AWS confirms instance is "running" but needs restart
- After Terraform apply, reboot to test auto-recovery feature
-
⏳ Create PR
- Branch: new feature branch with workflow + Terraform changes
- PR should include:
- n8n workflow JSON update (smart tags)
- infrastructure/ec2.tf update (auto-recovery)
- Updated README (this section)
Known Blockers:
- AWS credential chain issue: Terraform/AWS CLI failing with reference to
/Users/matttaylor/Documents/_dev/amver-hub/aws_token - Workaround: May need to manually configure AWS credentials or fix credential helper path
- SSH timeout: EC2 instance not responding — waiting for Terraform to enable auto-recovery, then reboot
Testing Plan (Tomorrow):
- Verify Terraform apply succeeds
- Reboot instance via AWS Console or CLI
- Verify n8n comes back online
- Test obsidian-to-youtube-posting workflow with tag generation
- Verify tags section created/merged correctly in Obsidian file
First time? Run the setup script:
bash scripts/setup.shThis validates your environment, credentials, and configuration in one command.
See CLAUDE.md for detailed setup and troubleshooting.
To prevent issues like credential leakage or environment contamination:
| Safeguard | How It Works |
|---|---|
| direnv (.envrc) | Auto-isolates environment when you cd into the directory — unsets problematic global vars |
| Pre-commit hooks | Prevents secrets and bad configs from being committed |
| Setup script | Validates all dependencies and configuration |
| GitHub Actions | Runs terraform plan on PRs to catch infrastructure issues |
All three are now in place and active. See CLAUDE.md for setup instructions.
- n8n on AWS EC2 (always-on, HTTPS, free tier)
- Obsidian → YouTube posting pipeline
- YouTube Shorts tracker
- Claude as default AI, Gemini as backup
- Terraform IaC — all AWS resources version-controlled in
infrastructure/ - Terraform remote state — S3 bucket + DynamoDB lock table
- GitHub Actions —
terraform planon PRs,terraform applyon merge to main - GitHub Actions — JSON validation, security scanning, Dependabot
- Automated S3 backups — every 2 days at 4am, 30-day retention, IAM instance profile auth
- PostgreSQL database — Docker on EC2, full schema for contacts/stats/templates, pgcrypto encryption
- EC2 Auto Recovery — automatically restart instance if unresponsive (in progress)
- n8n smart tag tracking — auto-generate and merge tags for post status tracking (in progress)
- SSH setup +
docker-compose uppostgres on EC2 (rundatabase/seed.sqlto populate) - Instagram access token (pending Facebook app review workaround)
- Workflow: multi-platform posting (IG + FB + YouTube from one trigger)
- Fix AWS credential helper path issue (amver-hub reference)
- Auto-update ig_mentions via n8n scheduled workflow
- YouTube stats import (user to provide export data)
- Obsidian → Instagram posting pipeline
- Event management (EventBrite API)
- CloudWatch monitoring + SNS alerts for critical failures
- Health check script for n8n container (restart on hang)
@StPeteMusic — Community music promoter, St. Petersburg FL
| Platform | URL |
|---|---|
| https://www.instagram.com/StPeteMusic | |
| https://www.facebook.com/StPeteFLMusic | |
| YouTube | https://youtube.com/@StPeteMusic |
| Linktree | https://linktr.ee/stpetemusic |
Anchor Events:
- Final Friday — Last Friday of each month, Suite E Studios
- Instant Noodles — Last Wednesday of each month, community jam
- Second Saturday Art Walk — Warehouse Arts District
Team: Matt Taylor (owner), Austen Van Der Bleek (co-owner), Rob Morey, Alex MacDonald
Last updated: March 2026 | Maintained by Matt Taylor (@maylortaylor)