{"id":"697c9efc090375fa10a230ed","title":"2026 01 29 Environment Setup Prerequisites","path":"how-to/technical-articles/2026-01-29-environment-setup-prerequisites","contentMarkdown":"# 29-Jan-2026 — Environment Setup Prerequisites\n\n_____\n\nThis guide explains how to set up a new NGX-Ramblers environment for a Ramblers group, covering all required services, credentials, and configuration options.\n\n## Overview\n\nThe environment setup feature automates the provisioning of new NGX-Ramblers group instances. It orchestrates:\n\n- Ramblers API integration for group data\n- AWS S3 bucket and IAM user creation\n- MongoDB Atlas database initialisation\n- Fly.io deployment configuration\n- Email service (Brevo) configuration\n\nTwo interfaces are available:\n- **CLI Tool** — Interactive command-line wizard\n- **Web UI** — Admin panel wizard (staging environments only)\n\n## Prerequisites\n\nBefore starting, ensure you have accounts and access to:\n\n| Service | Purpose | Sign-up URL |\n|---------|---------|-------------|\n| MongoDB Atlas | Database hosting | https://www.mongodb.com/cloud/atlas/register |\n| AWS | S3 storage for media files | https://aws.amazon.com/ |\n| Fly.io | Application hosting | https://fly.io/app/sign-up |\n| Brevo | Transactional email | https://www.brevo.com/free-signup/ |\n| Ramblers | Walks Manager API access | Contact Ramblers IT |\n\n### Optional Services\n\n| Service | Purpose | Sign-up URL |\n|---------|---------|-------------|\n| Google Cloud | Maps, Places, and Geocoding APIs | https://console.cloud.google.com/ |\n| Ordnance Survey | UK mapping tiles | https://osdatahub.os.uk/ |\n| Facebook | Social events integration | https://developers.facebook.com/ |\n| Meetup | Event synchronisation | https://www.meetup.com/api/oauth/list/ |\n| reCAPTCHA | Form spam protection | https://www.google.com/recaptcha/admin |\n\n## Required Credentials\n\n### Ramblers API\n\nContact Ramblers IT to obtain:\n- **API Key** — For Walks Manager API access\n- **Walks Manager Username/Password** (optional) — For walk synchronisation\n\n### MongoDB Atlas\n\n1. Create a cluster (M0 free tier is sufficient for small groups)\n2. Create a database user with read/write access\n3. Whitelist your IP addresses (or allow access from anywhere for Fly.io)\n4. Note your cluster hostname (e.g., `cluster0.abc123`)\n\n**Required values:**\n- Cluster hostname (without `.mongodb.net`)\n- Database username\n- Database password\n- Database name (e.g., `ngx-ramblers-mygroup`)\n\n### AWS S3\n\nFor automated bucket creation, you need AWS admin credentials. Alternatively, create the bucket manually.\n\n**For automated setup**, provide:\n- `AWS_ACCESS_KEY_ID` — Admin access key\n- `AWS_SECRET_ACCESS_KEY` — Admin secret key\n- `AWS_REGION` — Region (default: `eu-west-1`)\n\n**For manual setup**, create:\n1. An S3 bucket named `ngx-ramblers-{groupname}`\n2. An IAM user with S3 access to that bucket\n3. Access credentials for the IAM user\n\n### Brevo Email\n\n1. Sign up at https://www.brevo.com/\n2. Navigate to SMTP & API → API Keys\n3. Generate an API key\n\n### Fly.io\n\n1. Install the Fly CLI: `curl -L https://fly.io/install.sh | sh`\n2. Authenticate: `fly auth login`\n3. Note your organisation name (usually \"personal\")\n\n### Facebook (Optional)\n\nFor Facebook social events integration:\n\n1. Go to https://developers.facebook.com/\n2. Create a new app (Consumer type)\n3. Add the Facebook Login product\n4. Configure OAuth settings with your domain\n5. Note your App ID and App Secret\n\n**Required values:**\n- `FACEBOOK_APP_ID` — Application ID\n- `FACEBOOK_APP_SECRET` — Application secret\n\n### Meetup (Optional)\n\nFor Meetup event synchronisation:\n\n1. Go to https://www.meetup.com/api/oauth/list/\n2. Create a new OAuth Consumer\n3. Set the redirect URI to `https://yourdomain.com/api/meetup/oauth/callback`\n4. Note your OAuth credentials\n\n**Required values:**\n- `MEETUP_OAUTH_KEY` — OAuth consumer key\n- `MEETUP_OAUTH_SECRET` — OAuth consumer secret\n\n### Google Cloud (Optional)\n\nNGX-Ramblers uses multiple Google Cloud APIs. You need a single API key with access to:\n\n**Required APIs to enable:**\n- **Maps JavaScript API** — Interactive maps on walk pages\n- **Places API (New)** — Venue search and autocomplete\n- **Geocoding API** — Converting postcodes to coordinates\n\n**Setup steps:**\n\n1. Go to https://console.cloud.google.com/\n2. Create a new project (or select existing)\n3. Navigate to APIs & Services → Library\n4. Enable each of the three APIs listed above\n5. Navigate to APIs & Services → Credentials\n6. Create an API key\n7. Restrict the key to your domain(s) for security\n8. Restrict the key to only the required APIs\n\n**Required value:**\n- `GOOGLE_MAPS_APIKEY` — Single API key for all Google services\n\n**Billing note:** Google Cloud requires a billing account, but provides a generous free tier ($200/month credit) that covers most small group usage.\n\n## AWS IAM Setup for Multi-Environment Management\n\nIf you're managing multiple group environments, set up a master AWS account with delegated access.\n\n### Master Account Setup\n\n1. Create an IAM user for environment provisioning:\n   ```\n   User name: ngx-ramblers-provisioner\n   Access type: Programmatic access\n   ```\n\n2. Attach a custom policy allowing S3 and IAM operations:\n   ```json\n   {\n     \"Version\": \"2012-10-17\",\n     \"Statement\": [\n       {\n         \"Effect\": \"Allow\",\n         \"Action\": [\n           \"s3:CreateBucket\",\n           \"s3:PutBucketCors\",\n           \"s3:PutBucketPolicy\",\n           \"s3:PutPublicAccessBlock\"\n         ],\n         \"Resource\": \"arn:aws:s3:::ngx-ramblers-*\"\n       },\n       {\n         \"Effect\": \"Allow\",\n         \"Action\": [\n           \"iam:CreateUser\",\n           \"iam:CreateAccessKey\",\n           \"iam:PutUserPolicy\",\n           \"iam:AttachUserPolicy\"\n         ],\n         \"Resource\": \"arn:aws:iam::*:user/ngx-ramblers-*\"\n       }\n     ]\n   }\n   ```\n\n3. Store the access credentials securely (e.g., in a password manager)\n\n### Per-Environment Credentials\n\nThe setup process creates:\n- A dedicated IAM user per environment (e.g., `ngx-ramblers-mygroup-user`)\n- A bucket-specific policy with least-privilege access\n- Access credentials stored in the secrets file\n\nThis ensures each environment has isolated credentials that can be rotated independently.\n\n## Database Initialisation Options\n\n### Option 1: Fresh Database (Recommended for New Groups)\n\nThe setup wizard creates:\n- Configuration documents (system, Brevo, committee, walks)\n- Initial admin user account\n- System member account\n- Optional sample page content\n\n### Option 2: Restore from Backup\n\nFor migrating an existing group:\n\n1. Export the source database:\n   ```bash\n   mongodump --uri=\"mongodb+srv://user:pass@cluster.mongodb.net/source-db\" --out=./backup\n   ```\n\n2. Import to the new database:\n   ```bash\n   mongorestore --uri=\"mongodb+srv://user:pass@cluster.mongodb.net/new-db\" ./backup/source-db\n   ```\n\n3. Update configuration documents with new credentials (AWS, Brevo, etc.)\n\n### Option 3: Clone Existing Environment\n\nUse MongoDB Atlas's built-in backup/restore:\n1. Create a snapshot of the source cluster\n2. Restore to the target cluster with a new database name\n3. Update credentials in the `config` collection\n\n## Using the CLI Tool\n\n### Running the Wizard\n\n```bash\ncd server\nnpx tsx deploy/create-environment-cli.ts\n```\n\n### Interactive Steps\n\n1. **AWS Credentials** (optional)\n   - Enter admin credentials for automated S3 setup\n   - Skip to create bucket manually\n\n2. **Ramblers API Key**\n   - Enter your API key\n   - Validated against the Ramblers API\n\n3. **Group Selection**\n   - Enter group code directly (e.g., `01SURREY`)\n   - Or browse by area code (e.g., `01` for Surrey)\n\n4. **Environment Configuration**\n   - Environment name (derived from group name)\n   - Fly.io app name\n   - Memory allocation (MB)\n   - Instance count\n\n5. **MongoDB Configuration**\n   - Cluster hostname\n   - Username and password\n   - Database name\n\n6. **AWS S3 Configuration**\n   - Bucket name\n   - Region\n\n7. **Email Configuration**\n   - Brevo API key\n\n8. **Optional Services**\n   - Google Maps API key\n   - Walks Manager credentials\n\n9. **Admin User**\n   - Name, email, and password\n\n10. **Setup Options**\n    - Include sample pages\n    - Include notification configs\n    - Skip Fly.io deployment\n\n### Output Files\n\nThe wizard creates:\n\n| File | Purpose |\n|------|---------|\n| `non-vcs/secrets/secrets.{appName}.env` | Environment variables |\n| `non-vcs/fly-io/configs.json` | Fly.io deployment config |\n\n## Deploying to Fly.io\n\nAfter running the setup wizard:\n\n1. **Create the Fly.io app:**\n   ```bash\n   fly apps create ngx-ramblers-mygroup --org personal\n   ```\n\n2. **Import secrets:**\n   ```bash\n   fly secrets import < non-vcs/secrets/secrets.ngx-ramblers-mygroup.env -a ngx-ramblers-mygroup\n   ```\n\n3. **Deploy:**\n   ```bash\n   fly deploy -a ngx-ramblers-mygroup\n   ```\n\n4. **Verify:**\n   ```bash\n   fly status -a ngx-ramblers-mygroup\n   fly logs -a ngx-ramblers-mygroup\n   ```\n\n## Environment Variables Reference\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `NODE_ENV` | Yes | Set to `production` |\n| `MONGODB_URI` | Yes | Full MongoDB connection string |\n| `AUTH_SECRET` | Yes | 32-byte secret for JWT signing |\n| `AWS_ACCESS_KEY_ID` | Yes | S3 access key |\n| `AWS_SECRET_ACCESS_KEY` | Yes | S3 secret key |\n| `AWS_BUCKET` | Yes | S3 bucket name |\n| `AWS_REGION` | Yes | S3 region |\n| `GOOGLE_MAPS_APIKEY` | No | Google Maps API key |\n| `FACEBOOK_APP_ID` | No | Facebook application ID |\n| `FACEBOOK_APP_SECRET` | No | Facebook application secret |\n| `MEETUP_OAUTH_KEY` | No | Meetup OAuth consumer key |\n| `MEETUP_OAUTH_SECRET` | No | Meetup OAuth consumer secret |\n| `DEBUG` | No | Debug logging pattern |\n\n## Troubleshooting\n\n### MongoDB Connection Errors\n\n- Verify the cluster hostname is correct (without `.mongodb.net`)\n- Check the username and password are URL-encoded if they contain special characters\n- Ensure the IP whitelist includes Fly.io's IP ranges (or use 0.0.0.0/0)\n\n### AWS S3 Errors\n\n- Verify the IAM user has the required permissions\n- Check the bucket name is globally unique\n- Ensure CORS is configured for browser uploads\n\n### Fly.io Deployment Issues\n\n- Check logs: `fly logs -a appname`\n- Verify secrets are set: `fly secrets list -a appname`\n- Check machine status: `fly status -a appname`\n\n## Related Documentation\n\n- [Fly.io Documentation](https://fly.io/docs/)\n- [MongoDB Atlas Documentation](https://www.mongodb.com/docs/atlas/)\n- [AWS S3 Documentation](https://docs.aws.amazon.com/s3/)\n- [Brevo API Documentation](https://developers.brevo.com/)\n","contentHtml":"<h1>29-Jan-2026 — Environment Setup Prerequisites</h1>\n<hr>\n<p>This guide explains how to set up a new NGX-Ramblers environment for a Ramblers group, covering all required services, credentials, and configuration options.</p>\n<h2>Overview</h2>\n<p>The environment setup feature automates the provisioning of new NGX-Ramblers group instances. It orchestrates:</p>\n<ul>\n<li>Ramblers API integration for group data</li>\n<li>AWS S3 bucket and IAM user creation</li>\n<li>MongoDB Atlas database initialisation</li>\n<li>Fly.io deployment configuration</li>\n<li>Email service (Brevo) configuration</li>\n</ul>\n<p>Two interfaces are available:</p>\n<ul>\n<li><strong>CLI Tool</strong> — Interactive command-line wizard</li>\n<li><strong>Web UI</strong> — Admin panel wizard (staging environments only)</li>\n</ul>\n<h2>Prerequisites</h2>\n<p>Before starting, ensure you have accounts and access to:</p>\n<table>\n<thead>\n<tr>\n<th>Service</th>\n<th>Purpose</th>\n<th>Sign-up URL</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>MongoDB Atlas</td>\n<td>Database hosting</td>\n<td><a href=\"https://www.mongodb.com/cloud/atlas/register\">https://www.mongodb.com/cloud/atlas/register</a></td>\n</tr>\n<tr>\n<td>AWS</td>\n<td>S3 storage for media files</td>\n<td><a href=\"https://aws.amazon.com/\">https://aws.amazon.com/</a></td>\n</tr>\n<tr>\n<td>Fly.io</td>\n<td>Application hosting</td>\n<td><a href=\"https://fly.io/app/sign-up\">https://fly.io/app/sign-up</a></td>\n</tr>\n<tr>\n<td>Brevo</td>\n<td>Transactional email</td>\n<td><a href=\"https://www.brevo.com/free-signup/\">https://www.brevo.com/free-signup/</a></td>\n</tr>\n<tr>\n<td>Ramblers</td>\n<td>Walks Manager API access</td>\n<td>Contact Ramblers IT</td>\n</tr>\n</tbody></table>\n<h3>Optional Services</h3>\n<table>\n<thead>\n<tr>\n<th>Service</th>\n<th>Purpose</th>\n<th>Sign-up URL</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Google Cloud</td>\n<td>Maps, Places, and Geocoding APIs</td>\n<td><a href=\"https://console.cloud.google.com/\">https://console.cloud.google.com/</a></td>\n</tr>\n<tr>\n<td>Ordnance Survey</td>\n<td>UK mapping tiles</td>\n<td><a href=\"https://osdatahub.os.uk/\">https://osdatahub.os.uk/</a></td>\n</tr>\n<tr>\n<td>Facebook</td>\n<td>Social events integration</td>\n<td><a href=\"https://developers.facebook.com/\">https://developers.facebook.com/</a></td>\n</tr>\n<tr>\n<td>Meetup</td>\n<td>Event synchronisation</td>\n<td><a href=\"https://www.meetup.com/api/oauth/list/\">https://www.meetup.com/api/oauth/list/</a></td>\n</tr>\n<tr>\n<td>reCAPTCHA</td>\n<td>Form spam protection</td>\n<td><a href=\"https://www.google.com/recaptcha/admin\">https://www.google.com/recaptcha/admin</a></td>\n</tr>\n</tbody></table>\n<h2>Required Credentials</h2>\n<h3>Ramblers API</h3>\n<p>Contact Ramblers IT to obtain:</p>\n<ul>\n<li><strong>API Key</strong> — For Walks Manager API access</li>\n<li><strong>Walks Manager Username/Password</strong> (optional) — For walk synchronisation</li>\n</ul>\n<h3>MongoDB Atlas</h3>\n<ol>\n<li>Create a cluster (M0 free tier is sufficient for small groups)</li>\n<li>Create a database user with read/write access</li>\n<li>Whitelist your IP addresses (or allow access from anywhere for Fly.io)</li>\n<li>Note your cluster hostname (e.g., <code>cluster0.abc123</code>)</li>\n</ol>\n<p><strong>Required values:</strong></p>\n<ul>\n<li>Cluster hostname (without <code>.mongodb.net</code>)</li>\n<li>Database username</li>\n<li>Database password</li>\n<li>Database name (e.g., <code>ngx-ramblers-mygroup</code>)</li>\n</ul>\n<h3>AWS S3</h3>\n<p>For automated bucket creation, you need AWS admin credentials. Alternatively, create the bucket manually.</p>\n<p><strong>For automated setup</strong>, provide:</p>\n<ul>\n<li><code>AWS_ACCESS_KEY_ID</code> — Admin access key</li>\n<li><code>AWS_SECRET_ACCESS_KEY</code> — Admin secret key</li>\n<li><code>AWS_REGION</code> — Region (default: <code>eu-west-1</code>)</li>\n</ul>\n<p><strong>For manual setup</strong>, create:</p>\n<ol>\n<li>An S3 bucket named <code>ngx-ramblers-{groupname}</code></li>\n<li>An IAM user with S3 access to that bucket</li>\n<li>Access credentials for the IAM user</li>\n</ol>\n<h3>Brevo Email</h3>\n<ol>\n<li>Sign up at <a href=\"https://www.brevo.com/\">https://www.brevo.com/</a></li>\n<li>Navigate to SMTP &amp; API → API Keys</li>\n<li>Generate an API key</li>\n</ol>\n<h3>Fly.io</h3>\n<ol>\n<li>Install the Fly CLI: <code>curl -L https://fly.io/install.sh | sh</code></li>\n<li>Authenticate: <code>fly auth login</code></li>\n<li>Note your organisation name (usually &quot;personal&quot;)</li>\n</ol>\n<h3>Facebook (Optional)</h3>\n<p>For Facebook social events integration:</p>\n<ol>\n<li>Go to <a href=\"https://developers.facebook.com/\">https://developers.facebook.com/</a></li>\n<li>Create a new app (Consumer type)</li>\n<li>Add the Facebook Login product</li>\n<li>Configure OAuth settings with your domain</li>\n<li>Note your App ID and App Secret</li>\n</ol>\n<p><strong>Required values:</strong></p>\n<ul>\n<li><code>FACEBOOK_APP_ID</code> — Application ID</li>\n<li><code>FACEBOOK_APP_SECRET</code> — Application secret</li>\n</ul>\n<h3>Meetup (Optional)</h3>\n<p>For Meetup event synchronisation:</p>\n<ol>\n<li>Go to <a href=\"https://www.meetup.com/api/oauth/list/\">https://www.meetup.com/api/oauth/list/</a></li>\n<li>Create a new OAuth Consumer</li>\n<li>Set the redirect URI to <code>https://yourdomain.com/api/meetup/oauth/callback</code></li>\n<li>Note your OAuth credentials</li>\n</ol>\n<p><strong>Required values:</strong></p>\n<ul>\n<li><code>MEETUP_OAUTH_KEY</code> — OAuth consumer key</li>\n<li><code>MEETUP_OAUTH_SECRET</code> — OAuth consumer secret</li>\n</ul>\n<h3>Google Cloud (Optional)</h3>\n<p>NGX-Ramblers uses multiple Google Cloud APIs. You need a single API key with access to:</p>\n<p><strong>Required APIs to enable:</strong></p>\n<ul>\n<li><strong>Maps JavaScript API</strong> — Interactive maps on walk pages</li>\n<li><strong>Places API (New)</strong> — Venue search and autocomplete</li>\n<li><strong>Geocoding API</strong> — Converting postcodes to coordinates</li>\n</ul>\n<p><strong>Setup steps:</strong></p>\n<ol>\n<li>Go to <a href=\"https://console.cloud.google.com/\">https://console.cloud.google.com/</a></li>\n<li>Create a new project (or select existing)</li>\n<li>Navigate to APIs &amp; Services → Library</li>\n<li>Enable each of the three APIs listed above</li>\n<li>Navigate to APIs &amp; Services → Credentials</li>\n<li>Create an API key</li>\n<li>Restrict the key to your domain(s) for security</li>\n<li>Restrict the key to only the required APIs</li>\n</ol>\n<p><strong>Required value:</strong></p>\n<ul>\n<li><code>GOOGLE_MAPS_APIKEY</code> — Single API key for all Google services</li>\n</ul>\n<p><strong>Billing note:</strong> Google Cloud requires a billing account, but provides a generous free tier ($200/month credit) that covers most small group usage.</p>\n<h2>AWS IAM Setup for Multi-Environment Management</h2>\n<p>If you&#39;re managing multiple group environments, set up a master AWS account with delegated access.</p>\n<h3>Master Account Setup</h3>\n<ol>\n<li><p>Create an IAM user for environment provisioning:</p>\n<pre><code>User name: ngx-ramblers-provisioner\nAccess type: Programmatic access\n</code></pre>\n</li>\n<li><p>Attach a custom policy allowing S3 and IAM operations:</p>\n<pre><code class=\"language-json\">{\n  &quot;Version&quot;: &quot;2012-10-17&quot;,\n  &quot;Statement&quot;: [\n    {\n      &quot;Effect&quot;: &quot;Allow&quot;,\n      &quot;Action&quot;: [\n        &quot;s3:CreateBucket&quot;,\n        &quot;s3:PutBucketCors&quot;,\n        &quot;s3:PutBucketPolicy&quot;,\n        &quot;s3:PutPublicAccessBlock&quot;\n      ],\n      &quot;Resource&quot;: &quot;arn:aws:s3:::ngx-ramblers-*&quot;\n    },\n    {\n      &quot;Effect&quot;: &quot;Allow&quot;,\n      &quot;Action&quot;: [\n        &quot;iam:CreateUser&quot;,\n        &quot;iam:CreateAccessKey&quot;,\n        &quot;iam:PutUserPolicy&quot;,\n        &quot;iam:AttachUserPolicy&quot;\n      ],\n      &quot;Resource&quot;: &quot;arn:aws:iam::*:user/ngx-ramblers-*&quot;\n    }\n  ]\n}\n</code></pre>\n</li>\n<li><p>Store the access credentials securely (e.g., in a password manager)</p>\n</li>\n</ol>\n<h3>Per-Environment Credentials</h3>\n<p>The setup process creates:</p>\n<ul>\n<li>A dedicated IAM user per environment (e.g., <code>ngx-ramblers-mygroup-user</code>)</li>\n<li>A bucket-specific policy with least-privilege access</li>\n<li>Access credentials stored in the secrets file</li>\n</ul>\n<p>This ensures each environment has isolated credentials that can be rotated independently.</p>\n<h2>Database Initialisation Options</h2>\n<h3>Option 1: Fresh Database (Recommended for New Groups)</h3>\n<p>The setup wizard creates:</p>\n<ul>\n<li>Configuration documents (system, Brevo, committee, walks)</li>\n<li>Initial admin user account</li>\n<li>System member account</li>\n<li>Optional sample page content</li>\n</ul>\n<h3>Option 2: Restore from Backup</h3>\n<p>For migrating an existing group:</p>\n<ol>\n<li><p>Export the source database:</p>\n<pre><code class=\"language-bash\">mongodump --uri=&quot;mongodb+srv://user:pass@cluster.mongodb.net/source-db&quot; --out=./backup\n</code></pre>\n</li>\n<li><p>Import to the new database:</p>\n<pre><code class=\"language-bash\">mongorestore --uri=&quot;mongodb+srv://user:pass@cluster.mongodb.net/new-db&quot; ./backup/source-db\n</code></pre>\n</li>\n<li><p>Update configuration documents with new credentials (AWS, Brevo, etc.)</p>\n</li>\n</ol>\n<h3>Option 3: Clone Existing Environment</h3>\n<p>Use MongoDB Atlas&#39;s built-in backup/restore:</p>\n<ol>\n<li>Create a snapshot of the source cluster</li>\n<li>Restore to the target cluster with a new database name</li>\n<li>Update credentials in the <code>config</code> collection</li>\n</ol>\n<h2>Using the CLI Tool</h2>\n<h3>Running the Wizard</h3>\n<pre><code class=\"language-bash\">cd server\nnpx tsx deploy/create-environment-cli.ts\n</code></pre>\n<h3>Interactive Steps</h3>\n<ol>\n<li><p><strong>AWS Credentials</strong> (optional)</p>\n<ul>\n<li>Enter admin credentials for automated S3 setup</li>\n<li>Skip to create bucket manually</li>\n</ul>\n</li>\n<li><p><strong>Ramblers API Key</strong></p>\n<ul>\n<li>Enter your API key</li>\n<li>Validated against the Ramblers API</li>\n</ul>\n</li>\n<li><p><strong>Group Selection</strong></p>\n<ul>\n<li>Enter group code directly (e.g., <code>01SURREY</code>)</li>\n<li>Or browse by area code (e.g., <code>01</code> for Surrey)</li>\n</ul>\n</li>\n<li><p><strong>Environment Configuration</strong></p>\n<ul>\n<li>Environment name (derived from group name)</li>\n<li>Fly.io app name</li>\n<li>Memory allocation (MB)</li>\n<li>Instance count</li>\n</ul>\n</li>\n<li><p><strong>MongoDB Configuration</strong></p>\n<ul>\n<li>Cluster hostname</li>\n<li>Username and password</li>\n<li>Database name</li>\n</ul>\n</li>\n<li><p><strong>AWS S3 Configuration</strong></p>\n<ul>\n<li>Bucket name</li>\n<li>Region</li>\n</ul>\n</li>\n<li><p><strong>Email Configuration</strong></p>\n<ul>\n<li>Brevo API key</li>\n</ul>\n</li>\n<li><p><strong>Optional Services</strong></p>\n<ul>\n<li>Google Maps API key</li>\n<li>Walks Manager credentials</li>\n</ul>\n</li>\n<li><p><strong>Admin User</strong></p>\n<ul>\n<li>Name, email, and password</li>\n</ul>\n</li>\n<li><p><strong>Setup Options</strong></p>\n<ul>\n<li>Include sample pages</li>\n<li>Include notification configs</li>\n<li>Skip Fly.io deployment</li>\n</ul>\n</li>\n</ol>\n<h3>Output Files</h3>\n<p>The wizard creates:</p>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>non-vcs/secrets/secrets.{appName}.env</code></td>\n<td>Environment variables</td>\n</tr>\n<tr>\n<td><code>non-vcs/fly-io/configs.json</code></td>\n<td>Fly.io deployment config</td>\n</tr>\n</tbody></table>\n<h2>Deploying to Fly.io</h2>\n<p>After running the setup wizard:</p>\n<ol>\n<li><p><strong>Create the Fly.io app:</strong></p>\n<pre><code class=\"language-bash\">fly apps create ngx-ramblers-mygroup --org personal\n</code></pre>\n</li>\n<li><p><strong>Import secrets:</strong></p>\n<pre><code class=\"language-bash\">fly secrets import &lt; non-vcs/secrets/secrets.ngx-ramblers-mygroup.env -a ngx-ramblers-mygroup\n</code></pre>\n</li>\n<li><p><strong>Deploy:</strong></p>\n<pre><code class=\"language-bash\">fly deploy -a ngx-ramblers-mygroup\n</code></pre>\n</li>\n<li><p><strong>Verify:</strong></p>\n<pre><code class=\"language-bash\">fly status -a ngx-ramblers-mygroup\nfly logs -a ngx-ramblers-mygroup\n</code></pre>\n</li>\n</ol>\n<h2>Environment Variables Reference</h2>\n<table>\n<thead>\n<tr>\n<th>Variable</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>NODE_ENV</code></td>\n<td>Yes</td>\n<td>Set to <code>production</code></td>\n</tr>\n<tr>\n<td><code>MONGODB_URI</code></td>\n<td>Yes</td>\n<td>Full MongoDB connection string</td>\n</tr>\n<tr>\n<td><code>AUTH_SECRET</code></td>\n<td>Yes</td>\n<td>32-byte secret for JWT signing</td>\n</tr>\n<tr>\n<td><code>AWS_ACCESS_KEY_ID</code></td>\n<td>Yes</td>\n<td>S3 access key</td>\n</tr>\n<tr>\n<td><code>AWS_SECRET_ACCESS_KEY</code></td>\n<td>Yes</td>\n<td>S3 secret key</td>\n</tr>\n<tr>\n<td><code>AWS_BUCKET</code></td>\n<td>Yes</td>\n<td>S3 bucket name</td>\n</tr>\n<tr>\n<td><code>AWS_REGION</code></td>\n<td>Yes</td>\n<td>S3 region</td>\n</tr>\n<tr>\n<td><code>GOOGLE_MAPS_APIKEY</code></td>\n<td>No</td>\n<td>Google Maps API key</td>\n</tr>\n<tr>\n<td><code>FACEBOOK_APP_ID</code></td>\n<td>No</td>\n<td>Facebook application ID</td>\n</tr>\n<tr>\n<td><code>FACEBOOK_APP_SECRET</code></td>\n<td>No</td>\n<td>Facebook application secret</td>\n</tr>\n<tr>\n<td><code>MEETUP_OAUTH_KEY</code></td>\n<td>No</td>\n<td>Meetup OAuth consumer key</td>\n</tr>\n<tr>\n<td><code>MEETUP_OAUTH_SECRET</code></td>\n<td>No</td>\n<td>Meetup OAuth consumer secret</td>\n</tr>\n<tr>\n<td><code>DEBUG</code></td>\n<td>No</td>\n<td>Debug logging pattern</td>\n</tr>\n</tbody></table>\n<h2>Troubleshooting</h2>\n<h3>MongoDB Connection Errors</h3>\n<ul>\n<li>Verify the cluster hostname is correct (without <code>.mongodb.net</code>)</li>\n<li>Check the username and password are URL-encoded if they contain special characters</li>\n<li>Ensure the IP whitelist includes Fly.io&#39;s IP ranges (or use 0.0.0.0/0)</li>\n</ul>\n<h3>AWS S3 Errors</h3>\n<ul>\n<li>Verify the IAM user has the required permissions</li>\n<li>Check the bucket name is globally unique</li>\n<li>Ensure CORS is configured for browser uploads</li>\n</ul>\n<h3>Fly.io Deployment Issues</h3>\n<ul>\n<li>Check logs: <code>fly logs -a appname</code></li>\n<li>Verify secrets are set: <code>fly secrets list -a appname</code></li>\n<li>Check machine status: <code>fly status -a appname</code></li>\n</ul>\n<h2>Related Documentation</h2>\n<ul>\n<li><a href=\"https://fly.io/docs/\">Fly.io Documentation</a></li>\n<li><a href=\"https://www.mongodb.com/docs/atlas/\">MongoDB Atlas Documentation</a></li>\n<li><a href=\"https://docs.aws.amazon.com/s3/\">AWS S3 Documentation</a></li>\n<li><a href=\"https://developers.brevo.com/\">Brevo API Documentation</a></li>\n</ul>\n"}