# Work with Server-Side Database

LobeChat provides a battery-included experience with its client-side database.
While some features you really care about is only available at a server-side development.

In order to work with the aspect of server-side database,
you can setup all the prerequisites by following the [Deploying Server-Side Database](https://lobehub.com/docs/self-hosting/server-database) story.
But here is the easier approach that can reduce your pain.

## Quick Setup

### Environment Configuration

First, copy the example environment file to create your Docker Compose configuration:

```bash
cp docker-compose/local/.env.example docker-compose/local/.env
```

Edit `docker-compose/local/.env` as needed for your development setup. This file contains all necessary environment variables for the Docker services and configures:

- **Service Mode**: `NEXT_PUBLIC_SERVICE_MODE=server`
- **Database**: PostgreSQL with connection string
- **Authentication**: NextAuth with Casdoor SSO
- **Storage**: MinIO S3-compatible storage
- **Search**: SearXNG search engine

### Start Docker Services

Start all required services using Docker Compose:

```bash
docker-compose -f docker-compose.development.yml up -d
```

This will start the following services:

- PostgreSQL database (port 5432)
- MinIO storage (port 9000)
- Casdoor authentication (port 8000)
- SearXNG search (port 8080)

### Run Database Migrations

Execute the database migration script to create all necessary tables:

```bash
pnpm db:migrate
```

You should see: `✅ database migration pass.`

### Start Development Server

Launch the LobeChat development server:

```bash
pnpm dev
```

The server will start on `http://localhost:3010`

And you can check all Docker services are running by running:

```bash
docker-compose -f docker-compose.development.yml ps
```

## Image Generation Development

When working with image generation features (text-to-image, image-to-image), the Docker Compose setup already includes all necessary storage services for handling generated images and user uploads.

### Image Generation Configuration

The existing Docker Compose configuration already includes MinIO storage service and all necessary environment variables in `docker-compose/local/.env.example`. No additional setup is required.

### Image Generation Architecture

The image generation feature requires:

- **PostgreSQL**: Stores metadata about generated images
- **MinIO/S3**: Stores the actual image files
- **Server Mode**: Required for file handling (`NEXT_PUBLIC_SERVICE_MODE=server`)

### Storage Configuration

The `docker-compose/local/.env.example` file includes all necessary S3 environment variables:

```bash
# S3 Storage Configuration (MinIO for local development)
S3_ACCESS_KEY_ID=${MINIO_ROOT_USER}
S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}
S3_ENDPOINT=http://localhost:${MINIO_PORT}
S3_BUCKET=${MINIO_LOBE_BUCKET}
S3_PUBLIC_DOMAIN=http://localhost:${MINIO_PORT}
S3_ENABLE_PATH_STYLE=1  # Required for MinIO
S3_SET_ACL=0  # MinIO compatibility
```

### File Storage Structure

Generated images and user uploads are organized in the MinIO bucket:

```
lobe/                # S3 Bucket (MINIO_LOBE_BUCKET)
├── generated/       # Generated images
│   └── {userId}/
│       └── {sessionId}/
│           └── {imageId}.png
└── uploads/         # User uploads for image-to-image
    └── {userId}/
        └── {fileId}.{ext}
```

### Development Workflow for Images

When developing image generation features, generated images will be:

1. Created by the AI model
2. Uploaded to S3/MinIO via presigned URLs
3. Metadata stored in PostgreSQL
4. Served via the public S3 URL

Example code for testing image upload:

```typescript
// Example: Upload generated image
const uploadUrl = await trpc.upload.createPresignedUrl.mutate({
  filename: 'generated-image.png',
  contentType: 'image/png',
});

// Upload to S3
await fetch(uploadUrl, {
  method: 'PUT',
  body: imageBlob,
  headers: { 'Content-Type': 'image/png' },
});
```


### Service URLs

When running with Docker Compose development setup:

- **PostgreSQL**: `postgres://postgres@localhost:5432/lobechat`
- **MinIO API**: `http://localhost:9000`
- **MinIO Console**: `http://localhost:9001` (admin/CHANGE_THIS_PASSWORD_IN_PRODUCTION)
- **Application**: `http://localhost:3010`

### Reset Services

If you encounter issues, you can reset the entire stack:

```bash
# Stop and remove all containers
docker-compose -f docker-compose.development.yml down

# Remove volumes (this will delete all data)
docker-compose -f docker-compose.development.yml down -v

# Start fresh
docker-compose -f docker-compose.development.yml up -d
pnpm db:migrate
```


### Troubleshooting

#### Port Conflicts

If ports are already in use:

```bash
# Check what's using the ports
lsof -i :5432  # PostgreSQL
lsof -i :9000  # MinIO API
lsof -i :9001  # MinIO Console
```

#### Database Migrations

The setup script runs migrations automatically. If you need to run them manually:

```bash
pnpm db:migrate
```

Note: In development mode with `pnpm dev:desktop`, migrations also run automatically on startup.