Skip to content

Commit 7766a65

Browse files
authored
cleanup + document server envs (#1342)
* cleanup + document server envs * add self hosting link * fix types * filter desktop CI * needs
1 parent 0211831 commit 7766a65

File tree

8 files changed

+88
-72
lines changed

8 files changed

+88
-72
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ jobs:
3030
id: filter
3131
with:
3232
filters: |
33+
desktop:
34+
- 'apps/desktop/**'
3335
rust:
3436
- '.cargo/**'
3537
- '.github/**'
@@ -154,6 +156,8 @@ jobs:
154156

155157
build-desktop:
156158
name: Build Desktop
159+
needs: changes
160+
if: needs.changes.outputs.rust == 'true' || needs.changes.outputs.desktop == 'true'
157161
strategy:
158162
fail-fast: false
159163
matrix:

apps/web/app/api/waitlist/route.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

apps/web/content/docs/self-hosting.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ To send login links via email, you'll need to configure [Resend](https://resend.
6464
2. Connect a domain and set it as `RESEND_FROM_DOMAIN`
6565
3. Generate an API key and set it as `RESEND_API_KEY`
6666

67+
## Other Configuration
68+
69+
See [`env/server.ts`](https://github.com/CapSoftware/Cap/blob/main/packages/env/server.ts) for a description of all environment variables you can configure.
70+
6771
## Support
6872

6973
If you encounter a problem with the Docker image or think this documentation is lacking,

apps/web/instrumentation.node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export async function register() {
4242

4343
async function createS3Bucket() {
4444
const s3Client = new S3Client({
45-
endpoint: serverEnv().CAP_AWS_ENDPOINT,
45+
endpoint: serverEnv().S3_INTERNAL_ENDPOINT,
4646
region: serverEnv().CAP_AWS_REGION,
4747
credentials: {
4848
accessKeyId: serverEnv().CAP_AWS_ACCESS_KEY ?? "",

apps/web/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ const nextConfig = {
109109
env: {
110110
appVersion: version,
111111
},
112-
// If the DOCKER_BUILD environment variable is set to true, we are output nextjs to standalone ready for docker deployment
112+
// If the NEXT_PUBLIC_DOCKER_BUILD environment variable is set to true, we are output nextjs to standalone ready for docker deployment
113113
output:
114114
process.env.NEXT_PUBLIC_DOCKER_BUILD === "true" ? "standalone" : undefined,
115115
// webpack: (config) => {

packages/database/drizzle.config.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import type { Config } from "drizzle-kit";
22

3-
const URL = process.env.DATABASE_MIGRATION_URL ?? process.env.DATABASE_URL;
3+
const URL = process.env.DATABASE_URL;
44

5-
if (!URL)
6-
throw new Error("DATABASE_URL or DATABASE_MIGRATION_URL must be set!");
5+
if (!URL) throw new Error("DATABASE_URL must be set!");
76
if (!URL?.startsWith("mysql://"))
87
throw new Error(
98
"DATABASE_URL must be a 'mysql://' URI. Drizzle Kit doesn't support the fetch adapter!",

packages/env/server.ts

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,86 @@ const boolString = (_default = false) =>
1212
function createServerEnv() {
1313
return createEnv({
1414
server: {
15-
NODE_ENV: z.string(),
16-
DATABASE_URL: z.string(),
17-
WEB_URL: z.string(),
18-
DATABASE_MIGRATION_URL: z.string().optional(),
19-
DATABASE_ENCRYPTION_KEY: z.string().optional(),
20-
S3_PATH_STYLE: boolString(true),
15+
/// General configuration
16+
DATABASE_URL: z.string().describe("MySQL database URL"),
17+
WEB_URL: z
18+
.string()
19+
.describe("Public URL of the server eg. https://cap.so"),
20+
NEXTAUTH_SECRET: z.string().describe("32 byte base64 string"),
21+
NEXTAUTH_URL: z.string().describe("Should be the same as WEB_URL"),
22+
DATABASE_ENCRYPTION_KEY: z
23+
.string()
24+
.optional()
25+
.describe(
26+
"32 byte hex string for encrypting values like AWS access keys",
27+
),
28+
29+
// Cap uses Resend for email sending, including sending login code emails
30+
RESEND_API_KEY: z.string().optional(),
31+
RESEND_FROM_DOMAIN: z.string().optional(),
32+
33+
/// S3 configuration
34+
// Though they are prefixed with `CAP_AWS`, these don't have to be
35+
// for AWS, and can instead be for any S3-compatible service
2136
CAP_AWS_BUCKET: z.string(),
2237
CAP_AWS_REGION: z.string(),
23-
CAP_AWS_BUCKET_URL: z.string().optional(),
2438
CAP_AWS_ACCESS_KEY: z.string().optional(),
2539
CAP_AWS_SECRET_KEY: z.string().optional(),
26-
CAP_AWS_ENDPOINT: z.string().optional(),
27-
CAP_AWS_MEDIACONVERT_ROLE_ARN: z.string().optional(),
40+
S3_PUBLIC_ENDPOINT: z
41+
.string()
42+
.optional()
43+
.describe("Public endpoint for accessing S3"),
44+
S3_INTERNAL_ENDPOINT: z
45+
.string()
46+
.optional()
47+
.describe(
48+
"Internal endpoint for accessing S3. This is useful if accessing S3 over public internet is more expensive than via your hosting environment's local network.",
49+
),
50+
S3_PATH_STYLE: boolString(true).describe(
51+
"Whether the bucket should be accessed using path-style URLs (common for non-AWS providers, eg. '/{bucket}/{key}') or virtual-hosted-style URLs (eg. '{bucket}.s3.amazonaws.com/{key}').",
52+
),
53+
54+
/// CloudFront configuration
55+
// Configure these if you'd like to serve assets from the default bucket via CloudFront
56+
// In this case, CAP_AWS_BUCKET_URL should be your CloudFront distribution's URL
57+
CAP_AWS_BUCKET_URL: z
58+
.string()
59+
.optional()
60+
.describe("Public URL of the S3 bucket"),
2861
CAP_CLOUDFRONT_DISTRIBUTION_ID: z.string().optional(),
29-
NEXTAUTH_SECRET: z.string(),
30-
NEXTAUTH_URL: z.string(),
62+
CLOUDFRONT_KEYPAIR_ID: z.string().optional(),
63+
CLOUDFRONT_KEYPAIR_PRIVATE_KEY: z.string().optional(),
64+
65+
/// Google Auth
66+
// Provide these to allow Google login
3167
GOOGLE_CLIENT_ID: z.string().optional(),
3268
GOOGLE_CLIENT_SECRET: z.string().optional(),
69+
70+
/// WorkOS SSO
71+
// Provide these to use WorkOS for enterprise SSO
3372
WORKOS_CLIENT_ID: z.string().optional(),
3473
WORKOS_API_KEY: z.string().optional(),
35-
DUB_API_KEY: z.string().optional(),
36-
RESEND_API_KEY: z.string().optional(),
37-
RESEND_FROM_DOMAIN: z.string().optional(),
38-
DEEPGRAM_API_KEY: z.string().optional(),
39-
NEXT_LOOPS_KEY: z.string().optional(),
74+
75+
/// Settings
76+
CAP_VIDEOS_DEFAULT_PUBLIC: boolString(true).describe(
77+
"Should videos be public or private by default",
78+
),
79+
CAP_ALLOWED_SIGNUP_DOMAINS: z
80+
.string()
81+
.optional()
82+
.describe("Comma-separated list of permitted signup domains"),
83+
84+
/// AI providers
85+
DEEPGRAM_API_KEY: z.string().optional().describe("Audio transcription"),
86+
OPENAI_API_KEY: z.string().optional().describe("AI summaries"),
87+
GROQ_API_KEY: z.string().optional().describe("AI summaries"),
88+
89+
/// Cap Cloud
90+
// These are only needed for Cap Cloud (https://cap.so)
4091
STRIPE_SECRET_KEY: z.string().optional(),
4192
STRIPE_WEBHOOK_SECRET: z.string().optional(),
4293
DISCORD_FEEDBACK_WEBHOOK_URL: z.string().optional(),
4394
DISCORD_LOGS_WEBHOOK_URL: z.string().optional(),
44-
OPENAI_API_KEY: z.string().optional(),
45-
GROQ_API_KEY: z.string().optional(),
46-
INTERCOM_SECRET: z.string().optional(),
47-
CAP_VIDEOS_DEFAULT_PUBLIC: boolString(true),
48-
CAP_ALLOWED_SIGNUP_DOMAINS: z.string().optional(),
4995
VERCEL_ENV: z
5096
.union([
5197
z.literal("production"),
@@ -59,18 +105,21 @@ function createServerEnv() {
59105
VERCEL_URL_HOST: z.string().optional(),
60106
VERCEL_BRANCH_URL_HOST: z.string().optional(),
61107
VERCEL_PROJECT_PRODUCTION_URL_HOST: z.string().optional(),
62-
DOCKER_BUILD: z.string().optional(),
63-
POSTHOG_PERSONAL_API_KEY: z.string().optional(),
64-
CLOUDFRONT_KEYPAIR_ID: z.string().optional(),
65-
CLOUDFRONT_KEYPAIR_PRIVATE_KEY: z.string().optional(),
66-
S3_PUBLIC_ENDPOINT: z.string().optional(),
67-
S3_INTERNAL_ENDPOINT: z.string().optional(),
68108
VERCEL_AWS_ROLE_ARN: z.string().optional(),
109+
POSTHOG_PERSONAL_API_KEY: z.string().optional(),
110+
DUB_API_KEY: z.string().optional(),
111+
INTERCOM_SECRET: z.string().optional(),
112+
113+
/// Ignore
114+
NODE_ENV: z.string(),
69115
WORKFLOWS_RPC_URL: z.string().optional(),
70116
WORKFLOWS_RPC_SECRET: z.string().optional(),
71117
},
72118
experimental__runtimeEnv: {
119+
S3_PUBLIC_ENDPOINT: process.env.CAP_AWS_ENDPOINT,
120+
S3_INTERNAL_ENDPOINT: process.env.CAP_AWS_ENDPOINT,
73121
...process.env,
122+
NODE_ENV: process.env.NODE_ENV ?? "production",
74123
VERCEL_URL_HOST: process.env.VERCEL_URL,
75124
VERCEL_BRANCH_URL_HOST: process.env.VERCEL_BRANCH_URL,
76125
VERCEL_PROJECT_PRODUCTION_URL_HOST:

scripts/env-cli.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,9 @@ async function main() {
9292
allEnvs.DATABASE_URL ??
9393
"mysql://root:@localhost:3306/planetscale",
9494
}),
95-
DATABASE_MIGRATION_URL: (v) => {
96-
if (v.results.DATABASE_URL?.startsWith("http")) {
97-
log.info("Planetscale HTTP URL detected");
98-
return text({
99-
message: "DATABASE_MIGRATION_URL",
100-
});
101-
}
102-
},
10395
});
10496

10597
envs.DATABASE_URL = dbValues.DATABASE_URL;
106-
if (dbValues.DATABASE_MIGRATION_URL)
107-
envs.DATABASE_MIGRATION_URL = dbValues.DATABASE_MIGRATION_URL;
10898

10999
log.info("S3 Envs");
110100

@@ -138,7 +128,6 @@ async function main() {
138128
envs = { ...envs, ...s3Values };
139129
} else {
140130
envs.DATABASE_URL = DOCKER_DB_ENVS.url;
141-
envs.DATABASE_MIGRATION_URL = DOCKER_DB_ENVS.url;
142131

143132
envs.CAP_AWS_ACCESS_KEY = DOCKER_S3_ENVS.accessKey;
144133
envs.CAP_AWS_SECRET_KEY = DOCKER_S3_ENVS.secretKey;

0 commit comments

Comments
 (0)