Pocket‑Lab provisions a full‑stack, self‑hosted AI laboratory on any fresh Linux host.
Everything – from reverse‑proxy, observability, vector and relational stores up to LLM tooling is bootstrapped with repeatable automation.
Contents
- Pocket-Lab 🧪
- Stack overview
- Key features
- Repository map
- Requirements
- Quick start (Ansible path) 🚀
- Services & Configuration Reference 📝
- Traefik Basic‑Auth 🔒
- n8n 🔁
- Open WebUI 🌐
- RAGFlow 📚
- Stirling PDF 📄
- Ollama 🦙
- MinIO ☁️
- Secure-access layer - Tailscale 🔐
- MySQL 🐬
- Infinity ♾️
- Valkey (Redis drop-in) 🐏
- Elasticsearch 🔍
- Portainer 🛠️
- Prometheus 📊
- Grafana 📈
- Loki 📜
- SMTP relay ✉️
- Web search (Open WebUI + SearXNG) 🔎
- No-Code Architects Toolkit 🧰
- Typical workflows
- Provisioning with Ansible
- Private / no-public-IP deployments (localhost or tailnet)
- Table of all Variables
- Contributing & CI hints
- Release Process
| Layer | Component(s) |
|---|---|
| Reverse‑proxy | Traefik |
| LLMs & chat | Ollama, Open WebUI |
| Workflow | n8n |
| Document tools | Stirling PDF |
| Retrieval & RAG | RAGFlow, Elasticsearch, Infinity |
| Data plane | MySQL, MinIO (S3), Valkey (Redis) |
| Observability | Prometheus + Node‑Exporter, Grafana, Loki |
| Secure access | Tailscale subnet router |
| Dev UX | Portainer |
-
✨ One code base – three ways to deploy
- Ansible – run
task ansible_fullto install Docker and start the stack. - Go Task + Docker Compose – developer‑friendly shortcuts (
task compose‑*) that mirror the authoritative stack assets into./docker/. - Plain Docker Compose – copy
ansible/roles/pocket_lab/files/compose.yamlnext to a hand‑crafted.envand rundocker compose up -d.
- Ansible – run
-
✨ First run bootstrap for upstream projects without automated admin account creation
Short‑lived helper containers/scripts create the very first administrator and disable sign‑up where the upstream image offers neither:Service Bootstrap helper Variables n8n n8n-bootstrap → initial_admin_setup.shN8N_ADMIN_EMAIL,N8N_ADMIN_PASSWORDOpen WebUI openwebui-bootstrap → create_admin.pyOPENWEBUI_ADMIN_EMAIL,OPENWEBUI_ADMIN_PASSWORDRAGFlow ragflow/entrypoint.sh → create_admin.pyRAGFLOW_ADMIN_EMAIL,RAGFLOW_ADMIN_PASSWORD -
🔐 Secrets by design All credentials and tunables live in a single
.envfile. Ansible renders it fromtemplates/.env.j2– or – developers copy.env.templatemanually. A small guard scriptscripts/sync_env.pykeeps both sources of truth in sync and regeneratesdocs/ENVIRONMENT.md. -
🛡️ Secure defaults Traefik terminates TLS (Let’s Encrypt DNS‑01 via Cloudflare) and injects a Basic‑Auth middleware for every UI unless the upstream project has its own authentication.\
| Path | Purpose |
|---|---|
Taskfile.yaml |
Developer shortcuts for Go Task and Docker Compose |
.env.template |
Copy to .env to provide environment variables |
ansible/ |
Inventory, plays, roles and Galaxy requirements |
ansible/plays/00-deploy.yaml |
Install Docker and deploy the stack |
ansible/roles/pocket_lab |
Docker stack logic and templates |
ansible/roles/pocket_lab/files/compose.yaml |
The Docker Compose specification |
docs/ENVIRONMENT.md |
Autogenerated env reference |
scripts/sync_env.py |
Detect drift between .env.template and Ansible template |
- Linux host with Docker and docker compose installed
- Python 3.11 or newer
- Optional: Go Task for the helper commands
-
Add your target server to the inventory
cp ansible/inventory/hosts.yaml.template ansible/inventory/hosts.yaml
-
Set up the Python virtual‑env (installs Ansible + collections)
task venv:init
-
Provision the lab
task ansible_full
-
Mirror stack assets and generate the
.envfiletask compose-prepare
-
Edit and set strong passwords, API keys and any secrets marked
vim docker/.env
-
Launch the stack locally
cd docker docker compose up -d
-
Copy the compose spec and create
cp ansible/roles/pocket_lab/files/compose.yaml . cp .env.template .env -
Edit the
.envfile and replace every default credential with a secure value before starting the stack.vim .env
-
Bring up the stack
docker compose up -d
Note: this manual path skips Ansible – use for quick experiments only.
Pocket‑Lab ships with a demo hash (admin / admin) so the dashboards are reachable right away.
Generate your own credentials with:
htpasswd -nbB admin 'myStrongP@ssw0rd'- Copy the full
user:$2y$…string exactly as printed. - In all deployment modes place it in single quotes to preserve the
$signs:- Docker Compose / Taskfile → in
docker/.env:
- Docker Compose / Taskfile → in
Auth exceptions: UIs that already have their own authentication (e.g. Grafana, Open WebUI) are not protected by Traefik Basic-Auth. Grafana remains reachable without the middleware and uses its own login page.
```env
TRAEFIK_BASIC_AUTH='admin:$2y$…'
```
- Ansible → set
basic_auth: 'admin:$2y$…'in eitheransible/roles/pocket_lab/defaults/main.yaml, or- a dedicated
group_vars/<group>.yamlorhost_vars/<host>.yamlfile.
The lab bootstraps its n8n instance automatically. A short‑lived
n8n-bootstrap container runs initial_admin_setup.sh before the main
service starts. The script resets user management once and uses
N8N_ADMIN_EMAIL and N8N_ADMIN_PASSWORD from the env file to create the
global owner account. It marks the database so this runs only once. If the
bootstrap fails the stack still starts but no owner will exist.
n8n is served through Traefik at https://n8n.${TRAEFIK_DOMAIN}. The env
file wires this domain into WEBHOOK_URL, N8N_HOST and N8N_PROTOCOL
(optionally N8N_EDITOR_BASE_URL) so OAuth callbacks use the correct HTTPS
origin.
The openwebui-bootstrap container executes create_admin.py once before
the actual service comes up. It creates or updates the administrator defined
via OPENWEBUI_ADMIN_EMAIL and OPENWEBUI_ADMIN_PASSWORD. Registration
behaviour is controlled through ENABLE_SIGNUP, the default role via
DEFAULT_USER_ROLE and configuration persistence via
ENABLE_PERSISTENT_CONFIG.
- Open WebUI is wired to Ollama via
OLLAMA_BASE_URL(defaults to internalhttp://ollama:11434),OFFLINE_MODE=trueby default (no version pings/online features), but Web Search is enabled out-of-the-box and points to the bundled SearXNG instance.
RAGFlow runs behind an internal nginx with Traefik handling the public endpoint.
User sign‑up is disabled by default (REGISTER_ENABLED=0).
On container startup create_admin.py ensures the admin account defined via
RAGFLOW_ADMIN_EMAIL and RAGFLOW_ADMIN_PASSWORD exists and belongs to the
default tenant. Visit https://ragflow.${TRAEFIK_DOMAIN} to access the UI.
Tune registration behaviour or credentials in .env or the corresponding
Ansible defaults. RAGFlow talks to MySQL, MinIO and Valkey using the variables in
the env‑file (MINIO_USER, MINIO_PASSWORD, REDIS_HOST, …).
If LLM_CHAT_MODEL points to a model your provider does not authorise, the
admin bootstrap may fail. Before launching the stack set LLM_FACTORY and
LLM_CHAT_MODEL to a locally served model (for example via Ollama) or leave
them blank so RAGFlow uses its internal default.
The default language model backend is controlled via the user_default_llm
block in service_conf.yaml. Override values such as LLM_FACTORY,
LLM_API_KEY or LLM_CHAT_MODEL in your .env to point RAGFlow at a
different provider or model.
Stirling PDF offers browser-based PDF manipulation at https://pdf.${TRAEFIK_DOMAIN}. Its own login is disabled by default (STIRLING_PDF_ENABLE_LOGIN=false) and access is protected through Traefik's Basic-Auth middleware. Set STIRLING_PDF_ENABLE_LOGIN=true to enable the application's sign-in page. Configuration and data persist in dedicated volumes.
Ollama runs the local language models used by the lab. The service exposes the
standard API at https://ollama.${TRAEFIK_DOMAIN} and acts as the default LLM
backend for Open WebUI and RAGFlow. On first start a short-lived
ollama-bootstrap companion downloads all models listed in OLLAMA_PULL_MODELS so
they are available locally. The variable accepts a space-separated list and
defaults to llama3.1:8b deepseek-r1:7b qwen2.5-coder:7b bge-m3. The helper exits successfully if all models are
already present so it is safe to rerun.
- Default pre-pulled models on first run:
llama3.1:8b(general),deepseek-r1:7b(reasoning),qwen2.5-coder:7b(coding), plusbge-m3embeddings.
The lab ships with a MinIO server used as the S3 backend for
other services. Traefik simply forwards https://minio.${TRAEFIK_DOMAIN} to the
MinIO container, which serves both the API and the web console.
Key variables:
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD– console credentials.MINIO_SERVER_URL– external URL of the API and console (defaults to the Traefik hostname).
If you customise TRAEFIK_DOMAIN, adjust MINIO_SERVER_URL accordingly so the
dashboard can reach the backend.
Full variable reference lives in:
ansible/roles/pocket_lab/defaults/main.yaml
Pocket‑Lab ships with a lightweight Tailscale container that runs in host‑network mode, advertises the Docker bridge subnet and enables Tailscale SSH.
- Create an Auth Key in the Tailscale admin console → Keys → “Reusable, pre‑authorized”.
- Put it in
.envasTS_AUTHKEY. - (Optional) change
DOCKER_BRIDGE_SUBNETif you run multiple labs or the default ‑172.20.0.0/16– collides with an existing network.
# .env (excerpt)
TS_AUTHKEY = tskey-auth-ABC123...
DOCKER_BRIDGE_SUBNET = 172.20.0.0/16| Variable | Default | Purpose |
|---|---|---|
TS_AUTHKEY |
Auth key created in the TS admin console | |
DOCKER_BRIDGE_SUBNET |
172.20.0.0/16 |
CIDR routed into the tailnet |
No other Tailscale options need tweaking – advanced users can set TS_EXTRA_ARGS in docker-compose.yaml.
When the stack comes up the tailscale service automatically:
- joins your tailnet and appears as pocket‑lab.tail.ts.net
- advertises the subnet defined by
DOCKER_BRIDGE_SUBNET - enables Tailscale SSH on the host and every container (via
--ssh)
RAGFlow stores its relational data in a standalone MySQL container. Set
MYSQL_ROOT_PASSWORD for the root account and adjust MYSQL_DATABASE
to change the default schema. MYSQL_PORT and MYSQL_HOST control the
exposed port and container name.
Infinity provides the vector index used by RAGFlow. The included
infinity_conf.toml configures storage paths while the ports are
customisable through INFINITY_THRIFT_PORT, INFINITY_HTTP_PORT and
INFINITY_PSQL_PORT. The service registers under
INFINITY_HOST.
Valkey offers a Redis-compatible key–value store. Protect it with
REDIS_PASSWORD and change the image or port via REDIS_VERSION and
REDIS_PORT.
Elasticsearch indexes all documents for RAGFlow. Modify
ES_PASSWORD for the elastic user and ES_PORT for the HTTP API.
ES_HOST chooses the hostname while MEM_LIMIT limits container
memory usage.
Portainer exposes a small Docker dashboard at
https://portainer.${TRAEFIK_DOMAIN} protected by Traefik basic-auth.
Update PORTAINER_VERSION or change the UI port with PORTAINER_PORT.
Prometheus collects metrics from node-exporter and the stack. The image
tag is set via PROMETHEUS_VERSION. Additional scrape targets can be
defined in prometheus/prometheus.yaml.
Grafana visualises metrics at https://grafana.${TRAEFIK_DOMAIN}.
Initial credentials come from GRAFANA_ADMIN_USER and
GRAFANA_ADMIN_PASSWORD. Use GRAFANA_VERSION to upgrade.
Loki stores container logs that Grafana can query. Change
LOKI_VERSION if you need a different release.
A lightweight Postfix relay lets services send mail. Set SMTP_IMAGE
to choose the container, SMTP_PORT for the listening port and
SMTP_SSL to toggle TLS. The hostname is derived from SMTP_HOST.
Pocket-Lab ships a private SearXNG instance (internal-only) and wires it into Open WebUI as the default web search backend. JSON output is enabled and rate limiting is disabled for private use.
Defaults (override in .env / Ansible vars):
# endpoints & privacy
WEBUI_URL=https://chat.<your-domain>
OFFLINE_MODE=true
ENABLE_VERSION_UPDATE_CHECK=false
OLLAMA_BASE_URL=http://ollama:11434
# web search
ENABLE_WEB_SEARCH=true
WEB_SEARCH_ENGINE=searxng
SEARXNG_QUERY_URL=http://searxng:8080/search?q=<query>&format=json
WEB_SEARCH_RESULT_COUNT=5
WEB_SEARCH_CONCURRENT_REQUESTS=2
ENABLE_SEARCH_QUERY_GENERATION=falseWhy SearXNG? It avoids public-instance rate limits and API blocks while keeping search local to your stack. Open WebUI discovers it through
WEB_SEARCH_ENGINE=searxng+SEARXNG_QUERY_URL. See Open WebUI env config & tutorial. Also ensure SearXNG exposes JSON (search.formats: [html, json]). :contentReference[oaicite:2]{index=2}
Internal toolkit service available on the private network at http://ncat:8080. It targets the bundled MinIO (http://minio:9000) and stores data in the pocket_lab bucket by default. Configure it with NCA_VERSION, NCA_API_KEY, NCA_S3_ENDPOINT, NCA_S3_BUCKET, NCA_S3_ACCESS_KEY and NCA_S3_SECRET_KEY.
# list all lab containers – works from any device in the tailnet
tailscale status
# SSH into the host (root)
tailscale ssh root@pocket-lab
# SSH into a container by name
tailscale ssh root@mysql
# Expose a local dev port to the tailnet for 30 min
tailscale funnel 4040 --timeout 30mThe repository bundles a small automation layer under ansible/. After
preparing your .env and inventory you only need two commands:
task venv:init # install Ansible and required collections
task ansible_full # deploy the stackRun task ansible_deploy to execute the play directly.
You can deploy with almost all defaults. The only values you typically must provide are:
cloudflare_api_token(for automatic TLS via DNS-01), and/orts_authkey(if you want private tailnet access).
For full control over passwords/users/ports, copy the role defaults into host-specific vars and override only what you need:
mkdir -p ansible/host_vars
cp ansible/roles/pocket_lab/defaults/main.yaml ansible/host_vars/genai-vm.yaml
# edit ansible/host_vars/genai-vm.yaml and change only the vars you care aboutYou can also use
group_vars/<group>.yamlif you target multiple machines.
1) Inventory
cp ansible/inventory/hosts.yaml.template ansible/inventory/hosts.yaml
# set ansible_host and ansible_user2) Install Ansible toolchain
task venv:init3) Deploy
task ansible_full4) Local/self-deploy (no SSH) If you run Ansible on the target itself:
# ansible/inventory/hosts.yaml
genai_servers:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: /usr/bin/python3
ansible_user: rootThen task ansible_full.
Idempotent helpers
task ansible_check # dry-run
task ansible_deploy # re-run deploy playImportant
The very first run of the ansible playbook will trigger the pulling of all needed container images for the setup of this AI lab. Since many images are very large this can take a considerable amount of time, based on your machines network connection specifics. You might run into timeout errors resulting in the ansible run to fail. Either rerun the ansible playbook or connect to your machine and do a docker compose up -d in the /opt/pocket_lab directory (or the path you have specified for the deployment of the lab) to finish the initial installation.
Warning
Sometimes one of the docker containers might not come up correctly because of initial errors since the initial certificate creation might take some minutes. Either rerun the ansible automation or perform a docker compose down && docker compose up -d in the folder with the compose.yaml and .env files. If only some of the containers did not start you can also just do a docker compose up -d, this will never break your setup.
You can run Pocket-Lab on a host with no public IP and still get HTTPS + Traefik routing.
A) DNS-01 + /etc/hosts (recommended)
- Set a Cloudflare token (
CLOUDFLARE_DNS_API_TOKEN/cloudflare_api_token). - Deploy the stack.
- On the client you browse from (or on the server itself), add host entries mapping service names to the server IP (use
127.0.0.1when browsing on the server):
127.0.0.1 traefik.${TRAEFIK_DOMAIN} grafana.${TRAEFIK_DOMAIN} \
prometheus.${TRAEFIK_DOMAIN} portainer.${TRAEFIK_DOMAIN} \
n8n.${TRAEFIK_DOMAIN} chat.${TRAEFIK_DOMAIN} \
ragflow.${TRAEFIK_DOMAIN} minio.${TRAEFIK_DOMAIN} \
ollama.${TRAEFIK_DOMAIN}
ACME DNS-01 only checks TXT records, so you don’t need public A/AAAA records.
B) Tailscale-only access
- Set
TS_AUTHKEY/ts_authkeyand deploy. - Find the host’s tailnet IP or MagicDNS name (
tailscale status/tailscale ip). - Add
/etc/hostson your client mapping the same service names to that tailnet IP.
Sanity checks
curl -I -k -H "Host: grafana.${TRAEFIK_DOMAIN}" https://127.0.0.1| Command | What it does |
|---|---|
task ansible_deploy |
Install Docker and deploy the stack |
task ansible_full |
Same as above via ansible/site.yaml |
task docker-* |
Shortcuts for Compose up/down/logs |
| Variable | Default | Notes |
|---|---|---|
stack_domain, stack_email |
ai.lab.example.com, [email protected] |
Traefik host and ACME mail |
basic_auth |
bcrypt hash | Use htpasswd -nbB to generate |
ts_authkey |
– | Tailscale subnet router auth key |
docker_bridge_subnet |
172.20.0.0/16 |
Subnet advertised to the tailnet |
n8n_admin_email, n8n_admin_password |
[email protected] / changeme |
n8n owner account |
openwebui_admin_email, openwebui_admin_password |
[email protected] / changeme |
Open WebUI admin |
es_password, mysql_password, minio_root_password, … |
changeme |
Service credentials |
compose_repo |
/opt/pocket_lab |
Where compose files are deployed |
mem_limit |
4g |
Memory limit for ES and Infinity |
everything in .env.template |
– | Mirrors compose environment |
| Role | Purpose |
|---|---|
| geerlingguy.docker | Install Docker and Compose |
| pocket_lab | Deploy the Pocket-Lab stack |
| Variable | Default value | Service | Description | Comments |
|---|---|---|---|---|
CLOUDFLARE_DNS_API_TOKEN |
- |
Traefik | Cloudflare token for DNS-01 ACME challenges. | |
DEFAULT_MODELS |
llama3.1:8b |
Web search | Default models offered. | |
DEFAULT_PROMPT_SUGGESTIONS |
see .env.template |
Web search | JSON array of prompt suggestions. | |
DOCKER_BRIDGE_SUBNET |
172.20.0.0/16 |
Tailscale | Definition of the Subnet used by the Docker Compose Setup. This variable is used by Tailscale to determine to which subnet to route private traffic to | Variable has implication for the complete setup since all IPs of the services are dependent on it. It is currently only used by Tailscale for actively. |
DOC_ENGINE |
elasticsearch |
RAGFlow | Which backend vector/semantic engine RAGFlow uses. | |
ENABLE_SEARCH_QUERY_GENERATION |
true |
Web search | Auto-generate search queries. | |
ENABLE_VERSION_UPDATE_CHECK |
false |
Open WebUI | Allow WebUI to check for updates. | |
ENABLE_WEB_SEARCH |
true |
Web search | Enable Web search feature. | |
ES_HOST |
es01 |
Elasticsearch | Elasticsearch host for RAGFlow. | |
ES_PASSWORD |
changeme |
Elasticsearch | Elasticsearch super‑user password. | |
ES_PORT |
9200 |
Elasticsearch | Elasticsearch HTTP port. | |
ES_VERSION |
8.13.4 |
Elasticsearch | Elasticsearch image tag. | |
GF_ANALYTICS_CHECK_FOR_UPDATES |
false |
Misc | Let Grafana check for updates. | |
GF_ANALYTICS_REPORTING_ENABLED |
false |
Misc | Allow Grafana usage stats. | |
GRAFANA_ADMIN_PASSWORD |
admin |
Misc | Initial Grafana admin password. | |
GRAFANA_ADMIN_USER |
admin |
Misc | Initial Grafana admin user. | |
GRAFANA_VERSION |
10.4.3 |
Misc | Grafana image tag. | |
HF_ENDPOINT |
https://huggingface.co |
RAGFlow | HuggingFace API base‑URL. | |
INFINITY_HOST |
infinity |
Infinity | Infinity host name. | |
INFINITY_HTTP_PORT |
23820 |
Infinity | Infinity REST API port. | |
INFINITY_PSQL_PORT |
15432 |
Infinity | Infinity Postgres compatibility port. | |
INFINITY_THRIFT_PORT |
23817 |
Infinity | Infinity Thrift RPC port. | |
INFINITY_VERSION |
v0.6.0-dev3 |
Infinity | Infinity vector database image tag. | |
LOKI_VERSION |
3.0.0 |
Misc | Grafana Loki log aggregator version. | |
MACOS |
false |
Global | Set true when building on MacOS (disables some optimisations). | |
MEM_LIMIT |
4g |
Global | Memory limit for Elasticsearch and Infinity. | |
MINIO_CONSOLE_PORT |
9001 |
MinIO | MinIO web console port. | |
MINIO_PORT |
9000 |
MinIO | MinIO S3 API port. | |
MINIO_ROOT_PASSWORD |
minioadmin |
MinIO | MinIO root password. | |
MINIO_ROOT_USER |
minioadmin |
MinIO | MinIO root user. | |
MINIO_VERSION |
RELEASE.2025-04-22T22-12-26Z |
MinIO | MinIO object storage version. | |
MYSQL_DATABASE |
pocket_lab |
MySQL | MySQL schema for RAGFlow. | |
MYSQL_HOST |
mysql |
MySQL | MySQL host. | |
MYSQL_PORT |
3306 |
MySQL | MySQL TCP port. | |
MYSQL_ROOT_HOST |
% |
MySQL | Allowed root origin hosts. | |
MYSQL_ROOT_PASSWORD |
changeme |
MySQL | MySQL root password. | |
MYSQL_VERSION |
8.0.39 |
MySQL | MySQL database version. | |
N8N_ADMIN_EMAIL |
[email protected] |
n8n | n8n owner e‑mail. | |
N8N_ADMIN_PASSWORD |
changeme |
n8n | n8n owner password. | |
N8N_BASIC_AUTH_ACTIVE |
false |
n8n | Enable n8n basic auth before the UI loads. | |
N8N_DIAGNOSTICS_ENABLED |
false |
n8n | Share diagnostic data. | |
N8N_EDITOR_BASE_URL |
https://n8n.ai.lab.example.com/ |
n8n | Base URL for the n8n editor. | |
N8N_EMAIL_MODE |
smtp |
n8n | E‑mail mode for n8n notifications. | |
N8N_HOST |
n8n.ai.lab.example.com |
n8n | Domain used by n8n. | |
N8N_PERSONALIZATION_ENABLED |
false |
n8n | Share anonymous telemetry (false recommended). | |
N8N_PROTOCOL |
https |
n8n | Protocol for building callback URLs. | |
N8N_SMTP_HOST |
smtp |
n8n | SMTP relay host for n8n e‑mails. | |
N8N_SMTP_PORT |
25 |
n8n | SMTP relay port. | |
N8N_SMTP_SENDER |
"n8n <[email protected]>" |
n8n | “From:” address used in n8n mails. | |
N8N_SMTP_SSL |
false |
n8n | Use TLS for SMTP. | |
N8N_TEMPLATES_ENABLED |
false |
n8n | Enable community workflow templates. | |
N8N_USER_MANAGEMENT_DISABLED |
true |
n8n | Disable n8n built‑in sign‑up pages. | |
N8N_VERSION |
1.50.0 |
n8n | n8n automation tool version. | |
N8N_VERSION_NOTIFICATIONS_ENABLED |
false |
n8n | Allow update notifications. | |
NODE_EXPORTER_VERSION |
v1.9.1 |
Misc | Prometheus node exporter version. | |
OFFLINE_MODE |
true |
Open WebUI | Disable network access. | |
OLLAMA_BASE_URL |
http://ollama:11434 |
Open WebUI | Base URL for the Ollama API. | |
OLLAMA_CONTEXT_SIZE |
4096 |
Ollama | Default context window. | |
OLLAMA_IDLE_TIMEOUT |
120s |
Ollama | Time before idle models unload. | |
OLLAMA_KEEP_ALIVE |
5m |
Ollama | How long models stay in memory after last use. | |
OLLAMA_MAX_LOADED_MODELS |
3 |
Ollama | Maximum models kept loaded. | |
OLLAMA_MAX_QUEUE |
512 |
Ollama | Request queue size. | |
OLLAMA_MAX_REPLICAS |
4 |
Ollama | Maximum model replicas. | |
OLLAMA_MMAP |
true |
Ollama | Enable memory-mapped model loading. | |
OLLAMA_NUM_PARALLEL |
8 |
Ollama | Concurrent requests limit. | |
OLLAMA_PULL_MODELS |
llama3.1:8b deepseek-r1:7b qwen2.5-coder:7b bge-m3 |
Ollama | Models preloaded by ollama-bootstrap |
|
OLLAMA_VERSION |
0.10.0 |
Misc | Ollama model server version. | |
OPENWEBUI_ADMIN_EMAIL |
[email protected] |
Open WebUI | Bootstrapped Open WebUI admin account. | |
OPENWEBUI_ADMIN_PASSWORD |
changeme |
Open WebUI | Password for Open WebUI admin. | |
OPENWEBUI_DEFAULT_USER_ROLE |
pending |
Open WebUI | Role newly signed‑up users get. | |
OPENWEBUI_ENABLE_PERSISTENT_CONFIG |
true |
Open WebUI | Keep configuration across container restarts. | |
OPENWEBUI_ENABLE_SIGNUP |
false |
Open WebUI | Allow self‑registration (true/false). | |
OPENWEBUI_PORT |
8080 |
Open WebUI | Internal UI port inside container. | |
OPENWEBUI_VERSION |
v0.6.22 |
Open WebUI | Open WebUI image tag. | |
PORTAINER_PORT |
9000 |
Misc | Portainer web UI port. | |
PORTAINER_VERSION |
2.20.3 |
Misc | Portainer version. | |
PROMETHEUS_VERSION |
v3.3.1 |
Misc | Prometheus image tag. | |
RAGFLOW_ADMIN_EMAIL |
[email protected] |
RAGFlow | Bootstrapped RAGFlow admin account. | |
RAGFLOW_ADMIN_PASSWORD |
changeme |
RAGFlow | RAGFlow admin password. | |
RAGFLOW_EXTRA_PORTS |
9382 |
RAGFlow | Additional exposed ports (MCP). | |
RAGFLOW_HISTORY_DIR |
./ragflow/history_data_agent |
RAGFlow | Host path for chat history. | |
RAGFLOW_LOG_DIR |
./ragflow/ragflow-logs |
RAGFlow | Host path for RAGFlow logs. | |
RAGFLOW_NGINX_CONF_DIR |
\` |
RAGFlow | Optional mount to inject custom nginx.conf. | |
RAGFLOW_VERSION |
v0.18.0 |
RAGFlow | RAGFlow image tag. | |
REDIS_HOST |
redis |
Valkey | Valkey/Redis host. | |
REDIS_PASSWORD |
changeme |
Valkey | Valkey password. | |
REDIS_PORT |
6379 |
Valkey | Valkey port. | |
REDIS_VERSION |
8.1.0 |
Valkey | Valkey image tag. | |
REGISTER_ENABLED |
0 |
RAGFlow | Allow public sign‑up in RAGFlow. | |
SEARXNG_QUERY_URL |
http://searxng:8080/search?q=<query>&format=json |
Web search | Template URL for SearXNG queries. | |
SMTP_HOST |
smtp |
SMTP relay | Container name / hostname for SMTP relay. | |
SMTP_IMAGE |
boky/postfix:latest |
SMTP relay | Docker image for SMTP relay. | |
SMTP_PORT |
25 |
SMTP relay | Port the SMTP relay listens on. | |
SMTP_SSL |
false |
SMTP relay | Enable STARTTLS (true/false). | |
SVR_HTTP_PORT |
9380 |
RAGFlow | RAGFlow backend HTTP port. | |
TIMEZONE |
Europe/Berlin |
Global | Container timezone. | |
TRAEFIK_BASIC_AUTH |
admin:$2y$05$F6KSt6mnvnqqPhQ3VTLIAugnQuhhtJAhdi09Qf0oxBysbbZacqbXK |
Traefik | htpasswd‑style user:hash. Demo credentials = admin / admin – replace for production. |
user:hash used by Traefik basic-auth middleware for most UIs. |
TRAEFIK_DOMAIN |
ai.lab.example.com |
Traefik | Apex domain under which all sub‑services are published. | |
TRAEFIK_LE_EMAIL |
[email protected] |
Traefik | Contact e‑mail for Let’s Encrypt. | |
TRAEFIK_VERSION |
3.4.1 |
Traefik | Traefik docker image tag. | |
TS_AUTHKEY |
- |
Tailscale | Authentication key used to connect to your personal Tailscale tenant | |
WEBHOOK_URL |
https://n8n.ai.lab.example.com/ |
n8n | External webhook base URL for n8n. | |
WEBUI_URL |
`` | Open WebUI | External URL for the WebUI. | |
WEB_SEARCH_CONCURRENT_REQUESTS |
2 |
Web search | Parallel search requests. | |
WEB_SEARCH_ENGINE |
searxng |
Web search | Search engine to use. | |
WEB_SEARCH_RESULT_COUNT |
5 |
Web search | Number of results to fetch. |
For deep‑links and automatic change‑tracking the same table is regenerated in docs/ENVIRONMENT.md whenever scripts/sync_env.py --docs is executed.
- Use two‑space YAML indentation and keep block‑comment separators.
- Run a quick syntax check before committing:
ansible-playbook --syntax-check ansible/site.yaml && docker compose -f ansible/roles/pocket_lab/files/compose.yaml config - Keep this README and
docs/ENVIRONMENT.mdup‑to‑date when touching variables or behaviour.
We follow SemVer. Tag releases and publish notes.
git tag -a v0.1.0 -m "Pocket-Lab v0.1.0 — first public release"
git push origin v0.1.0