Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add supabase guide #297

Merged
merged 12 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ SESSION_SECRET=abcdef1234
MAGIC_LINK_SECRET=abcdef1234
ENCRYPTION_KEY=ae13021afef0819c3a307ad487071c06 # Must be a random 16 byte hex string. You can generate an encryption key by running `openssl rand -hex 16` in your terminal
LOGIN_ORIGIN=http://localhost:3030
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres?schema=public
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres?schema=public
# This sets the URL used for direct connections to the database and should only be needed in limited circumstances
# See: https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#fields:~:text=the%20shadow%20database.-,directUrl,-No
DIRECT_URL=${DATABASE_URL}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't just be empty as we have to use an env var in schema.prisma

REMIX_APP_PORT=3030
APP_ENV=development
APP_ORIGIN=http://localhost:3030
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ jobs:
# Setup environment variables
cp ./.env.example ./.env
cp ./examples/nextjs-test/.env.example ./examples/nextjs-test/.env.local
cp ./packages/database/.env.example ./packages/database/.env
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed anymore due to symlink


# Build packages
pnpm run build --filter @examples/nextjs-test^...
Expand Down
7 changes: 3 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ branch are tagged into a release monthly.
```
pnpm i
```
4. Create your `.env` files
4. Create your `.env` file
```
cp .env.example .env && cp packages/database/.env.example packages/database/.env
cp .env.example .env
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed anymore due to symlink

```
5. Open the root `.env` file and generate a new value for `ENCRYPTION_KEY`:
5. Open it and generate a new value for `ENCRYPTION_KEY`:

`ENCRYPTION_KEY` is used to two-way encrypt OAuth access tokens and so you'll probably want to actually generate a unique value, and it must be a random 16 byte hex string. You can generate one with the following command:

Expand Down Expand Up @@ -178,7 +178,6 @@ To run the end-to-end tests, follow the steps below:
```sh
cp ./.env.example ./.env
cp ./examples/nextjs-test/.env.example ./examples/nextjs-test/.env.local
cp ./packages/database/.env.example ./packages/database/.env
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed anymore due to symlink

```

2. Set up dependencies
Expand Down
1 change: 1 addition & 0 deletions apps/webapp/app/db.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ function getClient() {
datasources: {
db: {
url: DATABASE_URL,
// We can't set directUrl here, and we don't have to
},
},
log: [
Expand Down
1 change: 1 addition & 0 deletions apps/webapp/app/env.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SecretStoreOptionsSchema } from "./services/secrets/secretStore.server"
const EnvironmentSchema = z.object({
NODE_ENV: z.union([z.literal("development"), z.literal("production"), z.literal("test")]),
DATABASE_URL: z.string(),
DIRECT_URL: z.string(),
SESSION_SECRET: z.string(),
MAGIC_LINK_SECRET: z.string(),
ENCRYPTION_KEY: z.string(),
Expand Down
1 change: 1 addition & 0 deletions apps/webapp/app/services/worker.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ function getWorkerQueue() {
connectionString: env.DATABASE_URL,
concurrency: 5,
pollInterval: 1000,
noPreparedStatements: env.DATABASE_URL !== env.DIRECT_URL,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No way around this with pooling

},
schema: workerCatalog,
recurringTasks: {
Expand Down
1 change: 1 addition & 0 deletions docker/dev-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ services:
- db
environment:
DATABASE_URL: postgres://postgres:postgres@db:5432/postgres?schema=public
DIRECT_URL: postgres://postgres:postgres@db:5432/postgres?schema=public
SESSION_SECRET: secret123
MAGIC_LINK_SECRET: secret123
REMIX_APP_PORT: 3030
Expand Down
47 changes: 43 additions & 4 deletions docs/documentation/guides/self-hosting/supabase.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ ENCRYPTION_KEY=1189c93e399856a2a9a1454496171b2e
<img src="/images/supabase-project-setup.png" alt="Supabase - Project Setup" />
</Frame>

5. Navigate to Project `Settings -> Database` and copy your database connection string
5. Navigate to `Project Settings -> Database` and copy your database connection string

<Frame>
<img src="/images/supabase-db-url.png" alt="Supabase - Database URL" />
Expand Down Expand Up @@ -82,6 +82,7 @@ SESSION_SECRET=8d92078940c89588fc8b6f5481f2c6e0
ENCRYPTION_KEY=1189c93e399856a2a9a1454496171b2e

DATABASE_URL=postgresql://postgres:<PASSWORD>@db.<ID>.supabase.co:5432/postgres?schema=triggerdotdev
DIRECT_URL=${DATABASE_URL}

NODE_ENV=development
RUNTIME_PLATFORM=docker-compose
Expand Down Expand Up @@ -136,15 +137,53 @@ docker compose up

8. Congratulations, you're all set up and ready to go with Supabase and Docker! 🚀

{/* TODO: add pooling setup */}

## Bonus: Connection pooling

### What is connection pooling?

<Frame caption="Connection Pool - © 2023 Supabase, Apache License 2.0">
<img src="/images/supabase-connection-pool.png" alt="Supabase - Connection Pool" />
</Frame>

...coming soon!
When running on a single server, our app can be trusted to manage its own connections - it knows how many are open and can process its internal queue as needed.

<Tooltip tip="🐝">Serverless</Tooltip> changes things. Here, many concurrent app instances are started, each unaware of the others' connections. This can lead to a huge - potentially fatal - increase in connections straight to your DB.

<Info>
PostgreSQL has a [default connection limit](https://www.postgresql.org/docs/current/runtime-config-connection.html#:~:text=at%20server%20start.-,max_connections,-(integer)) of 100.
</Info>

**External connection pools** solve this by putting an additional layer between client and server, which essentially works like a message queue that gets processed as limits allow. The clients are blind to this and can keep sending their requests as before.

### Enable connection pooling

1. Copy and paste the connection string from earlier to `DIRECT_URL`

```sh .env (excerpt)
...
DIRECT_URL=postgresql://postgres:<PASSWORD>@db.<ID>.supabase.co:5432/postgres?schema=triggerdotdev
...
```

2. Navigate to `Project Settings -> Database` and copy your connection pool URL

<Frame>
<img src="/images/supabase-pool-url.png" alt="Supabase - Connection Pool URL" />
</Frame>

3. Paste it into your `.env` file next to `DATABASE_URL`

4. Append `?schema=triggerdotdev&pgbouncer=true` and insert your password

```sh .env (excerpt)
...
# notice the differing ports and additional query param
DATABASE_URL=postgresql://postgres:<PASSWORD>@db.<ID>.supabase.co:6543/postgres?schema=triggerdotdev&pgbouncer=true
DIRECT_URL=postgresql://postgres:<PASSWORD>@db.<ID>.supabase.co:5432/postgres?schema=triggerdotdev
...
```

5. All done! You can now enjoy the benefits of connection pooling ⚡️

## Next steps

Expand Down
Binary file added docs/images/supabase-pool-url.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/database/.env
1 change: 0 additions & 1 deletion packages/database/.env.example

This file was deleted.

4 changes: 2 additions & 2 deletions packages/database/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
node_modules
# Keep environment variables out of version control
.env
# Ensure the .env symlink is not removed by accident
!.env
5 changes: 3 additions & 2 deletions packages/database/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}

generator client {
Expand Down
1 change: 1 addition & 0 deletions tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const setDB = async (cb: SetDBCallback) => {
datasources: {
db: {
url: DATABASE_URL,
// We can't set directUrl here, and we don't have to
},
},
});
Expand Down
1 change: 1 addition & 0 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"REMIX_APP_PORT",
"CI",
"DATABASE_URL",
"DIRECT_URL",
"SESSION_SECRET",
"APP_ORIGIN",
"LOGIN_ORIGIN",
Expand Down