Hatchet
Overview
Hatchet is an open source distributed task queue and background job engine for durable workflow orchestration. You define workflows and tasks in code with your language SDK, and Hatchet runs them across a fleet of workers with automatic retries, concurrency and rate limits, fan-out and scheduling. A modern web dashboard then shows you every run, worker, event and schedule.
The SecureAnyCloud image runs Hatchet the officially supported way, as the upstream all-in-one container alongside a bundled PostgreSQL and RabbitMQ. Docker Compose orchestrates the stack under systemd, and nginx fronts it. Every image is pinned by digest and captured into the VM, so your instance starts in seconds.
A unique administrator, database password, message broker password and encryption keyset are generated for each VM on first boot, before the port is reachable. Open sign-up and tenant creation are disabled, so nobody can seize your instance before you sign in. The image is backed by 24/7 SecureAnyCloud support.
Hatchet is a trademark of its respective owner. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by Hatchet. It ships the free and open source, MIT-licensed, self-hosted core, unmodified.
What you get:
- Hatchet v0.94.10 (the MIT-licensed, self-hosted core), shipped as the official all-in-one hatchet-lite image pinned by image digest
- A bundled PostgreSQL 16 database and a bundled RabbitMQ message broker, both pinned by image digest and reachable only inside a private Docker network (never published to a host port)
- Docker Engine (Docker CE) with the Hatchet dashboard and API published to the loopback interface only, fronted by nginx on port
80 hatchet.service,hatchet-firstboot.serviceandnginx.serviceas systemd units, enabled and active on boot- A unique database password, message broker password, encryption keyset and a pre-seeded administrator, generated per VM on first boot and never baked into the image
- A clean, empty instance on first boot: no default account, no shipped secret, no prior data
- 24/7 SecureAnyCloud support
Prerequisites
- An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region.
- Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point. Increase the size for busier engines and more workers.
- NSG inbound rules: allow
22/tcpfrom your management network and80/tcpfor the web dashboard (and443/tcponce you add TLS). - If you plan to run workers outside the VM, also allow
7077/tcpfor the worker gRPC endpoint.
Hatchet serves plain HTTP on port 80. For production, put it behind TLS with your own domain, as described in the final step.
Step 1 - Deploy from the Azure Marketplace
- In the Azure portal, click Create a resource and search the Marketplace for the SecureAnyCloud Hatchet offer.
- Select the plan, and then click Create.
- On the Basics tab, pick your subscription, resource group and region, name the VM, and select Standard_B2s (or larger).
- Choose SSH public key authentication, enter the admin username
azureuser, and provide your public key. - On the Networking tab, allow inbound
22/tcpfrom your management network and80/tcpfor the web dashboard. - Review and create the VM. When the VM is running, note its public IP address.
Step 2 - Deploy from the Azure CLI
az vm image terms accept --urn sac1647283583153:hatchet:default:latest
az vm create \
--resource-group my-hatchet-rg \
--name hatchet \
--image sac1647283583153:hatchet:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardOpen the port that the web dashboard needs. SSH is opened by default:
az vm open-port --resource-group my-hatchet-rg --name hatchet --port 80 --priority 900If you connect workers from outside the VM, also open the worker gRPC port:
az vm open-port --resource-group my-hatchet-rg --name hatchet --port 7077 --priority 910Step 3 - Connect to your VM
Replace <vm-ip> with your VM's public IP address:
ssh azureuser@<vm-ip>Step 4 - Confirm the services are running
Hatchet, its bundled PostgreSQL and RabbitMQ, and nginx all come up automatically on first boot. Confirm they are active:
sudo systemctl is-active docker hatchet nginxExpected output:
active active activeThe stack runs as three containers on a private Docker network. PostgreSQL and RabbitMQ are never published to a host port. Only the Hatchet dashboard and API are published, and only to the loopback interface, with nginx in front on port 80.
Step 5 - Secure by default: a unique administrator, no default account
The stock Hatchet deployment seeds a well-known administrator and generates its secrets in place. The SecureAnyCloud image never ships those. On first boot, before the port is reachable, a unique administrator is created with a per-VM password. The encryption and cookie secrets are regenerated per VM, and open sign-up and tenant creation are disabled, so the instance cannot be seized. New members join by administrator invitation only.
You can see the whole posture at a glance. The default admin@example.com account is rejected because it was never created, and a blank password is rejected. Only the per-VM admin password is accepted, and an attempt to register a new account is refused because open sign-up is disabled:
Read your unique credentials, which are written to a root-only file:
sudo cat /root/hatchet-credentials.txtThe file holds the dashboard URL, the admin email (admin@hatchet.local) and the per-VM admin password. Keep this file safe.
Step 6 - Sign in to Hatchet
Open http://<vm-ip>/ in your browser. The Hatchet login screen appears, because there is no anonymous access. Sign in with the admin email and the password from the credentials file.
Step 7 - Explore the dashboard
After you sign in, you land on your tenant overview. The left sidebar is your home for the platform:
- Runs shows every task and workflow run with its status.
- Events is the live event feed.
- Logs streams task logs.
- Triggers and Resources cover scheduled runs, cron jobs, webhooks, workers, workflows and rate limits.
The onboarding panel walks you through installing the Hatchet CLI and running your first task.
Step 8 - Workflows and tasks
A workflow defines a sequence of tasks that execute together, with retries, concurrency limits and scheduling. You register workflows from your own code using a Hatchet SDK (Python, TypeScript or Go). Once a worker connects, its workflows appear here and every run is tracked end to end. Until then, the Workflows page guides you to the onboarding and the documentation.
Step 9 - Connect your workers
Workers are the processes that run your tasks. They connect to the Hatchet engine over gRPC and automatically pick up work, scaling up or down with your load.
Create an API token from Settings, and set it in your worker as HATCHET_CLIENT_TOKEN. Point the worker at your VM's gRPC endpoint (<vm-ip>:7077) and start it. If the worker runs outside the VM, open 7077/tcp in the NSG (Step 2). Connected workers appear on the Workers page.
Step 10 - Check the stack health from the command line
Hatchet exposes an unauthenticated liveness endpoint, which is useful for monitoring:
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1/api/liveExpected output (a healthy stack):
200The public metadata endpoint confirms the security posture: open sign-up and tenant creation are disabled.
curl -s http://127.0.0.1/api/v1/metaExpected output (trimmed):
{"allowChangePassword":true,"allowCreateTenant":false,"allowInvites":true,"allowSignup":false,"auth":{"schemes":["basic"]},"authDisabled":false}Step 11 - Invite your team
Because open sign-up is disabled, add colleagues from Settings while you are signed in as the administrator. Invited members set their own password when they accept, and you assign them to your tenant.
Step 12 - Production: your own domain with TLS
Hatchet serves plain HTTP on port 80. For production, point a DNS record at the VM and put Hatchet behind TLS. Then set the server URL to your https domain, so that dashboard links and worker connections use the right origin. A common approach is to add a certificate to nginx with Certbot:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d hatchet.example.comThen set SERVER_URL=https://hatchet.example.com and COOKIE_DOMAIN=hatchet.example.com in /etc/hatchet/hatchet.env and restart the stack with sudo systemctl restart hatchet. With a real domain, you can remove the nginx cookie domain workaround and let Hatchet set the cookie for your hostname directly. See the Hatchet documentation for the full production checklist.
Support
Every SecureAnyCloud image includes 24/7 support. If you have questions about deploying or operating Hatchet on Azure, contact the SecureAnyCloud team through the Azure Marketplace listing or at secureanycloud.com.
Deploy on Azure
Launch Hatchet on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Hatchet is an open source distributed task queue and background job engine for durable workflow orchestration. You define workflows and tasks in code with your existing language SDK, and Hatchet runs them across a fleet of workers with automatic retries, concurrency and rate limits, fan-out and scheduling. A modern web dashboard then shows you every run, worker, event and schedule.
This SecureAnyCloud image runs Hatchet as the official all-in-one hatchet-lite container (engine, REST API and dashboard in one image), alongside a bundled PostgreSQL datastore and a RabbitMQ message broker. Docker Compose orchestrates them under a single systemd service on a private container network.
The engine, dashboard and API bind to the loopback interface and are fronted by nginx on port 443 with a per-instance self-signed TLS certificate. PostgreSQL and RabbitMQ are never published to a host port.
Docker Engine and its entire data root live on a dedicated data volume mounted at /var/lib/docker. The data root includes the pre-pulled, digest-pinned images and the database, broker and configuration volumes. Your workflow state therefore survives OS-disk changes, and you can resize the volume independently.
Security is enforced from first boot. The stock Hatchet compose seeds a well-known default administrator and default secrets, and this image never ships them. Before the port is reachable, a unique administrator, a PostgreSQL password, a RabbitMQ password, an encryption keyset and the TLS certificate are all generated for the individual instance. Open sign-up and tenant creation are disabled, so the instance cannot be seized. The image is backed by 24/7 SecureAnyCloud support.
What you get:
- Hatchet v0.94.10, the MIT-licensed, self-hosted core, shipped as the official
hatchet-liteimage pinned by digest - A bundled PostgreSQL and RabbitMQ, pinned by digest and reachable only inside a private container network
- Docker Engine with the Hatchet dashboard and API on the loopback interface behind nginx over TLS on port 443
- A unique administrator, database password, broker password and encryption keyset generated per instance on first boot
- Open sign-up and tenant creation disabled, so the instance cannot be seized
- The Docker data root, workflow database and broker state on a dedicated data volume at
/var/lib/docker - An unauthenticated
/api/liveliveness endpoint for load-balancer health checks docker.service,hatchet.serviceandnginx.serviceas systemd units, enabled and active- 24/7 SecureAnyCloud support
Prerequisites
- An AWS account, an EC2 key pair in the target region, and a VPC with a public subnet.
- m5.large (2 vCPU / 8 GiB RAM) is the recommended instance type.
- Security group inbound rules: allow
22/tcpfrom your management network for SSH and443/tcpfor the web dashboard. - To connect external workers over the engine gRPC port, also allow
7077/tcpfrom your worker network.
Step 1 - Launch the AMI
Subscribe to the listing in AWS Marketplace, and then launch an instance from the AMI into your VPC with the security group described above. Choose the m5.large instance type and attach your EC2 key pair.
The image keeps the pre-pulled container images on the dedicated data volume, so the Hatchet stack comes up within seconds of first boot with no image re-pull.
Step 2 - Connect to your instance
Connect over SSH as the default login user for the operating system variant that you launched. The login user differs per OS, so use the row for your variant:
OS variant SSH login user Example
Ubuntu 24.04 ubuntu ssh -i your-key.pem ubuntu@<instance-public-ip>
ssh -i your-key.pem ubuntu@<public-ip>Step 3 - Read your unique administrator credential
On first boot, the instance generates a unique administrator email and password. It writes them, along with the resolved dashboard URL, to a root-only file. Read the file with sudo:
sudo cat /root/hatchet-credentials.txtThe file shows the dashboard URL and the administrator email and password for this instance:
HATCHET_URL=https://<instance-public-ip> HATCHET_ADMIN_EMAIL=admin@hatchet.local HATCHET_ADMIN_PASSWORD=<unique-per-instance-password> HATCHET_WORKER_GRPC=<instance-public-ip>:7077No two instances share this credential, and the well-known default administrator (admin@example.com / Admin123!!) is never created.
Step 4 - Confirm the stack and the security model from the command line
The three containers run under docker compose, managed by hatchet.service. Confirm they are up and healthy:
sudo docker compose -f /etc/hatchet/compose.yaml psSERVICE IMAGE STATUS hatchet-lite ghcr.io/hatchet-dev/hatchet/hatchet-lite@sha256:... Up 8 minutes postgres postgres@sha256:... Up 9 minutes (healthy) rabbitmq rabbitmq@sha256:... Up 9 minutes (healthy)Confirm the systemd services are active:
systemctl is-active docker hatchet nginxactive active activeThe engine, dashboard and API listen only on the loopback interface, and PostgreSQL and RabbitMQ are not published to any host port. Only nginx is exposed:
sudo ss -tlnp | grep -E ':443|:8888|:7077|:5432|:5672'LISTEN 0.0.0.0:443
# nginx (TLS reverse proxy) LISTEN 127.0.0.1:8888
# hatchet dashboard + API (loopback only) LISTEN 127.0.0.1:7077
# hatchet worker gRPC (loopback only)There is no 0.0.0.0:5432 (PostgreSQL) or 0.0.0.0:5672 (RabbitMQ) listener, because both stay inside the private container network. The liveness endpoint answers without authentication, and the server metadata confirms that open sign-up and tenant creation are disabled:
curl -ks -o /dev/null -w '%{http_code}\n' https://127.0.0.1/api/live
curl -ks https://127.0.0.1/api/v1/meta | jq '{allowSignup, allowCreateTenant}'200 { "allowSignup": false, "allowCreateTenant": false }Step 5 - Sign in to the dashboard
Open the dashboard in your browser at https://<instance-public-ip>/. The instance uses a per-instance self-signed TLS certificate, so your browser shows a certificate warning on first visit. Accept the warning to proceed. For production, front the instance with your own domain and certificate.
Sign in with the administrator email and password from Step 3.
After you sign in, you land on the Runs view, which lists every workflow run with its status, workflow, timing and duration. The activity timeline at the top shows run volume over time.
Select any run to see its detail. The detail view shows the task steps that make up the workflow, the run status and duration, and a full activity trace. The trace shows each task being queued, assigned to a worker, started and completed.
Step 6 - Register your first worker and workflow
Hatchet runs your code on workers that connect to the engine and pull tasks. Create an API token from Settings, and then point a worker at the instance using your language SDK. On a machine that can reach the instance, install the SDK and define a simple workflow:
# On a separate machine that can reach the instance (worker host):
python3 -m venv hatchet && ./hatchet/bin/pip install hatchet-sdk# worker.py from hatchet_sdk import Hatchet, Context, EmptyModel hatchet = Hatchet() pipeline = hatchet.workflow(name="sample-pipeline") @pipeline.task() def extract(input: EmptyModel, ctx: Context) -> dict: return {"records": 42} @pipeline.task(parents=[extract]) def transform(input: EmptyModel, ctx: Context) -> dict: return {"transformed": 84} if __name__ == "__main__": worker = hatchet.worker("sample-worker", workflows=[pipeline]) worker.start()Run the worker with the API token and the engine address in the environment:
export HATCHET_CLIENT_TOKEN='<your-token>'
export HATCHET_CLIENT_HOST_PORT='<public-ip>:7077' python worker.pyOnce the worker connects it appears on the Workers view as active, with its available slots and SDK version:
Trigger a run of the workflow from your code (pipeline.run()), from a schedule, or from an event. Watch each step execute in real time on the Runs view.
New team members join by administrator invitation only, from Settings. Open self sign-up is disabled.
Step 7 - Confirm the dedicated data volume
The Docker data root, and therefore the PostgreSQL database, the RabbitMQ store and the pre-pulled images, live on a dedicated EBS data volume mounted at /var/lib/docker, separate from the OS disk:
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/docker df -h /var/lib/docker/dev/nvme1n1 /var/lib/docker ext4 Filesystem Size Used Avail Use% Mounted on /dev/nvme1n1 40G 74M 37G 1% /var/lib/dockerBack it up with EBS snapshots or AWS Backup, and resize it independently of the OS disk as your throughput grows.
Security notes
- No default or shared credentials. The well-known default administrator that the stock Hatchet compose seeds is never created. A unique administrator is generated on each instance's first boot and written only to
/root/hatchet-credentials.txt. - Per-instance secrets. The PostgreSQL password, RabbitMQ password, encryption master keyset, JWT keysets and cookie secrets are all generated per instance on first boot.
- Closed registration. Open sign-up and tenant creation are disabled, so the instance cannot be seized. New members join by administrator invitation only.
- Network isolation. The engine, dashboard and API bind exclusively to the loopback interface. PostgreSQL and RabbitMQ are never published to a host port, and only the nginx TLS proxy is exposed. Restrict the security group to trusted networks, and for production front the instance with your own domain and certificate.
- Rotate the administrator password from your account settings after your first sign in.
Support
SecureAnyCloud provides 24/7 technical support for this product by email and live chat.
- Contact: sales@secureanycloud.com
- Support covers deployment, reverse-proxy termination with your own domain and TLS certificate, connecting external workers, scaling the bundled PostgreSQL and RabbitMQ, and backup planning for your workflow database using EBS snapshots or AWS Backup.
Deploy on AWS
Launch Hatchet with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com