Deployment
Tako deploys locally built apps to servers you control. The CLI validates project state, builds and packages the release, uploads artifacts over signed private HTTP management, and asks tako-server to prepare and roll the release into traffic.
Server Setup
Install the server on a Linux host:
sudo sh -c "$(curl -fsSL https://tako.sh/install-server.sh)"
Custom public ports:
curl -fsSL https://tako.sh/install-server.sh | sudo sh -s -- --http-port 8080 --https-port 8443
The installer creates the tako service user, the shared tako-app group, /opt/tako, /var/run/tako, service files, maintenance helpers, restricted sudoers policy, public HTTP/HTTPS listeners, local metrics, libvips runtime support, and private Tailscale management.
Normal installs require Tailscale for remote management. The CLI expects a Tailscale MagicDNS host or Tailscale IP, verifies SSH recovery access, enrolls the SSH key for signed management, and then uses signed HTTP for app operations.
Add A Server
tako servers add my-server.tailnet.ts.net --install
or:
tako servers add ubuntu@my-server.tailnet.ts.net
--install and admin@host flows install or repair tako-server before writing local config.toml. The add flow stores host, SSH port, public HTTP/HTTPS ports, description, and detected target metadata (arch, libc).
Configure An Environment
[envs.production]
route = "app.example.com"
servers = ["la"]
Deploy targets the servers listed in [envs.<env>].servers. If production has no server mapping and exactly one global server exists, deploy can select it and persist the mapping. Other non-development environments require explicit server mappings.
Deploy
tako deploy
tako deploy --env staging
tako deploy --env production --yes
When --env is omitted, deploy targets production. In an interactive terminal, an implicit production deploy asks for confirmation. Passing --env production, --yes, or -y makes the target explicit.
Deploy validates secrets, storage credentials, provider credentials, routes, server target metadata, workflow/channel storage requirements, and local-storage limitations before build work starts.
Build And Artifact Rules
Build precedence:
[[build_stages]][build]- Runtime default
- No-op
Tako copies the source root into .tako/build, respects .gitignore, symlinks node_modules from the original tree for JS builds, preserves symlinks as symlinks, runs build commands, merges assets into public/, verifies the resolved main, and archives the result without node_modules.
Always-excluded paths: .git/, .tako/, .env*, and node_modules/.
Version names are based on git state: clean commit hash, dirty commit plus content hash, or nogit_<hash> when no git commit is available.
Native Releases
Native releases use runtime plugins or explicit start commands. JS runtimes run through SDK entrypoint wrappers. Go binaries run directly. Explicit start commands skip runtime defaults and runtime version probing.
Native HTTP instances bind 127.0.0.1 on an OS-assigned port and signal readiness through fd 4. Secrets, storage bindings, and the internal health token arrive through fd 3.
Container Releases
container = "Dockerfile"
Container releases upload source and let tako-server build the image with Podman. HTTP containers run from the image defaults and receive HOST=0.0.0.0, PORT=3000, app vars, TAKO_BUILD, and TAKO_BOOTSTRAP_DATA.
Use a Tako SDK inside the container so secrets, storage bindings, internal status, and health-probe authentication follow the same contract as native releases. In v0, container HTTP instances do not receive fd 3, fd 4, the internal socket, or TAKO_DATA_DIR.
A configured workflow run starts a separate container process from the same image with an entrypoint override, args from run[1..], a mounted internal socket, and TAKO_BOOTSTRAP_DATA.
Release Commands
release = "bun run db:migrate"
[envs.staging]
release = ""
The release command runs once on the leader server after extract and production install but before rolling update. Followers wait for the leader result. If the command fails, times out, or exits by signal, deploy aborts on every server and leaves the old release serving.
The command runs with the same env as new HTTP instances, plus freshly decrypted secrets as env vars. The hard timeout is 10 minutes.
Rolling Updates
For each server, Tako starts a new instance, waits for health, adds it to the load balancer, drains an old instance, and repeats until the stored desired instance count is replaced. The current symlink moves only after the rolling update succeeds.
After finalize, each server keeps the active release and prunes non-active releases older than 30 days or beyond 50 total releases.
If desired instances are 0, deploy still starts one warm instance for the new build so traffic works immediately. It can later idle out.
Failures keep old instances running, clean partial release directories when needed, and report per-server results.
Scaling
tako scale 3 --env production
tako scale 0 --env production
Desired instances are server-side state. They persist across deploys, rollbacks, and server restarts. Scaling above the effective server maximum fails. Scaling to zero enables cold starts after idle timeout.
Secrets And Credentials
App secrets:
tako secrets set DATABASE_URL --env production
tako secrets sync --env production
Provider credentials:
tako credentials set ssl.cloudflare --env production
tako credentials set postgres_url --env production
Deploy sends app secrets only when the server’s current secret hash differs. Provider credentials are sent only for the runtime binding that needs them, such as Cloudflare SSL, Let’s Encrypt DNS-01, or shared channel/workflow storage.
Storage And Backups
Attach app storage:
tako storages add uploads --env production --provider s3 --bucket app-uploads --endpoint https://example.r2.cloudflarestorage.com --region auto
Set backup-only credentials:
tako storages credentials private_backups --env production
Backups are enabled in tako.toml with backup = { storage = "resource" }. Deploy sends backup storage separately from app storage, and it is not exposed through SDK storage bindings unless also listed in [envs.<env>].storages.
TLS
Let’s Encrypt is the default. Exact routes can use HTTP-01; wildcard routes require Cloudflare DNS-01 with ssl.cloudflare. ssl = "cloudflare" uses Cloudflare Origin CA and also requires ssl.cloudflare.
If public HTTPS uses a non-default port, deploy summaries include that port and HTTP redirects target it.
Server Maintenance
tako servers reload la
tako servers reload la --force
tako servers upgrade la
tako servers uninstall la --yes
reload is zero-downtime by default. --force performs a restart. upgrade installs a new tako-server binary, enters upgrade mode, reloads, waits for readiness, and rolls back to the previous binary if readiness fails. uninstall removes the remote service and data, then removes the local server entry.
Logs And Releases
tako logs --env production
tako logs --env production --tail
tako logs --env production --json
tako releases list --env production
tako releases rollback <release-id> --env production
Logs include app stdout/stderr and app-scoped server diagnostics. Releases show merged release history across mapped servers and mark the current release.