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

(self-host|3): self-hostable platform! #982

Merged
merged 41 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6ba77ea
feat: allow local file uploads with minio
tefkah Jan 27, 2025
60758c9
feat: allow different email providers to be used when self-hosting, o…
tefkah Feb 12, 2025
c3bee15
fix: handle errors and fix types
tefkah Feb 12, 2025
745ed9f
chore: merge
tefkah Feb 12, 2025
8b17fd8
fix: make minio slightly easier to start
tefkah Feb 12, 2025
c25e50a
fix: add upload test
tefkah Feb 12, 2025
fad6bd4
chore: format
tefkah Feb 17, 2025
d57d64a
chore: merge
tefkah Feb 17, 2025
d43f265
chore: format?
tefkah Feb 17, 2025
2614c9d
fix: get docker compose stuff in reasonable state
tefkah Feb 18, 2025
3250fc2
fix: hopefully make ci run correctly
tefkah Feb 18, 2025
32c2050
fix: env vars?
tefkah Feb 18, 2025
7db5920
fix: unfix env vars
tefkah Feb 18, 2025
a4393ff
fix: remove unecessary option
tefkah Feb 18, 2025
408e68a
fix: shuffle things around more
tefkah Feb 18, 2025
e2bb652
fix: add manual database_url back
tefkah Feb 18, 2025
e8770ca
fix: don't use non-existint postgres_name var, use postgres_db
tefkah Feb 18, 2025
9c7477f
fix: log on cancel, and max fail 3 tests
tefkah Feb 18, 2025
51b0b38
fix: change db url
tefkah Feb 18, 2025
7fb5233
fix: actually pass in correct env vars this time??
tefkah Feb 18, 2025
c3b0357
fix: change a bit how i'm doing env vars (shocking)
tefkah Feb 18, 2025
8b2f9e4
fix: don't use env.docker-compose in ci directly
tefkah Feb 18, 2025
29d413f
fix: okay i have learned how env vars work. you cannot set 'environme…
tefkah Feb 18, 2025
1fe827b
fix: minio_root_user instead
tefkah Feb 18, 2025
2385cab
chore: restore dirty
tefkah Feb 19, 2025
bd4b834
docs: update self-host docs
tefkah Feb 19, 2025
84f73c9
chore: clean up test file
tefkah Feb 19, 2025
a8ea108
chore: remove file staged for later commit
tefkah Feb 19, 2025
3315a1c
feat: add docker-compose file for self hosting
tefkah Feb 19, 2025
4bd6154
feat: add caddy file config and all that jazz
tefkah Feb 19, 2025
c1f3351
feat: add way to add admin user
tefkah Feb 19, 2025
9961154
docs: update environment variable docs
tefkah Feb 19, 2025
503022f
docs: provide better documentation
tefkah Feb 19, 2025
6c7c53b
chore: remove console.log
tefkah Feb 19, 2025
3ebc6e0
fix: better env vars for db
tefkah Feb 19, 2025
6d46157
chore: add explanatory comment
tefkah Feb 20, 2025
60cce53
Merge branch 'tfk/minio' into tfk/self-host-setup
tefkah Feb 20, 2025
df89acd
chore: merge
tefkah Feb 27, 2025
e2f921c
fix: improve order of .env.example a bit
tefkah Feb 27, 2025
486c65a
chore: do not log out password after account creation
tefkah Feb 27, 2025
cd840da
chore: start minio for test again (oops)
tefkah Feb 27, 2025
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
94 changes: 94 additions & 0 deletions core/prisma/create-admin-user.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* eslint-disable no-console */

import { createEnv } from "@t3-oss/env-nextjs";
import { Kysely, PostgresDialect } from "kysely";
import * as pg from "pg";
import { z } from "zod";

import { Database } from "db/Database";

import { isUniqueConstraintError } from "../kysely/errors";
import { createPasswordHash } from "../lib/authentication/password";

const env = createEnv({
server: {
ADMIN_EMAIL: z.string().email(),
ADMIN_PASSWORD: z.string().min(8),
ADMIN_FIRSTNAME: z.string(),
ADMIN_LASTNAME: z.string(),
DATABASE_URL: z.string(),
},
client: {},
experimental__runtimeEnv: {},
});

const dialect = new PostgresDialect({
pool: new pg.Pool({
connectionString: env.DATABASE_URL,
}),
});

const db = new Kysely<Database>({
dialect,
});

async function createAdminUser({
email,
password,
firstName,
lastName,
}: {
email: string;
password: string;
firstName: string;
lastName: string;
}) {
const values = {
slug: email.split("@")[0],
email,
firstName,
lastName,
passwordHash: await createPasswordHash(password),
isSuperAdmin: true,
};

return db.insertInto("users").values(values).returningAll().executeTakeFirstOrThrow();
}

async function main() {
const adminEmail = env.ADMIN_EMAIL;
const adminPassword = env.ADMIN_PASSWORD;
const adminFirstName = env.ADMIN_FIRSTNAME;
const adminLastName = env.ADMIN_LASTNAME;

if (!adminEmail || !adminPassword) {
throw new Error("ADMIN_EMAIL and ADMIN_PASSWORD must be set for admin initialization");
}

try {
await createAdminUser({
email: adminEmail,
password: adminPassword,
firstName: adminFirstName,
lastName: adminLastName,
});
console.log("✨ Admin user created successfully!");
console.log(`You can now log in with:`);
console.log(`${adminEmail}`);
} catch (e) {
if (isUniqueConstraintError(e)) {
console.log("⚠️ Admin user already exists, skipping initialization");
return;
}
throw e;
}
}

if (require.main === module) {
main()
.then(() => process.exit(0))
.catch((e) => {
console.error(e);
process.exit(1);
});
}
2 changes: 0 additions & 2 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ services:
networks:
- app-network
profiles:
- test
- integration

minio-init:
Expand All @@ -40,7 +39,6 @@ services:
networks:
- app-network
profiles:
- test
- integration

inbucket:
Expand Down
44 changes: 44 additions & 0 deletions self-host/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# the default url of the platform
PUBPUB_URL=http://localhost:3000 # the url of the platform
# change this to eg
# PUBPUB_URL=https://platform.example.com
# for a production environment


# configure these things with safe values
# or the values of a remote postgres database
POSTGRES_USER=my-postgres-user # change this!
POSTGRES_PASSWORD=my-postgres-password # change this!
POSTGRES_DB=my-postgres-db # change this! this is hard to change after the database has been created
POSTGRES_HOST=db # change this to the name of the service in docker-compose.yml, or the domain of a remote postgres database if you're using that instead
POSTGRES_PORT=5432 # don't forget to update the port in docker-compose.yml if you change this

# not needed if you're using a remote file server like AWS S3
MINIO_ROOT_USER= # change this! this is the username for your file server!
MINIO_ROOT_PASSWORD= # change this! this is the password for your file server!

ASSETS_BUCKET_NAME=assets
ASSETS_UPLOAD_KEY= # change this! example: asset-user
ASSETS_UPLOAD_SECRET_KEY= # change this!
ASSETS_REGION=us-east-1 # leave this unchanged, unless you are hosting files on a different region on actual AWS

# this is the default value but you ideally should set this up more nicely using our caddy service
ASSETS_STORAGE_ENDPOINT="http://localhost:9000"
# you could also set this to the secured endpoint of your file server
# ASSETS_STORAGE_ENDPOINT="https://example.com/assets"

MAILGUN_SMTP_HOST=localhost
MAILGUN_SMTP_PORT=54325
MAILGUN_SMTP_PASSWORD="xxx"
MAILGUN_SMTP_USERNAME="xxx"

API_KEY="super_secret_key"

OTEL_SERVICE_NAME="pubpub-v7-dev" # should be shared across components but not environments
HONEYCOMB_API_KEY="xxx"

# KYSELY_DEBUG="true"

GCLOUD_KEY_FILE='xxx'

SELF_HOST="true"
2 changes: 2 additions & 0 deletions self-host/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
minio/.minio.sys
Loading
Loading