Porting from Heroku
Tapitalee gives you a Heroku-style workflow (build an image, deploy, attach add-ons, set config vars, run one-off commands) but the infrastructure lives in your own AWS account. Apps run as containers on ECS Fargate, databases are RDS instances, files go in S3, and you pay AWS directly for what you use.
If you already know Heroku, most concepts carry across one-to-one. This section explains the differences and the equivalent tapit commands so you can get an app moved with minimal surprises.
The big picture
| Heroku | Tapitalee | Notes |
|---|---|---|
| Heroku account / Team | Team | Every user has a Personal team; create a team to collaborate. Teams are linked to one AWS account. |
| App | App | Belongs to a team, lives in one AWS region (in a VPC). |
Dyno / process type (web, worker) |
Process | The default process is the internet-facing one (Heroku web). Other processes are private background services. |
| Dyno size (Standard-1X, Performance-M) | Process cpu / memory |
Any Fargate combination of vCPU and GB, set per process. |
Dyno count (heroku ps:scale web=3) |
demand_count + spot_count |
Spot containers cost roughly a third of on-demand. Optional CPU autoscaling. |
| Slug / buildpack build | Container image | Built with Cloud Native Buildpacks (no Dockerfile needed) or your Dockerfile, pushed to a private ECR registry. |
Release (v123) |
Deploy and optional Release record | Rolling deploy with automatic rollback on failure. |
Release phase (release: in Procfile) |
Pre-deploy steps | Ordered commands run before each deploy completes; a failure aborts the deploy. |
| Config vars | Variables | Plain variables plus secrets stored in AWS Secrets Manager. |
| Add-ons (Postgres, Redis, etc.) | Add-ons | Real AWS services (RDS, ElastiCache, S3, EFS, …) in your account. |
heroku run |
Tasks and console sessions | One-off ECS tasks in a fresh ephemeral container. |
| Heroku Scheduler | Scheduled commands | Real cron expressions, not just 10-min/hourly/daily. |
| Custom domains + ACM / Automated Certificate Management | Domains + SecureProxy | Let’s Encrypt certificates via a Traefik proxy, or use Cloudflare. |
heroku logs --tail |
tapit show logs -f |
CloudWatch Logs under the hood. |
| Review apps | Preview apps | Clone of the parent app, optional auto-delete after N days. |
| Pipelines / promote | Multiple apps + create deploy docker_tag=... |
The same image tag can be deployed to any app in the team. |
API key / HEROKU_API_KEY in CI |
Deploy tokens | Scoped tokens for CI/CD. |
| Collaborators / Team members | Memberships and roles | read_only, member, admin, owner, plus granular access rights. |
What is different
- You bring the AWS account. Tapitalee provisions and manages resources in it. Billing for compute, databases and storage is on your AWS bill, not bundled.
- Containers, not slugs. Every deploy is a Docker image. If you have no Dockerfile,
tapit image deploybuilds one for you with buildpacks, much like Heroku did. - One public process. Only the
defaultprocess receives internet traffic. There is no router in front of your app unless you add a proxy add-on (SecureProxy, CertWrapper or Cloudflare), which is where TLS termination and zero-downtime switchover happen. See Webserving. - Dynamic IPs, no
herokuapp.comrouter. Apps get an internal*.dns.tapitalee.nethostname to CNAME to. IPs change on deploy, so point DNS at the hostname or use the Route53 or Cloudflare add-ons to manage records for you. - No dyno sleeping, no 24-hour restarts. Containers keep running until you deploy, restart or disable them.
- No 30-second router timeout, no 512 MB free tier. Resource limits are whatever you allocate.
- Ephemeral filesystem, as on Heroku, but you can attach a persistent shared volume with the EFS add-on.
- Regions. Heroku offered US and EU (plus Private Spaces). Tapitalee can deploy to any AWS region; each team gets one VPC per region.
Sections
CLI at a glance
The tapit CLI follows a verb resource key=value pattern rather than Heroku’s topic:command pattern. Almost every command takes -t TEAM -a APP (or TAPIT_TEAM / TAPIT_APP env vars, or a tapit.toml created by tapit init).
| heroku | tapit |
|---|---|
heroku login |
tapit ping (logs in if needed) |
heroku apps |
tapit -t TEAM list apps |
heroku create myapp |
tapit -t TEAM create app myapp region=us-east-1 |
heroku info |
tapit show app / tapit show summary |
git push heroku main |
tapit image deploy |
heroku releases |
tapit list deploys / tapit list releases |
heroku rollback v122 |
tapit create deploy docker_tag=<previous tag> |
heroku ps |
tapit list processes / tapit show service |
heroku ps:scale web=2 worker=1 |
tapit set process name=default demand_count=2 etc. |
heroku ps:restart |
tapit restart process name=default |
heroku config |
tapit list variables / tapit export variables |
heroku config:set KEY=val |
tapit set variable KEY val [secret=yes] |
heroku config:unset KEY |
tapit delete variable KEY |
heroku run rails console |
tapit run 'rails console' |
heroku run:detached rake task |
tapit create task 'rake task' |
heroku logs --tail |
tapit show logs -f |
heroku addons |
tapit list addons |
heroku addons:create heroku-postgresql |
tapit create rds engine=postgres name=maindb |
heroku addons:create heroku-redis |
tapit create elasticache engine=redis name=cache |
heroku addons:destroy NAME |
tapit delete addon name=NAME |
heroku domains:add www.example.com |
tapit create domain name=www.example.com |
heroku certs:auto:enable |
tapit create secureproxy acme_email=you@example.com |
heroku pg:backups:capture |
tapit create snapshot addon=maindb |
heroku pg:psql |
tapit run bash then psql $DATABASE_URL |
heroku apps:destroy |
tapit delete app myapp |
Run tapit help, tapit help <command> or browse the CLI and API reference for every option.