Files
qiming/qiming-file-server/docs/ENV.md

19 KiB

Environment variables — full reference

qiming-file-server can be configured entirely through environment variables. This document lists every supported variable.

Precedence

From highest to lowest:

  1. CLI arguments
  2. Process environment variables
  3. Env files (.env.production, .env.development, .env.test — loaded according to project conventions; see src/env.*)
  4. Built-in defaults

Env files

Files under src/ are selected based on NODE_ENV:

Mode File Purpose
development env.development Local development
production env.production Production
test env.test Tests

Core settings

Server

Variable Default Description
NODE_ENV development development / production / test
PORT 60000 HTTP listen port
REQUEST_BODY_LIMIT 2000mb Express body size limit

Logging

Variable Default Description
LOG_BASE_DIR Base directory for log files
LOG_LEVEL debug error / warn / info / debug
LOG_CONSOLE_ENABLED true Mirror logs to console
LOG_PREFIX_API api Prefix for API logs
LOG_PREFIX_BUILD build Prefix for build logs

Project paths

Variable Default Description
INIT_PROJECT_NAME_REACT react-vite-template Built-in scaffold name for React projects
INIT_PROJECT_NAME_VUE3 vue3-vite-template Built-in scaffold name for Vue3 projects
INIT_PROJECT_DIR Scaffold / init project directory
UPLOAD_PROJECT_DIR Directory for uploaded project archives
PROJECT_SOURCE_DIR Unpacked / working project sources
DIST_TARGET_DIR Build output directory (e.g. served by nginx)
COMPUTER_WORKSPACE_DIR “Computer” feature workspace
COMPUTER_LOG_DIR “Computer” feature logs

Build

Variable Default Description
MAX_BUILD_CONCURRENCY 20 Max concurrent builds
DEV_SERVER_PORT_TIMEOUT 5000 Dev-server port probe timeout (ms)
DEV_SERVER_STOP_TIMEOUT 5000 Dev-server stop timeout (ms)
DEV_SERVER_STOP_CHECK_INTERVAL 100 Poll interval while stopping dev server (ms)
DEV_SERVER_STOP_MAX_ATTEMPTS 50 Max stop retries

Uploads

Variable Default Description
MAX_INLINE_FILE_SIZE_BYTES 1048576 Max size (bytes) to return inline; larger files are not inlined
UPLOAD_MAX_FILE_SIZE_BYTES 1048576000 Max archive upload size (bytes)
UPLOAD_ALLOWED_EXTENSIONS .zip Allowed extensions (comma-separated)
UPLOAD_SINGLE_FILE_SIZE_BYTES 1048576000 Max single upload size (bytes)

Traversal / filters

Variable Default Description
TRAVERSE_EXCLUDE_DIRS dist,node_modules,.pnpm-store,__MACOSX,.attachments Comma-separated dirs to skip when traversing
BACKUP_TRAVERSE_EXCLUDE_FILES pnpm-lock.yaml,yarn.lock,package-lock.json Comma-separated files to skip in backup traversal
CONTENT_TRAVERSE_EXCLUDE_FILES AGENT.md,AGENTS.md,CLAUDE.md,pnpm-lock.yaml,yarn.lock,package-lock.json Comma-separated files to skip for content API
INLINE_IMAGE_EXTENSIONS .png,.jpg,.jpeg,.gif,.bmp,.svg,.ico,.webp,.avif Image extensions eligible for inline serving
TOP_LEVEL_NOISE_PATTERNS __MACOSX,Thumbs.db,node_modules,.pnpm-store,.attachments Comma-separated noise patterns for top-level flattening after unzip

pnpm prune scheduler

Variable Default Description
PNPM_PRUNE_ENABLED true Enable scheduled pnpm store maintenance
PNPM_PRUNE_SCHEDULE 0 2 * * * Cron expression
PNPM_PRUNE_TIMEZONE Asia/Shanghai Time zone for the schedule
PNPM_PRUNE_RUN_ON_START false Run once immediately on startup

Example cron expressions:

Expression Meaning
0 2 * * 0 Every Sunday 02:00
0 3 * * * Every day 03:00
0 2 1 * * 1st of month 02:00
0 */6 * * * Every 6 hours

Log cache

Variable Default Description
LOG_CACHE_ENABLED true Enable in-memory log cache
LOG_CACHE_DURATION 180000 TTL (ms); default 3 minutes
LOG_CACHE_MAX_ENTRIES 100 Max cached entries
LOG_CACHE_MAX_FILE_SIZE 2097152 Max cached file size (bytes); default 2 MB

CLI-only

Variable Default Description
CLI_PID_DIR system temp Directory for PID file
CLI_PID_FILE server.pid PID filename
CLI_STOP_TIMEOUT 30000 Graceful stop timeout (ms)
CLI_CHECK_INTERVAL 500 Poll interval when stopping (ms)
CLI_LOG_DIR system temp CLI log directory

Extra CLI environment

Variable Description
CONFIG_FILE Optional path to an extra env file (CLI)

Examples

Use production defaults but override paths

In real deployments you often keep env.production as the base and only override paths:

Example A: production + custom paths

qiming-file-server start \
  --env production \
  --port 60000 \
  PROJECT_SOURCE_DIR=/data/my-projects \
  DIST_TARGET_DIR=/var/www/my-app \
  UPLOAD_PROJECT_DIR=/data/uploads \
  LOG_BASE_DIR=/var/log/qiming

Example B: multiple instances on one host

# Instance 1 — main
qiming-file-server start \
  --env production \
  --port 60001 \
  PROJECT_SOURCE_DIR=/data/main-site \
  DIST_TARGET_DIR=/var/www/main-site

# Instance 2 — staging
qiming-file-server start \
  --env production \
  --port 60002 \
  PROJECT_SOURCE_DIR=/data/test-site \
  DIST_TARGET_DIR=/var/www/test-site

# Instance 3 — internal
qiming-file-server start \
  --env production \
  --port 60003 \
  PROJECT_SOURCE_DIR=/data/internal \
  DIST_TARGET_DIR=/var/www/internal

Only pass --port and the paths you need; everything else comes from env.production.

Example C: override file

cat > env.override << 'EOF'
# Path overrides for production
PROJECT_SOURCE_DIR=/data/override-projects
DIST_TARGET_DIR=/var/www/override-nginx
UPLOAD_PROJECT_DIR=/data/override-uploads
LOG_BASE_DIR=/var/log/override
EOF

qiming-file-server start --env production --env-file ./env.override

Example D: Kubernetes ConfigMap

kubectl create configmap qiming-overrides \
  --from-literal=PROJECT_SOURCE_DIR=/data/k8s-projects \
  --from-literal=DIST_TARGET_DIR=/usr/share/nginx/apps \
  --from-literal=UPLOAD_PROJECT_DIR=/data/k8s-uploads \
  --from-literal=LOG_BASE_DIR=/var/log/qiming

Reference it in the Deployment:

envFrom:
  - configMapRef:
      name: qiming-overrides

Example E: full path set (illustrative)

Below lists path-related variables you might set. Trim to what you actually need:

# Production with defaults from env.production, paths overridden
qiming-file-server start \
  --env production \
  --port 60000

# Or set paths explicitly
qiming-file-server start \
  --env production \
  --port 60000 \
  INIT_PROJECT_NAME_REACT=react-vite-template \
  INIT_PROJECT_NAME_VUE3=vue3-vite-template \
  INIT_PROJECT_DIR=/app/project_init \
  UPLOAD_PROJECT_DIR=/app/project_zips \
  PROJECT_SOURCE_DIR=/app/project_workspace \
  DIST_TARGET_DIR=/app/project_nginx \
  LOG_BASE_DIR=/app/logs/project_logs \
  COMPUTER_WORKSPACE_DIR=/app/computer-project-workspace \
  COMPUTER_LOG_DIR=/app/logs/computer_logs

Path variables as documented for env.production

Variable Example default Description
INIT_PROJECT_NAME_REACT react-vite-template Built-in scaffold name for React projects
INIT_PROJECT_NAME_VUE3 vue3-vite-template Built-in scaffold name for Vue3 projects
INIT_PROJECT_DIR /app/project_init Init project directory
UPLOAD_PROJECT_DIR /app/project_zips Uploaded zips
PROJECT_SOURCE_DIR /app/project_workspace Project workspace
DIST_TARGET_DIR /app/project_nginx Build output (nginx root)
LOG_BASE_DIR /app/logs/project_logs Log root
COMPUTER_WORKSPACE_DIR /app/computer-project-workspace Computer workspace
COMPUTER_LOG_DIR /app/logs/computer_logs Computer logs

Path-only snippets

# 1) Only change project sources
qiming-file-server start \
  --env production \
  --port 60000 \
  PROJECT_SOURCE_DIR=/data/my-projects

# 2) Several paths
qiming-file-server start \
  --env production \
  --port 60000 \
  PROJECT_SOURCE_DIR=/data/projects \
  DIST_TARGET_DIR=/var/www/html \
  UPLOAD_PROJECT_DIR=/data/uploads

# 3) Full path set
qiming-file-server start \
  --env production \
  --port 60000 \
  INIT_PROJECT_NAME_REACT=my-react-template \
  INIT_PROJECT_NAME_VUE3=my-vue3-template \
  INIT_PROJECT_DIR=/data/init \
  UPLOAD_PROJECT_DIR=/data/zips \
  PROJECT_SOURCE_DIR=/data/workspace \
  DIST_TARGET_DIR=/var/www/nginx \
  LOG_BASE_DIR=/var/logs/project_logs \
  COMPUTER_WORKSPACE_DIR=/data/computer \
  COMPUTER_LOG_DIR=/var/logs/computer

--port selects the HTTP port; unset path keys keep their values from env.production.

Verify overrides

qiming-file-server status
curl http://localhost:60000/health | jq

# Check startup logs for loaded env (messages are in English, e.g. "Loaded environment files: ...")
grep -E "Loaded environment|Environment configuration file" /var/log/qiming/server.log

CLI overrides precedence

CLI wins over env files and plain env:

qiming-file-server start --port 8080

qiming-file-server start --env production

qiming-file-server start --env production --port 8080

Shell environment

Linux / macOS

export PORT=8080
export NODE_ENV=production
export LOG_LEVEL=info

# Persist in ~/.bashrc or ~/.zshrc
echo 'export PORT=8080' >> ~/.bashrc
source ~/.bashrc

Windows

set PORT=8080
set NODE_ENV=production

setx PORT 8080
setx NODE_ENV production

Docker / Compose

docker-compose.yml

version: '3.8'

services:
  qiming-file-server:
    image: qiming-file-server:latest
    container_name: qiming-file-server
    restart: unless-stopped
    environment:
      - NODE_ENV=production
      - PORT=60000

      - LOG_BASE_DIR=/app/logs
      - LOG_LEVEL=info
      - LOG_CONSOLE_ENABLED=false

      - PROJECT_SOURCE_DIR=/app/projects
      - DIST_TARGET_DIR=/app/nginx
      - UPLOAD_PROJECT_DIR=/app/uploads
      - INIT_PROJECT_DIR=/app/init
      - COMPUTER_WORKSPACE_DIR=/app/computer
      - COMPUTER_LOG_DIR=/app/computer-logs

      - MAX_BUILD_CONCURRENCY=20

      - PNPM_PRUNE_ENABLED=true
      - PNPM_PRUNE_SCHEDULE=0 3 * * *
      - PNPM_PRUNE_TIMEZONE=Asia/Shanghai

      - LOG_CACHE_ENABLED=true
      - LOG_CACHE_DURATION=180000
      - LOG_CACHE_MAX_ENTRIES=100
      - LOG_CACHE_MAX_FILE_SIZE=2097152

    volumes:
      - ./projects:/app/projects
      - ./logs:/app/logs
      - ./nginx:/app/nginx
      - ./uploads:/app/uploads
      - ./init:/app/init
      - ./computer:/app/computer

    ports:
      - "60000:60000"

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:60000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

Dockerfile

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install -g pnpm && pnpm install --frozen-lockfile

COPY . .

RUN mkdir -p /app/logs /app/projects /app/nginx /app/uploads /app/init /app/computer

EXPOSE 60000

CMD ["node", "scripts/start-cli.js"]

Sample env files

.env.production

# ==================== Server ====================
NODE_ENV=production
PORT=60000
REQUEST_BODY_LIMIT=2000mb

# ==================== Logging ====================
LOG_BASE_DIR=/app/logs
LOG_LEVEL=info
LOG_CONSOLE_ENABLED=false
LOG_PREFIX_API=api
LOG_PREFIX_BUILD=build

# ==================== Paths ====================
INIT_PROJECT_NAME_REACT=react-vite-template
INIT_PROJECT_NAME_VUE3=vue3-vite-template
INIT_PROJECT_DIR=/app/project_init
UPLOAD_PROJECT_DIR=/app/project_zips
PROJECT_SOURCE_DIR=/app/project_workspace
DIST_TARGET_DIR=/app/project_nginx
COMPUTER_WORKSPACE_DIR=/app/computer-project-workspace
COMPUTER_LOG_DIR=/app/logs/computer_logs

# ==================== Build ====================
MAX_BUILD_CONCURRENCY=20
DEV_SERVER_PORT_TIMEOUT=5000
DEV_SERVER_STOP_TIMEOUT=5000
DEV_SERVER_STOP_CHECK_INTERVAL=100
DEV_SERVER_STOP_MAX_ATTEMPTS=50

# ==================== Uploads ====================
MAX_INLINE_FILE_SIZE_BYTES=1048576
UPLOAD_MAX_FILE_SIZE_BYTES=1048576000
UPLOAD_ALLOWED_EXTENSIONS=.zip
UPLOAD_SINGLE_FILE_SIZE_BYTES=1048576000

# ==================== Traversal / filters ====================
TRAVERSE_EXCLUDE_DIRS=dist,node_modules,.pnpm-store,__MACOSX,.attachments
BACKUP_TRAVERSE_EXCLUDE_FILES=pnpm-lock.yaml,yarn.lock,package-lock.json
CONTENT_TRAVERSE_EXCLUDE_FILES=AGENT.md,AGENTS.md,CLAUDE.md,pnpm-lock.yaml,yarn.lock,package-lock.json
INLINE_IMAGE_EXTENSIONS=.png,.jpg,.jpeg,.gif,.bmp,.svg,.ico,.webp,.avif
TOP_LEVEL_NOISE_PATTERNS=__MACOSX,Thumbs.db,node_modules,.pnpm-store,.attachments

# ==================== pnpm prune ====================
PNPM_PRUNE_ENABLED=true
PNPM_PRUNE_SCHEDULE=0 2 * * *
PNPM_PRUNE_TIMEZONE=Asia/Shanghai
PNPM_PRUNE_RUN_ON_START=false

# ==================== Log cache ====================
LOG_CACHE_ENABLED=true
LOG_CACHE_DURATION=180000
LOG_CACHE_MAX_ENTRIES=100
LOG_CACHE_MAX_FILE_SIZE=2097152

# ==================== CLI ====================
CLI_PID_DIR=/tmp/qiming-file-server
CLI_STOP_TIMEOUT=30000
CLI_CHECK_INTERVAL=500
CLI_LOG_DIR=/tmp/qiming-file-server/logs

.env.development

# ==================== Server ====================
NODE_ENV=development
PORT=60000
REQUEST_BODY_LIMIT=2000mb

# ==================== Logging ====================
LOG_BASE_DIR=./logs
LOG_LEVEL=debug
LOG_CONSOLE_ENABLED=true
LOG_PREFIX_API=api
LOG_PREFIX_BUILD=build

# ==================== Paths ====================
INIT_PROJECT_NAME_REACT=react-vite-template
INIT_PROJECT_NAME_VUE3=vue3-vite-template
INIT_PROJECT_DIR=./project_init
UPLOAD_PROJECT_DIR=./project_zips
PROJECT_SOURCE_DIR=./project_workspace
DIST_TARGET_DIR=./project_nginx
COMPUTER_WORKSPACE_DIR=./computer-project-workspace
COMPUTER_LOG_DIR=./computer_logs

# ==================== Build ====================
MAX_BUILD_CONCURRENCY=20
DEV_SERVER_PORT_TIMEOUT=5000
DEV_SERVER_STOP_TIMEOUT=5000
DEV_SERVER_STOP_CHECK_INTERVAL=100
DEV_SERVER_STOP_MAX_ATTEMPTS=50

# ==================== Uploads ====================
MAX_INLINE_FILE_SIZE_BYTES=1048576
UPLOAD_MAX_FILE_SIZE_BYTES=1048576000
UPLOAD_ALLOWED_EXTENSIONS=.zip
UPLOAD_SINGLE_FILE_SIZE_BYTES=1048576000

# ==================== Traversal / filters ====================
TRAVERSE_EXCLUDE_DIRS=dist,node_modules,.pnpm-store,__MACOSX,.attachments
BACKUP_TRAVERSE_EXCLUDE_FILES=pnpm-lock.yaml,yarn.lock,package-lock.json
CONTENT_TRAVERSE_EXCLUDE_FILES=AGENT.md,AGENTS.md,CLAUDE.md,pnpm-lock.yaml,yarn.lock,package-lock.json
INLINE_IMAGE_EXTENSIONS=.png,.jpg,.jpeg,.gif,.bmp,.svg,.ico,.webp,.avif
TOP_LEVEL_NOISE_PATTERNS=__MACOSX,Thumbs.db,node_modules,.pnpm-store,.attachments

# ==================== pnpm prune ====================
PNPM_PRUNE_ENABLED=false
PNPM_PRUNE_SCHEDULE=0 2 * * *
PNPM_PRUNE_TIMEZONE=Asia/Shanghai
PNPM_PRUNE_RUN_ON_START=false

# ==================== Log cache ====================
LOG_CACHE_ENABLED=true
LOG_CACHE_DURATION=180000
LOG_CACHE_MAX_ENTRIES=100
LOG_CACHE_MAX_FILE_SIZE=2097152

# ==================== CLI ====================
CLI_PID_DIR=./tmp
CLI_STOP_TIMEOUT=30000
CLI_CHECK_INTERVAL=500
CLI_LOG_DIR=./tmp/logs

Kubernetes example

apiVersion: v1
kind: ConfigMap
metadata:
  name: qiming-file-server-config
data:
  NODE_ENV: "production"
  PORT: "60000"
  LOG_BASE_DIR: "/app/logs"
  LOG_LEVEL: "info"
  LOG_CONSOLE_ENABLED: "false"
  PROJECT_SOURCE_DIR: "/app/projects"
  DIST_TARGET_DIR: "/app/nginx"
  UPLOAD_PROJECT_DIR: "/app/uploads"
  INIT_PROJECT_DIR: "/app/init"
  COMPUTER_WORKSPACE_DIR: "/app/computer"
  COMPUTER_LOG_DIR: "/app/computer-logs"
  MAX_BUILD_CONCURRENCY: "20"
  PNPM_PRUNE_ENABLED: "true"
  PNPM_PRUNE_SCHEDULE: "0 3 * * *"
  PNPM_PRUNE_TIMEZONE: "Asia/Shanghai"
  LOG_CACHE_ENABLED: "true"
  LOG_CACHE_DURATION: "180000"
  LOG_CACHE_MAX_ENTRIES: "100"
  LOG_CACHE_MAX_FILE_SIZE: "2097152"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: qiming-file-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: qiming-file-server
  template:
    metadata:
      labels:
        app: qiming-file-server
    spec:
      containers:
      - name: qiming-file-server
        image: qiming-file-server:latest
        ports:
        - containerPort: 60000
        envFrom:
        - configMapRef:
            name: qiming-file-server-config
        volumeMounts:
        - name: projects
          mountPath: /app/projects
        - name: logs
          mountPath: /app/logs
        - name: nginx
          mountPath: /app/nginx
        - name: uploads
          mountPath: /app/uploads
        - name: init
          mountPath: /app/init
        - name: computer
          mountPath: /app/computer
        livenessProbe:
          httpGet:
            path: /health
            port: 60000
          initialDelaySeconds: 10
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /health
            port: 60000
          initialDelaySeconds: 5
          periodSeconds: 10
      volumes:
      - name: projects
        hostPath:
          path: /data/projects
      - name: logs
        hostPath:
          path: /data/logs
      - name: nginx
        hostPath:
          path: /data/nginx
      - name: uploads
        hostPath:
          path: /data/uploads
      - name: init
        hostPath:
          path: /data/init
      - name: computer
        hostPath:
          path: /data/computer

Verifying configuration

curl http://localhost:60000/health

The JSON body includes the active environment name (e.g. "env": "production").

Troubleshooting

Changes not applied

  1. Confirm the correct env file path and NODE_ENV.
  2. Variable names are case-sensitive.
  3. Validate YAML/JSON if you embed config in manifests.
  4. Read server logs for load errors.

Port already in use

If PORT is taken, startup fails. Pick another port or free the listener.

Permissions

Ensure log and data directories are writable:

chmod -R 755 /path/to/logs
mkdir -p /path/to/logs /path/to/projects

Docker env not visible

Pass variables with environment: or envFrom::

environment:
  - NODE_ENV=production
  - PORT=60000

envFrom:
  - configMapRef:
      name: my-config