diff --git a/.gitignore b/.gitignore index 5beaa9be..37ec3e0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# Docker volumnes +docker/volumes/db/data +docker/volumes/storage + # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. __pycache__/ *.pyc @@ -59,4 +63,3 @@ next-env.d.ts dist/ lui/src/style.css - diff --git a/client/.env.local.example b/client/.env.local.example new file mode 100644 index 00000000..e61d3ff9 --- /dev/null +++ b/client/.env.local.example @@ -0,0 +1,2 @@ +SELF_PATH=/client/ +NEXT_PUBLIC_API_DOMAIN=http://localhost:8001 \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index f3377f10..00000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,53 +0,0 @@ -# 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 - -name: petercat -version: "1.0" - -services: - backend-core: - image: petercat-backend-base - build: - context: ../server - dockerfile: ../docker/Dockerfile.aws.lambda - restart: always - ports: - - 8080:8080 - environment: - AWS_GITHUB_SECRET_NAME: ${AWS_GITHUB_SECRET_NAME} - S3_TEMP_BUCKET_NAME: ${S3_TEMP_BUCKET_NAME} - API_URL: ${API_URL} - WEB_URL: ${WEB_URL} - X_GITHUB_APP_ID: ${X_GITHUB_APP_ID} - X_GITHUB_APPS_CLIENT_ID: ${X_GITHUB_APPS_CLIENT_ID} - X_GITHUB_APPS_CLIENT_SECRET: ${X_GITHUB_APPS_CLIENT_SECRET} - API_IDENTIFIER: ${API_IDENTIFIER} - FASTAPI_SECRET_KEY: ${FASTAPI_SECRET_KEY} - OPENAI_API_KEY: ${OPENAI_API_KEY} - GEMINI_API_KEY: ${GEMINI_API_KEY} - SUPABASE_SERVICE_KEY: ${SUPABASE_SERVICE_KEY} - SUPABASE_URL: ${SUPABASE_URL} - GITHUB_TOKEN: ${GITHUB_TOKEN} - TAVILY_API_KEY: ${TAVILY_API_KEY} - SQS_QUEUE_URL: ${SQS_QUEUE_URL} - AUTH0_DOMAIN: ${AUTH0_DOMAIN} - AUTH0_CLIENT_ID: ${AUTH0_CLIENT_ID} - AUTH0_CLIENT_SECRET: ${AUTH0_CLIENT_SECRET} - front-end: - image: petercat-frontend - depends_on: - - backend-core - build: - context: .. - dockerfile: ./docker/Dockerfile.vercel - restart: always - ports: - - 3000:3000 - environment: - SUPABASE_URL: ${SUPABASE_URL} - SUPABASE_SERVICE_KEY: ${SUPABASE_SERVICE_KEY} - NEXT_PUBLIC_API_DOMAIN: http://0.0.0.0:8080 - NEXT_STANDALONE: true \ No newline at end of file diff --git a/docs/guides/self_hosted_local.md b/docs/guides/self_hosted_local.md index 2ee2a075..57a71d68 100644 --- a/docs/guides/self_hosted_local.md +++ b/docs/guides/self_hosted_local.md @@ -1,6 +1,7 @@ -# Self-Hosting +``` +# Self-Hosting Guide -## Install Locally +## Local Installation ### Step 1: Clone the Repository Clone the project repository to your local machine: @@ -16,83 +17,47 @@ Install all required dependencies using Yarn: yarn run bootstrap ``` -### Step 3: Copy the `.env.example` Files -Copy the server environment configuration example files: +### Step 3: Copy `.env.example` Files +Copy the server environment configuration example file: ```bash cp server/.env.example server/.env ``` -Copy the Client environment configuration example files: +Copy the client environment configuration example file: ```bash cp client/.env.example client/.env ``` -### Step 4: Update the `.env` Files -Open the `.env` file and update the necessary keys. You can use any text editor, like `vim`, `emacs`, `vscode`, or `nano`: - -```bash -vim server/.env -``` - -For local development, configure only the Supabase and OpenAI settings: +### Step 4: Start Supabase Locally with Docker Compose ```bash -# Supabase Project URL from https://supabase.com/dashboard/project/_/settings/database -SUPABASE_URL=https://{{YOUR_PROJECT_ID}}.supabase.co - -# Supabase Project API key for `anon public` -SUPABASE_SERVICE_KEY=xxxx.yyyyy.zzzzz - -# OpenAI API key -OPENAI_API_KEY=sk-xxxx +yarn run docker ``` -### Step 5: Initialize the Database Structure +### Step 5: Initialize the Database Schema #### Step 5.1: Navigate to the Migrations Folder -Navigate to the `migrations` folder to prepare for the database setup: +Navigate to the `migrations` folder to prepare for database setup: ```bash cd migrations ``` #### Step 5.2: Install Supabase CLI -Install the Supabase CLI following the instructions on [Supabase's Getting Started Guide](https://supabase.com/docs/guides/cli/getting-started): +Install the Supabase CLI following the instructions in the [Supabase Getting Started Guide](https://supabase.com/docs/guides/cli/getting-started): ```bash brew install supabase/tap/supabase ``` -#### Step 5.3: Link to the Remote Project -To connect to the Supabase project, you'll need to enter the database password. You can find this password in the [Supabase Dashboard](https://supabase.com/dashboard/project/_/settings/database): - -```bash -supabase link --project-ref {YOUR_PROJECT_ID} -``` - -If the connection is successful, you'll see output like this: - -``` -Enter your database password (or leave blank to skip): -Connecting to remote database... -Finished supabase link. -Local config differs from linked project. Try updating supabase/config.toml -[api] -enabled = true -port = 54321 -schemas = ["public", "graphql_public"] -extra_search_path = ["public", "extensions"] -max_rows = 1000 -``` - -#### Step 5.4: Perform Migration +#### Step 5.3: Apply Migrations Apply the database migrations to your remote database: ```bash -supabase db push +supabase db push --db-url "postgres://postgres.your-tenant-id:your-super-secret-and-long-postgres-password@127.0.0.1:5432/postgres" ``` -If successful, you'll see output similar to: +If successful, you will see output similar to the following: ``` Connecting to remote database... @@ -104,7 +69,7 @@ Applying migration 20240902023033_remote_schema.sql... Finished supabase db push. ``` -### Step 6: Bootstrap Server +### Step 6: Start the Server Start the server with the following command: ```bash @@ -113,7 +78,7 @@ yarn run server Check if the server is running by opening `http://127.0.0.1:8000/api/health_checker` in your browser. -### Step 7: Bootstrap Client +### Step 7: Start the Client Start the client with the following command: ```bash @@ -121,3 +86,4 @@ yarn run client ``` You can check the client service by opening `http://127.0.0.1:3000` in your browser. +``` \ No newline at end of file diff --git a/docs/guides/self_hosted_local_cn.md b/docs/guides/self_hosted_local_cn.md index 31c06ae9..2885f3b8 100644 --- a/docs/guides/self_hosted_local_cn.md +++ b/docs/guides/self_hosted_local_cn.md @@ -27,24 +27,10 @@ cp server/.env.example server/.env cp client/.env.example client/.env ``` -### 第四步:更新 `.env` 文件 -打开 `.env` 文件并更新必要的键值。您可以使用任何文本编辑器,例如 `vim`、`emacs`、`vscode` 或 `nano`: +### 第四步:使用 docker compose 在本地启动 supabase ```bash -vim server/.env -``` - -对于本地开发,只需配置 Supabase 和 OpenAI 设置: - -```bash -# Supabase 项目 URL,获取路径:https://supabase.com/dashboard/project/_/settings/database -SUPABASE_URL=https://{{YOUR_PROJECT_ID}}.supabase.co - -# Supabase 项目 API 密钥,`anon public` -SUPABASE_SERVICE_KEY=xxxx.yyyyy.zzzzz - -# OpenAI API 密钥 -OPENAI_API_KEY=sk-xxxx +yarn run docker ``` ### 第五步:初始化数据库结构 @@ -63,33 +49,11 @@ cd migrations brew install supabase/tap/supabase ``` -#### 第五步 5.3:连接到远程项目 -要连接到 Supabase 项目,您需要输入数据库密码。您可以在 [Supabase 控制面板](https://supabase.com/dashboard/project/_/settings/database) 中找到该密码: - -```bash -supabase link --project-ref {YOUR_PROJECT_ID} -``` - -如果连接成功,您将看到类似以下的输出: - -``` -Enter your database password (or leave blank to skip): -Connecting to remote database... -Finished supabase link. -Local config differs from linked project. Try updating supabase/config.toml -[api] -enabled = true -port = 54321 -schemas = ["public", "graphql_public"] -extra_search_path = ["public", "extensions"] -max_rows = 1000 -``` - -#### 第五步 5.4:执行迁移 +#### 第五步 5.3:执行迁移 将数据库迁移应用到您的远程数据库: ```bash -supabase db push +supabase db push --db-url "postgres://postgres.your-tenant-id:your-super-secret-and-long-postgres-password@127.0.0.1:5432/postgres" ``` 如果成功,您将看到类似以下的输出: diff --git a/docs/guides/self_hosting_docker.md b/docs/guides/self_hosting_docker.md deleted file mode 100644 index 7eaa7bea..00000000 --- a/docs/guides/self_hosting_docker.md +++ /dev/null @@ -1,49 +0,0 @@ -# Self-Hosting with Docker - -Docker is the easiest way to get started with self-hosted Petercat. This guide assumes you are running the command from the machine you intend to host from. - -## Before you begin - -You need the following installed in your system: -- [Git](https://git-scm.com/downloads) -- Docker ([Windows](https://docs.docker.com/desktop/install/windows-install/), [MacOS](https://docs.docker.com/desktop/install/mac-install/), or [Linux](https://docs.docker.com/desktop/install/linux-install/)). - - -## Running Petercat - -Follow these steps to start Supabase locally: - - -- **Step 0**: Clone the repository: - - ```bash - git clone https://github.com/petercat-ai/petercat.git && cd server - ``` - -- **Step 1**: Copy the `.env.example` files - - ```bash - cp .env.example .env - ``` - -- **Step 2**: Update the `.env` files - - ```bash - vim .env # or emacs or vscode or nano - ``` - Update services keys in the `.env` file. - - ***OPENAI***: - - You need to update the `OPENAI_API_KEY` variable in the `.env` file. You can get your API key [here](https://platform.openai.com/api-keys). You need to create an account first. And put your credit card information. Don't worry, you won't be charged unless you use the API. You can find more information about the pricing [here](https://openai.com/pricing/). - - ***SUPABASE***: - - You need to update the `SUPABASE_URL` and `SUPABASE_SERVICE_KEY` variable in the `.env` file. You can get your help from [here](https://supabase.com/docs/guides/database/connecting-to-postgres#finding-your-database-hostname). You need to create a supabase account first. - - -- **Step 4**: Launch the project - - ```bash - docker compose --env-file .env -f docker/docker-compose.yml up - ``` diff --git a/package.json b/package.json index 2cc59f55..e2d038d7 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,15 @@ "client": "cd client && yarn run dev", "assistant": "cd assistant && yarn run dev", "server": "cd server && ./venv/bin/python3 -m uvicorn main:app --reload", + "server-local": "cd server && python3 -m uvicorn main:app --port 8001 --reload", "env:pull": "cd server && ./venv/bin/python3 scripts/envs.py pull", "client:server": "concurrently \"yarn run server\" \"yarn run client\"", "assistant:server": "concurrently \"yarn run server\" \"yarn run assistant\"", "build:docker": "docker build -t petercat .", "build:pypi": "rm -rf dist && python3 -m build", "publish:test": "python3 -m twine upload --repository petercat-utils dist/* ", - "publish:pypi": "python3 -m twine upload --repository pypi dist/* " + "publish:pypi": "python3 -m twine upload --repository pypi dist/* ", + "docker": "docker compose --env-file server/.env -f docker/docker-compose.yml up -d" }, "engines": { "node": "^18 || >=20" diff --git a/server/.env.example b/server/.env.example index ae5b7302..06e94291 100644 --- a/server/.env.example +++ b/server/.env.example @@ -1,3 +1,85 @@ +############ +# Secrets +# YOU MUST CHANGE THESE BEFORE GOING INTO PRODUCTION +############ + +POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password +JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long +ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE +SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q +DASHBOARD_USERNAME=supabase +DASHBOARD_PASSWORD=this_password_is_insecure_and_should_be_updated + +############ +# Database - You can change these to any PostgreSQL database that has logical replication enabled. +############ + +POSTGRES_HOST=db +POSTGRES_DB=postgres +POSTGRES_PORT=5432 +# default user is postgres + +############ +# Supavisor -- Database pooler +############ +POOLER_PROXY_PORT_TRANSACTION=6543 +POOLER_DEFAULT_POOL_SIZE=20 +POOLER_MAX_CLIENT_CONN=100 +POOLER_TENANT_ID=your-tenant-id + + +############ +# API Proxy - Configuration for the Kong Reverse proxy. +############ + +KONG_HTTP_PORT=8001 +KONG_HTTPS_PORT=8443 + + +############ +# API - Configuration for PostgREST. +############ + +PGRST_DB_SCHEMAS=public,storage,graphql_public + +############ +# Studio - Configuration for the Dashboard +############ + +STUDIO_DEFAULT_ORGANIZATION=Default Organization +STUDIO_DEFAULT_PROJECT=Default Project + +STUDIO_PORT=3000 +# replace if you intend to use Studio outside of localhost +SUPABASE_PUBLIC_URL=http://localhost:8000 + +# Enable webp support +IMGPROXY_ENABLE_WEBP_DETECTION=true + +############ +# Functions - Configuration for Functions +############ +# NOTE: VERIFY_JWT applies to all functions. Per-function VERIFY_JWT is not supported yet. +FUNCTIONS_VERIFY_JWT=false + +############ +# Logs - Configuration for Logflare +# Please refer to https://supabase.com/docs/reference/self-hosting-analytics/introduction +############ + +LOGFLARE_LOGGER_BACKEND_API_KEY=your-super-secret-and-long-logflare-key + +# Change vector.toml sinks to reflect this change +LOGFLARE_API_KEY=your-super-secret-and-long-logflare-key + +# Docker socket location - this value will differ depending on your OS +DOCKER_SOCKET_LOCATION=/var/run/docker.sock + +# Google Cloud Project details +GOOGLE_PROJECT_ID=GOOGLE_PROJECT_ID +GOOGLE_PROJECT_NUMBER=GOOGLE_PROJECT_NUMBER + + # App Base Configures API_URL=http://localhost:8000 WEB_URL=http://localhost:3000 @@ -6,9 +88,9 @@ STATIC_URL=STATIC_URL FASTAPI_SECRET_KEY=fastapi_secret_key # `Project URL` field of https://supabase.com/dashboard/project/_/settings/database -SUPABASE_URL=https://xxxx.supabase.co +SUPABASE_URL=${SUPABASE_PUBLIC_URL} # `Project API keys`: `anon public` field of https://supabase.com/dashboard/project/_/settings/database -SUPABASE_SERVICE_KEY=xxxx.yyyy.zzzz-aaa +SUPABASE_SERVICE_KEY=${SERVICE_ROLE_KEY} SUPABASE_PASSWORD=aABCDEFG # OpenAI API KEY diff --git a/server/main.py b/server/main.py index 0d4c82fc..793489de 100644 --- a/server/main.py +++ b/server/main.py @@ -71,11 +71,13 @@ def home_page(): @app.get("/api/health_checker") def health_checker(): + supabase_url = get_env_variable("SUPABASE_URL") return { "ENVIRONMENT": ENVIRONMENT, "API_URL": API_URL, "WEB_URL": WEB_URL, "CALLBACK_URL": CALLBACK_URL, + "supabase_url": supabase_url, } @@ -84,8 +86,8 @@ def health_checker(): uvicorn.run( "main:app", host="0.0.0.0", - port=int(os.environ.get("PORT", "8080")), + port=int(os.environ.get("PETERCAT_PORT", "8080")), reload=True, ) else: - uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", "8080"))) + uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PETERCAT_PORT", "8080")))