---
title: Deploy LobeHub with database on Vercel
description: >-
  Learn how to deploy LobeHub with database on Vercel with ease, including:
  database, authentication and S3 storage service.
tags:
  - Deploy LobeHub
  - Vercel Deployment
  - Better Auth
  - S3 Storage
---

# Deploying Server Database Version on Vercel

This article will detail how to deploy the server database version of LobeHub on Vercel, including: 1) database configuration; 2) identity authentication service configuration; 3) steps for setting up the S3 storage service.

<Callout type={'warning'}>
  Before proceeding, please make sure of the following:

  - Export all data, as after deploying the server-side database, existing user data cannot be automatically migrated and can only be manually imported after backup!
  - When configuring the environment variables required for the server-side database, make sure to fill in all of them before deployment, otherwise you may encounter database migration issues!
</Callout>

## 1. Configure the Database

<Steps>
  ### Prepare the Server Database Instance and Obtain the Connection URL

  Before deployment, make sure you have prepared a Postgres database instance. You can choose one of the following methods:

  - `A.` Use Serverless Postgres instances like Vercel / Neon;
  - `B.` Use self-deployed Postgres instances like Docker.

  The configuration for both methods is slightly different, and will be distinguished in the next step.

  ### Add Environment Variables in Vercel

  In Vercel's deployment environment variables, add `DATABASE_URL` and other environment variables, and fill in the Postgres database connection URL prepared in the previous step. The typical format for the database connection URL is `postgres://username:password@host:port/database`.

  <Tabs items={['Serverless Postgres', 'Node Postgres']}>
    <Tab>
      <Callout type={'warning'}>
        Please confirm the `Postgres` type provided by your vendor. If it is `Node Postgres`, switch to
        the `Node Postgres` Tab.
      </Callout>

      Variables to be filled for Serverless Postgres are as follows:

      ```shell
      # Serverless Postgres DB Url
      DATABASE_URL=
      ```

      An example of filling in Vercel is as follows:

      <Image alt={'Add Serverless Postgres DATABASE_URL'} src={'/blog/assets28616219/d4a710cd-6404-4196-90d0-cd08ca385074.webp'} />
    </Tab>

    <Tab>
      Variables to be filled for Node Postgres are as follows:

      ```shell
      # Node Postgres DB Url
      DATABASE_URL=

      # Specify Postgres database driver as node
      DATABASE_DRIVER=node
      ```

      An example of filling in Vercel is as follows:

      <Image alt={'Add Node Postgres DATABASE_URL'} src={'/blog/assets28616219/1c689738-809b-4199-b305-ba5770d39da7.webp'} />
    </Tab>
  </Tabs>

  <Callout type={'info'}>
    If you wish to enable SSL when connecting to the database, please refer to the
    [link](https://stackoverflow.com/questions/14021998/using-psql-to-connect-to-postgresql-in-ssl-mode)
    for setup instructions.
  </Callout>

  ### Add the `KEY_VAULTS_SECRET` Environment Variable

  After adding the `DATABASE_URL` environment variable for the database, you need to add a `KEY_VAULTS_SECRET` environment variable. This variable is used to encrypt sensitive information such as apikeys stored by users. Click the button below to generate:

  <GenerateSecret envName="KEY_VAULTS_SECRET" />

  Make sure to add this to the Vercel environment variables as well.

  ### Add the `APP_URL` Environment Variable

  Finally, you need to add the `APP_URL` environment variable, which specifies the URL address of the LobeHub application.
</Steps>

## 2. Configure Authentication Service

The server-side database needs to be paired with a user authentication service to function properly. Therefore, the corresponding authentication service needs to be configured.

<Steps>
  ### Add Authentication Environment Variables

  In Vercel's deployment environment variables, add the following environment variables to enable authentication (powered by [Better Auth](https://www.better-auth.com)):

  Click the button below to generate `AUTH_SECRET` (session encryption key):

  <GenerateSecret envName="AUTH_SECRET" />

  You also need to configure the `JWKS_KEY` environment variable for signing and verifying JWTs. Click the button below to generate:

  <GenerateJWKSKey />

  With these variables, users can register and login with email and password.

  <Callout type={'info'}>
    For advanced features like SSO providers, magic link login, and email verification, see [Authentication Service](/docs/self-hosting/auth).
  </Callout>
</Steps>

By completing these steps, you have successfully configured the authentication service. Next, we will configure the S3 storage service.

## 3. Configure S3 Storage Service

In the server-side database, we need to configure the S3 storage service to store files.

<Callout type={'info'}>
  In this article, S3 refers to a compatible S3 storage solution, which supports object storage
  systems that comply with the Amazon S3 API. Common examples include Cloudflare R2, Alibaba Cloud
  OSS, etc., all of which support S3-compatible APIs.
</Callout>

<Steps>
  ### Configure and Obtain S3 Bucket

  You need to go to your S3 service provider (such as AWS S3, Cloudflare R2, etc.) and create a new storage bucket. The following steps will use Cloudflare R2 as an example to explain the creation process.

  The interface of Cloudflare R2 is shown below:

  <Image alt={'Cloudflare R2 Storage Interface'} src={'/blog/assets28616219/41f7f677-0153-4a96-b849-5ac9b7ebefee.webp'} />

  When creating a storage bucket, specify its name and then click create.

  <Image alt={'Create Storage Bucket in R2'} src={'/blog/assets28616219/9c0d184c-3169-40fa-9115-011cfffb9ca7.webp'} />

  ### Obtain Environment Variables for the Bucket

  In the settings of the R2 storage bucket, you can view the bucket configuration information:

  <Image alt={'View Storage Bucket Information'} src={'/blog/assets28616219/2ceb210c-eca0-4439-ba27-8734d4ebb3ee.webp'} />

  The corresponding environment variables are:

  ```shell
  # Storage bucket name
  S3_BUCKET=LobeHub
  # Storage bucket request endpoint (note that the path in this link includes the bucket name, which must be removed, or use the link provided on the S3 API token application page)
  S3_ENDPOINT=https://0b33a03b5c993fd2f453379dc36558e5.r2.cloudflarestorage.com
  ```

  <Callout type={'warning'}>
    `S3_ENDPOINT` must have its path removed, otherwise uploaded files will not be accessible
  </Callout>

  ### Obtain S3 Key Environment Variables

  You need to obtain the access key for S3 so that the LobeHub server has permission to access the S3 storage service. In R2, you can configure the access key in the account details:

  <Image alt={'View Storage Bucket Access Key'} src={'/blog/assets28616219/be0c95c0-6693-44ee-a490-7e8dfaa8b34d.webp'} />

  Click the button in the upper right corner to create an API token and enter the create API Token page.

  <Image alt={'Create Corresponding API Token'} src={'/blog/assets28616219/7b0ea46c-5157-40a8-888f-f47664a4884f.webp'} />

  Since our server-side database needs to read and write to the S3 storage service, the permission needs to be set to `Object Read and Write`, then click create.

  <Image alt={'Configure API Token Permissions'} src={'/blog/assets28616219/d6f5a918-7b50-4d6e-83a6-3894ab930ddf.webp'} />

  After creation, you can see the corresponding S3 API token.

  <Image alt={'Copy API Token'} src={'/blog/assets28616219/763b18f9-2b5f-44bb-a479-9b56d46f7397.webp'} />

  The corresponding environment variables are:

  ```shell
  S3_ACCESS_KEY_ID=9998d6757e276cf9f1edbd325b7083a6
  S3_SECRET_ACCESS_KEY=55af75d8eb6b99f189f6a35f855336ea62cd9c4751a5cf4337c53c1d3f497ac2
  ```

  ### Adding Corresponding Environment Variables in Vercel

  The steps to obtain the required environment variables may vary for different S3 service providers, but the obtained environment variables should be consistent:

  <Callout type={'warning'}>
    The `https://` in the URL is essential and must be maintained for the completeness of the URL.
  </Callout>

  ```shell
  # S3 Keys
  S3_ACCESS_KEY_ID=9998d6757e276cf9f1edbd325b7083a6
  S3_SECRET_ACCESS_KEY=55af75d8eb6b99f189f6a35f855336ea62cd9c4751a5cf4337c53c1d3f497ac2

  # Bucket name
  S3_BUCKET=LobeHub
  # Bucket request endpoint
  S3_ENDPOINT=https://0b33a03b5c993fd2f453379dc36558e5.r2.cloudflarestorage.com
  # Bucket region, such as us-west-1, generally not required, but some providers may need to configure
  # S3_REGION=us-west-1
  ```

  Then, insert the above environment variables into Vercel's environment variables:

  <Image alt={'Adding S3 environment variables in Vercel'} src={'/blog/assets28616219/cd74152d-0ae8-44fd-b815-3307c56a3c18.webp'} />

  ### Configuring Cross-Origin Resource Sharing (CORS)

  Since S3 storage services are often on a separate domain, cross-origin access needs to be configured.

  In R2, you can find the CORS configuration in the bucket settings:

  <Image alt={'Cloudflare R2 CORS settings'} src={'/blog/assets28616219/ab008be7-26b2-4b78-8bd9-24301bf34d23.webp'} />

  Add a CORS rule to allow requests from your domain (in this case, `https://your-project.vercel.app`):

  <Image alt={'Configuring allowed site domain'} src={'/blog/assets28616219/dfcc2cb3-2958-4498-a8a4-51bec584fe7d.webp'} />

  Example configuration:

  ```json
  [
    {
      "AllowedOrigins": ["https://your-project.vercel.app"],
      "AllowedMethods": ["GET", "PUT", "HEAD", "POST", "DELETE"],
      "AllowedHeaders": ["*"]
    }
  ]
  ```

  After configuring, click save.
</Steps>

## Four, Deployment and Verification

After completing the steps above, the configuration of the server-side database should be done. Next, we can deploy LobeHub to Vercel and then visit your Vercel link to verify if the server-side database is working correctly.

<Steps>
  ### Redeploy the latest commit

  After configuring the environment variables, you need to redeploy the latest commit and wait for the deployment to complete.

  <Image alt={'Redeploy the latest commit'} src={'/blog/assets28616219/b3a78112-adc8-4837-b4e3-48f67058f16e.webp'} />

  ### Check if the features are working properly

  If you click on the login button in the top left corner and the login popup appears normally, then you have successfully configured it. Enjoy using it\~

  <Image alt={'User login popup'} src={'/blog/assets28616219/da84edc3-46f7-4e2b-a0cd-dc33a98bf5cb.webp'} />

  <Image alt={'Login successful state'} src={'/blog/assets28616219/9cb5150d-6e1e-4c59-9a18-4e418dce1a5d.webp'} />
</Steps>

## Platform Limitations

<Callout type={'warning'}>
  Be aware of these Vercel platform limitations before deploying.
</Callout>

**Serverless function timeout:**

| Plan       | Timeout     |
| ---------- | ----------- |
| Hobby      | 10 seconds  |
| Pro        | 60 seconds  |
| Enterprise | 900 seconds |

Long-running AI requests may timeout on the Hobby plan. Streaming responses (enabled by default) help keep connections alive.

**No WebSocket support** — Vercel serverless functions don't support persistent WebSocket connections. Real-time features use Server-Sent Events (SSE) instead.

**Cold starts** — Serverless functions may be slower on first request after idle periods (1–3 seconds). This is normal behavior for serverless platforms.

**File size limits** — Deployment size: 250 MB (compressed). Function size: 50 MB.

## Keeping Updated

<Callout type={'warning'}>
  If you used the one-click deploy button, Vercel creates a **new** repository instead of forking the original. This prevents automatic upstream updates.
</Callout>

To receive future LobeHub updates:

1. **Delete** the current project from Vercel dashboard (Settings → Delete Project)
2. Manually **fork** [lobehub/lobehub](https://github.com/lobehub/lobehub) on GitHub
3. **Import** your forked repository to Vercel (Add New → Project)
4. Re-configure your environment variables and deploy
5. In your fork's GitHub **Actions** tab, enable the `upstream-sync` workflow — it automatically checks for updates daily

To sync manually: Actions → Upstream Sync → Run workflow.

## Troubleshooting

**Deployment fails** — Check build logs in Vercel Dashboard → Deployments → click the failed deployment → Build Logs. Common causes: missing environment variables, TypeScript errors, or out of memory (fix with `NODE_OPTIONS=--max-old-space-size=4096`).

**Function timeout** — If requests timeout on Hobby plan: upgrade to Pro (60s timeout), use faster AI models (e.g., GPT-4o-mini instead of GPT-4o), reduce max tokens, or ensure streaming is enabled.

**Database connection fails** — Verify `DATABASE_URL` format. Ensure `?sslmode=require` is appended for managed databases. Check that the database's IP allowlist includes Vercel IPs (or use `0.0.0.0/0` for open access). Test locally with `psql "$DATABASE_URL"`.

**502 Bad Gateway** — Common causes: function timeout, out of memory, or database connection pool exhausted. Use a connection pooler (PgBouncer), reduce concurrent connections, or check database logs.

**Environment variables not updating** — After changing env vars, go to Deployments → Redeploy (three dots menu) → select "Use existing Build Cache: No".

## Appendix

### Overview of Server-side Database Environment Variables

For easy copying, here is a summary of the environment variables required to configure the server-side database:

```shell
APP_URL=https://your-project.com

# Postgres database URL
DATABASE_URL=
KEY_VAULTS_SECRET=jgwsK28dspyVQoIf8/M3IIHl1h6LYYceSYNXeLpy6uk=

# Authentication
AUTH_SECRET=jgwsK28dspyVQoIf8/M3IIHl1h6LYYceSYNXeLpy6uk=
JWKS_KEY='{"keys":[...]}'

# S3 related configurations
# S3 keys
S3_ACCESS_KEY_ID=9998d6757e276cf9f1edbd325b7083a6
S3_SECRET_ACCESS_KEY=55af75d8eb6b99f189f6a35f855336ea62cd9c4751a5cf4337c53c1d3f497ac2

# Bucket name
S3_BUCKET=LobeHub
# Bucket request endpoint
S3_ENDPOINT=https://0b33a03b5c993fd2f453379dc36558e5.r2.cloudflarestorage.com
# Bucket region, such as us-west-1, generally not needed to add, but some service providers may require configuration
# S3_REGION=us-west-1
```
