--- title: Installation description: 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. navigation: icon: i-lucide-download --- 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](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) installed - Ports `8888` (web) and `1725` (API) available - you can change these in the compose file ## Step 1: Create a project directory ```bash 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: ```env POSTGRES_USER=taskview_db_user POSTGRES_PASSWORD=your_secure_password POSTGRES_DB=taskviewdb ``` **`.env.taskview`** - application config (**example, do not forget add your data**): ```env DB_HOST="db" DB_USER="taskview_db_user" DB_PASSWORD="your_secure_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" ``` ::callout{icon="i-lucide-shield" color="warning"} Replace `your_secure_password` and `JWT_SIGN` with real secrets. Never use the example values in production. :: ## Step 3: Create docker-compose.yml ```yaml 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: - ./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 ```bash 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](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. ::callout{icon="i-lucide-alert-triangle" color="error"} **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: ```ts import { hashSync } from 'bcryptjs' const passwordHash = hashSync('your-secure-password', 12) console.log(passwordHash) ``` Or as a one-liner: ```bash 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: ```bash 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](/docs/configuration/environment-variables) for details. ## What's next - [Create your first project](/docs/features/projects-and-lists) - set up a project with lists and tasks - [Invite your team](/docs/collaboration/members) - add members and assign roles - [Connect GitHub or GitLab](/docs/integrations/setup) - sync issues as tasks