|
1 | | -External services and secrets to configure |
| 1 | +# External Services & Environment Configuration |
2 | 2 |
|
3 | | -- S3 bucket |
4 | | -- S3 access key |
5 | | -- OpenAI API key |
6 | | -- Sentry Project and API key |
7 | | -- Sendgrid API Key |
8 | | -- Secret key base |
9 | | -- Rails encryption key |
10 | | -- Rails encrypted credentials |
| 3 | +This guide lists external services used in production and the environment variables required to configure them. See `.env.prod.sample` for a concise reference of the variables used by this project. |
11 | 4 |
|
| 5 | +Important notes: |
| 6 | +- Prefer setting a single `DATABASE_URL`, `REDIS_URL`, and `ELASTICSEARCH_URL` where supported. |
| 7 | +- Hostnames and asset/CDN domains must be consistent (`APP_HOST`, `ASSET_HOST`). |
| 8 | +- Keep secrets out of the repo; use your platform’s secret manager (e.g., Dokku `config:set`). |
| 9 | + |
| 10 | +## Amazon S3 / Asset Storage & CDN |
| 11 | + |
| 12 | +Used for precompiled asset uploads and optionally as a CDN origin. The project uses `fog-aws` and `asset_sync` (see `spec/dummy/config/initializers/asset_sync.rb`). |
| 13 | + |
| 14 | +Required variables: |
| 15 | +- `AWS_ACCESS_KEY_ID`: AWS access key for the asset bucket. |
| 16 | +- `AWS_SECRET_ACCESS_KEY`: AWS secret key. |
| 17 | +- `FOG_DIRECTORY`: S3 bucket name (alias: `S3_BUCKET_NAME`). |
| 18 | +- `FOG_REGION`: S3 region (alias: `S3_REGION`). |
| 19 | + |
| 20 | +Recommended/optional: |
| 21 | +- `FOG_HOST`: Custom host for S3-compatible providers or CDN origin. |
| 22 | +- `ASSET_HOST`: Public CDN domain serving compiled assets. |
| 23 | +- `CDN_DISTRIBUTION_ID`: If using CloudFront or similar for invalidations. |
| 24 | +- `AWS_SESSION_TOKEN`: Temporary credentials session token (if using STS). |
| 25 | + |
| 26 | +Example environment: |
| 27 | +```bash |
| 28 | +# S3 / CDN |
| 29 | +AWS_ACCESS_KEY_ID=... |
| 30 | +AWS_SECRET_ACCESS_KEY=... |
| 31 | +FOG_DIRECTORY=your-bucket |
| 32 | +FOG_REGION=us-east-1 |
| 33 | +# Optional for S3-compatible providers/CDN |
| 34 | +FOG_HOST=s3.amazonaws.com |
| 35 | +ASSET_HOST=cdn.yourdomain.com |
| 36 | +CDN_DISTRIBUTION_ID=E123EXAMPLE |
| 37 | +``` |
| 38 | + |
| 39 | +Rails configuration references: |
| 40 | +- `spec/dummy/config/initializers/asset_sync.rb:5` – S3 credentials and bucket settings |
| 41 | +- `spec/dummy/config/environments/production.rb:39` – `config.asset_host` |
| 42 | + |
| 43 | +## OpenAI (Optional Features) |
| 44 | + |
| 45 | +Some features (e.g., translations, bots) use OpenAI if available. If unset, those features remain disabled. |
| 46 | + |
| 47 | +Required to enable: |
| 48 | +- `OPENAI_ACCESS_TOKEN`: API key used by helpers and robots. |
| 49 | + |
| 50 | +Optional: |
| 51 | +- `OPENAI_API_BASE`: Override API base (e.g., Azure OpenAI endpoint). |
| 52 | + |
| 53 | +Example environment: |
| 54 | +```bash |
| 55 | +OPENAI_ACCESS_TOKEN=sk-... |
| 56 | +# Optional for Azure/OpenAI proxy |
| 57 | +# OPENAI_API_BASE=https://your-azure-endpoint.openai.azure.com |
| 58 | +``` |
| 59 | + |
| 60 | +References: |
| 61 | +- `app/robots/better_together/application_bot.rb:10` |
| 62 | +- `app/helpers/better_together/translatable_fields_helper.rb:20` |
| 63 | + |
| 64 | +## Sentry (Backend + Browser) |
| 65 | + |
| 66 | +Backend error reporting and performance traces: |
| 67 | +- `SENTRY_DSN`: Server DSN for the Ruby SDK. |
| 68 | +- `GIT_REV`: Git SHA/version for release tagging. |
| 69 | +- Optional sampling: `SENTRY_TRACES_SAMPLE_RATE`, `SENTRY_PROFILES_SAMPLE_RATE`. |
| 70 | + |
| 71 | +Browser (frontend) error reporting: |
| 72 | +- `SENTRY_CLIENT_KEY`: Public key used by the Sentry browser SDK loaded in layouts. |
| 73 | + |
| 74 | +Example environment: |
| 75 | +```bash |
| 76 | +SENTRY_DSN=https://<key>@o<org>.ingest.sentry.io/<project> |
| 77 | +SENTRY_CLIENT_KEY=<public-browser-key> |
| 78 | +GIT_REV=$(git rev-parse --short HEAD) |
| 79 | +# Optional sampling |
| 80 | +# SENTRY_TRACES_SAMPLE_RATE=0.2 |
| 81 | +# SENTRY_PROFILES_SAMPLE_RATE=0.1 |
| 82 | +``` |
| 83 | + |
| 84 | +References: |
| 85 | +- `spec/dummy/config/initializers/sentry.rb:3` |
| 86 | +- `app/views/layouts/better_together/application.html.erb:5` |
| 87 | +- `app/views/layouts/better_together/turbo_native.html.erb:5` |
| 88 | + |
| 89 | +## Email (SMTP / SendGrid) |
| 90 | + |
| 91 | +Used by Action Mailer for transactional emails. Configure your SMTP provider (SendGrid, Postmark, SES SMTP, etc.). |
| 92 | + |
| 93 | +Required variables: |
| 94 | +- `SMTP_ADDRESS`: SMTP server hostname. |
| 95 | +- `SMTP_PORT`: SMTP port (587 for STARTTLS or 465 for TLS). |
| 96 | +- `SMTP_USERNAME`: SMTP username. |
| 97 | +- `SMTP_PASSWORD`: SMTP password. |
| 98 | + |
| 99 | +Example environment: |
| 100 | +```bash |
| 101 | +SMTP_ADDRESS=smtp.sendgrid.net |
| 102 | +SMTP_PORT=587 |
| 103 | +SMTP_USERNAME=apikey |
| 104 | +SMTP_PASSWORD=SG.XXXX... |
| 105 | +``` |
| 106 | + |
| 107 | +Minimal Action Mailer example (Rails initializer): |
| 108 | +```ruby |
| 109 | +# config/initializers/mailer.rb |
| 110 | +Rails.application.configure do |
| 111 | + config.action_mailer.smtp_settings = { |
| 112 | + address: ENV.fetch('SMTP_ADDRESS'), |
| 113 | + port: Integer(ENV.fetch('SMTP_PORT', 587)), |
| 114 | + user_name: ENV.fetch('SMTP_USERNAME'), |
| 115 | + password: ENV.fetch('SMTP_PASSWORD'), |
| 116 | + authentication: :plain, |
| 117 | + enable_starttls_auto: true |
| 118 | + } |
| 119 | +end |
| 120 | +``` |
| 121 | + |
| 122 | +## Elasticsearch |
| 123 | + |
| 124 | +Used for search indexing via `elasticsearch-model`. |
| 125 | + |
| 126 | +Preferred: |
| 127 | +- `ELASTICSEARCH_URL`: Full URL (e.g., `http://localhost:9200`). |
| 128 | + |
| 129 | +Fallback variables (if `ELASTICSEARCH_URL` is not set): |
| 130 | +- `ES_HOST`: Host URL (default `http://localhost`). |
| 131 | +- `ES_PORT`: Port (default `9200`). |
| 132 | + |
| 133 | +Example environment: |
| 134 | +```bash |
| 135 | +ELASTICSEARCH_URL=http://elasticsearch:9200 |
| 136 | +# or |
| 137 | +# ES_HOST=http://elasticsearch |
| 138 | +# ES_PORT=9200 |
| 139 | +``` |
| 140 | + |
| 141 | +Reference: |
| 142 | +- `config/initializers/elasticsearch.rb:6` |
| 143 | + |
| 144 | +## Redis |
| 145 | + |
| 146 | +Used by Sidekiq (background jobs) and optionally Rack::Attack cache store. |
| 147 | + |
| 148 | +Variables: |
| 149 | +- `REDIS_URL`: Redis connection string (e.g., `redis://:password@host:6379/0`). |
| 150 | +- `RACK_ATTACK_REDIS_URL`: Optional Redis for Rack::Attack throttling/cache. |
| 151 | + |
| 152 | +Example environment: |
| 153 | +```bash |
| 154 | +REDIS_URL=redis://redis:6379/0 |
| 155 | +# Optional dedicated Redis for Rack::Attack |
| 156 | +# RACK_ATTACK_REDIS_URL=redis://redis:6379/1 |
| 157 | +``` |
| 158 | + |
| 159 | +Reference: |
| 160 | +- `config/initializers/rack_attack.rb:15` |
| 161 | + |
| 162 | +## PostgreSQL (PostGIS) |
| 163 | + |
| 164 | +Database connection is provided via `DATABASE_URL`. PostGIS is required in production. |
| 165 | + |
| 166 | +Variables: |
| 167 | +- `DATABASE_URL`: Full Postgres connection string. |
| 168 | + |
| 169 | +Example: |
| 170 | +```bash |
| 171 | +DATABASE_URL=postgres://user:password@db:5432/community_engine_production |
| 172 | +``` |
| 173 | + |
| 174 | +## Hostnames & Rails Keys |
| 175 | + |
| 176 | +Hostnames: |
| 177 | +- `ALLOWED_HOSTS`: Comma-separated hostnames allowed by Rails. |
| 178 | +- `APP_HOST`: Public host used for URL generation. |
| 179 | +- `BASE_URL`: Base URL without scheme if used by external scripts. |
| 180 | + |
| 181 | +Rails secrets: |
| 182 | +- `SECRET_KEY_BASE`: Rails secret key base (required in production). |
| 183 | +- `RAILS_MASTER_KEY`: Key to decrypt credentials if using `config/credentials/*.yml.enc`. |
| 184 | + |
| 185 | +Example: |
| 186 | +```bash |
| 187 | +ALLOWED_HOSTS=yourdomain.com |
| 188 | +APP_HOST=yourdomain.com |
| 189 | +BASE_URL=yourdomain.com |
| 190 | + |
| 191 | +SECRET_KEY_BASE=<generated-secret> |
| 192 | +# If using Rails encrypted credentials |
| 193 | +# RAILS_MASTER_KEY=<your-master-key> |
| 194 | +``` |
| 195 | + |
| 196 | +## Quick Checklist |
| 197 | + |
| 198 | +- S3/CDN: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `FOG_DIRECTORY`, `FOG_REGION`, `ASSET_HOST` |
| 199 | +- OpenAI: `OPENAI_ACCESS_TOKEN` (optional) |
| 200 | +- Sentry: `SENTRY_DSN`, `SENTRY_CLIENT_KEY`, `GIT_REV` |
| 201 | +- Email: `SMTP_ADDRESS`, `SMTP_PORT`, `SMTP_USERNAME`, `SMTP_PASSWORD` |
| 202 | +- Elasticsearch: `ELASTICSEARCH_URL` or `ES_HOST` + `ES_PORT` |
| 203 | +- Redis: `REDIS_URL` (+ `RACK_ATTACK_REDIS_URL` optional) |
| 204 | +- PostgreSQL: `DATABASE_URL` |
| 205 | +- Host/Secrets: `ALLOWED_HOSTS`, `APP_HOST`, `SECRET_KEY_BASE` |
0 commit comments