From 8ef8d1ec648ae01f99f0294a7750c26f883cafa0 Mon Sep 17 00:00:00 2001
From: Fabian Buchenberger <37747351+ffabss@users.noreply.github.com>
Date: Tue, 20 Dec 2022 21:51:39 +0000
Subject: [PATCH 01/42] fix broken self-host/docker link in documentation
---
apps/docs/pages/guides/self-hosting.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/docs/pages/guides/self-hosting.mdx b/apps/docs/pages/guides/self-hosting.mdx
index 1c99b9765d9..950432a3803 100644
--- a/apps/docs/pages/guides/self-hosting.mdx
+++ b/apps/docs/pages/guides/self-hosting.mdx
@@ -149,7 +149,7 @@ We realize that database migrations are difficult, and this is one of the proble
While Supabase officially supports Docker, we have several other deployment strategies managed by the community:
-- [supabase-docker](../../guides/hosting/docker) (Official)
+- [supabase-docker](./docker) (Official)
- [supabase-kubernetes](https://github.com/supabase-community/supabase-kubernetes) (Unofficial)
- [supabase-terraform](https://github.com/supabase-community/supabase-terraform) (Unofficial)
- [supabase-traefik](https://github.com/supabase-community/supabase-traefik) (Unofficial)
From f9d46684c4aee6dd4f0b202e2a52e014cef54ef1 Mon Sep 17 00:00:00 2001
From: dng
Date: Tue, 20 Dec 2022 14:07:49 -0800
Subject: [PATCH 02/42] Update apps/docs/pages/guides/self-hosting.mdx
---
apps/docs/pages/guides/self-hosting.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/docs/pages/guides/self-hosting.mdx b/apps/docs/pages/guides/self-hosting.mdx
index 950432a3803..3092dd9cf45 100644
--- a/apps/docs/pages/guides/self-hosting.mdx
+++ b/apps/docs/pages/guides/self-hosting.mdx
@@ -149,7 +149,7 @@ We realize that database migrations are difficult, and this is one of the proble
While Supabase officially supports Docker, we have several other deployment strategies managed by the community:
-- [supabase-docker](./docker) (Official)
+- [supabase-docker](/docs/guides/self-hosting/docker) (Official)
- [supabase-kubernetes](https://github.com/supabase-community/supabase-kubernetes) (Unofficial)
- [supabase-terraform](https://github.com/supabase-community/supabase-terraform) (Unofficial)
- [supabase-traefik](https://github.com/supabase-community/supabase-traefik) (Unofficial)
From b5b1a58d408f7e0935196c3e32a0d1c04bf5e339 Mon Sep 17 00:00:00 2001
From: dng
Date: Tue, 20 Dec 2022 14:13:40 -0800
Subject: [PATCH 03/42] Clean up docs callout
---
apps/docs/pages/guides/integrations/weweb.mdx | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/apps/docs/pages/guides/integrations/weweb.mdx b/apps/docs/pages/guides/integrations/weweb.mdx
index 93ddbd5f2bc..c65a695400e 100644
--- a/apps/docs/pages/guides/integrations/weweb.mdx
+++ b/apps/docs/pages/guides/integrations/weweb.mdx
@@ -39,12 +39,7 @@ Once you have added both to WeWeb, you will have the option to enable realtime t
**🚨 Warning 🚨**
-> Realtime is disabled by default in Supabase for better database performance and security. Learn more about [realtime functionalities](https://supabase.com/docs/guides/database#realtime) in our documentation.
-> Member
-> @awalias awalias 16 days ago
-> might just wanna change these ones to be relative but otherwise looks great 👍
-
-@EWMAs Reply...
+> Realtime is disabled by default in Supabase for better database performance and security. Learn more about [realtime functionalities](/docs/guides/realtime).
## Step 2: GET Data from Supabase
From 10235c32b210f7261ea6009d350505862c0d1f09 Mon Sep 17 00:00:00 2001
From: dannykng
Date: Tue, 20 Dec 2022 14:41:45 -0800
Subject: [PATCH 04/42] Add code block language for syntax highlighting
---
.../pages/guides/integrations/authsignal.mdx | 340 ++++++++----------
1 file changed, 154 insertions(+), 186 deletions(-)
diff --git a/apps/docs/pages/guides/integrations/authsignal.mdx b/apps/docs/pages/guides/integrations/authsignal.mdx
index 250b822b483..65d83b22d01 100644
--- a/apps/docs/pages/guides/integrations/authsignal.mdx
+++ b/apps/docs/pages/guides/integrations/authsignal.mdx
@@ -61,7 +61,7 @@ cd supabase-authsignal-example
Create a `.env.local` file and enter the following values:
-```
+```sh
NEXT_PUBLIC_SUPABASE_URL=get-from-supabase-dashboard
NEXT_PUBLIC_SUPABASE_ANON_KEY=get-from-supabase-dashboard
AUTHSIGNAL_SECRET=get-from-authsignal-dashboard
@@ -84,19 +84,19 @@ npm run dev
Install the Supabase client and Auth helpers for Next.js:
-```
+```bash
npm install @supabase/supabase-js @supabase/auth-helpers-nextjs
```
Install the Authsignal Node.js client:
-```
+```bash
npm install @authsignal/node
```
Finally install 2 packages to help encrypt and serialize session data in cookies:
-```
+```bash
npm install @hapi/iron cookie
npm install --save-dev @types/cookie
```
@@ -105,18 +105,18 @@ npm install --save-dev @types/cookie
Add the following code to `/lib/authsignal.ts`:
-```
-import { Authsignal } from "@authsignal/node";
+```ts
+import { Authsignal } from '@authsignal/node'
-const secret = process.env.AUTHSIGNAL_SECRET;
+const secret = process.env.AUTHSIGNAL_SECRET
if (!secret) {
- throw new Error("AUTHSIGNAL_SECRET is undefined");
+ throw new Error('AUTHSIGNAL_SECRET is undefined')
}
-const redirectUrl = "http://localhost:3000/api/callback";
+const redirectUrl = 'http://localhost:3000/api/callback'
-export const authsignal = new Authsignal({ secret, redirectUrl });
+export const authsignal = new Authsignal({ secret, redirectUrl })
```
The `redirectUrl` here is a Next.js API route which Authsignal will redirect back to after an MFA challenge. We'll implement this below.
@@ -131,83 +131,72 @@ Next we will add some helper functions for managing cookies:
Add the following code to `/lib/cookies.ts`:
-```
-import Iron from "@hapi/iron";
-import { Session } from "@supabase/supabase-js";
-import { parse, serialize } from "cookie";
-import { NextApiRequest, NextApiResponse } from "next";
+```ts
+import Iron from '@hapi/iron'
+import { Session } from '@supabase/supabase-js'
+import { parse, serialize } from 'cookie'
+import { NextApiRequest, NextApiResponse } from 'next'
export async function setTempCookie(session: Session, res: NextApiResponse) {
- const token = await Iron.seal(session, TEMP_TOKEN_SECRET, Iron.defaults);
+ const token = await Iron.seal(session, TEMP_TOKEN_SECRET, Iron.defaults)
const cookie = serialize(TEMP_COOKIE, token, {
maxAge: session.expires_in,
httpOnly: true,
- secure: process.env.NODE_ENV === "production",
- path: "/",
- sameSite: "lax",
- });
+ secure: process.env.NODE_ENV === 'production',
+ path: '/',
+ sameSite: 'lax',
+ })
- res.setHeader("Set-Cookie", cookie);
+ res.setHeader('Set-Cookie', cookie)
}
-export async function getSessionFromTempCookie(
- req: NextApiRequest
-): Promise {
- const cookie = req.headers.cookie as string;
+export async function getSessionFromTempCookie(req: NextApiRequest): Promise {
+ const cookie = req.headers.cookie as string
- const cookies = parse(cookie ?? "");
+ const cookies = parse(cookie ?? '')
- const tempCookie = cookies[TEMP_COOKIE];
+ const tempCookie = cookies[TEMP_COOKIE]
if (!tempCookie) {
- return undefined;
+ return undefined
}
- const session = await Iron.unseal(
- tempCookie,
- TEMP_TOKEN_SECRET,
- Iron.defaults
- );
+ const session = await Iron.unseal(tempCookie, TEMP_TOKEN_SECRET, Iron.defaults)
- return session;
+ return session
}
export function setAuthCookie(session: Session, res: NextApiResponse) {
- const { access_token, refresh_token, expires_in } = session;
+ const { access_token, refresh_token, expires_in } = session
const authCookies = [
{ name: ACCESS_TOKEN_COOKIE, value: access_token },
- refresh_token
- ? { name: REFRESH_TOKEN_COOKIE, value: refresh_token }
- : undefined,
+ refresh_token ? { name: REFRESH_TOKEN_COOKIE, value: refresh_token } : undefined,
]
.filter(isDefined)
.map(({ name, value }) =>
serialize(name, value, {
maxAge: expires_in,
httpOnly: true,
- secure: process.env.NODE_ENV === "production",
- path: "/",
- sameSite: "lax",
+ secure: process.env.NODE_ENV === 'production',
+ path: '/',
+ sameSite: 'lax',
})
- );
+ )
// Also clear the temp cookie
- const updatedCookies = [
- ...authCookies,
- serialize(TEMP_COOKIE, "", { maxAge: -1, path: "/" }),
- ];
+ const updatedCookies = [...authCookies, serialize(TEMP_COOKIE, '', { maxAge: -1, path: '/' })]
- res.setHeader("Set-Cookie", updatedCookies);
+ res.setHeader('Set-Cookie', updatedCookies)
}
-const isDefined = (value: T | undefined): value is T => !!value;
+const isDefined = (value: T | undefined): value is T => !!value
-const TEMP_TOKEN_SECRET = process.env.TEMP_TOKEN_SECRET!;
-const TEMP_COOKIE = "as-mfa-cookie";
-const ACCESS_TOKEN_COOKIE = "sb-access-token";
-const REFRESH_TOKEN_COOKIE = "sb-refresh-token";
+const TEMP_TOKEN_SECRET = process.env.TEMP_TOKEN_SECRET!
+const TEMP_COOKIE = 'as-mfa-cookie'
+const ACCESS_TOKEN_COOKIE = 'sb-access-token'
+const REFRESH_TOKEN_COOKIE = 'sb-refresh-token'
```
## Step 7: Building the UI
@@ -216,34 +205,34 @@ We will add some form components for signing in and signing up as well as a basi
Add the following code to `/pages/sign-up.tsx`:
-```
-import Link from "next/link";
-import { useRouter } from "next/router";
+```ts
+import Link from 'next/link'
+import { useRouter } from 'next/router'
export default function SignUpPage() {
- const router = useRouter();
+ const router = useRouter()
return (
- {"Already have an account? "}
+ {'Already have an account? '}
Sign in
- );
+ )
}
```
Then add the following code to `/pages/sign-in.tsx`:
-```
-import Link from "next/link";
-import { useRouter } from "next/router";
+```ts
+import Link from 'next/link'
+import { useRouter } from 'next/router'
export default function SignInPage() {
- const router = useRouter();
+ const router = useRouter()
return (
- );
+ )
}
```
Now we will use Supabase's `withPageAuth` wrapper around `getServerSideProps` to make the home page require authentication via SSR. Replace the existing code in `/pages/index.tsx` with the following:
-```
-import { getUser, User, withPageAuth } from "@supabase/auth-helpers-nextjs";
-import { GetServerSideProps } from "next";
-import { useRouter } from "next/router";
-import { authsignal } from "../lib/authsignal";
+```ts
+import { getUser, User, withPageAuth } from '@supabase/auth-helpers-nextjs'
+import { GetServerSideProps } from 'next'
+import { useRouter } from 'next/router'
+import { authsignal } from '../lib/authsignal'
interface Props {
- user: User;
- isEnrolled: boolean;
+ user: User
+ isEnrolled: boolean
}
export const getServerSideProps: GetServerSideProps = withPageAuth({
- redirectTo: "/sign-in",
+ redirectTo: '/sign-in',
async getServerSideProps(ctx) {
- const { user } = await getUser(ctx);
+ const { user } = await getUser(ctx)
- const { isEnrolled } = await authsignal.getUser({userId: user.id});
+ const { isEnrolled } = await authsignal.getUser({ userId: user.id })
return {
props: { user, isEnrolled },
- };
+ }
},
-});
+})
export default function HomePage({ user, isEnrolled }: Props) {
- const router = useRouter();
+ const router = useRouter()
return (
@@ -351,29 +340,29 @@ export default function HomePage({ user, isEnrolled }: Props) {
Signed in as: {user?.email}
-
+
- );
+ )
}
```
Optional: To make things look a bit nicer, you can add the following to `/styles/globals.css`:
-```
+```css
main {
min-height: 100vh;
display: flex;
@@ -435,113 +424,95 @@ Now we'll replace the existing api routes in `/pages/api/` with 5 new routes:
Add the following code to `/pages/api/sign-in.ts`:
-```
-import { supabaseClient } from "@supabase/auth-helpers-nextjs";
-import { NextApiRequest, NextApiResponse } from "next";
-import { authsignal } from "../../lib/authsignal";
-import { setAuthCookie, setTempCookie } from "../../lib/cookies";
+```ts
+import { supabaseClient } from '@supabase/auth-helpers-nextjs'
+import { NextApiRequest, NextApiResponse } from 'next'
+import { authsignal } from '../../lib/authsignal'
+import { setAuthCookie, setTempCookie } from '../../lib/cookies'
-export default async function signIn(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- const { email, password } = req.body;
+export default async function signIn(req: NextApiRequest, res: NextApiResponse) {
+ const { email, password } = req.body
- const { data, error } = await supabaseClient.auth.api.signInWithEmail(
- email,
- password
- );
+ const { data, error } = await supabaseClient.auth.api.signInWithEmail(email, password)
if (error || !data?.user) {
- return res.send({ error });
+ return res.send({ error })
}
const { state, url: mfaUrl } = await authsignal.track({
- action: "signIn",
+ action: 'signIn',
userId: data.user.id,
- });
+ })
- if (state === "CHALLENGE_REQUIRED") {
- await setTempCookie(data, res);
+ if (state === 'CHALLENGE_REQUIRED') {
+ await setTempCookie(data, res)
} else {
- setAuthCookie(data, res);
+ setAuthCookie(data, res)
}
- res.send({ state, mfaUrl });
+ res.send({ state, mfaUrl })
}
```
Then to handle new sign-ups add the following to `/pages/api/sign-up.ts`:
-```
-import { supabaseClient } from "@supabase/auth-helpers-nextjs";
-import { Session } from "@supabase/supabase-js";
-import { NextApiRequest, NextApiResponse } from "next";
-import { setAuthCookie } from "../../lib/cookies";
+```ts
+import { supabaseClient } from '@supabase/auth-helpers-nextjs'
+import { Session } from '@supabase/supabase-js'
+import { NextApiRequest, NextApiResponse } from 'next'
+import { setAuthCookie } from '../../lib/cookies'
-export default async function signUp(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- const { email, password } = req.body;
+export default async function signUp(req: NextApiRequest, res: NextApiResponse) {
+ const { email, password } = req.body
- const { data, error } = await supabaseClient.auth.api.signUpWithEmail(
- email,
- password
- );
+ const { data, error } = await supabaseClient.auth.api.signUpWithEmail(email, password)
if (error || !isSession(data)) {
- res.send({ error });
+ res.send({ error })
} else {
- setAuthCookie(data, res);
- res.send({ data });
+ setAuthCookie(data, res)
+ res.send({ data })
}
}
-const isSession = (data: any): data is Session => !!data?.access_token;
+const isSession = (data: any): data is Session => !!data?.access_token
```
To clear the auth cookies on sign-out add the following to `/pages/api/sign-out.ts`:
-```
-import { supabaseClient } from "@supabase/auth-helpers-nextjs";
-import { NextApiRequest, NextApiResponse } from "next";
+```ts
+import { supabaseClient } from '@supabase/auth-helpers-nextjs'
+import { NextApiRequest, NextApiResponse } from 'next'
-export default async function signOut(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- supabaseClient.auth.api.deleteAuthCookie(req, res, { redirectTo: "/sign-in" });
+export default async function signOut(req: NextApiRequest, res: NextApiResponse) {
+ supabaseClient.auth.api.deleteAuthCookie(req, res, { redirectTo: '/sign-in' })
}
```
To handle the user's actions to set up MFA or manage their existing MFA settings, add the following to `/pages/api/mfa.ts`:
-```
-import { getUser, withApiAuth } from "@supabase/auth-helpers-nextjs";
-import { NextApiRequest, NextApiResponse } from "next";
-import { authsignal } from "../../lib/authsignal";
+```ts
+import { getUser, withApiAuth } from '@supabase/auth-helpers-nextjs'
+import { NextApiRequest, NextApiResponse } from 'next'
+import { authsignal } from '../../lib/authsignal'
-export default withApiAuth(async function mfa(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- if (req.method !== "POST") {
- return res.status(405).send({ message: "Only POST requests allowed" });
+export default withApiAuth(async function mfa(req: NextApiRequest, res: NextApiResponse) {
+ if (req.method !== 'POST') {
+ return res.status(405).send({ message: 'Only POST requests allowed' })
}
- const { user } = await getUser({ req, res });
+ const { user } = await getUser({ req, res })
- const { isEnrolled } = req.body;
+ const { isEnrolled } = req.body
const { url: mfaUrl } = await authsignal.track({
- action: isEnrolled ? "manageSettings" : "enroll",
+ action: isEnrolled ? 'manageSettings' : 'enroll',
userId: user.id,
redirectToSettings: isEnrolled,
- });
+ })
- res.send({ mfaUrl });
-});
+ res.send({ mfaUrl })
+})
```
Because the user should be authenticated with Supabase to set up or manage MFA, we can use Supabase's `withApiAuth` wrapper to protect this route.
@@ -550,28 +521,25 @@ The `redirectToSettings` param specifies whether the user should be redirected t
Finally we need a route to handle the redirect back from Authsignal after an MFA challenge. Add the following to `/pages/api/callback.ts`:
-```
-import { NextApiRequest, NextApiResponse } from "next";
-import { authsignal } from "../../lib/authsignal";
-import { getSessionFromTempCookie, setAuthCookie } from "../../lib/cookies";
+```ts
+import { NextApiRequest, NextApiResponse } from 'next'
+import { authsignal } from '../../lib/authsignal'
+import { getSessionFromTempCookie, setAuthCookie } from '../../lib/cookies'
-export default async function callback(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- const token = req.query.token as string;
+export default async function callback(req: NextApiRequest, res: NextApiResponse) {
+ const token = req.query.token as string
- const { success } = await authsignal.validateChallenge({ token });
+ const { success } = await authsignal.validateChallenge({ token })
if (success) {
- const session = await getSessionFromTempCookie(req);
+ const session = await getSessionFromTempCookie(req)
if (session) {
- setAuthCookie(session, res);
+ setAuthCookie(session, res)
}
}
- res.redirect("/");
+ res.redirect('/')
}
```
From efbd726b12ab0fcb89ebe030bc9c50a9b3a87934 Mon Sep 17 00:00:00 2001
From: dannykng
Date: Tue, 20 Dec 2022 14:42:08 -0800
Subject: [PATCH 05/42] Allow images from raw.githubusercontent.com
---
apps/docs/next.config.mjs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs
index 9762c179622..bf98d6d34fd 100644
--- a/apps/docs/next.config.mjs
+++ b/apps/docs/next.config.mjs
@@ -48,7 +48,12 @@ const nextConfig = {
basePath: '/docs',
images: {
dangerouslyAllowSVG: true,
- domains: ['avatars.githubusercontent.com', 'github.com', 'user-images.githubusercontent.com'],
+ domains: [
+ 'avatars.githubusercontent.com',
+ 'github.com',
+ 'user-images.githubusercontent.com',
+ 'raw.githubusercontent.com',
+ ],
},
experimental: {
mdxRs: true,
From ec7dc6dd7e5ebe0bf60654324906a33a525f402f Mon Sep 17 00:00:00 2001
From: ethicnology
Date: Wed, 21 Dec 2022 00:22:58 +0100
Subject: [PATCH 06/42] fix: deprecated docker-compose in favour of compose v2
---
apps/docs/pages/faq.mdx | 2 +-
apps/docs/pages/guides/self-hosting/docker.mdx | 6 +++---
apps/www/_blog/2020-07-10-alpha-launch-postmortem.mdx | 8 ++++----
apps/www/_blog/2021-03-31-supabase-cli.mdx | 2 +-
docker/docker-compose.yml | 8 ++++----
package.json | 8 ++++----
studio/README.md | 4 ++--
tests/package.json | 4 ++--
8 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/apps/docs/pages/faq.mdx b/apps/docs/pages/faq.mdx
index eced1e89829..66c0c120969 100644
--- a/apps/docs/pages/faq.mdx
+++ b/apps/docs/pages/faq.mdx
@@ -16,7 +16,7 @@ Self-hosting Supabase is free. If you wish to use our cloud-platform, we provide
### How do I host Supabase?
-You can use the docker-compose script [here](https://github.com/supabase/supabase/tree/master/docker), and find detailed instructions [here](/docs/guides/hosting/overview).
+You can use the docker compose script [here](https://github.com/supabase/supabase/tree/master/docker), and find detailed instructions [here](/docs/guides/hosting/overview).
Supabase is an amalgamation of open source tools. Some of these tools are made by Supabase (like our [Realtime Server](https://github.com/supabase/realtime)), some we support directly (like [PostgREST](http://postgrest.org/en/v7.0.0/)), and some are third-party tools (like [KonSupabase is an amalgamation open sourceg](https://github.com/Kong/kong)).
diff --git a/apps/docs/pages/guides/self-hosting/docker.mdx b/apps/docs/pages/guides/self-hosting/docker.mdx
index 08da99ae31c..0a32049889b 100644
--- a/apps/docs/pages/guides/self-hosting/docker.mdx
+++ b/apps/docs/pages/guides/self-hosting/docker.mdx
@@ -11,7 +11,7 @@ Docker is the easiest way to get started with self-hosted Supabase.
You need the following installed in your system:
-- [Docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/)
+- [Docker](https://docs.docker.com/engine/install/) and [docker compose](https://docs.docker.com/compose/install/)
- [Git](https://git-scm.com/downloads)
## Quick Start
@@ -31,7 +31,7 @@ cd supabase/docker
cp .env.example .env
# Start
-docker-compose up
+docker compose up
```
Now visit [http://localhost:3000](http://localhost:3000) to start using Supabase Studio.
@@ -97,7 +97,7 @@ Once you have done this, you can safely comment out the `db` section of the `doc
### Setting database's `log_min_messages`
-By default, `docker-compose` sets the database's `log_min_messages` configuration to `fatal` to prevent redundant logs generated by Realtime.
+By default, `docker compose` sets the database's `log_min_messages` configuration to `fatal` to prevent redundant logs generated by Realtime.
However, you might miss important log messages such as database errors. Configure `log_min_messages` based on your needs.
### File storage backend on macOS
diff --git a/apps/www/_blog/2020-07-10-alpha-launch-postmortem.mdx b/apps/www/_blog/2020-07-10-alpha-launch-postmortem.mdx
index 61bb85d236e..f0186212be6 100644
--- a/apps/www/_blog/2020-07-10-alpha-launch-postmortem.mdx
+++ b/apps/www/_blog/2020-07-10-alpha-launch-postmortem.mdx
@@ -37,13 +37,13 @@ GitHub stars rocketed for our two main repos, [supabase](https://github.com/supa
Here are the things that survived well.
-### Middleware: docker-compose up
+### Middleware: docker compose up
-This was the most surprising survivor. Our middleware was served from a single Ubuntu server with 4 CPUs and 8GB of RAM. This server was running our middleware using `docker-compose up`:
+This was the most surprising survivor. Our middleware was served from a single Ubuntu server with 4 CPUs and 8GB of RAM. This server was running our middleware using `docker compose up`:
-
+
-In case you're wondering why any sane company would use that in production, it's because we weren't planning to launch - the HackerNews post was created by an early GitHub follower, while we were alpha testing, and it was too scary to migrate the middleware while it was servicing the thundering herd. All Supabase projects use the same middleware stack (sans docker-compose), so I guess this counts as as a successful load test.
+In case you're wondering why any sane company would use that in production, it's because we weren't planning to launch - the HackerNews post was created by an early GitHub follower, while we were alpha testing, and it was too scary to migrate the middleware while it was servicing the thundering herd. All Supabase projects use the same middleware stack (without docker compose), so I guess this counts as a successful load test.
We have since migrated our middleware to multiple ECS clusters, globally load-balanced using AWS's [Global Accelerator](https://aws.amazon.com/global-accelerator/).
diff --git a/apps/www/_blog/2021-03-31-supabase-cli.mdx b/apps/www/_blog/2021-03-31-supabase-cli.mdx
index b24682700de..ea8d4c94ed8 100644
--- a/apps/www/_blog/2021-03-31-supabase-cli.mdx
+++ b/apps/www/_blog/2021-03-31-supabase-cli.mdx
@@ -217,7 +217,7 @@ Also check `kong.yml` inside the `kong` directory where you'll see how all the s
Once you're all set, you can start the stack by running:
```bash
-docker-compose up
+docker compose up
```
Head over to the [Self Hosting Docs](/docs/guides/self-hosting) for a more complete walk through, it also includes several [one-click deploys](/docs/guides/self-hosting#one-click-deploys), so you can easily deploy into your own cloud hosting provider.
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 70da7c553bd..659c501cde3 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -1,8 +1,8 @@
# Usage
-# Start: docker-compose up
-# With helpers: docker-compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up
-# Stop: docker-compose down
-# Destroy: docker-compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans
+# Start: docker compose up
+# With helpers: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up
+# Stop: docker compose down
+# Destroy: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans
version: "3.8"
diff --git a/package.json b/package.json
index 4a605d28309..bf893aa1978 100644
--- a/package.json
+++ b/package.json
@@ -22,10 +22,10 @@
"dev:www": "turbo run dev --filter=www --parallel",
"lint": "turbo run lint",
"format": "prettier --write \"apps/**/*.{js,jsx,ts,tsx,css,md,json}\"",
- "docker:dev": "cd docker && docker-compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up --renew-anon-volumes",
- "docker:up": "cd docker && docker-compose up",
- "docker:down": "cd docker && docker-compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down --remove-orphans",
- "docker:remove": "cd docker && docker-compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml rm -vfs",
+ "docker:dev": "cd docker && docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up --renew-anon-volumes",
+ "docker:up": "cd docker && docker compose up",
+ "docker:down": "cd docker && docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down --remove-orphans",
+ "docker:remove": "cd docker && docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml rm -vfs",
"test": "jest",
"test:studio": "turbo run test --filter=studio",
"perf:kong": "ab -t 5 -c 20 -T application/json http://localhost:8000/",
diff --git a/studio/README.md b/studio/README.md
index 4b9929f4a48..2c4fda0ba60 100644
--- a/studio/README.md
+++ b/studio/README.md
@@ -19,7 +19,7 @@ As such, the features exposed on Studio for existing deployments are limited to
## Managing Project Settings
-Project settings are managed outside of the Dashboard. If you use docker-compose, you should manage the settings in your docker-compose file. If you're deploying Supabase to your own cloud, you should store your secrets and env vars in a vault or secrets manager.
+Project settings are managed outside of the Dashboard. If you use docker compose, you should manage the settings in your docker-compose file. If you're deploying Supabase to your own cloud, you should store your secrets and env vars in a vault or secrets manager.
## How to contribute?
@@ -51,7 +51,7 @@ Follow the [self-hosting guide](https://supabase.com/docs/guides/hosting/docker)
```
cd ..
cd docker
-docker-compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up
+docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up
```
Once you've got that set up, update `.env` in the studio folder with the corresponding values.
diff --git a/tests/package.json b/tests/package.json
index 1633462bdbc..4f6b77c6c84 100644
--- a/tests/package.json
+++ b/tests/package.json
@@ -3,8 +3,8 @@
"version": "1.0.0",
"description": "These tests can be run with Docker.",
"scripts": {
- "docker:up": "cd ../docker && ENABLE_EMAIL_AUTOCONFIRM=true docker-compose --env-file ./.env -f docker-compose.yml -f dev/docker-compose.dev.yml up -d",
- "docker:down": "cd ../docker && docker-compose --env-file ./.env -f docker-compose.yml -f dev/docker-compose.dev.yml down",
+ "docker:up": "cd ../docker && ENABLE_EMAIL_AUTOCONFIRM=true docker compose --env-file ./.env -f docker-compose.yml -f dev/docker-compose.dev.yml up -d",
+ "docker:down": "cd ../docker && docker compose --env-file ./.env -f docker-compose.yml -f dev/docker-compose.dev.yml down",
"test": "jest",
"test:local": "jest --testNamePattern '^((?!\\[skip-local\\]).)*$' --testPathPattern '^((?!realtime).)*$' --detectOpenHandles",
"test:stage": "jest --testNamePattern '^((?!\\[skip-stage\\]).)*$' --detectOpenHandles",
From d36cc5de2601494cfc4e008bc0a674ee4071709e Mon Sep 17 00:00:00 2001
From: Long Hoang
Date: Wed, 21 Dec 2022 10:13:20 +0700
Subject: [PATCH 07/42] Remove currently happening
---
apps/www/pages/launch-week/index.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/www/pages/launch-week/index.tsx b/apps/www/pages/launch-week/index.tsx
index 225de69fcb0..d9248069b7c 100644
--- a/apps/www/pages/launch-week/index.tsx
+++ b/apps/www/pages/launch-week/index.tsx
@@ -38,7 +38,7 @@ export default function launchweek() {
const { isDarkMode } = useTheme()
const title = 'Launch Week 6'
const description = 'Supabase Launch Week 6 | 12-18 Dec 2022'
- const liveDay = 'Friday'
+ const liveDay = null
const [supabase] = useState(() =>
createClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!)
From eab07390b72e1b79f7747dea7b317ce2d309b0ea Mon Sep 17 00:00:00 2001
From: Long Hoang
Date: Wed, 21 Dec 2022 10:26:35 +0700
Subject: [PATCH 08/42] Remove jump to current day on launchweek page
---
apps/www/pages/launch-week/index.tsx | 5 -----
1 file changed, 5 deletions(-)
diff --git a/apps/www/pages/launch-week/index.tsx b/apps/www/pages/launch-week/index.tsx
index d9248069b7c..7888948b8c7 100644
--- a/apps/www/pages/launch-week/index.tsx
+++ b/apps/www/pages/launch-week/index.tsx
@@ -219,11 +219,6 @@ export default function launchweek() {
)}
>
-
-
{intent !== undefined ? (
From 52548ec10416ab22e5f8c3619427655bd0f79db5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kevin=20Gr=C3=BCneberg?=
Date: Tue, 20 Dec 2022 14:10:04 +0100
Subject: [PATCH 18/42] pain
---
.../AddNewPaymentMethodModal.tsx | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx b/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx
index d40e165c652..0883d871175 100644
--- a/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx
+++ b/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx
@@ -30,6 +30,13 @@ const AddNewPaymentMethodModal: FC = ({ visible, returnUrl, onCancel }) =
setCaptchaRef(node)
}, [])
+ /**
+ * We want to load the Stripe payment elements only after successfully verifying captcha.
+ * To execute hCaptcha when displaying the modal, we need to ensure hCaptcha is actually loaded.
+ * The `onLoad` method from hCaptcha is only executed ONCE for the entire application, so we cannot listen to it.
+ * One way to find out if hCaptcha has been initialized, is checking `window.hcaptcha`. When checking via window,
+ * we know if the hCaptcha has been initialized from a different part of the app or through this component.
+ */
useEffect(() => {
setCaptchaLoaded(true)
// @ts-ignore
@@ -37,7 +44,6 @@ const AddNewPaymentMethodModal: FC = ({ visible, returnUrl, onCancel }) =
useEffect(() => {
const loadPaymentForm = async () => {
- console.log('load payment form', { visible, captchaLoaded, captchaRef })
if (visible && captchaRef && captchaLoaded) {
let token = captchaToken
if (!token) {
@@ -45,8 +51,6 @@ const AddNewPaymentMethodModal: FC = ({ visible, returnUrl, onCancel }) =
token = captchaResponse?.response ?? null
}
- console.log('Setting up intent', { token })
-
await setupIntent(token ?? undefined)
resetCaptcha()
}
@@ -56,7 +60,6 @@ const AddNewPaymentMethodModal: FC = ({ visible, returnUrl, onCancel }) =
}, [visible, captchaRef, captchaLoaded])
const resetCaptcha = () => {
- console.log('Resetting captcha')
setCaptchaToken(null)
captchaRef?.resetCaptcha()
}
@@ -113,7 +116,7 @@ const AddNewPaymentMethodModal: FC = ({ visible, returnUrl, onCancel }) =
{intent !== undefined ? (
-
+
) : (
From 284ce90b1767524dbada3d2fb49f7d0ace7010fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kevin=20Gr=C3=BCneberg?=
Date: Tue, 20 Dec 2022 14:32:16 +0100
Subject: [PATCH 19/42] move captcha outside of modal
---
.../AddNewPaymentMethodModal.tsx | 33 +++++++++----------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx b/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx
index 0883d871175..065027c7847 100644
--- a/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx
+++ b/studio/components/interfaces/Billing/AddNewPaymentMethodModal/AddNewPaymentMethodModal.tsx
@@ -94,14 +94,9 @@ const AddNewPaymentMethodModal: FC = ({ visible, returnUrl, onCancel }) =
}
return (
-
+ // We cant display the hCaptcha in the modal, as the modal auto-closes when clicking the captcha
+ // So we only show the modal if the captcha has been executed successfully (intent loaded)
+ <>
= ({ visible, returnUrl, onCancel }) =
setCaptchaToken(null)
}}
/>
-