Sign inSign up

tiag0ss/myelin

By tiag0ss

β€’Updated 7 days ago

Self-hosted project management with tasks, Gantt planning, time tracking, and team collaboration

Image
0

77

tiag0ss/myelin repository overview

⁠Myelin

Docker Hub Docker Image

Myelin is a full-stack, self-hosted project and delivery platform with task tracking, resource planning, time tracking, and multi-tenant organization support.

Version 1.0 β€” production-ready core (projects, planning, time, tickets, reporting, integrations). Report bugs and feature requests on GitHub.

⁠Features

  • πŸ“‹ Project & Task Management β€” Kanban boards, Gantt view, task hierarchy (parent/subtasks), dependencies, custom statuses/priorities/types with Lucide icons, and quick navigation between tasks and projects
  • πŸ“Š Resource Planning β€” Gantt chart with drag-and-drop allocation, user availability tracking, intelligent replanning, recurring blocks, Outlook calendar overlay (loads in background), and split planning
  • ⏱️ Time Tracking β€” Daily and weekly timesheet views, per-task time entries, timers, CSV export
  • βœ… Approvals Center β€” Team-lead/admin approval flows for time entries, vacations, and expenses (partial reimbursement supported)
  • πŸ–οΈ Vacations & Holidays β€” Annual vacation management, out-of-office requests, non-working-day-aware requests, and country holiday calendars
  • πŸ‘₯ Multi-Tenant Organizations β€” Multiple organizations, team management, permission groups
  • πŸ” Role-Based Permissions β€” Developer, Support, Manager roles with granular permission control
  • 🎫 Ticket System β€” Support ticket management with auto-numbering, auto-assignment, task conversion, Jira integration, and per-organization statuses/priorities
  • 🌐 Customer Portal β€” Customer-facing overview with ticket/project visibility and constrained ticket creation
  • πŸ‘€ Customer Management β€” Customer database with organization associations and default support user assignment
  • πŸ“ž Call Records β€” Structured call logging with time, participants, notes, and optional task/project linkage
  • πŸ› οΈ Application Lifecycle Management β€” Application registry, version control, release management with PDF exports, task-to-release linking
  • πŸ”— Integrations β€” Jira, GitHub, Gitea, and Outlook calendar (Microsoft Graph); credentials encrypted at rest
  • πŸ“¬ Outlook Email Task Queue β€” Route emails via Cloudflare Email Routing to a per-user queue; import as tasks from the project UI (setup guide⁠)
  • πŸ”‘ API Tokens β€” Personal pt_... tokens for webhooks, Workers, and integrations (Profile β†’ API Tokens)
  • πŸ“ Rich Text Editor β€” Tiptap-based editor with formatting; images upload to /uploads/editor (URL references; base64 fallback only if upload is unavailable)
  • πŸ“” Memos System β€” Calendar-based notes with visibility controls (Private, Organizations, Public), tags, and rich content
  • πŸ”„ Recurring Tasks β€” Outlook-style recurring time blocks for meetings, standups, and fixed schedules
  • πŸ“§ Email Notifications β€” SMTP integration; assignment, status/priority change, @mention, and due-date reminders
  • πŸ”‘ Password Recovery β€” Forgot-password flow with temporary email reset links
  • 🚦 RAG Health Score β€” Automatic Red/Amber/Green project health indicator
  • πŸ“ˆ Dashboard KPIs & Statistics β€” Configurable widgets and aggregate reporting
  • πŸ“Š Reporting Hub β€” Organization/portfolio/delivery/capacity packs, expense analytics (optional module), CSV extract, and advanced Explore pivots (/reporting)
  • πŸ’Έ Expenses (optional) β€” Project/internal costs, invoice attachments, approval and reimbursement workflow with category caps
  • πŸ” Global Search β€” Cross-entity search with paginated results (including users β†’ profile pages)
  • πŸ”” Real-Time Updates β€” Socket.io notifications and live UI refresh
  • πŸŒ™ Dark Mode β€” Full dark mode support across the UI
  • πŸ“± Responsive Design β€” Mobile-friendly interface with grouped navigation
  • πŸ–₯️ Desktop App β€” Optional Electron wrapper (pnpm run desktop:dev)
  • 🧩 IDE Extensions β€” VS Code / Cursor Kanban sidebar for tasks linked to this app (extras/ide-extensions/README.md⁠)
  • πŸ§™ Install Wizard β€” Guided first-time setup
  • ⚑ Optional Redis Cache β€” Read-through cache with invalidate-on-write for faster loads; disabled by default
  • 🧠 Synapse⁠ β€” Companion Markdown vaults (SSO with Myelin; optional checkboxβ†’task push)
  • πŸ€– AI Assistant (optional) β€” SQL-backed assistant; DB views are created on server start via ensureAiAssistantViews (see server/utils/aiAssistantViews.ts)

⁠Additional Notes

  • This README is intentionally concise to comply with Docker Hub overview size limits.
  • For feature walkthroughs and conventions, see AGENTS.md⁠, docs/FEATURES.md⁠, and the in-app user manual at /docs.
  • Legacy /reports redirects to Reporting β†’ Extract; manager analytics live under /reporting.
  • API documentation (Swagger): http://localhost:3000/api-docs when the server is running.

⁠Tech Stack

ComponentTechnology
FrontendNext.js 16, React 19, TypeScript, Tailwind CSS, Lucide icons
Rich TextTiptap (StarterKit, Image, Placeholder extensions)
BackendNode.js 20, Express.js, TypeScript
DatabaseMySQL 8.0 or MSSQL (SQL Server) β€” portable SQL via server/config/database.ts
Cache (optional)Redis 7 (ioredis), disabled when REDIS_ENABLED=false
AuthJWT + personal API tokens (pt_...)
Real-timeSocket.io
IntegrationsJira / GitHub / Gitea REST APIs, Microsoft Graph (Outlook), AES-256-CBC encryption
ContainerAlpine-based Node.js image

⁠Local Development

git clone https://github.com/tiag0ss/myelin.git
cd myelin
pnpm install
cp .env.example .env
# Edit .env (database, JWT_SECRET, etc.)

Run the app (Express custom server embeds Next.js on the same port):

pnpm run dev

Open http://localhost:3000, complete the install wizard on first run, then sign in.

Production after pnpm run build:

pnpm start
# same as: pnpm run start:prod

Optional desktop shell:

pnpm run desktop:dev

Run tests:

pnpm test

⁠Quick Start (Docker)

⁠1. Create environment file
cp .env.docker.example .env.docker
# Edit .env.docker with your values

MySQL example (default):

DB_PROVIDER=mysql
DB_HOST=mysql
DB_PORT=3306
DB_USER=appuser
DB_PASSWORD=your-strong-password-here
DB_NAME=projectmanagement
DB_CONNECTION_LIMIT=50

JWT_SECRET=your-super-secret-jwt-key-minimum-64-characters
ALLOWED_ORIGINS=http://localhost:3000,https://yourdomain.com
NEXT_PUBLIC_API_URL=http://localhost:3000
API_URL=http://localhost:3000
LOG_LEVEL=warn

MSSQL example:

DB_PROVIDER=mssql
DB_HOST=your-sqlserver-host
DB_PORT=1433
DB_USER=sa
DB_PASSWORD=your-strong-password-here
DB_NAME=projectmanagement
DB_CONNECTION_LIMIT=50
DB_ENCRYPT=false
DB_TRUST_SERVER_CERT=true

JWT_SECRET=your-super-secret-jwt-key-minimum-64-characters
ALLOWED_ORIGINS=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:3000
API_URL=http://localhost:3000
LOG_LEVEL=warn

Optional Redis (faster reads; MySQL/MSSQL remain source of truth):

REDIS_ENABLED=true
REDIS_URL=redis://redis:6379
REDIS_KEY_PREFIX=pm:
REDIS_DEFAULT_TTL_SECONDS=300

Set ENCRYPTION_KEY (64-char hex) in production if you use Jira, Outlook, or other encrypted integration settings. If omitted, JWT_SECRET is used as fallback.

⁠2. Run with Docker Compose

Use the docker-compose.yml⁠ in this repository:

docker compose up -d

With optional Redis cache:

docker compose --profile redis up -d

When using the Redis profile, set REDIS_ENABLED=true and REDIS_URL=redis://redis:6379 in .env.docker.

For MSSQL, point DB_HOST to your SQL Server instance instead of the bundled MySQL service.

⁠3. Run standalone (with external DB)
docker run -d \
  --name myelin \
  -p 3000:3000 \
  --env-file .env.docker \
  tiag0ss/myelin:latest
⁠4. First-Time Setup
  1. Open http://localhost:3000 in your browser
  2. The Install Wizard guides you through:
    • Admin account creation
    • Organization setup
    • Email configuration (optional)
  3. Configure integrations under Administration β†’ System Settings (SMTP, Jira, Outlook, etc.)

⁠Environment Variables

VariableRequiredDefaultDescription
DB_PROVIDERNomysqlDatabase provider (mysql or mssql)
DB_HOSTYesmysql (Docker)Database host
DB_USERYesappuserDatabase user
DB_PASSWORDYesβ€”Database password
DB_NAMENoprojectmanagementDatabase name
DB_CONNECTION_LIMITNo50Connection pool size
DB_PORTNo3306 / 1433Database port
DB_ENCRYPTNofalseMSSQL TLS encrypt flag
DB_TRUST_SERVER_CERTNotrueMSSQL trust server certificate
JWT_SECRETYesβ€”Secret key for JWT tokens
ENCRYPTION_KEYNoβ€”64-char hex key for encrypted settings (falls back to JWT_SECRET)
ALLOWED_ORIGINSNoβ€”CORS allowed origins (comma-separated)
NEXT_PUBLIC_API_URLNohttp://localhost:3000Public API URL (browser)
API_URLNohttp://localhost:3000Internal API URL
LOG_LEVELNowarnLog level (debug / info / warn / error)
PORTNo3000Application port
NODE_ENVNodevelopmentSet to production in production
DEMONofalseWhen true, enables demo-mode UI restrictions
REDIS_ENABLEDNofalseEnable Redis read cache
REDIS_URLNoredis://localhost:6379Redis connection URL
REDIS_KEY_PREFIXNopm:Key prefix for all cache entries
REDIS_DEFAULT_TTL_SECONDSNo300Safety TTL for cached entities (invalidated on writes)
ALLOWED_SSO_REDIRECTSNoβ€”Comma-separated SSO callback URLs (e.g. Synapse http://localhost:3010/api/auth/sso/callback)
SSO_CLIENT_ID / SSO_CLIENT_SECRETNoβ€”SSO client credentials for companions such as Synapse⁠

⁠Ports

PortDescription
3000Application (frontend + API)
3010Synapse⁠ companion (optional, separate process)
6379Redis (optional, Docker redis profile only)
3306MySQL (Docker Compose default)

⁠Volumes

PathDescription
/app/logsApplication log files
/app/uploadsFile attachments (Tasks, Tickets, Projects, Organizations, Customers, Memos)

Note: Rich text editor images are stored as base64 in the database, not in the uploads folder.

⁠Health Check

GET http://localhost:3000/health

Example response:

{
  "status": "healthy",
  "timestamp": "2026-07-02T22:00:00.000Z",
  "uptime": 3600,
  "database": "connected",
  "redis": "disabled"
}

redis is connected, disabled, or error. Redis failures do not fail the health check β€” the app falls back to the database.

If you see stale lists after a create/update with Redis enabled, confirm invalidation is wired on that write route; as a fallback, restart the API or flush Redis keys matching your REDIS_KEY_PREFIX (default pm:*).

⁠Architecture

Single container serves Next.js frontend and Express API. MySQL or MSSQL is the system of record. Redis is optional.

+----------------------------------+
|   myelin:latest      |
|                                  |
|  +-----------+  +------------+   |
|  | Next.js   |  | Express    |   |
|  | Frontend  |  | API        |   |
|  +-----------+  +------------+   |
|         Port 3000                |
+----------------------------------+
          |              |
          |              +-----> Redis (optional)
          |
   +------+------+
   | MySQL / MSSQL |
   +---------------+
  • Base image: node:20-alpine
  • Runs as: Non-root user (nodejs, UID 1001)
  • Process: node dist/server/index.js
  • Cache: When REDIS_ENABLED=true, reads are cached with invalidate-on-write; writes always go to the database first

⁠Updating

docker compose pull
docker compose up -d

⁠Backup

⁠Database (MySQL)
docker exec myelin-mysql \
  mysqldump -u root -p"$DB_PASSWORD" projectmanagement > backup.sql
⁠Restore (MySQL)
docker exec -i myelin-mysql \
  mysql -u root -p"$DB_PASSWORD" projectmanagement < backup.sql

For MSSQL, use your standard backup/restore tools (BACKUP DATABASE / RESTORE DATABASE).

⁠Testing

Comprehensive testing scenarios are in TESTING_SCENARIOS.md⁠:

  • 220+ test scenarios covering major features
  • Authentication, authorization, and security cases
  • Integration and end-to-end flows
  • Performance and browser compatibility notes
pnpm test
pnpm run test:coverage
pnpm run test:integration

⁠License

MIT

Tag summary

Content type

Image

Digest

sha256:0838c10b8…

Size

677.1 MB

Last updated

7 days ago

docker pull tiag0ss/myelin