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

Key Features

  • Multi-env deploy — local/staging/prod with different runtimes
  • @remote prefix — commands run via SSH on target server
  • Variable substitution${VAR}, {{VAR}}, cascading: global → env → CLI → OS
  • Task dependenciesdeps: [test, push, generate]
  • Environment filtersenv: [prod] restricts task to specific envs
  • 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)
  -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

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.6

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: taskfile-0.3.6.tar.gz
  • Upload date:
  • Size: 41.9 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.6.tar.gz
Algorithm Hash digest
SHA256 b4bde030297550767c9d7027ce1310cdeff294bece3a0904d459f99979e2e6ae
MD5 c1b5767e76aef2e6b5edb6962d90f292
BLAKE2b-256 323128afad4e6683f61f59c6959538bc0961a58afb407b13143b2553defbd519

See more details on using hashes here.

File details

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

File metadata

  • Download URL: taskfile-0.3.6-py3-none-any.whl
  • Upload date:
  • Size: 45.3 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.6-py3-none-any.whl
Algorithm Hash digest
SHA256 efbfaa2de3f23edd1749e50b36a5852451bce7b54955405c6385b769e6bf5c60
MD5 b9559eee12a21c217b570996496fc3da
BLAKE2b-256 ebff27a5a18a5e1dd3e8ae6cefd02003e25eed519e8c25af24ea785aed38dc76

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