Project management tools are easy to underestimate from the outside.

A task board is simple. A real team workspace is not. Once you add comments, files, due dates, priorities, time tracking, reports, workload, invitations, notifications, client access, and billing boundaries, the app becomes infrastructure.

Worklenz is in that second category. It is an all-in-one project management app with a React frontend, TypeScript Express backend, PostgreSQL database, object storage, Socket.IO realtime layer, nginx, and Docker Compose deployment files.

It is also open-core, so the license boundary matters as much as the Docker command.

What is Worklenz?

Worklenz is a project management platform for teams. The README positions it around project planning, task management, collaboration, time tracking, reporting, analytics, resource management, and project templates.

The repository is not a thin wrapper around a single app. It contains:

  • main frontend
  • backend API
  • client portal
  • PostgreSQL SQL files and migrations
  • Dockerfiles
  • top-level Docker Compose file
  • nginx configuration
  • setup and management scripts
  • self-hosting docs

From a self-hosting point of view, Worklenz is closer to a business application stack than a casual weekend dashboard.

Tech Stack

The backend is TypeScript on Express with PostgreSQL and Socket.IO.

Important backend pieces include:

  • Express API server
  • Passport authentication
  • PostgreSQL through pg
  • session middleware
  • CSRF protection
  • Helmet and explicit security headers
  • CORS configuration
  • AWS S3 and SES SDK integrations
  • Azure Blob Storage support
  • file uploads and image processing
  • cron jobs
  • PostgreSQL notification listener
  • OpenAPI/Swagger docs

The main frontend is React with Vite and Ant Design.

Frontend pieces include:

  • React Router
  • Redux Toolkit
  • Axios API client
  • Socket.IO client
  • i18next
  • Chart.js
  • DnD Kit
  • Tailwind CSS
  • Sentry integration
  • Mixpanel integration
  • Vitest

There is also a separate worklenz-client-portal package, built with React, Vite, Ant Design, Redux Toolkit, i18next, and Socket.IO client.

Repository Tour

The top-level layout is:

README.md
DOCKER_SETUP.md
docs/SELF_HOSTING.md
docker-compose.yml
.env.example
quick-setup.sh
manage.sh
update-docker-env.sh
nginx/
worklenz-backend/
worklenz-frontend/
worklenz-client-portal/

The backend has a broad controller surface:

worklenz-backend/src/controllers/
worklenz-backend/src/routes/
worklenz-backend/src/middlewares/
worklenz-backend/src/services/
worklenz-backend/src/socket.io/
worklenz-backend/src/cron_jobs/
worklenz-backend/database/

The frontend has the shape you expect from a large React app:

worklenz-frontend/src/app/routes/
worklenz-frontend/src/api/
worklenz-frontend/src/components/
worklenz-frontend/src/features/
worklenz-frontend/src/layouts/
worklenz-frontend/src/pages/
worklenz-frontend/src/services/
worklenz-frontend/src/utils/

There are many SQL migrations. The database layer is not incidental; it is a core part of the product.

Docker Compose Shape

The inspected docker-compose.yml defines these services:

frontend
backend
client-portal
nginx
minio
createbuckets
db
db-backup

The published ports in this checkout are:

frontend:      5000
backend:       3000
client portal: 5174
nginx:         80, 443
minio:         9000, 9001

Images in the compose file:

chamikajaycey/worklenz-frontend:3.1.0-beta
chamikajaycey/worklenz-backend:3.1.0-beta
chamikajaycey/worklenz-client-portal:latest
nginx:alpine
minio/minio:latest
minio/mc
postgres:15

The Compose file validated locally with:

cp .env.example .env
docker compose -p worklenz-foss-config config

I did not run docker compose up on this host. The compose file publishes common ports, and this machine already has many unrelated containers running. Rendering the config is useful evidence; starting the stack would have risked port collisions and would have created containers on a busy host.

Important Deployment Caveats

The sample .env.example is well-commented, but it contains placeholder values that must be changed before any serious deployment:

DB_PASSWORD=CHANGE_THIS_SECURE_PASSWORD_123
SESSION_SECRET=CHANGE_THIS_TO_RANDOM_HEX_STRING_32_CHARS
COOKIE_SECRET=CHANGE_THIS_TO_RANDOM_HEX_STRING_32_CHARS
JWT_SECRET=CHANGE_THIS_TO_RANDOM_HEX_STRING_32_CHARS
AWS_SECRET_ACCESS_KEY=CHANGE_THIS_MINIO_PASSWORD
REDIS_PASSWORD=CHANGE_THIS_REDIS_PASSWORD

The compose file also uses fixed container_name values:

worklenz_frontend
worklenz_backend
worklenz_client_portal
worklenz_nginx
worklenz_minio
worklenz_db
worklenz_db_backup

That is fine for a single quick-start stack, but it is less flexible if you run multiple deployments, test branches, or several apps on the same Docker host. Fixed container names can also conflict with old runs.

There is one docs mismatch worth knowing. DOCKER_SETUP.md talks about profile-based deployment and Redis, but the inspected top-level compose file does not contain Compose profiles keys and does not define a Redis service. The .env.example includes Redis variables, and the backend has a Redis dependency, but the compose file I validated does not start Redis.

For a real deployment, trust the compose file you are about to run, not only the prose docs.

Licensing

Worklenz is open-core.

The root license says the repository is AGPLv3 except for:

  • any src/ee/ directory, such as worklenz-backend/src/ee/ and worklenz-frontend/src/ee/
  • the entire worklenz-client-portal/ package

Those excluded parts are under the Worklenz Commercial License.

The self-hosting document says the AGPLv3 core includes projects, tasks, boards, time tracking, team management, comments, attachments, scheduling, self-hosted auth, the core REST API, and notifications. It says Business Plan features such as billing, subscriptions, Slack integration, project finance/rate cards, client portal backend, corresponding UI, and the client portal package require a paid subscription or separate agreement for production use.

One especially important note from the self-hosting doc: the codebase does not yet technically enforce that production-use restriction for self-hosted deployments. In other words, do not assume “it runs” means “the license permits this production use.” Read the license files for your exact use case.

Local Field Note

I cloned the repo and validated the Docker Compose configuration without starting containers.

Environment:

Node: v18.19.1
npm: 9.2.0
Docker Compose: v5.5.1

Commands:

git clone --depth 1 https://github.com/Worklenz/worklenz /tmp/foss-post-worklenz/worklenz
cd /tmp/foss-post-worklenz/worklenz
cp .env.example .env
docker compose -p worklenz-foss-config config

Result:

clone: success
compose config: success
containers started: no
containers modified: no

I did not run a local npm build because the backend package declares Node >=20.0.0, and this machine currently has Node v18.19.1.

How I Would Self-Host It

For a clean test VM or VPS, I would start from the official Docker path, but I would not run it blindly on a busy homelab host.

First, clone it:

git clone https://github.com/Worklenz/worklenz
cd worklenz

Create the environment file:

cp .env.example .env

Generate real secrets:

openssl rand -hex 32

Replace the placeholder values for database, sessions, cookies, JWT, MinIO, and any external providers you actually enable.

Then render the config before starting:

docker compose config

Check the published ports and fixed container names. If 80, 443, 3000, 5000, 5174, 9000, or 9001 are already used, change the compose file or deploy on a cleaner host.

Then start:

docker compose up -d

The README documents these local URLs:

Frontend:      http://localhost:5000
Backend API:   http://localhost:3000
MinIO Console: http://localhost:9001

The README also documents default MinIO credentials:

username: minioadmin
password: minioadmin

Change those for anything beyond a throwaway local test.

FAQ

Is Worklenz fully open source?

It is open-core. The core is AGPLv3, while src/ee/ areas and the full worklenz-client-portal/ package are under the Worklenz Commercial License.

Can I self-host it?

Yes, the repository includes Docker Compose and self-hosting docs. For production, read the license boundaries and replace all placeholder secrets.

Did I run the Worklenz UI locally?

No. I validated the Compose configuration but did not start the stack because the compose file uses common ports and this host already had many unrelated containers running.

What are the default MinIO credentials?

The README documents minioadmin / minioadmin for the MinIO console in local Docker setup. Change them for any persistent deployment.

Does the compose file include Redis?

Not in the checkout I inspected. The docs and .env.example mention Redis, and the backend has Redis-related code/dependencies, but the validated top-level docker-compose.yml did not define a Redis service.

What Node version do I need for backend development?

The backend package declares Node >=20.0.0.

Conclusion

Worklenz is a capable self-hosted project management stack, but it is not a tiny single-container app.

The architecture is familiar and workable: React, Vite, Ant Design, TypeScript, Express, PostgreSQL, Socket.IO, MinIO-compatible storage, nginx, and Docker Compose. The repo also has enough operational surface that you should read the compose file, check the license boundaries, rotate secrets, and plan ports before starting it.

For a team that wants self-hosted project management with task boards, reporting, time tracking, scheduling, and collaboration, Worklenz is worth a look. Just treat it like real business infrastructure from the first deployment.