You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Configuration changes required for running Freehub (Rails 2.3) on DigitalOcean.
3
+
Freehub is hosted on the [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform) with a managed MySQL database.
4
4
5
-
---
6
-
7
-
### 1. App Platform Environment Variables
8
-
9
-
Set these app-level environment variables:
5
+
> **Tip**: [Claude Code](https://docs.anthropic.com/en/docs/claude-code) is a helpful assistant for configuring and managing the DigitalOcean application environment.
10
6
11
-
1. Go to **App Platform** → your app → **Settings**
12
-
2. Under **App-Level Environment Variables**, add:
4. Select **Legacy - MySQL 5.x** (`mysql_native_password`) → **Save**
30
-
31
-
**Why**: The old `mysql` gem in Rails 2.3 doesn't support MySQL 8.0's default `caching_sha2_password` authentication plugin.
32
-
33
-
**Security note**: `mysql_native_password` is less secure than `caching_sha2_password`, but is required for compatibility with older MySQL client libraries.
We disabled `sql_require_primary_key` on the DigitalOcean managed MySQL database to support Rails 2.3 HABTM (has_and_belongs_to_many) join tables which don't have primary keys.
40
-
41
-
**What was changed:**
33
+
## External Services
42
34
43
-
Disabled `sql_require_primary_key` via DigitalOcean API:
35
+
### Email (Resend)
44
36
45
-
```bash
46
-
doctl databases configuration update af845ccd-eb8d-4f0d-99b5-2c8cffc71681 --engine mysql --config-json '{"sql_require_primary_key": false}'
47
-
```
37
+
Transactional emails (account activation, password reset, etc.) are sent via [Resend](https://resend.com) SMTP.
48
38
49
-
**Why**: The `roles_users` join table (for the `Role has_and_belongs_to_many :users` relationship) doesn't have a primary key. Rails 2.3 HABTM doesn't support primary keys on join tables, but DigitalOcean's default MySQL 8.0 configuration requires them for replication purposes.
39
+
-**SMTP host**: `smtp.resend.com`
40
+
-**Port**: 2587
41
+
-**Domain**: `bikekitchen.org`
50
42
51
-
**Affected tables:**
43
+
The API key is configured via the `RESEND_API_KEY` environment variable.
52
44
53
-
| Table | Purpose | Notes |
54
-
|-------|---------|-------|
55
-
|`roles_users`| User role assignments (HABTM join table) | Small, rarely updated |
56
-
|`schema_info`| Legacy Rails 1.x migration tracking | Not used at runtime, may exist in old backups |
57
-
|`schema_migrations`| Rails migration version tracking | Only written during deploys |
45
+
### Error Tracking (Airbrake)
58
46
59
-
**Implications:**
47
+
Errors are tracked by [Airbrake](https://airbrake.io) and notifications are sent to configured team members.
60
48
61
-
-**Single-node cluster**: No impact
62
-
-**Multi-node cluster**: Potential replication lag on updates/deletes to tables without PKs, since MySQL must do full table scans to identify rows. Risk is minimal for `roles_users` due to its small size and infrequent updates.
49
+
The API key is configured via the `AIRBRAKE_API_KEY` environment variable.
Usage statistics are tracked in Google Analytics (GA4). Access via the Google Analytics dashboard.
70
54
71
-
2. Re-enable the requirement:
72
-
```bash
73
-
doctl databases configuration update af845ccd-eb8d-4f0d-99b5-2c8cffc71681 --engine mysql --config-json '{"sql_require_primary_key": true}'
74
-
```
55
+
---
75
56
76
-
3. Optionally, convert the HABTM to `has_many :through` in the Rails models for a cleaner long-term solution.
57
+
## DigitalOcean Configuration
77
58
78
-
---
59
+
### Apps
79
60
80
-
### 4. Database Tier
61
+
| App | URL | Auto-deploy |
62
+
|-----|-----|-------------|
63
+
|**Production**|https://freehub.bikekitchen.org| OFF (manual) |
64
+
|**Staging**|https://freehub-staging.bikekitchen.org| ON (from master) |
81
65
82
-
Using **Premium AMD, 1 vCPU, 2GB RAM** ($36/mo) with NVMe storage. Upgraded from Regular 1 vCPU/1GB for better query performance — dedicated CPU and NVMe disk significantly improve aggregation queries across large tables.
66
+
### Environment Variables
83
67
84
-
---
68
+
Set in App Platform → Settings → App-Level Environment Variables:
85
69
86
-
### 5. Database Trusted Sources
70
+
| Variable | Value |
71
+
|----------|-------|
72
+
|`RAILS_ENV`|`production`|
73
+
|`SITE_URL`|`https://freehub.bikekitchen.org`|
74
+
|`AIRBRAKE_API_KEY`|*(Airbrake API key)*|
75
+
|`RESEND_API_KEY`|*(Resend SMTP API key)*|
87
76
88
-
By default, DigitalOcean managed databases block external connections. To allow developers to connect directly to the database:
77
+
`RAILS_ENV` is required — without it, Rails defaults to development mode.
89
78
90
-
1. Go to **Databases** → your database cluster → **Settings**
91
-
2. Scroll to **Trusted Sources**
92
-
3. Add the developer's IP address (find it with `curl ifconfig.me`)
79
+
### Database
93
80
94
-
**Note**: For security, avoid using "Allow all IPv4". Add specific IPs as needed.
These settings were required for Rails 2.3 compatibility with MySQL 8.
155
+
156
+
### Legacy Password Encryption
157
+
158
+
The `freehub_app` user uses legacy MySQL 5.x password encryption (`mysql_native_password`) because the old `mysql` gem doesn't support MySQL 8.0's default `caching_sha2_password`.
159
+
160
+
To configure: **Databases** → cluster → **Users & Databases** → `freehub_app` → **Edit Password Encryption** → **Legacy - MySQL 5.x**
161
+
162
+
### Disabled sql_require_primary_key
163
+
164
+
Rails 2.3 HABTM join tables don't have primary keys, but MySQL 8 requires them by default.
--engine mysql --config-json '{"sql_require_primary_key": false}'
159
169
```
160
170
161
-
### Rollback
171
+
**Affected tables:**
162
172
163
-
To rollback production to a previous version, redeploy a previous commit from the App Platform console under **Activity** → select a previous deployment → **Redeploy**.
173
+
| Table | Purpose |
174
+
|-------|---------|
175
+
|`roles_users`| User role assignments (HABTM join table) |
0 commit comments