Installation

Install and deploy TaskView using Docker Compose. Step-by-step setup guide for a self-hosted task management server with PostgreSQL, Node.js API, and Vue web app. Deploy on any server in 5 minutes.

TaskView runs as a set of Docker containers - a database, an API server, a web app, and a one-time migration runner. The whole setup takes about 5 minutes.

Prerequisites

  • A server or local machine with Docker and Docker Compose installed
  • Ports 8888 (web) and 1725 (API) available - you can change these in the compose file

Step 1: Create a project directory

mkdir taskview && cd taskview

Step 2: Create environment files

You need two env files - one for PostgreSQL, one for the TaskView API.

.env.postgresql - database credentials:

POSTGRES_USER=tvdbuser
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=taskviewdb

.env.taskview - application config (example, do not forget add your data):

DB_HOST="db"
DB_USER="taskview_db_user"
DB_PASSWORD="password"
DB_NAME="taskviewdb"
DB_PORT=5432
APP_PORT=1401
JWT_ALG="HS256"
JWT_SIGN="secret"
ACCESS_LIFE_TIME="3d"
REFRESH_LIFE_TIME="9d"

SMTP_HOST=smtp
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_ENCRYPTION=tls
SMTP_FROM_NAME=TaskView
SMTP_FROM_EMAIL=

# Your domain 
APP_URL="https://app.taskview.tech"

GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
#You domain
GOOGLE_CALLBACK_URL="https://api.taskview.tech/module/auth/provider/google/callback"
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
GITHUB_CALLBACK_URL="https://api.taskview.tech/module/auth/provider/github/callback"
APPLE_CLIENT_ID=""
APPLE_TEAM_ID=""
APPLE_KEY_ID=""
APPLE_KEY_LOCATION="/usr/src/app/AuthKey.p8"
# Your domain
APPLE_CALLBACK_URL="https://api.taskview.tech/module/auth/provider/apple/callback"

#integrations
GITHUB_INTEGRATION_CLIENT_ID=
GITHUB_INTEGRATION_CLIENT_SECRET=
GITHUB_INTEGRATION_CALLBACK_URL=https://api.taskview.tech/module/integrations/oauth/github/callback

GITLAB_INTEGRATION_CLIENT_ID=
GITLAB_INTEGRATION_CLIENT_SECRET=
GITLAB_INTEGRATION_CALLBACK_URL=https://api.taskview.tech/module/integrations/oauth/github/callback

ENCRYPTION_KEY=

#!!! ADD YOUR DOMAIN SEPARATED BY ","
CORS_ALLOWED_ORIGINS="http://localhost:5173,http://127.0.0.1:5173,http://localhost:3000,http://localhost:8888,http://127.0.0.1:3000,http://127.0.0.1:8888"
Replace your_secure_password and JWT_SIGN with real secrets. Never use the example values in production.

Step 3: Create docker-compose.yml

networks:
  backend:
services:
  db:
    image: postgres:17
    restart: unless-stopped
    env_file:
      - ./.env.postgresql
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5433:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U taskview_db_user -d taskviewdb"]
      interval: 5s
      timeout: 5s
      retries: 5
    networks: [backend]
  migration:
    image: gimanhead/taskview-ce-db-migration:latest
    restart: "no"
    depends_on:
      db:
        condition: service_healthy
    env_file:
      - ./.env.taskview
    networks: [backend]

  taskview-api-server:
    image: gimanhead/taskview-ce-api-server:latest
    restart: "unless-stopped"
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=1
      - net.ipv6.conf.default.disable_ipv6=1
    ports:
      - "1725:1401"
    depends_on:
      db:
        condition: service_healthy
      migration:
        condition: service_completed_successfully
    env_file:
      - ./.env.taskview
    volumes:
      - /local/logs:/usr/src/app/logs
      - /local/AuthKey.p8:/usr/src/app/AuthKey.p8
    networks: [backend]

  taskview-webapp:
    image: gimanhead/taskview-ce-webapp:latest
    restart: unless-stopped
    ports:
      - "8888:80"
volumes:
  pgdata:

Step 4: Start everything

docker compose up -d

Docker will pull the images, start the database, run migrations, and launch the API and web app.

Step 5: Open TaskView

Go to http://localhost:8888 in your browser. You'll see the login screen.

The database migration creates a default user so you can log in right away:

  • Login: user
  • Password: user1!#Q

Use these credentials to verify that everything is working - check that the UI loads, you can create a project, add tasks, etc.

Important: The default user is for initial setup only. Once you've confirmed the system works, delete the default user and create your own account with a secure password.

Replacing the default user

  1. Log in with the default credentials
  2. Register a new account with your real email and a strong password
  3. Delete the default admin account

If you prefer to create the first user directly in the database, generate a password hash:

import { hashSync } from 'bcryptjs'

const passwordHash = hashSync('your-secure-password', 12)
console.log(passwordHash)

Or as a one-liner:

node -e "console.log(require('bcryptjs').hashSync('your-secure-password', 12))"

Then insert the user into the database with the generated hash.

Updating

To update TaskView to a new version:

docker compose pull
docker compose up -d

The migration container will automatically apply any new database changes on startup.

Production tips

  • Use a reverse proxy (Nginx, Caddy, Traefik) to terminate SSL and serve everything over HTTPS
  • Update APP_URL and API_URL in .env.taskview to match your production domain
  • Back up the database - the pgdata volume contains all your data
  • Set restart: unless-stopped on all services so they survive server reboots
  • SMTP setup - add SMTP variables to .env.taskview if you want email features (password recovery, invitations). See Configuration for details.

What's next

Built with Nuxt UI • © 2026 Thank you Nuxt Team for this awesome UI library and for the template!