---
layout: 'page'
uri: '/deployment/docker-setup'
position: 1
slug: 'deployment-docker-setup'
parent: 'deployment'
navTitle: 'Docker setup'
title: 'Docker setup'
description: 'Production Dockerfile for Documan with build-time validation, import, and vectorization.'
---
# Docker setup
The production Dockerfile validates, imports, and optionally vectorizes your docs at build time. If anything fails — broken links, invalid frontmatter — the build fails and broken docs never reach production.
For local development with live file changes, see [Docker Compose setup](/deployment/docker-compose-setup). For CI/CD pipelines, see [CI/CD integration](/deployment/ci-cd-integration).
## Quick start
The interactive quickstart creates the Dockerfile, docker-compose.yml, and .env for you:
```bash
curl -fsSL https://raw.githubusercontent.com/documan-ai/documan/main/scripts/quickstart.sh | bash
```
If you prefer to set things up manually, follow the steps below.
## Dockerfile
Create `docker/documan/Dockerfile`:
```dockerfile
# syntax=docker/dockerfile:1
# check=skip=SecretsUsedInArgOrEnv
FROM jzaplet/documan:latest
COPY ./docs /documan/data/docs
WORKDIR /documan/data
ENV DOCUMAN_PROJECT_NAME='My Docs'
ENV DOCUMAN_DOCS_FILES='**/*.md'
ENV DOCUMAN_EXCLUDED_FILES=''
ENV DOCUMAN_HTTP_PORT=3000
ENV DOCUMAN_OPENAI_EMBEDDING_MODEL='text-embedding-3-small'
ENV DOCUMAN_CHUNK_MAX_LEN=250
ARG DOCUMAN_LICENSE_KEY=''
ARG DOCUMAN_OPENAI_API_KEY=''
# Set to "true" to skip lint, import, and vectorize during build.
# Useful for first-time setup when docs may not have valid frontmatter yet.
ARG SKIP_BUILD_STEPS=false
# Validate markdown files — checks for broken links, invalid frontmatter, etc.
# Fails the build if any issues are found
RUN if [ "$SKIP_BUILD_STEPS" = "false" ]; then /documan/bin/documan lint; fi
# Import docs (license key optional — needed for >100 files)
# Uses Docker secret if available, otherwise falls back to ARG
RUN --mount=type=secret,id=DOCUMAN_LICENSE_KEY,required=false \
if [ "$SKIP_BUILD_STEPS" = "true" ]; then exit 0; fi && \
if [ -f /run/secrets/DOCUMAN_LICENSE_KEY ]; then \
export DOCUMAN_LICENSE_KEY=$(cat /run/secrets/DOCUMAN_LICENSE_KEY); \
fi && \
/documan/bin/documan import
# Vectorize docs (only runs if OpenAI API key is provided)
# Uses Docker secret if available, otherwise falls back to ARG
RUN --mount=type=secret,id=DOCUMAN_OPENAI_API_KEY,required=false \
if [ "$SKIP_BUILD_STEPS" = "true" ]; then exit 0; fi && \
if [ -f /run/secrets/DOCUMAN_OPENAI_API_KEY ]; then \
export DOCUMAN_OPENAI_API_KEY=$(cat /run/secrets/DOCUMAN_OPENAI_API_KEY); \
fi && \
if [ -n "${DOCUMAN_OPENAI_API_KEY}" ]; then /documan/bin/documan vectorize; fi
CMD ["/documan/bin/documan", "serve"]
```
## What happens at build time
1. **lint** — validates all markdown files (frontmatter, internal links). Fails the build on errors.
2. **import** — parses and imports docs into the embedded database.
3. **vectorize** — generates embeddings for semantic search (only if `DOCUMAN_OPENAI_API_KEY` is provided).
If `SKIP_BUILD_STEPS=true` is passed as a build arg, all three steps are skipped. This is useful for the first build when docs may not have valid frontmatter yet — run `fix` and `import` manually after starting the container.
## Build and run
```bash
docker build -f docker/documan/Dockerfile -t myproject-docs:latest .
docker run -d -p 3000:3000 myproject-docs:latest
```
## Secrets and API keys
Two build steps require secrets:
- **import** — requires `DOCUMAN_LICENSE_KEY` (for projects with more than 100 files)
- **vectorize** — requires `DOCUMAN_OPENAI_API_KEY` (enables semantic search)
The preferred way is to use [Docker secrets](https://docs.docker.com/build/building/secrets/):
```bash
docker build -f docker/documan/Dockerfile \
--secret id=DOCUMAN_LICENSE_KEY,src=.secrets/license_key \
--secret id=DOCUMAN_OPENAI_API_KEY,src=.secrets/openai_key \
-t myproject-docs:latest .
```
If your platform doesn't support Docker secrets (e.g., PaaS like EasyPanel), the Dockerfile falls back to build arguments (`ARG`). The platform injects them as environment variables automatically.
## Configuration
Customize the `ENV` values in the Dockerfile to match your project. See [Configuration](/configuration) for all available variables.
When running via [Docker Compose](/deployment/docker-compose-setup), the `.env` file overrides these values at runtime.
---
[← 🚢 Deployment](/deployment.md) | [Docker Compose →](/deployment/docker-compose-setup.md)