Skip to main content

Universal Taskfile runner with multi-environment deploy support. CI/CD agnostic — run locally or from any pipeline.

Project description

taskfile

PyPI version Python version License: Apache-2.0 Build Status Codecov Documentation Status

Universal task runner with multi-environment deploy support.

Write your deploy logic once in Taskfile.yml, run it from your terminal, GitLab CI, GitHub Actions, Gitea, Jenkins — or any other pipeline. Zero CI/CD lock-in.


Table of Contents


The Problem This Solves

You have one project with multiple deployment stages:

local   → Docker Compose + Traefik  (dev on laptop)
staging → Docker Compose over SSH   (test server)
prod    → Podman Quadlet + Traefik  (512MB VPS)
fleet   → 20× Raspberry Pi kiosks   (edge deploy)

Without taskfile, you maintain separate scripts, CI configs, and fleet tools for each. With taskfile:

┌──────────────────────────────────────────────────┐
│              Taskfile.yml                        │
│  (environments + tasks + groups = one file)      │
│                                                  │
│  taskfile --env local run dev                    │
│  taskfile --env prod run deploy                  │
│  taskfile -G kiosks run deploy-kiosk             │
│  taskfile fleet status                           │
│  taskfile auth setup                             │
└──────────────────────────────────────────────────┘

One YAML file. All environments, platforms, device groups, and deploy tasks in one place.


Install

pip install taskfile

Short alias tf is also available after install:

tf --env prod run deploy

Quick Start

# 1. Create project from template
taskfile init --template full

# 2. See available tasks
taskfile list

# 3. Local development
taskfile --env local run dev

# 4. Deploy to production
taskfile --env prod run deploy

# 5. Dry run — see what would happen
taskfile --env prod --dry-run run deploy

Taskfile.yml Reference

A complete Taskfile.yml can contain these top-level sections:

version: "1"
name: my-project
description: Project description
default_env: local
default_platform: web

# ─── Global variables ────────────────────────────
variables:
  APP_NAME: my-project
  IMAGE: ghcr.io/myorg/my-project
  TAG: latest

# ─── Environments (WHERE to deploy) ──────────────
environments:
  local:
    container_runtime: docker
    compose_command: docker compose
    variables:
      DOMAIN: localhost

  prod:
    ssh_host: prod.example.com
    ssh_user: deploy
    ssh_key: ~/.ssh/id_ed25519
    container_runtime: podman
    service_manager: quadlet
    variables:
      DOMAIN: app.example.com

# ─── Environment Groups (fleet / batch deploy) ───
environment_groups:
  kiosks:
    members: [kiosk-1, kiosk-2, kiosk-3]
    strategy: rolling        # rolling | canary | parallel
    max_parallel: 2

# ─── Platforms (WHAT to deploy) ───────────────────
platforms:
  web:
    desc: Web application
    variables:
      BUILD_DIR: dist/web
  desktop:
    desc: Electron desktop app
    variables:
      BUILD_DIR: dist/desktop

# ─── Tasks ────────────────────────────────────────
tasks:
  build:
    desc: Build the application
    cmds:
      - docker build -t ${IMAGE}:${TAG} .

  deploy:
    desc: Deploy to target environment
    deps: [build, push]          # run dependencies first
    parallel: true               # run deps concurrently
    env: [prod]                  # only run on prod
    platform: [web]              # only run for web platform
    condition: "test -f Dockerfile"  # skip if condition fails
    continue_on_error: true      # don't stop on failure
    cmds:
      - "@remote podman pull ${IMAGE}:${TAG}"
      - "@remote systemctl --user restart ${APP_NAME}"

Key Concepts

  • environments — WHERE to deploy (local machine, remote server via SSH)
  • platforms — WHAT to deploy (web, desktop, mobile)
  • environment_groups — batch of environments for fleet/group deploy
  • tasks — commands to execute, with deps, filters, conditions
  • variables — cascade: global → environment → platform → --var CLI overrides
  • @remote prefix — command runs via SSH on the target environment's host

CLI Commands

Global Options

taskfile [OPTIONS] COMMAND [ARGS...]

Options:
  --version                Show version
  -f, --file PATH          Path to Taskfile.yml
  -e, --env ENV            Target environment (default: local)
  -G, --env-group GROUP    Target environment group (fleet deploy)
  -p, --platform PLATFORM  Target platform (e.g. desktop, web)
  --var KEY=VALUE           Override variable (repeatable)
  --dry-run                Show commands without executing
  -v, --verbose            Verbose output

Core Commands

Command Description
taskfile run <tasks...> Run one or more tasks
taskfile list List tasks, environments, groups, platforms, variables
taskfile info <task> Show detailed info about a task
taskfile validate Check Taskfile.yml for errors
taskfile init [--template T] Create Taskfile.yml from template

Deploy & Release

Command Description
taskfile deploy Smart deploy — auto-detects strategy per environment
taskfile release [--tag v1.0] Full release pipeline: tag → build → deploy → health
taskfile rollback [--target TAG] Rollback to previous version
taskfile setup <IP> One-command VPS provisioning + deploy

Fleet Management

Command Description
taskfile fleet status SSH health check on all remote environments
taskfile fleet status --group kiosks Check only devices in a group
taskfile fleet list List remote environments and groups
taskfile fleet repair <env> 8-point diagnostics + auto-fix
taskfile -G kiosks run deploy Deploy to all devices in a group

Registry Auth

Command Description
taskfile auth setup Interactive token setup for registries
taskfile auth setup --registry pypi Setup for one registry only
taskfile auth verify Test all configured credentials

Infrastructure

Command Description
taskfile quadlet generate Generate Podman Quadlet from docker-compose.yml
taskfile quadlet upload Upload Quadlet files to server via SSH
taskfile ci generate Generate CI/CD config (GitHub Actions, GitLab, etc.)
taskfile health Check health of deployed services

Multi-Environment Deploy

Define environments in Taskfile.yml, then target them with --env:

# Local development
taskfile --env local run dev

# Staging deploy
taskfile --env staging run deploy

# Production deploy
taskfile --env prod run deploy

# Override variables per-run
taskfile --env prod run deploy --var TAG=v1.2.3 --var DOMAIN=new.example.com

Remote Commands with @remote

Any command prefixed with @remote runs on the environment's SSH host:

tasks:
  restart:
    env: [prod]
    cmds:
      - "@remote systemctl --user restart ${APP_NAME}"
      - "@remote podman ps --filter name=${APP_NAME}"

This translates to: ssh -i ~/.ssh/id_ed25519 deploy@prod.example.com 'systemctl --user restart my-app'

Deploy Shortcut

taskfile deploy auto-detects the right strategy:

taskfile --env local deploy    # → docker compose up -d
taskfile --env prod deploy     # → generate Quadlet → scp → systemctl restart

Multi-Platform Deploy

Deploy to desktop and web platforms across environments:

┌──────────┬───────────────────────┬──────────────────────────┐
│          │ local                 │ prod                     │
├──────────┼───────────────────────┼──────────────────────────┤
│ desktop  │ npm run dev:electron  │ electron-builder publish │
│ web      │ docker compose up     │ podman pull + restart    │
└──────────┴───────────────────────┴──────────────────────────┘
taskfile --env local --platform desktop run deploy
taskfile --env prod --platform web run deploy
taskfile run release    # all platforms at once

Variables cascade: global → environment → platform → CLI overrides.

Generate a multiplatform scaffold:

taskfile init --template multiplatform

Environment Groups & Fleet Management

Manage fleets of devices (Raspberry Pi, edge nodes, kiosks) using environment_groups in Taskfile.yml. Each device is an environment with ssh_host; groups define batch-deploy strategies.

Defining a Fleet

environments:
  kiosk-lobby:
    ssh_host: 192.168.1.10
    ssh_user: pi
    container_runtime: podman
  kiosk-cafe:
    ssh_host: 192.168.1.11
    ssh_user: pi
    container_runtime: podman
  kiosk-entrance:
    ssh_host: 192.168.1.12
    ssh_user: pi
    container_runtime: podman

environment_groups:
  kiosks:
    members: [kiosk-lobby, kiosk-cafe, kiosk-entrance]
    strategy: rolling       # rolling | canary | parallel
    max_parallel: 2         # for rolling: how many at a time
    canary_count: 1         # for canary: how many to test first

Group Deploy Strategies

  • rolling — deploy to max_parallel devices at a time, wait for success, then next batch
  • canary — deploy to canary_count devices first, confirm, then deploy to rest
  • parallel — deploy to all devices simultaneously
# Deploy to all kiosks with rolling strategy
taskfile -G kiosks run deploy-kiosk --var TAG=v2.0

# Deploy to a single device
taskfile --env kiosk-lobby run deploy-kiosk --var TAG=v2.0

Fleet Status & Health

# Check all remote devices (parallel SSH: temp, RAM, disk, containers, uptime)
taskfile fleet status

# Check only devices in a group
taskfile fleet status --group kiosks

# List all remote environments and groups
taskfile fleet list

Example output:

┌─────────────────┬──────────────┬────────┬──────┬─────┬──────┬────────────┬─────────┐
│ Name            │ IP           │ Status │ Temp │ RAM │ Disk │ Containers │ Uptime  │
├─────────────────┼──────────────┼────────┼──────┼─────┼──────┼────────────┼─────────┤
│ kiosk-cafe      │ 192.168.1.11 │ ✅ UP  │ 52°C │ 41% │ 23%  │          3 │ up 14d  │
│ kiosk-entrance  │ 192.168.1.12 │ ✅ UP  │ 48°C │ 38% │ 19%  │          3 │ up 14d  │
│ kiosk-lobby     │ 192.168.1.10 │ ✅ UP  │ 55°C │ 45% │ 27%  │          3 │ up 14d  │
└─────────────────┴──────────────┴────────┴──────┴─────┴──────┴────────────┴─────────┘

Fleet Repair

Diagnose and auto-fix issues on a device with 8-point check: ping, SSH, disk, RAM, temperature, Podman, containers, NTP.

# Interactive repair
taskfile fleet repair kiosk-lobby

# Auto-fix without prompts
taskfile fleet repair kiosk-lobby --auto-fix

Parallel Tasks & Error Handling

Parallel Dependencies

Run task dependencies concurrently for faster builds:

tasks:
  deploy:
    deps: [test, lint, build]
    parallel: true              # test, lint, build run at the same time
    cmds:
      - echo "All deps done, deploying..."

Continue on Error

Allow tasks to continue even if a command fails:

tasks:
  lint:
    cmds:
      - ruff check .
    continue_on_error: true     # alias for ignore_errors: true

  deploy:
    deps: [lint, test]
    parallel: true
    continue_on_error: true     # failed deps won't stop the deploy
    cmds:
      - "@remote systemctl --user restart ${APP_NAME}"

Conditional Execution

Skip tasks when conditions aren't met:

tasks:
  migrate:
    condition: "test -f migrations/pending.sql"
    cmds:
      - "@remote psql < migrations/pending.sql"

Registry Authentication

Interactively configure API tokens for package registries. Tokens are saved to .env (auto-gitignored).

# Setup all registries
taskfile auth setup

# Setup one registry
taskfile auth setup --registry pypi

# Verify all configured tokens
taskfile auth verify

Supported registries:

Registry Token variable How to get
PyPI PYPI_TOKEN https://pypi.org/manage/account/token/
npm NPM_TOKEN npm token create
Docker Hub DOCKER_TOKEN https://hub.docker.com/settings/security
GitHub GITHUB_TOKEN https://github.com/settings/tokens
crates.io CARGO_TOKEN https://crates.io/settings/tokens

Multi-Registry Publishing

Generate a publish scaffold for releasing to multiple registries:

taskfile init --template publish

This creates a Taskfile.yml with tasks for:

  • PyPItwine upload
  • npmnpm publish
  • Docker Hub / GHCRdocker push
  • GitHub Releasesgh release create
  • Landing page — build & deploy
# Publish to all registries
taskfile run publish-all --var TAG=v1.0.0

# Publish to single registry
taskfile run publish-pypi --var TAG=v1.0.0
taskfile run publish-docker --var TAG=v1.0.0

Quadlet Generator

Automatically generate Podman Quadlet .container files from your existing docker-compose.yml.

taskfile quadlet generate --env-file .env.prod -o deploy/quadlet

Reads docker-compose.yml, resolves ${VAR:-default} with .env.prod values, generates Quadlet units with:

  • [Container] — image, env, volumes, labels, ports, resource limits
  • [Unit]After=/Requires= from depends_on
  • AutoUpdate=registry for automatic updates
  • Traefik labels preserved
  • Named volumes → .volume units
  • Networks → .network units

No podlet binary needed — pure Python.

# Generate + upload to server
taskfile quadlet generate --env-file .env.prod
taskfile --env prod quadlet upload

VPS Setup (One-Command)

Provision a fresh VPS and deploy your app in one command:

taskfile setup 123.45.67.89 --domain app.example.com

This runs:

  1. SSH key provisioning
  2. System update + Podman install
  3. Firewall configuration
  4. Deploy user creation
  5. Application deployment

Options:

taskfile setup 123.45.67.89 \
  --domain app.example.com \
  --ssh-key ~/.ssh/custom_key \
  --user admin \
  --ports 80,443,8080

# Dry run
taskfile setup 123.45.67.89 --dry-run

# Skip steps
taskfile setup 123.45.67.89 --skip-provision
taskfile setup 123.45.67.89 --skip-deploy

Release Pipeline

Full release orchestration: tag → build → deploy → health check.

# Full release
taskfile release --tag v1.0.0

# Skip desktop build
taskfile release --tag v1.0.0 --skip-desktop

# Dry run
taskfile release --tag v1.0.0 --dry-run

Steps:

  1. Create git tag
  2. Build desktop applications
  3. Build and deploy web (SaaS)
  4. Upload desktop binaries
  5. Build and deploy landing page
  6. Run health checks

Rollback:

taskfile rollback                   # rollback to previous tag
taskfile rollback --target v0.9.0   # rollback to specific tag
taskfile rollback --dry-run

CI/CD Integration

Same commands work everywhere — terminal, GitLab CI, GitHub Actions, Jenkins:

# Terminal
taskfile --env prod run deploy --var TAG=v1.2.3

# GitLab CI
script: taskfile --env prod run deploy --var TAG=$CI_COMMIT_SHORT_SHA

# GitHub Actions
run: taskfile --env prod run deploy --var TAG=${{ github.sha }}

# Jenkins
sh 'taskfile --env prod run deploy --var TAG=${BUILD_NUMBER}'

Generate CI configs automatically:

# Generate GitHub Actions workflow
taskfile ci generate --provider github

# Generated workflows support:
# - Tag-triggered releases (v*)
# - Secrets injection from GitHub Secrets
# - Multi-job pipelines

Scaffold Templates

Generate a Taskfile.yml from built-in templates:

taskfile init --template <name>
Template Description
minimal Basic build/deploy, 2 environments
web Web app with Docker + Traefik, 3 environments
podman Podman Quadlet + Traefik, optimized for low-RAM
full All features: multi-env, release, cleanup, quadlet
codereview 3-stage: local(Docker) → staging → prod(Podman Quadlet)
multiplatform Desktop + Web × Local + Prod deployment matrix
publish Multi-registry publishing: PyPI, npm, Docker, GitHub

Templates are stored as plain YAML files and can be customized.


Project Structure

my-project/
├── Taskfile.yml                # tasks, environments, groups
├── docker-compose.yml          # container definitions (source of truth)
├── .env.local                  # local variables
├── .env.prod                   # production variables (gitignored)
├── deploy/
│   └── quadlet/                # auto-generated .container files
└── Dockerfile

Examples

Getting Started

Example Complexity Features
minimal test, build, run — no environments
saas-app ⭐⭐ local/staging/prod with pipeline
multiplatform ⭐⭐⭐ Web + Desktop, CI/CD generation
codereview.pl ⭐⭐⭐⭐ 6 CI platforms, Quadlet, docker-compose

Publishing (one registry per example)

Example Registry Language Artifact
publish-pypi PyPI Python wheel + sdist
publish-npm npm Node.js / TypeScript npm package
publish-cargo crates.io Rust crate
publish-docker GHCR + Docker Hub any Docker image (multi-arch)
publish-github GitHub Releases Go (example) binaries + checksums

Advanced

Example Complexity Features
fleet-rpi ⭐⭐⭐⭐ 6 Raspberry Pi, 3 groups, rolling/canary deploy
multi-artifact ⭐⭐⭐⭐⭐ Python + Rust + Node.js + Docker → 5 registries
# Fleet management
cd examples/fleet-rpi
taskfile fleet status
taskfile -G all-kiosks run deploy-kiosk --var TAG=v2.0

# Multi-artifact monorepo
cd examples/multi-artifact
taskfile run test-all       # 3 languages in parallel
taskfile run publish-all    # 5 registries in parallel

License

Apache License 2.0 - see LICENSE for details.

Author

Created by Tom Sapletta - tom@sapletta.com

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

taskfile-0.3.12.tar.gz (100.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

taskfile-0.3.12-py3-none-any.whl (96.2 kB view details)

Uploaded Python 3

File details

Details for the file taskfile-0.3.12.tar.gz.

File metadata

  • Download URL: taskfile-0.3.12.tar.gz
  • Upload date:
  • Size: 100.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for taskfile-0.3.12.tar.gz
Algorithm Hash digest
SHA256 aaedf67b0b9566d61eb561943843a336062d4dc4437f1b6bc225fd8242d42169
MD5 3e308fa7af58a3aedcab6aa1cb553504
BLAKE2b-256 7b6859bf585e5a2993c462369fa516ef909b52bf7fe07a4b4e5d1c96894e604f

See more details on using hashes here.

File details

Details for the file taskfile-0.3.12-py3-none-any.whl.

File metadata

  • Download URL: taskfile-0.3.12-py3-none-any.whl
  • Upload date:
  • Size: 96.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for taskfile-0.3.12-py3-none-any.whl
Algorithm Hash digest
SHA256 53ec54d70aeb1bc6500c3f6f1415c82d6e2a4b962a8c5c10b8485c8ebf25210d
MD5 2e05174123a00a489a3b428c59a2b3a2
BLAKE2b-256 975aa5a84440fc42c1c2b077f5278e9e7a6170c2cdac6beae12aefcbc2076dc5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page