# How to Deploy AnythingLLM on Bare Metal vs Docker: Complete Deployment Guide

> Deploy AnythingLLM on bare metal or Docker. Learn the complete guide for setting up AnythingLLM on your own hardware or within containers for maximum control and isolation.

- Repository: [Mintplex Labs/anything-llm](https://github.com/Mintplex-Labs/anything-llm)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Deploying AnythingLLM on bare metal requires manually installing Node.js dependencies, building the Vite frontend, and running the server and collector processes directly on your host OS, while Docker deployment packages everything into the official `mintplexlabs/anythingllm` image with volume mounts for data persistence and provides superior process isolation.**

AnythingLLM by Mintplex-Labs is a full-stack document-to-chat application that consists of three integrated components. Whether you choose bare metal or Docker deployment according to the Mintplex-Labs/anything-llm source code, both methods ultimately run the same three processes—but differ significantly in how they handle dependency isolation, data persistence, and system updates.

## Understanding the AnythingLLM Architecture

Before choosing a deployment method, understand that AnythingLLM comprises three distinct services that must all run simultaneously:

1. **Frontend** – A Vite-built single-page application served from `frontend/` that communicates with the backend over `/api`.
2. **Server** – The Node/Express backend ([`server/index.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/index.js)) that serves the API, manages the vector store, and handles LLM connections.
3. **Collector** – A lightweight Node process ([`collector/index.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/collector/index.js)) that monitors a hot folder for new documents and imports them into the system.

Both bare metal and Docker deployments result in these three processes running, but they differ in process isolation, dependency management, and upgrade workflows.

## Bare Metal Deployment

Bare metal deployment runs the three processes directly on your host operating system without containerization. The repository provides a comprehensive guide in **[BARE_METAL.md](https://github.com/Mintplex-Labs/anything-llm/blob/master/BARE_METAL.md)** that outlines the exact command sequence required.

### Prerequisites and Environment Setup

Running AnythingLLM on bare metal requires **Node.js v18**, **Yarn**, and at least **2 GiB RAM** (10 GiB storage recommended). You must also ensure `STORAGE_DIR` is set in your environment to define where vector databases and uploaded files persist across restarts.

Because processes run directly on the host, you can mount `STORAGE_DIR` on any filesystem or NFS share, giving you complete control over data location and backup strategies. However, the documentation warns that bare-metal deployments are **not officially supported**, leaving you fully responsible for security hardening, firewall configuration, and backup procedures.

### Step-by-Step Installation

Execute these commands from the repository root to deploy on bare metal:

```bash

# 1. Clone the repository

git clone https://github.com/Mintplex-Labs/anything-llm.git
cd anything-llm

# 2. Install all dependencies (frontend, server, collector)

yarn setup

# 3. Configure environment variables

cp server/.env.example server/.env
cp frontend/.env.example frontend/.env

# Edit frontend/.env to set VITE_API_BASE='/api' for production

# 4. Build the frontend for production

cd frontend && yarn build

# 5. Deploy built assets to server's public folder

cp -R dist ../server/public

# 6. Run database migrations (creates SQLite DB)

cd ../server
npx prisma generate --schema=./prisma/schema.prisma
npx prisma migrate deploy --schema=./prisma/schema.prisma

# 7. Start the API server (production mode)

NODE_ENV=production node index.js &

# 8. Start the document collector (in separate shell)

cd ../collector
NODE_ENV=production node index.js &

```

### Updates and Maintenance

Upgrading a bare metal installation requires pulling new code from the repository, rebuilding the frontend assets, and rerunning Prisma migrations. No container rebuilds are necessary, but you must manually ensure Node.js version compatibility and dependency conflicts are resolved.

## Docker Deployment

Docker deployment packages the server, collector, and frontend build environment into a single container image. The official instructions reside in **[docker/HOW_TO_USE_DOCKER.md](https://github.com/Mintplex-Labs/anything-llm/blob/master/docker/HOW_TO_USE_DOCKER.md)**, with the orchestration defined in **[docker/docker-compose.yml](https://github.com/Mintplex-Labs/anything-llm/blob/master/docker/docker-compose.yml)**.

### Official Image and Container Structure

The Docker approach uses the `mintplexlabs/anythingllm` image published on Docker Hub. The **[docker/Dockerfile](https://github.com/Mintplex-Labs/anything-llm/blob/master/docker/Dockerfile)** builds the frontend, copies it into the image, and installs server and collector dependencies. This bundles exact Node.js and Yarn versions, meaning your host only requires a working Docker engine.

### Storage Persistence and Networking

The compose file mounts critical host volumes to ensure data survives container recreation:

- `../server/storage` maps to `/app/server/storage` (vector database and uploaded files)
- `../collector/hotdir/` and `../collector/outputs/` map to their respective container paths

Port `3001` is exposed for web access. For connecting to LLMs running on the host machine, the compose file includes `extra_hosts: ["host.docker.internal:host-gateway"]`, allowing the container to reach host services via `http://host.docker.internal:<port>`.

### Quick Start with Docker Run

For simple deployments, use this one-liner (Linux/macOS) from the official documentation:

```bash
export STORAGE_LOCATION=$HOME/anythingllm && \
mkdir -p $STORAGE_LOCATION && \
touch "$STORAGE_LOCATION/.env" && \
docker run -d -p 3001:3001 \
  --cap-add SYS_ADMIN \
  -v ${STORAGE_LOCATION}:/app/server/storage \
  -v ${STORAGE_LOCATION}/.env:/app/server/.env \
  -e STORAGE_DIR="/app/server/storage" \
  mintplexlabs/anythingllm

```

The `SYS_ADMIN` capability is required for certain filesystem operations within the container.

### Production Docker Compose Configuration

For production environments, use the official compose file to ensure proper UID/GID mapping and persistent storage:

```yaml

# docker/docker-compose.yml

version: '3.8'
services:
  anything-llm:
    container_name: anythingllm
    build:
      context: ../.
      dockerfile: ./docker/Dockerfile
      args:
        ARG_UID: ${UID:-1000}
        ARG_GID: ${GID:-1000}
    cap_add:
      - SYS_ADMIN
    volumes:
      - "./.env:/app/server/.env"
      - "../server/storage:/app/server/storage"
      - "../collector/hotdir/:/app/collector/hotdir"
      - "../collector/outputs/:/app/collector/outputs"
    user: "${UID:-1000}:${GID:-1000}"
    ports:
      - "3001:3001"
    env_file:
      - .env
    networks:
      - anything-llm
    extra_hosts:
      - "host.docker.internal:host-gateway"
networks:
  anything-llm:
    driver: bridge

```

Deploy with:

```bash
docker compose -f docker/docker-compose.yml up -d --build

```

The `ARG_UID` and `ARG_GID` arguments propagate your host user permissions into the container, preventing permission-denied errors on mounted volumes.

## Bare Metal vs Docker: Key Differences

| Aspect | Bare Metal | Docker |
|--------|------------|--------|
| **Process Isolation** | Runs directly on host OS; no container sandbox. | All components live inside isolated container environment. |
| **Startup Method** | Execute `node index.js` manually for server and collector. | Single command: `docker compose up -d`. |
| **Dependencies** | Host must have Node.js v18 and Yarn installed. | Image bundles Node.js; host only needs Docker engine. |
| **Persistence** | Direct filesystem access via `STORAGE_DIR`. | Host-mounted volumes (`../server/storage`) persist data. |
| **Upgrades** | Pull code, rebuild frontend, rerun migrations manually. | `docker pull` and `docker compose up -d --build`. |
| **Portability** | Tied to specific host OS and environment. | Portable across any Docker-compatible system. |
| **Security** | Requires full host hardening (firewall, user permissions). | Container adds isolation layer; still requires host security. |

Choose **bare metal** when you require absolute control over the environment, need to run on systems where Docker is unavailable, or prefer direct filesystem access without volume abstraction. Choose **Docker** for reproducible deployments, simplified dependency management, and easier horizontal scaling or migration between hosts.

## Summary

- **Bare metal deployments** run the frontend, server, and collector processes directly on the host OS using Node.js v18 and Yarn, requiring manual builds and migrations as documented in [`BARE_METAL.md`](https://github.com/Mintplex-Labs/anything-llm/blob/main/BARE_METAL.md).
- **Docker deployments** utilize the official `mintplexlabs/anythingllm` image with volume mounts for `STORAGE_DIR`, providing process isolation and simplified upgrades via `docker pull`.
- Both methods support the same three-process architecture and API surface, differing primarily in dependency management and system isolation.
- The Docker Compose configuration in [`docker/docker-compose.yml`](https://github.com/Mintplex-Labs/anything-llm/blob/main/docker/docker-compose.yml) handles UID/GID mapping and persistent storage through host-mounted volumes.
- Bare metal offers greater control but lacks official support, while Docker provides better security isolation and portability across environments.

## Frequently Asked Questions

### Is bare metal deployment officially supported by AnythingLLM?

No, bare metal deployment is explicitly marked as **not officially supported** in the repository's [`BARE_METAL.md`](https://github.com/Mintplex-Labs/anything-llm/blob/main/BARE_METAL.md). While the documentation provides complete installation instructions, you assume full responsibility for security hardening, firewall configuration, and system maintenance when running directly on host hardware.

### How do I persist data when upgrading AnythingLLM in Docker?

Data persists automatically through host-mounted volumes defined in [`docker/docker-compose.yml`](https://github.com/Mintplex-Labs/anything-llm/blob/main/docker/docker-compose.yml). The compose file maps `../server/storage` to `/app/server/storage` inside the container, ensuring your vector database and uploaded files survive container recreation. Simply run `docker pull mintplexlabs/anythingllm` followed by `docker compose up -d --build` to upgrade without data loss.

### Can I run AnythingLLM on a VPS with limited RAM?

The minimum requirement is **2 GiB RAM** for both deployment methods, though 10 GiB storage is recommended. For VPS deployments with tight resource constraints, Docker is often preferable because it eliminates the overhead of running separate Node.js installations and ensures clean process isolation that prevents memory leaks from affecting the host system.

### How do I connect AnythingLLM Docker to a local LLM running on my host machine?

Use the `host.docker.internal` hostname enabled by the `extra_hosts: ["host.docker.internal:host-gateway"]` entry in [`docker-compose.yml`](https://github.com/Mintplex-Labs/anything-llm/blob/main/docker-compose.yml). Configure your LLM endpoint in the container's environment variables to point to `http://host.docker.internal:<port>` where `<port>` is your local LLM's listening port. This bridge network allows the containerized application to communicate with services running on the Docker host.