Skip to content

Commit 18be6a7

Browse files
authored
Merge pull request #432 from TineoC/fix/handle-relative-domains
refactor: use relative URLs and centralize API endpoints (closes #431)
2 parents 76cee02 + 556d5dd commit 18be6a7

File tree

20 files changed

+533
-82
lines changed

20 files changed

+533
-82
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: "Deploy: Downstream Clusters"
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
tag:
9+
description: 'Image tag to deploy (e.g. 1.1.0)'
10+
required: true
11+
default: 'latest'
12+
13+
jobs:
14+
update-sandbox:
15+
name: Update Sandbox Cluster
16+
runs-on: ubuntu-latest
17+
outputs:
18+
tag: ${{ steps.get_tag.outputs.TAG }}
19+
steps:
20+
- name: Checkout App
21+
uses: actions/checkout@v4
22+
23+
- name: Get Release Tag
24+
id: get_tag
25+
run: |
26+
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
27+
echo "TAG=${{ inputs.tag }}" >> $GITHUB_OUTPUT
28+
else
29+
echo "TAG=${GITHUB_REF:11}" >> $GITHUB_OUTPUT
30+
fi
31+
32+
- name: Checkout Sandbox Cluster
33+
uses: actions/checkout@v4
34+
with:
35+
repository: CodeForPhilly/cfp-sandbox-cluster
36+
token: ${{ secrets.BOT_GITHUB_TOKEN }}
37+
path: sandbox
38+
39+
- name: Update Sandbox Image Tag
40+
working-directory: sandbox/balancer
41+
run: |
42+
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
43+
./kustomize edit set image ghcr.io/codeforphilly/balancer-main/app:${{ steps.get_tag.outputs.TAG }}
44+
rm kustomize
45+
46+
- name: Create Sandbox PR
47+
uses: peter-evans/create-pull-request@v6
48+
with:
49+
token: ${{ secrets.BOT_GITHUB_TOKEN }}
50+
path: sandbox
51+
commit-message: "Deploy balancer ${{ steps.get_tag.outputs.TAG }} to sandbox"
52+
title: "Deploy balancer ${{ steps.get_tag.outputs.TAG }}"
53+
body: "Updates balancer image tag to ${{ steps.get_tag.outputs.TAG }}"
54+
branch: "deploy/balancer-${{ steps.get_tag.outputs.TAG }}"
55+
base: main
56+
delete-branch: true
57+
58+
update-live:
59+
name: Update Live Cluster
60+
needs: update-sandbox
61+
runs-on: ubuntu-latest
62+
steps:
63+
- name: Checkout Live Cluster
64+
uses: actions/checkout@v4
65+
with:
66+
repository: CodeForPhilly/cfp-live-cluster
67+
token: ${{ secrets.BOT_GITHUB_TOKEN }}
68+
path: live
69+
70+
- name: Update Live Image Tag
71+
working-directory: live/balancer
72+
run: |
73+
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
74+
./kustomize edit set image ghcr.io/codeforphilly/balancer-main/app:${{ needs.update-sandbox.outputs.tag }}
75+
rm kustomize
76+
77+
- name: Create Live PR
78+
uses: peter-evans/create-pull-request@v6
79+
with:
80+
token: ${{ secrets.BOT_GITHUB_TOKEN }}
81+
path: live
82+
commit-message: "Deploy balancer ${{ needs.update-sandbox.outputs.tag }} to live"
83+
title: "Deploy balancer ${{ needs.update-sandbox.outputs.tag }}"
84+
body: "Updates balancer image tag to ${{ needs.update-sandbox.outputs.tag }}"
85+
branch: "deploy/balancer-${{ needs.update-sandbox.outputs.tag }}"
86+
base: main
87+
delete-branch: true

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ Tools used for development:
3939
Start the Postgres, Django REST, and React services by starting Docker Desktop and running `docker compose up --build`
4040

4141
#### Postgres
42+
43+
The application supports connecting to PostgreSQL databases via:
44+
45+
1. **CloudNativePG** - Kubernetes-managed PostgreSQL cluster (for production/sandbox)
46+
2. **AWS RDS** - External PostgreSQL database (AWS managed)
47+
3. **Local Docker Compose** - For local development
48+
49+
See [Database Connection Documentation](./docs/DATABASE_CONNECTION.md) for detailed configuration.
50+
51+
**Local Development:**
4252
- Download a sample of papers to upload from [https://balancertestsite.com](https://balancertestsite.com/)
4353
- The email and password of `pgAdmin` are specified in `balancer-main/docker-compose.yml`
4454
- The first time you use `pgAdmin` after building the Docker containers you will need to register the server.

config/env/dev.env.example

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
DEBUG=True
22
SECRET_KEY=foo
33

4+
# Database Configuration
5+
# Supports both CloudNativePG (Kubernetes service) and AWS RDS (external host)
46
SQL_ENGINE=django.db.backends.postgresql
57
SQL_DATABASE=balancer_dev
68
SQL_USER=balancer
79
SQL_PASSWORD=balancer
10+
11+
# Connection Type Examples:
12+
#
13+
# CloudNativePG (Kubernetes service within cluster):
14+
# SQL_HOST=balancer-postgres-rw
15+
# SQL_HOST=balancer-postgres-rw.balancer.svc.cluster.local
16+
# (SSL typically not required within cluster)
17+
#
18+
# AWS RDS (External database):
19+
# SQL_HOST=balancer-db.xxxxx.us-east-1.rds.amazonaws.com
20+
# (SSL typically required - set SQL_SSL_MODE if needed)
21+
#
22+
# Local development:
23+
# SQL_HOST=localhost
24+
# SQL_HOST=db # Docker Compose service name
825
SQL_HOST=db
926
SQL_PORT=5432
1027

28+
# Optional: SSL mode for PostgreSQL connections
29+
# Options: disable, allow, prefer, require, verify-ca, verify-full
30+
# Default: require for external hosts (AWS RDS), disabled for CloudNativePG
31+
# SQL_SSL_MODE=require
32+
1133
LOGIN_REDIRECT_URL=
1234
OPENAI_API_KEY=
1335
ANTHROPIC_API_KEY=

docs/DATABASE_CONNECTION.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Database Connection Configuration
2+
3+
The balancer application supports connecting to PostgreSQL databases via two methods:
4+
5+
1. **CloudNativePG** - Kubernetes-managed PostgreSQL cluster (within cluster)
6+
2. **AWS RDS** - External PostgreSQL database (AWS managed)
7+
8+
The application automatically detects the connection type based on the `SQL_HOST` environment variable format.
9+
10+
## Connection Type Detection
11+
12+
The application determines the connection type by analyzing the `SQL_HOST` value:
13+
14+
- **CloudNativePG**:
15+
- Contains `.svc.cluster.local` (Kubernetes service DNS)
16+
- Short service name (e.g., `balancer-postgres-rw`)
17+
- Typically no SSL required within cluster
18+
19+
- **AWS RDS**:
20+
- Full domain name (e.g., `balancer-db.xxxxx.us-east-1.rds.amazonaws.com`)
21+
- External IP address
22+
- Typically requires SSL
23+
24+
## Configuration
25+
26+
### Environment Variables
27+
28+
All database configuration is done via environment variables:
29+
30+
- `SQL_ENGINE`: Database engine (default: `django.db.backends.postgresql`)
31+
- `SQL_DATABASE`: Database name
32+
- `SQL_USER`: Database username
33+
- `SQL_PASSWORD`: Database password
34+
- `SQL_HOST`: Database host (see examples below)
35+
- `SQL_PORT`: Database port (default: `5432`)
36+
- `SQL_SSL_MODE`: Optional SSL mode (see SSL Configuration below)
37+
38+
### CloudNativePG Configuration
39+
40+
When using CloudNativePG, the application connects to the Kubernetes service created by the operator.
41+
42+
**Example Configuration:**
43+
```bash
44+
SQL_ENGINE=django.db.backends.postgresql
45+
SQL_DATABASE=balancer
46+
SQL_USER=balancer
47+
SQL_PASSWORD=<password-from-secret>
48+
SQL_HOST=balancer-postgres-rw
49+
SQL_PORT=5432
50+
```
51+
52+
**Service Names:**
53+
- `{cluster-name}-rw`: Read-write service (primary instance)
54+
- `{cluster-name}-r`: Read service (replicas)
55+
- `{cluster-name}-ro`: Read-only service
56+
57+
**Full DNS Name:**
58+
```bash
59+
SQL_HOST=balancer-postgres-rw.balancer.svc.cluster.local
60+
```
61+
62+
### AWS RDS Configuration
63+
64+
When using AWS RDS, the application connects to the external RDS endpoint.
65+
66+
**Example Configuration:**
67+
```bash
68+
SQL_ENGINE=django.db.backends.postgresql
69+
SQL_DATABASE=balancer
70+
SQL_USER=balancer
71+
SQL_PASSWORD=<rds-password>
72+
SQL_HOST=balancer-db.xxxxx.us-east-1.rds.amazonaws.com
73+
SQL_PORT=5432
74+
SQL_SSL_MODE=require
75+
```
76+
77+
## SSL Configuration
78+
79+
### CloudNativePG
80+
81+
SSL is typically **not required** for connections within the Kubernetes cluster. The application will not use SSL by default for CloudNativePG connections.
82+
83+
### AWS RDS
84+
85+
SSL is typically **required** for AWS RDS connections. The application defaults to `require` mode for external hosts, but you can override this:
86+
87+
**SSL Mode Options:**
88+
- `disable`: No SSL
89+
- `allow`: Try non-SSL first, then SSL
90+
- `prefer`: Try SSL first, then non-SSL (default for external)
91+
- `require`: Require SSL
92+
- `verify-ca`: Require SSL and verify CA
93+
- `verify-full`: Require SSL and verify CA and hostname
94+
95+
**Example:**
96+
```bash
97+
SQL_SSL_MODE=require
98+
```
99+
100+
## Migration Guide
101+
102+
### From AWS RDS to CloudNativePG
103+
104+
1. Update the `SQL_HOST` environment variable in your SealedSecret:
105+
```bash
106+
# Old (AWS RDS)
107+
SQL_HOST=balancer-db.xxxxx.us-east-1.rds.amazonaws.com
108+
109+
# New (CloudNativePG)
110+
SQL_HOST=balancer-postgres-rw
111+
```
112+
113+
2. Update database credentials to match CloudNativePG secret
114+
115+
3. Remove or set `SQL_SSL_MODE` to `disable` (optional, as it's auto-detected)
116+
117+
4. Restart the application pods
118+
119+
### From CloudNativePG to AWS RDS
120+
121+
1. Update the `SQL_HOST` environment variable:
122+
```bash
123+
# Old (CloudNativePG)
124+
SQL_HOST=balancer-postgres-rw
125+
126+
# New (AWS RDS)
127+
SQL_HOST=balancer-db.xxxxx.us-east-1.rds.amazonaws.com
128+
```
129+
130+
2. Update database credentials to match RDS credentials
131+
132+
3. Set `SQL_SSL_MODE=require` (or appropriate mode)
133+
134+
4. Ensure network connectivity (VPC peering, security groups, etc.)
135+
136+
5. Restart the application pods
137+
138+
## Troubleshooting
139+
140+
### Connection Issues
141+
142+
1. **Verify host format**: Check that `SQL_HOST` matches the expected format for your connection type
143+
144+
2. **Check network connectivity**:
145+
- CloudNativePG: Ensure pods are in the same namespace
146+
- AWS RDS: Verify VPC peering, security groups, and network ACLs
147+
148+
3. **Verify credentials**: Ensure username, password, and database name are correct
149+
150+
4. **Check SSL configuration**: For AWS RDS, ensure SSL is properly configured
151+
152+
### Common Errors
153+
154+
**"Connection refused"**
155+
- Verify the host and port are correct
156+
- Check if the database service is running
157+
- Verify network connectivity
158+
159+
**"SSL required"**
160+
- Add `SQL_SSL_MODE=require` for AWS RDS connections
161+
- Verify SSL certificates are available
162+
163+
**"Authentication failed"**
164+
- Verify username and password
165+
- Check database user permissions
166+
- Ensure the database exists
167+
168+
## References
169+
170+
- [Django Database Configuration](https://docs.djangoproject.com/en/4.2/ref/settings/#databases)
171+
- [CloudNativePG Documentation](https://cloudnative-pg.io/)
172+
- [AWS RDS PostgreSQL](https://docs.aws.amazon.com/rds/latest/userguide/CHAP_PostgreSQL.html)
173+
- [PostgreSQL SSL Configuration](https://www.postgresql.org/docs/current/libpq-ssl.html)
174+

0 commit comments

Comments
 (0)