How to Self-Host OneDev with Docker Compose
OneDev sits in a unique spot between lightweight Git servers like Gitea and heavyweight platforms like GitLab CE. It ships CI/CD, Kanban boards, package registries, and language-aware code search in a single container that runs on 2 GB of RAM. If you want an all-in-one DevOps platform without GitLab’s 4-8 GB memory tax, OneDev is worth a serious look.
What Is OneDev?
OneDev is an open-source DevOps platform that combines Git hosting, visual CI/CD pipelines, issue tracking with automated Kanban boards, code review with auto-reviewer suggestions, and built-in package registries (Docker, NPM, Maven, NuGet, PyPI). It also includes dependency scanning, secret detection, and symbol-level code search out of the box. OneDev replaces GitHub, separate CI/CD tools, and issue trackers with a single self-hosted application — lighter than GitLab CE but far more capable than Gitea or Forgejo alone.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 2 GB of free RAM (1 GB possible for small deployments)
- 2 CPU cores
- 10 GB of free disk space (excluding repository data)
- A domain name (optional, for remote access)
Docker Compose Configuration
OneDev uses an embedded HSQLDB database by default, which works fine for small teams. For production use with multiple concurrent users, PostgreSQL is recommended.
Simple Setup (Embedded Database)
Create a docker-compose.yml file:
services:
onedev:
image: 1dev/server:14.1.6
container_name: onedev
restart: unless-stopped
ports:
- "6610:6610"
- "6611:6611"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- onedev_data:/opt/onedev
environment:
- initial_user=admin
- initial_password=${ADMIN_PASSWORD}
- initial_email=${ADMIN_EMAIL}
- initial_server_url=${SERVER_URL}
volumes:
onedev_data:
Create a .env file:
ADMIN_PASSWORD=CHANGE_ME_TO_A_STRONG_PASSWORD
ADMIN_EMAIL=[email protected]
SERVER_URL=http://your-server-ip:6610
The initial_* variables skip the web setup wizard on first boot. They are ignored on subsequent starts.
Production Setup (PostgreSQL)
For teams with 3+ users or heavier CI/CD workloads, use PostgreSQL:
services:
onedev:
image: 1dev/server:14.1.6
container_name: onedev
restart: unless-stopped
ports:
- "6610:6610"
- "6611:6611"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- onedev_data:/opt/onedev
environment:
- hibernate_dialect=io.onedev.server.persistence.PostgreSQLDialect
- hibernate_connection_driver_class=org.postgresql.Driver
- hibernate_connection_url=jdbc:postgresql://onedev-db:5432/onedev
- hibernate_connection_username=onedev
- hibernate_connection_password=${DB_PASSWORD}
- initial_user=admin
- initial_password=${ADMIN_PASSWORD}
- initial_email=${ADMIN_EMAIL}
- initial_server_url=${SERVER_URL}
depends_on:
onedev-db:
condition: service_healthy
onedev-db:
image: postgres:16-alpine
container_name: onedev-db
restart: unless-stopped
environment:
POSTGRES_DB: onedev
POSTGRES_USER: onedev
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- onedev_db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U onedev"]
interval: 30s
timeout: 10s
retries: 5
volumes:
onedev_data:
onedev_db:
Create a .env file:
DB_PASSWORD=CHANGE_ME_TO_A_STRONG_PASSWORD
ADMIN_PASSWORD=CHANGE_ME_TO_A_STRONG_PASSWORD
ADMIN_EMAIL=[email protected]
SERVER_URL=http://your-server-ip:6610
Start the stack:
docker compose up -d
Initial Setup
If you set the initial_* environment variables, the setup wizard is skipped and you can log in immediately. Otherwise:
- Open
http://your-server-ip:6610in your browser - The setup wizard prompts for admin credentials, server URL, and database settings
- After setup, log in with the admin account you created
- Go to Administration → Security → General Settings to disable self-registration if needed
Configuration
Volume Mounts
| Volume | Container Path | Contents |
|---|---|---|
onedev_data | /opt/onedev | All OneDev data: repositories, embedded database, build artifacts, logs, packages, configuration |
| Docker socket | /var/run/docker.sock | Required for built-in CI/CD to spawn build containers |
The Docker socket mount is only necessary if you use OneDev’s built-in CI/CD with Docker executors. If you only need Git hosting and issue tracking, you can omit it.
For rootless Docker, mount $XDG_RUNTIME_DIR/docker.sock instead of /var/run/docker.sock.
Key Environment Variables
| Variable | Default | Description |
|---|---|---|
initial_user | — | Admin username (first run only) |
initial_password | — | Admin password (first run only) |
initial_email | — | Admin email (first run only) |
initial_server_url | — | Server URL for generated links (first run only) |
initial_ssh_root_url | — | SSH URL base (e.g., ssh://your-server:6611) |
hibernate_dialect | HSQLDB | Database dialect class |
hibernate_connection_url | embedded | JDBC connection URL |
http_port | 6610 | HTTP port inside the container |
ssh_port | 6611 | SSH port inside the container |
External Database Options
OneDev supports MySQL, MariaDB, and PostgreSQL as external databases. Use the hibernate_* environment variables to configure:
MySQL:
hibernate_dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate_connection_driver_class=com.mysql.cj.jdbc.Driver
hibernate_connection_url=jdbc:mysql://db-host:3306/onedev?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false&disableMariaDbDriver=true
MariaDB:
hibernate_dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate_connection_driver_class=org.mariadb.jdbc.Driver
hibernate_connection_url=jdbc:mariadb://db-host:3306/onedev
PostgreSQL uses OneDev’s custom dialect (io.onedev.server.persistence.PostgreSQLDialect), not the standard Hibernate one.
CI/CD Configuration
OneDev’s CI/CD works out of the box with the Docker socket mount. Build pipelines are defined per-project through the web UI or a .onedev-buildspec.yml file in the repository root.
Executor types available:
- Docker executor — spawns containers on the host (requires Docker socket)
- Kubernetes executor — runs jobs in a Kubernetes cluster
- Remote agent — distributes builds to remote machines running the OneDev agent
- Bare metal — runs directly on the host
Configure executors in Administration → Job Executors.
Reverse Proxy
When running behind a reverse proxy, set SERVER_URL to your public HTTPS URL and configure your proxy to forward both HTTP and SSH:
Nginx Proxy Manager config for HTTP:
- Scheme: http
- Forward Hostname: onedev
- Forward Port: 6610
- Enable WebSocket support
- Enable SSL with Let’s Encrypt
For SSH access through the proxy, forward port 6611 directly (TCP passthrough) or expose it separately:
ports:
- "6611:6611"
Users clone with: git clone ssh://git@your-server:6611/project/repo
See Reverse Proxy Setup for full configuration.
Backup
All OneDev data lives in the onedev_data volume at /opt/onedev. Back up this volume to capture repositories, configuration, build artifacts, and the embedded database.
If using PostgreSQL, also back up the database:
docker exec onedev-db pg_dump -U onedev onedev > onedev_backup.sql
OneDev also supports creating backups from the web UI: Administration → Database Backup.
See Backup Strategy for automated backup workflows.
Troubleshooting
CI/CD jobs fail with “docker not found”
Symptom: Build jobs fail immediately with errors about Docker not being available.
Fix: Ensure the Docker socket is mounted in your Compose file: /var/run/docker.sock:/var/run/docker.sock. Check that the socket has the correct permissions. For rootless Docker, use $XDG_RUNTIME_DIR/docker.sock instead.
Web UI inaccessible after startup
Symptom: Port 6610 returns connection refused or timeouts.
Fix: OneDev takes 1-2 minutes to start (Java application). Check logs with docker logs -f onedev. If the container keeps restarting, check available RAM — OneDev needs at least 1 GB free. Verify no other service is using port 6610.
SSH clone fails with “connection refused”
Symptom: git clone ssh://git@server:6611/project/repo fails.
Fix: Verify port 6611 is exposed in your Compose file and not blocked by a firewall. If running behind a reverse proxy, SSH must be forwarded as raw TCP — HTTP proxying will not work for SSH.
PostgreSQL connection errors on startup
Symptom: OneDev logs show “Connection refused” to the database.
Fix: Ensure depends_on with condition: service_healthy is set so OneDev waits for PostgreSQL to be ready. Verify the hibernate_connection_url hostname matches the database service name in your Compose file.
Out of memory with large repositories
Symptom: OneDev becomes unresponsive or crashes when cloning large repositories. Fix: OneDev can cache up to 200 MB per large repository and each concurrent git operation uses ~100 MB. For repositories approaching Linux kernel size, allocate 4+ GB of RAM. For most projects, 2 GB is sufficient.
Resource Requirements
- RAM: ~500 MB idle with embedded database, ~1 GB under moderate load, 2 GB recommended for teams
- CPU: 2 cores minimum (Java application with background indexing)
- Disk: ~400 MB for the application, plus storage for repositories, build artifacts, and packages
Verdict
OneDev occupies a smart middle ground. It gives you 80% of GitLab’s functionality at 25% of the resource cost. The built-in CI/CD with a visual editor, package registries, and symbol-level code search are genuine differentiators — Gitea and Forgejo require separate tools for CI/CD. The trade-off is a smaller community and Java’s higher baseline memory compared to Go-based alternatives. For small-to-medium teams that want integrated CI/CD and issue tracking without dedicating 8 GB of RAM to GitLab CE, OneDev is the best option available. For teams that only need Git hosting with pull requests, Gitea or Forgejo at 200 MB of RAM are the lighter choice.
Related
- OneDev vs Gitea: Which Should You Self-Host?
- OneDev vs GitLab CE: Which Should You Self-Host?
- How to Self-Host Gitea — lightweight Git hosting
- How to Self-Host Forgejo — community fork of Gitea
- How to Self-Host GitLab CE — full DevOps platform
- Gitea vs Forgejo — choosing between the lightweight options
- Best Self-Hosted Git Hosting — full category roundup
- Docker Compose Basics — prerequisite guide
- Reverse Proxy Setup — remote access configuration
- Backup Strategy — protect your data
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments