mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-07-24 12:50:50 +08:00
Merge pull request #45 from LAION-AI/web-deployment
Setup the website to be deployed in docker
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# Install dependencies only when needed
|
||||
FROM node:16.19 AS deps
|
||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||
# RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies based on the preferred package manager
|
||||
COPY ./website/package.json ./website/package-lock.json ./
|
||||
RUN \
|
||||
if [ -f package-lock.json ]; then npm ci; \
|
||||
else echo "Lockfile not found." && exit 1; \
|
||||
fi
|
||||
|
||||
# Rebuild the source code only when needed
|
||||
FROM node:16.19 AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY ./website/ .
|
||||
|
||||
# Next.js collects completely anonymous telemetry data about general usage.
|
||||
# Learn more here: https://nextjs.org/telemetry
|
||||
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
# RUN yarn build
|
||||
RUN npx prisma generate
|
||||
RUN npm run build
|
||||
|
||||
# Production image, copy all the files and run next
|
||||
FROM node:16.19 AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV production
|
||||
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Copy over the prisma schema so we can to `npx prisma db push` and ensure the
|
||||
# database exists on startup.
|
||||
COPY --chown=nextjs:nodejs ./website/prisma/schema.prisma ./
|
||||
# Copy over a startup script that'll run `npx prisma db push` before starting
|
||||
# the webserver. This ensures the webserver can actually check user accounts.
|
||||
# This is a prisma variant of the postgres solution suggested in
|
||||
# https://docs.docker.com/compose/startup-order/
|
||||
COPY --chown=nextjs:nodejs ./website/wait-for-postgres.sh ./
|
||||
|
||||
# Automatically leverage output traces to reduce image size
|
||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV PORT 3000
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
@@ -0,0 +1,14 @@
|
||||
# End to End Demo
|
||||
|
||||
This sets up an entire stack needed to run Open Assistant, including the
|
||||
website, backend, and associated dependent services.
|
||||
|
||||
To start the service, do the following:
|
||||
|
||||
```sh
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Then, navigate to `http://localhost:3000` and interact with the website. When
|
||||
logging in, navigate to `http://localhost:1080` to get the magic email login
|
||||
link.
|
||||
@@ -0,0 +1,90 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
# This DB is for the FastAPI Backend.
|
||||
db:
|
||||
image: postgres
|
||||
restart: always
|
||||
ports:
|
||||
- 5432:5432
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "postgres"]
|
||||
interval: 2s
|
||||
timeout: 2s
|
||||
retries: 10
|
||||
|
||||
# This DB is for Web Authentication and data caching.
|
||||
webdb:
|
||||
image: postgres
|
||||
restart: always
|
||||
ports:
|
||||
- 5433:5432
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "postgres"]
|
||||
interval: 2s
|
||||
timeout: 2s
|
||||
retries: 10
|
||||
|
||||
# This lets you manually inspect the web and backend databases.
|
||||
adminer:
|
||||
image: adminer
|
||||
restart: always
|
||||
ports:
|
||||
- 8089:8080
|
||||
|
||||
# This fakes an SMTP email server used by website authentication.
|
||||
# User registration emails can be found by going to localhost:1080 and
|
||||
# opening the emails listed.
|
||||
maildev:
|
||||
image: maildev/maildev
|
||||
restart: always
|
||||
environment:
|
||||
- MAILDEV_WEB_PORT=1080
|
||||
- MAILDEV_SMTP_PORT=1025
|
||||
ports:
|
||||
- "1080:1080"
|
||||
- "1025:1025"
|
||||
|
||||
# The oassist backend service.
|
||||
backend:
|
||||
build:
|
||||
dockerfile: docker/Dockerfile.backend
|
||||
context: ../../
|
||||
image: oasst-backend
|
||||
environment:
|
||||
- POSTGRES_HOST=db
|
||||
- ALLOW_ANY_API_KEY=True
|
||||
- MAX_WORKERS=1
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
# The oassist web service.
|
||||
web:
|
||||
build:
|
||||
dockerfile: docker/Dockerfile.website
|
||||
context: ../../
|
||||
image: oasst-web
|
||||
environment:
|
||||
- DATABASE_URL=postgres://postgres:postgres@webdb/ocgpt_website
|
||||
- FASTAPI_URL=http://backend:8080
|
||||
- FASTAPI_KEY=1234
|
||||
- NEXTAUTH_SECRET=O/M2uIbGj+lDD2oyNa8ax4jEOJqCPJzO53UbWShmq98=
|
||||
- EMAIL_SERVER_HOST=maildev
|
||||
- EMAIL_SERVER_PORT=1025
|
||||
- EMAIL_FROM=info@example.com
|
||||
- NEXTAUTH_URL=http://localhost:3000
|
||||
depends_on:
|
||||
webdb:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "3000:3000"
|
||||
command: bash wait-for-postgres.sh node server.js
|
||||
@@ -47,8 +47,9 @@ services:
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
# This fakes and SMTP email server. User registration emails can be found by going to
|
||||
# localhost:1080 and opening the emails listed.
|
||||
# This fakes an SMTP email server used by website authentication.
|
||||
# User registration emails can be found by going to localhost:1080 and
|
||||
# opening the emails listed.
|
||||
maildev:
|
||||
image: maildev/maildev
|
||||
restart: always
|
||||
|
||||
+95
-25
@@ -1,31 +1,109 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
# Open-Assistant NextJS Website
|
||||
|
||||
## Required Environment Variables
|
||||
## Purpose
|
||||
|
||||
This requires:
|
||||
This provides a comprehensive webapp interface for LAION's Open Assistant
|
||||
project. Initially it will support:
|
||||
|
||||
- `NEXT_PUBLIC_SUPABASE_URL`: A supabase Authorization URL
|
||||
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`: A public supabase key for Authorization
|
||||
1. User registration using either Discord or Email.
|
||||
1. Adding responses to incomplete Open Assistant tasks.
|
||||
1. Rating or Ranking responses to Open Assistant tasks.
|
||||
1. Viewing an activity leaderboard.
|
||||
1. Tracking community wide updates.
|
||||
|
||||
These can both be optained from the Supabase project settings page.
|
||||
This interface compliments the Discord bot and will give access to the same
|
||||
underlying tasks.
|
||||
|
||||
## Getting Started
|
||||
## Contributing
|
||||
|
||||
First, run the development server:
|
||||
### Major Dependencies
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
This website is built using:
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
1. [npm](https://www.npmjs.com/): The node package manager for building.
|
||||
1. [React](https://reactjs.org/): The core frontend framework.
|
||||
1. [Next.js](https://nextjs.org/): A React scaffolding framework to streamline
|
||||
development.
|
||||
1. [Prisma](https://www.prisma.io/): An ORM to interact with a web specific
|
||||
[Postgres](https://www.postgresql.org/) database.
|
||||
1. [NextAuth.js](https://next-auth.js.org/): A user authentication framework
|
||||
to ensure we handle accounts with best practices.
|
||||
1. [TailwindCSS](https://tailwindcss.com/): A general purpose framework for
|
||||
styling any component.
|
||||
1. [Chakra-UI](https://chakra-ui.com/): A wide collection of pre-built UI
|
||||
components that generally look pretty good.
|
||||
|
||||
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
|
||||
### Set up your environment
|
||||
|
||||
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
|
||||
To contribute to the website, make sure you have the following setup and
|
||||
installed:
|
||||
|
||||
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
|
||||
1. [NVM](https://github.com/nvm-sh/nvm): The Node Version Manager makes it
|
||||
easy to ensure you have the right NodeJS version installed. Once installed,
|
||||
run `nvm use 16` to use Node 16.x. The website is known to be stable with
|
||||
NodeJS version 16.x. This will install both Node and NPM.
|
||||
1. [Docker](https://www.docker.com/): We use docker to simplify running
|
||||
dependent services.
|
||||
|
||||
### Getting everything up and running
|
||||
|
||||
If you're doing active development we suggest the following workflow:
|
||||
|
||||
1. In one tab, navigate to
|
||||
`${OPEN_ASSISTANT_ROOT}/scripts/frontend-development`.
|
||||
1. Run `docker compose up --build`. You can optionally include `-d` to detach and
|
||||
later track the logs if desired.
|
||||
1. In another tab navigate to `${OPEN_ASSISTANT_ROOT/website`.
|
||||
1. Run `npm install`
|
||||
1. Run `npx prisma db push` (This is also needed when you restart the docker
|
||||
stack from scratch).
|
||||
1. Run `npm run dev`. Now the website is up and running locally at
|
||||
`http://localhost:3000`.
|
||||
1. To create an account, login via the user using email authentication and
|
||||
navigate to `http://localhost:1080`. Check the email listed and click the
|
||||
log in link. You're now logged in and authenticated.
|
||||
|
||||
## Code Layout
|
||||
|
||||
### React Code
|
||||
|
||||
All react code is under `src/` with a few sub directories:
|
||||
|
||||
1. `pages/`: All pages a user could navigate too and API URLs which are under `pages/api/`.
|
||||
1. `components/`: All re-usable React components. If something gets used
|
||||
twice we should create a component and put it here.
|
||||
1. `lib/`: A generic place to store library files that are used anywhere.
|
||||
This doesn't have much structure yet.
|
||||
|
||||
NOTE: `styles/` can be ignored for now.
|
||||
|
||||
### Database
|
||||
|
||||
All database configurations are stored in `prisma/schema.prisma`.
|
||||
|
||||
### Static Content
|
||||
|
||||
All static images, fonts, svgs, etc are stored in `public/`.
|
||||
|
||||
### Styles
|
||||
|
||||
We're not really using CSS styles. `styles/` can be ignored.
|
||||
|
||||
## Best Practices
|
||||
|
||||
When writing code for the website, we have a few best practices:
|
||||
|
||||
1. When importing packages import external dependencies first then local
|
||||
dependencies. Order them alphabetically according to the package name.
|
||||
1. When trying to implement something new, check if
|
||||
[Chakra-UI](https://chakra-ui.com/) has components that are close enough to
|
||||
your need. For example Sliders, Radio Buttons, Progress indicators, etc. They
|
||||
have a lot and we can save time by re-using what they have and tweaking the
|
||||
style as needed.
|
||||
1. Format everything with [Prettier](https://prettier.io/). This is done by
|
||||
default with pre-submits. We currently don't have any custom settings.
|
||||
1. Define functional React components (with types for all properties when
|
||||
feasible).
|
||||
|
||||
## Learn More
|
||||
|
||||
@@ -33,11 +111,3 @@ To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: "standalone",
|
||||
reactStrictMode: true,
|
||||
experimental: {
|
||||
scrollRestoration: true,
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
"@heroicons/react": "^2.0.13",
|
||||
"@next-auth/prisma-adapter": "^1.0.5",
|
||||
"@prisma/client": "^4.7.1",
|
||||
"@supabase/auth-helpers-nextjs": "^0.5.2",
|
||||
"@supabase/auth-helpers-react": "^0.3.1",
|
||||
"@supabase/auth-ui-react": "^0.2.6",
|
||||
"@supabase/supabase-js": "^2.1.4",
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"axios": "^1.2.1",
|
||||
|
||||
@@ -16,7 +16,7 @@ export function CallToAction() {
|
||||
here:
|
||||
</p>
|
||||
<div className="mt-8 flex justify-center">
|
||||
<a href="https://discord.gg/pXtnYk9c" target="_blank">
|
||||
<a href="https://discord.gg/pXtnYk9c" rel="noreferrer" target="_blank">
|
||||
<button
|
||||
type="button"
|
||||
className="mb-2 ml-6 flex items-center rounded-md border border-transparent bg-blue-600 px-6 py-3 text-base font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||
@@ -31,7 +31,7 @@ export function CallToAction() {
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/LAION-AI/Open-Assistant" target="_blank">
|
||||
<a href="https://github.com/LAION-AI/Open-Assistant" rel="noreferrer" target="_blank">
|
||||
<button
|
||||
type="button"
|
||||
className="mb-2 ml-6 flex items-center rounded-md border border-transparent bg-blue-600 px-6 py-3 text-base font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import Link from "next/link";
|
||||
import { signOut, useSession } from "next-auth/react";
|
||||
import { Button } from "@chakra-ui/react";
|
||||
import { Popover } from "@headlessui/react";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { signOut, useSession } from "next-auth/react";
|
||||
|
||||
import { Container } from "./Container";
|
||||
import Image from "next/image";
|
||||
import { NavLinks } from "./NavLinks";
|
||||
|
||||
function MenuIcon(props) {
|
||||
@@ -40,23 +41,14 @@ function AccountButton() {
|
||||
const { data: session } = useSession();
|
||||
if (session) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => signOut()}
|
||||
className="inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
>
|
||||
<Button variant="outline" onClick={() => signOut()}>
|
||||
Log out
|
||||
</button>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Link href="/auth/signin" aria-label="Home" className="flex items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
>
|
||||
Log in
|
||||
</button>
|
||||
<Button variant="outline">Log in</Button>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AuthOptions } from "next-auth";
|
||||
import NextAuth from "next-auth";
|
||||
import DiscordProvider from "next-auth/providers/discord";
|
||||
import EmailProvider from "next-auth/providers/email";
|
||||
@@ -31,7 +32,7 @@ if (process.env.DISCORD_CLIENT_ID) {
|
||||
);
|
||||
}
|
||||
|
||||
export const authOptions = {
|
||||
export const authOptions: AuthOptions = {
|
||||
// Ensure we can store user data in a database.
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { getToken } from "next-auth/jwt";
|
||||
|
||||
import prisma from "src/lib/prismadb";
|
||||
import { authOptions } from "src/pages/api/auth/[...nextauth]";
|
||||
|
||||
/**
|
||||
@@ -10,7 +11,7 @@ import { authOptions } from "src/pages/api/auth/[...nextauth]";
|
||||
* 3) Send and Ack to the Task Backend with our local id for the task.
|
||||
* 4) Return everything to the client.
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const handler = async (req, res) => {
|
||||
const { task_type } = req.query;
|
||||
|
||||
const token = await getToken({ req });
|
||||
@@ -69,3 +70,5 @@ export default async (req, res) => {
|
||||
// Send the results to the client.
|
||||
res.status(200).json(registeredTask);
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { getToken } from "next-auth/jwt";
|
||||
|
||||
import prisma from "src/lib/prismadb";
|
||||
import { authOptions } from "src/pages/api/auth/[...nextauth]";
|
||||
|
||||
/**
|
||||
@@ -11,7 +12,7 @@ import { authOptions } from "src/pages/api/auth/[...nextauth]";
|
||||
* 3) (TODO) Acks the new task with our local task ID to the Task Backend.
|
||||
* 4) Returns the newly created task to the client.
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const handler = async (req, res) => {
|
||||
const token = await getToken({ req });
|
||||
|
||||
// Return nothing if the user isn't registered.
|
||||
@@ -76,3 +77,5 @@ export default async (req, res) => {
|
||||
// Send the next task in the sequence to the client.
|
||||
res.status(200).json(newRegisteredTask);
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
||||
@@ -134,7 +134,7 @@ const GradeOutput = () => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => submitResponse(tasks[0])}
|
||||
className="nline-flex items-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
className="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve"
|
||||
"jsx": "preserve",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
# wait-for-postgres.sh
|
||||
#
|
||||
# This script tries to connect to a postgres database and then runs
|
||||
# `npx prisma db push`
|
||||
# It repeats until that setup completes (running multiple times will be a
|
||||
# noop). Then, it'll run the next command provided.
|
||||
#
|
||||
# You don't need to provide the connection URL. This reads it from the
|
||||
# DATABASE_URL environment variable which should be set.
|
||||
#
|
||||
# To run we suggest:
|
||||
# ./wait-for-postgres.sh npm run dev
|
||||
|
||||
set -e
|
||||
|
||||
until npx prisma db push --skip-generate; do
|
||||
>&2 echo "Postgres is unavailable - sleeping"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
>&2 echo "Postgres is up - executing command"
|
||||
# Print and execute all other arguments starting with `$1`
|
||||
# So `exec "$1" "$2" "$3" ...`
|
||||
exec "$@"
|
||||
Reference in New Issue
Block a user