HEROKU
#
IntroductionHeroku is a container-based cloud Platform as a Service (PaaS). Developers use Heroku to deploy, manage, and scale modern applications. It is elegant, flexible, and easy to use, offering developers the simplest path to getting their applications to market. Heroku is fully managed, giving developers the freedom to focus on their core product without the distraction of maintaining servers, hardware, or infrastructure. The Heroku experience provides services, tools, workflows, and polyglot support—all designed to enhance developer productivity. Heroku officially supports Python, Node.js, PHP, Java, Ruby, Go, Scala and Clojure languages. In addition to these languages, any language that runs on Linux with Heroku via a third-party buildpack can be used.
#
Getting startedPricing : Flexible pricing options, from personal projects to enterprise applications, and everything in between.
Create an account
Install the Heroku CLI
- On macOS :
$ brew tap heroku/brew && brew install heroku
- On ubuntu :
$ sudo snap install --classic heroku
- On Windows : Download the appropriate installer
To get the installed version :
$ heroku --version
All the heroku CLI commands can be found here.
- On macOS :
Uninstall the heroku CLI
- On macOS :
$ brew uninstall heroku && rm -rf ~/.local/share/heroku ~/Library/Caches/heroku
- On ubuntu :
$ sudo apt-get remove heroku heroku-toolbelt && rm /etc/apt/sources.list.d/heroku.list
- On Windows :
Start > Control Panel > Programs > Programs and Features
Select Heroku CLI, and then click Uninstall
- On macOS :
Login :
$ heroku login
to be redirect to the browser or$ heroku login -i
to be promted to enter the login credentialsCreate an application with a random name
$ heroku create
or specify a custom name$ heroku create <app_name>
Open an application :
$ heroku open -a <app_name>
Running bash :
$ heroku run bash -a <app_name>
Accessing the heroku postgres database :
heroku pg:psql <postgres_addon_name> -a <app_name>
Troubleshooting : Put
HEROKU_DEBUG=1
before the command to show debugging informationsConfig vars : It is highly recommended to use environment variables especially in production environment. So, to set a config var
$ heroku config:set <env_var_name>=<value> -a <app_name>
and to remove it$ heroku config:unset <env_var_name> -a <app_name>
Runtime : Heroku runs applications inside dynos — smart containers on a reliable, fully managed runtime environment where the system and language stacks are continually monitored, patched, and upgraded by the Heroku team.
Github integration : The seamless GitHub integration means every pull request spins up a disposable Review App for testing, and any repository can be set up to auto-deploy with every GitHub push to a choosen branch (i.e master).
Continuous delivery : Heroku Flow uses Heroku Pipelines, Review Apps and GitHub Integration to make building, iterating, staging, and shipping apps easy, visual, and efficient.
Application metrics and analytics : Always know what’s going on with the applications thanks to built-in monitoring of throughput, response times, memory, CPU load, and errors.
Security and compliance : Heroku regularly performs audits and maintains PCI, HIPAA, ISO, and SOC compliance.
Heroku ChatOps : Heroku ChatOps brings Heroku’s popular Pipelines deployment workflow to Slack. With Heroku ChatOps you can deploy and promote code, and get CI test and pull request statuses directly within Slack and more.
Code and data rollback : Heroku’s build system and Postgres service give the possibility to roll back the code or the database to a previous state in an instant.
Display recent logs :
$ heroku logs -a <app_name>
to fetch application’s most recent logs or$ heroku logs --tail -a <app_name>
to display recent logs and leave the session open for real-time logs to stream in.Maintenance mode : Enabling by
$ heroku maintenance:on -a <app_name>
and when maintenance actions are completed$ heroku maintenance:off -a <app_name>
.Add-ons : Extend, enhance, and manage applications with pre-integrated services. Here are the most used ones :
- Heroku Postgres : Reliable and secure PostgreSQL as a service with easy setup, encryption at rest, simple scaling, database forking, continuous protection, and more.
- cloudAMQP : Automates every part of the setup, running and scaling of RabbitMQ clusters.
- SendGrid : Offers the industry’s most advanced deliverability tools and expertise to make sure the email gets delivered. It’s easy to integrate and highly scalable email infrastructure with powerful and customizable APIs.
- Sentry : Errors and exceptions tracking that helps to monitor and fix crashes in real time by the integration with many services like Github, Slack, Jira and more.
- Elasticsearch : Open source, distributed, RESTful search engine, usable by any language that speaks JSON and HTTP.
- Moesif API Analytics : Leverage user-centric API analytics to drive adoption, usage, and retention.
- Deploy Hooks : Send a message to specified services (email, campfire, basecamp, IRC, or a custom HTTP end-point) whenever changes deployed.
To provision an add-on
$ heroku addons:create <addon_name> -a <app_name>
or$ heroku addons:remove <addon_name> -a <app_name>
to remove it. More add-ons are listed here.
#
DeploymentProcfile : it is a simple text file without a file extension. It must live in the application’s root directory. It specifies the commands that are executed by the application on startup. It can declare a variety of process types, including:
- The application’s web server
- Multiple types of worker processes
- A singleton process, such as a clock
- Tasks to run before a new release is deployed
Example for a web application:
web: gunicorn mysite.wsgi --log-file - release: python manage.py migrate --no-input worker: celery -A config worker -l info
#
1. Deploying with GitTrack the application in Git
$ cd repo_name $ git init $ git add . $ git commit -m "Commit message"
Create a Heroku remote
For a new Heroku application
$ heroku create <app_name>
For an existing Heroku application
$ heroku git:remote -a <app_name>
Deploy the code
From
master
branch$ git push heroku master
From a branch besides
master
$ git push heroku <branch_name>:master
#
2. Deploying with DockerUsing Container Registry
Login to the registry
$ heroku container:login -a <app_name>
Build & push the image
$ heroku container:push web -a <app_name>
Release the pushed image
$ heroku container:release web -a <app_name>
By building docker images with heroku.yml file
Here’s an example that illustrates using a heroku.yml manifest to build Docker images:
setup: addons: - plan: heroku-postgresql as: DATABASE - plan: cloudamqp as: BROKER - plan: sentry as: SENTRYbuild: docker: web: Dockerfilerelease: command: - python manage.py migrate image: webrun: web: command: - python manage.py collectstatic --no-input -v 0 && /bin/bash heroku-exec.sh \ && uwsgi --http :$PORT --enable-threads --http-keepalive --mimefile /etc/mime.types \ --processes 4 --wsgi-file config/wsgi.py --check-static /public_assets \ --static-map /static=/public_assets --static-map /favicon.ico=/public_assets/favicon.ico \ --logto /dev/stdout --logto2 /dev/stderr image: web worker: command: - bash heroku-exec.sh && celery -A config worker -l info image: web
The heroku-exec.sh script
`[ -z "$SSH_CLIENT" ] && source <(curl --fail --retry 3 -sSL "$HEROKU_EXEC_URL")`
Is used by Heroku to create a SSH tunnel to the docker container via Heroku CLI.
Heroku dynos expose a dynamic port for the application to bind to. This value is exposed in the \$PORT environment variable.
When heroku.yml is used, the Procfile is not required.
#
3. Deployment integrations- Github
- Terraform
- Heroku to Deploy button
#
Heroku Exec (SSH Tunneling)According to Heroku documentation Heroku Exec is a feature for creating secure TCP and SSH tunnels into a dyno. It allows for SSH sessions, port forwarding, remote debugging, and inspection with popular Java diagnostic tools.
#
SSH sessionsIt can be enabled by running this command :
$ heroku ps:exec -a <app_name>
Or optionally by specifying the dyno type (i.e web.1) :
$ heroku ps:exec --dyno=<dyno_type> -a <app_name>
Also, it's possible to check the status of Exec connection :
$ heroku ps:exec --status -a <app_name>
#
Port forwarding$ heroku ps:forward 9000 --dyno=<dyno_type> -a <app_name>
This command will forward traffic on the local port (9000) to the port (9000)
inside the specified dyno.
Then the browser can be connected to localhost:9000, and the requests will be routed through a secure socket
to port 9000 in the dyno. To stop port forwarding : CTRL+C
#
Usage with DockerHeroku exec is not officially supported and requires the following config :
- Create a new file
heroku-exec.sh
:
[ -z "$SSH_CLIENT" ] && source <(curl --fail --retry 3 -sSL "$HEROKU_EXEC_URL")
- Include it in
/app/.profile.d
directory inDockerfile
:
ADD ./.profile.d /app/.profile.d
- Ensure the default shell is Bash by including the following line in
Dockerfile
:
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
#
Disabling the feature$ heroku features:disable runtime-heroku-exec
#
Remove the Heroku Exec buildpack$ heroku buildpacks:remove heroku/exec
#
Limitations#
Connection- Each Heroku Exec connection lasts a maximum of one hour
- Not supported in Shield Private Spaces
- Not enabled for one-off dynos
#
Environment variablesThe SSH session created by Heroku Exec will not have the config vars set as environment variables
(i.e., env
in a session will not list config vars set by $ heroku config:set
)
In this case, environment variables must be exported, copied and pasted into the console when exec like the following :
`$ heroku config -s > env`
`$ cat env | sed 's/^/export /'`
< copy the output from the cat cmd >
`$ heroku ps:exec -a <app_name>`
< paste the output from the cat cmd >
## Data backup and restore for local use
For Docker db container
$ rm latest.dump $ heroku pg:backups:capture -a <app_name> $ heroku pg:backups:download -a <app_name> $ docker cp latest.dump <db_container>:/latest.dump \$ docker exec -i <db_container> pg_restore --verbose --clean --no-acl --no-owner -U postgres -d <local_db_name> /latest.dump
For local db (i.e using pgAdmin4)
$ rm latest.dump $ heroku pg:backups:capture -a <app_name> $ heroku pg:backups:download -a <app_name> $ pg_restore --verbose --clean --no-acl --no-owner -h localhost -U postgres -d <local_db_name> latest.dump
#
App performanceWorker Dynos, Background jobs and Queueing
RabbitMQ and Celery configuration
Set
CELERY_RESULT_BACKEND = None
andBROKER_POOL_LIMIT = 1
If a
Error R14 (Memory quota exceeded)
is returned, just upgrade the worker's dynos planEnable HTTP cache headers
Use AWS S3 to store static assets and file uploads
Optimize Dyno usage
- Use a concurrent web server
- Set up instrumentation to measure the impact of load on the application
- Observe the application’s performance, and adjust the concurrency as necessary
#
Recommended Features- Add a custom domain
- Provision Heroku Postgres
- Create a Team
- Create a pipeline
- Setup a Heroku CI
- Use WebSocket protocol
#
Debugging- Logging : runtime logs (app, system, API and add-on) & build logs
- Heroku error codes
- Application metrics
- Production check : Dyno redundancy, DNS & SSL, Heroku Postgres, visibility & monitoring