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.

The Problem This Solves

You have one project (codereview.pl) with deployment stages:

local   → Docker Compose + Traefik  (dev on laptop)
prod    → Podman Quadlet + Traefik  (512MB VPS)

Without taskfile, you maintain separate configs for each. With taskfile:

┌─────────────────────────────────────────────┐
│         docker-compose.yml                  │
│         (single source of truth)            │
│                                             │
│  .env.local    →  docker compose up         │
│  .env.prod     →  generate Quadlet → deploy │
└─────────────────────────────────────────────┘

One compose file, .env files for differences, automatic Quadlet generation.

Install

PyPI

pip install taskfile

Quick Start

# Create project from template
taskfile init --template codereview

# See available tasks
taskfile list

# Local development
taskfile --env local run dev

# Deploy to production (generates Quadlet, uploads, restarts)
taskfile --env prod run deploy

# Or use the deploy shortcut (auto-detects strategy)
taskfile --env prod deploy

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

Short alias tf is also available:

tf --env prod run deploy-quick

How It Works

Project Structure

my-project/
├── docker-compose.yml          # SINGLE SOURCE OF TRUTH
├── .env.local                  # local: localhost, no TLS, relaxed limits
├── .env.prod                   # prod: TLS, tight limits
├── Taskfile.yml                # all deploy tasks
├── deploy/
│   └── quadlet/                # auto-generated .container files
└── Dockerfile

docker-compose.yml — Same File, All Environments

All differences between environments are captured in variables:

services:
  app:
    image: ${REGISTRY}/my-app:${TAG:-latest}
    labels:
      traefik.http.routers.app.rule: "Host(`${DOMAIN:-app.localhost}`)"
      traefik.http.routers.app.tls: "${TLS_ENABLED:-false}"
    deploy:
      resources:
        limits:
          memory: ${APP_MEMORY:-128m}

Deploy Commands

# Local development
taskfile --env local run dev          # docker compose up --build
taskfile --env local run dev-logs     # follow logs

# Production deploy
taskfile --env prod run deploy        # full: build → push → quadlet → upload → restart
taskfile --env prod run deploy-quick  # just: pull → restart
taskfile --env prod run deploy-service --var SVC=app

# Quadlet generation
taskfile quadlet generate --env-file .env.prod
taskfile --env prod quadlet upload

# Operations
taskfile --env prod run status
taskfile --env prod run logs --var SVC=app
taskfile --env prod run ram

Quadlet Generator

The killer feature: 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.

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 local and production environments using one standardized format:

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

# Web app — production
taskfile --env prod --platform web run deploy

# Release all platforms at once
taskfile run release

Define platforms in Taskfile.yml:

platforms:
  desktop:
    desc: Electron desktop application
    variables:
      BUILD_DIR: dist/desktop
  web:
    desc: Web application (Docker container)
    variables:
      BUILD_DIR: dist/web

tasks:
  deploy-web-prod:
    env: [prod]
    platform: [web]
    cmds:
      - docker push ${REGISTRY}/${APP_NAME}:${TAG}
      - "@remote podman pull ${REGISTRY}/${APP_NAME}:${TAG}"

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

See examples/multiplatform/ for a full working example, or generate one:

taskfile init --template multiplatform

Key Features

  • Multi-env deploy — local/staging/prod with different runtimes
  • Multi-platform deploy — desktop/web/mobile with platform-specific variables and filters
  • @remote prefix — commands run via SSH on target server
  • Variable substitution${VAR}, {{VAR}}, cascading: global → env → platform → CLI → OS
  • Task dependenciesdeps: [test, push, generate]
  • Environment filtersenv: [prod] restricts task to specific envs
  • Platform filtersplatform: [web] restricts task to specific platforms
  • Conditional executioncondition: "test -f migrations/pending.sql"
  • Dry run--dry-run shows commands without executing

CI/CD Integration

Same command everywhere:

# 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 }}

CLI Reference

taskfile run <tasks...>          Run one or more tasks
taskfile list                    List tasks and environments
taskfile init                    Create Taskfile.yml
taskfile validate                Check for errors
taskfile info <task>             Show task details
taskfile deploy                  Smart deploy (auto-detects strategy)
taskfile quadlet generate        Generate Quadlet from docker-compose.yml
taskfile quadlet upload          Upload Quadlet files to server

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

Templates: minimal | web | podman | codereview | full | multiplatform

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

This version

0.3.7

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.7.tar.gz (44.6 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.7-py3-none-any.whl (47.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: taskfile-0.3.7.tar.gz
  • Upload date:
  • Size: 44.6 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.7.tar.gz
Algorithm Hash digest
SHA256 064bbd4322711ba2ded858fa6c4554b5795f46f41a0d74e91ec64569c11343c8
MD5 e5d71d7a6c93c4e612811e46bf08287f
BLAKE2b-256 3ff9eb1f01744fd73d10c3f70a34d5e6aeb2ff9d1d5c9530455c15a1db81c6a1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: taskfile-0.3.7-py3-none-any.whl
  • Upload date:
  • Size: 47.6 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.7-py3-none-any.whl
Algorithm Hash digest
SHA256 9c99e1733ff80302b3fc16e4a6ac2822d2b97d3088d937926ff97877a76aed00
MD5 f5fa507a275114545326151a40130ebb
BLAKE2b-256 1a39175706f89ca370b20f4667e314d353466616d393832ff0a04c51f0d1b21b

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