Docker
ElyOS fully supports Docker-based development and deployment. This document details how to use Docker with ElyOS.
Why Docker?
Section titled “Why Docker?”Using Docker provides several benefits:
- Consistent environment — every developer and server uses the same environment
- Simple setup — no need to install Node.js, Bun, or PostgreSQL locally
- Isolated services — database and application run in separate containers
- Quick startup — entire system starts with a single command
- Reproducible builds — Docker image always builds the same way
Prerequisites
Section titled “Prerequisites”Installing Docker
Section titled “Installing Docker”Install Docker on your system:
- macOS: OrbStack (recommended) or Docker Desktop
- Linux: Docker Engine
- Windows: Docker Desktop
Installing Bun (Optional)
Section titled “Installing Bun (Optional)”Installing Bun is not required but makes running Docker commands easier:
curl -fsSL https://bun.sh/install | bashDocker can be used without Bun, just run raw docker compose commands.
Quick Start with Docker
Section titled “Quick Start with Docker”1. Clone Repository
Section titled “1. Clone Repository”git clone https://github.com/ElyOS-webOS/elyos-corecd elyos-core2. Configure Environment Variables
Section titled “2. Configure Environment Variables”Copy the example file and fill in values:
cp .env.example .envWith Varlock + Infisical (recommended):
INFISICAL_CLIENT_ID=your-machine-identity-client-idINFISICAL_CLIENT_SECRET=your-machine-identity-client-secretWithout Infisical (local fallback mode):
VARLOCK_FALLBACK=local# ... fill in all variables from .env.example3. Start System
Section titled “3. Start System”With Bun:
bun docker:upWithout Bun:
docker compose -f docker/docker-compose.yml up -d4. Open Application
Section titled “4. Open Application”Open in browser: http://localhost:3000
Docker Compose Services
Section titled “Docker Compose Services”The docker/docker-compose.yml file defines three services that start in order:
1. postgres
Section titled “1. postgres”PostgreSQL 18 database with custom image including postgres-json-schema extension.
postgres: build: context: postgres dockerfile: Dockerfile ports: - '${POSTGRES_PORT:-5432}:5432' volumes: - elyos-data:/var/lib/postgresql healthcheck: test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-elyos} -d ${POSTGRES_DB:-elyos}'] interval: 10s timeout: 5s retries: 5Features:
- Port:
5432(configurable:POSTGRES_PORT) - Persistent storage:
elyos-datavolume - Health check: checks database availability every 10 seconds
- Auto-restart:
unless-stopped
2. db-init
Section titled “2. db-init”One-time initialization: runs Drizzle migrations and loads seed data.
db-init: command: > sh -c 'bun --filter @elyos/database db:init ${RESET:+-- --reset}' depends_on: postgres: condition: service_healthy restart: 'no'Features:
- Only starts when
postgresservice is healthy - Runs
bun db:initcommand - One-time execution:
restart: no - Supports
RESET=1environment variable for complete database reset
3. elyos
Section titled “3. elyos”ElyOS web application (SvelteKit + Express + Socket.IO).
elyos: ports: - '${ELYOS_PORT:-3000}:3000' depends_on: db-init: condition: service_completed_successfully volumes: - ../apps/web/uploads:/app/uploads restart: unless-stoppedFeatures:
- Port:
3000(configurable:ELYOS_PORT) - Only starts when
db-initcompletes successfully - Persistent file storage:
uploadsfolder - Auto-restart:
unless-stopped - Health check: checks
/api/healthendpoint every 30 seconds
Startup Order
Section titled “Startup Order”Services start in sequence, ensuring proper dependencies:
1. postgres (starts) ↓2. postgres (healthy) ↓3. db-init (starts and runs) ↓4. db-init (completed successfully) ↓5. elyos (starts)Database Initialization and Reset
Section titled “Database Initialization and Reset”Normal Initialization
Section titled “Normal Initialization”The db-init container is idempotent — safe to run multiple times, doesn’t duplicate data (upsert logic).
bun docker:upComplete Database Reset
Section titled “Complete Database Reset”If complete database reset is needed (delete all data and reseed):
RESET=1 bun docker:upThis runs the same db-init container but truncates all tables before seeding.
Without Bun:
RESET=1 docker compose -f docker/docker-compose.yml up -dDevelopment with Docker
Section titled “Development with Docker”Hot Reload Support
Section titled “Hot Reload Support”Docker-based development supports hot reload via volume mount. Modify docker-compose.yml:
elyos: volumes: - ../apps/web:/app/apps/web - ../packages:/app/packages command: bun run app:devRunning Database Only
Section titled “Running Database Only”If you want only the database in Docker and run the application locally:
bun docker:dbThis starts only the postgres service.
Without Bun:
docker compose -f docker/docker-compose.yml up -d postgresDocker Commands
Section titled “Docker Commands”Basic Commands
Section titled “Basic Commands”# Start containers (background)bun docker:up# ordocker compose -f docker/docker-compose.yml up -d
# Stop containersbun docker:down# ordocker compose -f docker/docker-compose.yml down
# Follow container logsbun docker:logs# ordocker compose -f docker/docker-compose.yml logs -f
# Start PostgreSQL onlybun docker:db# ordocker compose -f docker/docker-compose.yml up -d postgresChecking Container Status
Section titled “Checking Container Status”# List running containersdocker ps
# List all containers (including stopped)docker ps -a
# View container logsdocker logs elyos-appdocker logs elyos-postgresdocker logs elyos-db-initEntering Containers
Section titled “Entering Containers”# Enter ElyOS containerdocker exec -it elyos-app sh
# Enter PostgreSQL containerdocker exec -it elyos-postgres psql -U elyos -d elyosCleaning Up
Section titled “Cleaning Up”# Remove containers and networkdocker compose -f docker/docker-compose.yml down
# Remove containers, network, and volumes (database data too)docker compose -f docker/docker-compose.yml down -v
# Remove imagesdocker rmi elyos-elyos elyos-postgresMulti-Stage Build
Section titled “Multi-Stage Build”The docker/Dockerfile uses an optimized multi-stage build with three phases:
1. deps — Install Dependencies
Section titled “1. deps — Install Dependencies”FROM oven/bun:1 AS depsWORKDIR /appCOPY package.json bun.lock ./COPY apps/web/package.json ./apps/web/RUN bun install --frozen-lockfileFeatures:
- Copies only
package.jsonandbun.lockfiles - Cacheable layer — if dependencies don’t change, this layer comes from cache
- Frozen lockfile — reproducible build
2. builder — Build Application
Section titled “2. builder — Build Application”FROM oven/bun:1 AS builderWORKDIR /appCOPY --from=deps /app/node_modules ./node_modulesCOPY apps/web ./apps/webCOPY packages/database ./packages/databaseENV NODE_ENV=productionRUN bun run app:buildFeatures:
- Copies dependencies from
depsphase - Copies source code
- Runs SvelteKit build (
adapter-nodeoutput)
3. runner — Production Image
Section titled “3. runner — Production Image”FROM oven/bun:1-alpine AS runnerWORKDIR /appRUN addgroup -g 1001 -S nodejs && \ adduser -S elyos -u 1001 -G nodejsCOPY --from=builder --chown=elyos:nodejs /app/apps/web/build ./apps/web/buildRUN bun install --production --frozen-lockfileRUN bun add -g varlockUSER elyosCMD ["varlock", "run", "--", "bun", "run", "apps/web/server.js"]Features:
- Alpine Linux-based image — minimal size
- Non-root user — security
- Production dependencies only
- Global Varlock installation — secrets management
- Health check — checks
/api/healthendpoint
Building Images
Section titled “Building Images”Local Build
Section titled “Local Build”docker build -f docker/Dockerfile -t elyos/core:latest .Build Arguments
Section titled “Build Arguments”docker build \ -f docker/Dockerfile \ -t elyos/core:latest \ --build-arg NODE_ENV=production \ .Multi-Platform Build
Section titled “Multi-Platform Build”docker buildx build \ -f docker/Dockerfile \ -t elyos/core:latest \ --platform linux/amd64,linux/arm64 \ .Environment Variables
Section titled “Environment Variables”Docker Compose automatically loads the root .env file. The following variables are configurable:
| Variable | Default | Description |
|---|---|---|
ELYOS_PORT | 3000 | ElyOS application port |
POSTGRES_PORT | 5432 | PostgreSQL port |
POSTGRES_USER | elyos | PostgreSQL username |
POSTGRES_PASSWORD | elyos123 | PostgreSQL password |
POSTGRES_DB | elyos | PostgreSQL database name |
INFISICAL_CLIENT_ID | - | Infisical Machine Identity Client ID |
INFISICAL_CLIENT_SECRET | - | Infisical Machine Identity Client Secret |
VARLOCK_FALLBACK | - | Varlock fallback mode (local) |
RESET | - | Database reset (1 = complete reset) |
Troubleshooting
Section titled “Troubleshooting”Container Won’t Start
Section titled “Container Won’t Start”Problem: Container stops immediately after starting.
Solution:
-
Check logs:
Terminál docker logs elyos-app -
Check environment variables:
Terminál docker exec elyos-app env -
Check health check:
Terminál docker inspect elyos-app | grep -A 10 Health
Database Connection Error
Section titled “Database Connection Error”Problem: ECONNREFUSED or Connection refused error.
Solution:
-
Check if
postgrescontainer is running:Terminál docker ps | grep postgres -
Check
DATABASE_URLenvironment variable:Terminál # Correct format:postgresql://elyos:elyos123@postgres:5432/elyos -
Wait for
postgrescontainer to be healthy:Terminál docker compose -f docker/docker-compose.yml ps
Port Already in Use
Section titled “Port Already in Use”Problem: Bind for 0.0.0.0:3000 failed: port is already allocated.
Solution:
-
Change port in
.envfile:Terminál ELYOS_PORT=3001 -
Or stop the other service:
Terminál lsof -ti:3000 | xargs kill -9
Further Information
Section titled “Further Information”- Getting Started — local development environment setup
- Environment Variables — detailed environment variables description
- Scripts Reference — all available script commands
- Docker Documentation — official Docker documentation
- OrbStack Documentation — OrbStack usage guide