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..345b7495 100644 --- a/docs/guides/self_hosted_local.md +++ b/docs/guides/self_hosted_local.md @@ -1,6 +1,7 @@ +``` # Self-Hosting -## Install Locally +## Local Installation ### Step 1: Clone the Repository Clone the project repository to your local machine: @@ -10,89 +11,71 @@ git clone https://github.com/petercat-ai/petercat.git ``` ### Step 2: Install Dependencies -Install all required dependencies using Yarn: +Install all necessary dependencies using Yarn: ```bash yarn run bootstrap ``` -### Step 3: Copy the `.env.example` Files -Copy the server environment configuration example files: +### Step 3: Start Supabase Locally + +Refer to [Supabase Self-Hosting Guide](https://supabase.com/docs/guides/self-hosting/docker#installing-and-running-supabase): ```bash -cp server/.env.example server/.env -``` -Copy the Client environment configuration example files: -```bash -cp client/.env.example client/.env -``` +# Get the code +git clone --depth 1 https://github.com/supabase/supabase -### 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`: +# Go to the docker folder +cd supabase/docker -```bash -vim server/.env -``` +# Copy the fake env vars +cp .env.example .env -For local development, configure only the Supabase and OpenAI settings: +# Pull the latest images +docker compose pull -```bash -# Supabase Project URL from https://supabase.com/dashboard/project/_/settings/database -SUPABASE_URL=https://{{YOUR_PROJECT_ID}}.supabase.co +# Start the services (in detached mode) +docker compose up -d +``` -# Supabase Project API key for `anon public` -SUPABASE_SERVICE_KEY=xxxx.yyyyy.zzzzz +### Step 4: Copy the `.env.example` Files +Copy the client environment configuration example file: +```bash +cp client/.env.local.example client/.env +``` -# OpenAI API key -OPENAI_API_KEY=sk-xxxx +Copy the server environment configuration example file: +```bash +cp server/.env.local.example server/.env ``` -### Step 5: Initialize the Database Structure +Open the `server/.env` file and update the `SERVICE_ROLE_KEY` field to match the value of `SERVICE_ROLE_KEY` from the `docker/.env` file in Supabase. + +### Step 5: Initialize 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 [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: Run Migrations Apply the database migrations to your remote database: ```bash -supabase db push +# The postgres db URL can be found in the .env file from Step 4 +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 should see output similar to the following: ``` Connecting to remote database... @@ -104,20 +87,21 @@ 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 -yarn run server +yarn run server:local ``` -Check if the server is running by opening `http://127.0.0.1:8000/api/health_checker` in your browser. +Verify the server is running by opening `http://127.0.0.1:8001/api/health_checker` in your browser. -### Step 7: Bootstrap Client +### Step 7: Start the Client Start the client with the following command: ```bash yarn run client ``` -You can check the client service by opening `http://127.0.0.1:3000` in your browser. +Verify 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..322ef118 100644 --- a/docs/guides/self_hosted_local_cn.md +++ b/docs/guides/self_hosted_local_cn.md @@ -16,37 +16,41 @@ git clone https://github.com/petercat-ai/petercat.git yarn run bootstrap ``` -### 第三步:复制 `.env.example` 文件 -复制服务器环境配置示例文件: +### 第三步:在本地启动 supabase + +参考 https://supabase.com/docs/guides/self-hosting/docker#installing-and-running-supabase -```bash -cp server/.env.example server/.env -``` -复制客户端环境配置示例文件: -```bash -cp client/.env.example client/.env ``` +# Get the code +git clone --depth 1 https://github.com/supabase/supabase -### 第四步:更新 `.env` 文件 -打开 `.env` 文件并更新必要的键值。您可以使用任何文本编辑器,例如 `vim`、`emacs`、`vscode` 或 `nano`: +# Go to the docker folder +cd supabase/docker -```bash -vim server/.env -``` +# Copy the fake env vars +cp .env.example .env + +# Pull the latest images +docker compose pull -对于本地开发,只需配置 Supabase 和 OpenAI 设置: +# Start the services (in detached mode) +docker compose up -d +``` +### 第四步:复制 `.env.example` 文件 +复制客户端环境配置示例文件: ```bash -# Supabase 项目 URL,获取路径:https://supabase.com/dashboard/project/_/settings/database -SUPABASE_URL=https://{{YOUR_PROJECT_ID}}.supabase.co +cp client/.env.local.example client/.env +``` -# Supabase 项目 API 密钥,`anon public` -SUPABASE_SERVICE_KEY=xxxx.yyyyy.zzzzz +复制服务器环境配置示例文件: -# OpenAI API 密钥 -OPENAI_API_KEY=sk-xxxx +```bash +cp server/.env.local.example server/.env ``` +打开 `server/.env` 文件,把 `SERVICE_ROLE_KEY` 字段改成从 supabase 的 `docker/.env` 文件的 `SERVICE_ROLE_KEY` 的值 + ### 第五步:初始化数据库结构 #### 第五步 5.1:导航到 Migrations 文件夹 @@ -63,33 +67,12 @@ 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 +# postgres db url 在第四步的 .env 文件中可以找到 +supabase db push --db-url "postgres://postgres.your-tenant-id:your-super-secret-and-long-postgres-password@127.0.0.1:5432/postgres" ``` 如果成功,您将看到类似以下的输出: @@ -108,10 +91,10 @@ Finished supabase db push. 使用以下命令启动服务器: ```bash -yarn run server +yarn run server:local ``` -通过在浏览器中打开 `http://127.0.0.1:8000/api/health_checker` 检查服务器是否正在运行。 +通过在浏览器中打开 `http://127.0.0.1:8001/api/health_checker` 检查服务器是否正在运行。 ### 第七步:启动客户端 使用以下命令启动客户端: 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..669c086e 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "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 && ./venv/bin/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\"", diff --git a/server/.env.example b/server/.env.example index ae5b7302..3fd11573 100644 --- a/server/.env.example +++ b/server/.env.example @@ -6,9 +6,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/.env.local.example b/server/.env.local.example new file mode 100644 index 00000000..54648bc6 --- /dev/null +++ b/server/.env.local.example @@ -0,0 +1,40 @@ +# App Base Configures +API_URL=http://localhost:8001 +WEB_URL=http://localhost:3000 +# OPTIONAL - standalong static url if required +STATIC_URL=STATIC_URL + +FASTAPI_SECRET_KEY=fastapi_secret_key +# `Project URL`: +SUPABASE_URL=http://localhost:8001 +# `Project API keys`: SERVICE_ROLE_KEY from supabase .env file +SUPABASE_SERVICE_KEY=${SERVICE_ROLE_KEY} + +SUPABASE_PASSWORD=aABCDEFG +# OpenAI API KEY +OPENAI_API_KEY=sk-xxxx +# OPTIONAL - Gemini +GEMINI_API_KEY=gemini_api_key +# Tavily Api Key +TAVILY_API_KEY=tavily_api_key + +# OPTIONAL - Github Apps Configures +X_GITHUB_APP_ID=github_app_id +X_GITHUB_APPS_CLIENT_ID=github_apps_client_id +X_GITHUB_APPS_CLIENT_SECRET=github_apps_client_secret + + +# OPTIONAL - AUTH0 Configures +API_IDENTIFIER=api_identifier +AUTH0_DOMAIN=auth0_domain +AUTH0_CLIENT_ID=auth0_client_id +AUTH0_CLIENT_SECRET=auth0_client_secret + +# OPTIONAL - AWS Configures +SQS_QUEUE_URL=https://sqs.ap-northeast-1.amazonaws.com/{your_aws_user}/{your_aws_sqs_message} +AWS_GITHUB_SECRET_NAME="prod/githubapp/petercat/pem" +AWS_STATIC_SECRET_NAME="prod/petercat/static" +AWS_LLM_TOKEN_SECRET_NAME="prod/petercat/llm" +AWS_LLM_TOKEN_PUBLIC_NAME="petercat/prod/llm/pub" +AWS_STATIC_KEYPAIR_ID="xxxxxx" +S3_TEMP_BUCKET_NAME=S3_TEMP_BUCKET_NAME 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")))