Cloud Integration & Deployment (Heroku/AWS)

Chapter 3
Heroku Platform Deployment

Bachelors Program in Full Stack Development
Cloud Integration & Deployment (Heroku/AWS)   •   Bachelor

Heroku Platform Deployment

Introduction

Heroku is a platform as a service (PaaS) that converts application source code into managed, executable releases. Developers concentrate on application code and configuration, while the platform manages build infrastructure, process isolation, routing, basic load distribution, release history, logs, certificates, and integrations with backing services.

This abstraction makes Heroku especially useful for web applications, APIs, prototypes, teaching, and teams that prefer rapid delivery over low-level infrastructure control. It does not eliminate operational responsibility. Developers must still design stateless processes, protect secrets, operate databases responsibly, monitor performance, and choose an appropriate scaling strategy.

Heroku product names, supported runtimes, plan availability, limits, and prices change over time. Production decisions should therefore be checked against current official documentation.

Learning Objectives

After completing this chapter, students should be able to:

  1. Explain Heroku’s PaaS abstractions and deployment lifecycle.
  2. Deploy an application through a Git-based workflow.
  3. Configure buildpacks, process types, dynos, and release-phase tasks.
  4. Manage configuration variables and add-ons securely.
  5. Use pipelines, review apps, releases, and rollback mechanisms.
  6. Interpret runtime logs and distinguish them from build output.
  7. Configure custom domains and TLS certificates.
  8. Compare horizontal scaling, dyno-size scaling, and supported autoscaling.
  9. Analyze Heroku’s limitations and identify suitable use cases.

1. Heroku as a Platform as a Service

Traditional infrastructure as a service exposes virtual machines, networks, disks, and operating-system administration. A PaaS instead provides a higher-level execution contract. In Heroku, the principal abstractions are:

AbstractionPurpose
AppAdministrative container for code, configuration, resources, domains, and releases
BuildpackDetects, compiles, and prepares source code for execution
Slug or build artifactImmutable packaged application produced by a successful build
ReleaseVersioned combination used to deploy an artifact with app-specific release state
DynoIsolated process execution unit
Process typeNamed command, such as web, worker, or release
Config varEnvironment-based application configuration
Add-onManaged service attached to an application
PipelineOrdered grouping of apps representing delivery stages

This model is closely related to twelve-factor application principles: one codebase, explicitly declared dependencies, environment-based configuration, attached backing services, disposable processes, and separate build, release, and run stages.

A major consequence is that the application must cooperate with the platform. For example, a web process must bind to the port supplied through the PORT environment variable rather than assuming a fixed port.

2. The Build–Release–Run Model

A deployment can be understood as three conceptually separate stages:

  1. Build: source code and dependencies are transformed into an executable artifact.
  2. Release: the artifact is associated with the target app’s configuration, and release-phase work may be performed.
  3. Run: declared process types execute in dynos.
Heroku build, release, and run workflow Git source commit Build buildpack dependencies artifact Release target app config release command versioned record web dynos HTTP requests worker dynos background jobs one-off dynos administration
Heroku build release and run workflow
Figure: Heroku build release and run workflow

Figure: Source code is built once, released with target-app configuration, and run through declared process types.

Separating these stages improves repeatability. An artifact should not be modified after building; environment-specific behavior belongs in configuration rather than source-code branches.

3. Git-Based Deployment

3.1 Preparing an Application

A deployable repository normally contains:

  • application source code;
  • a dependency manifest and lock file;
  • an appropriate runtime declaration where required;
  • process declarations;
  • database migrations;
  • automated tests;
  • no embedded production secrets.

A typical command-line workflow is:

git init
git add .
git commit -m "Prepare application for deployment"
heroku create example-api
git push heroku main

The final command sends the selected Git branch to the app’s Heroku Git remote. A platform build begins after the push. GitHub-based deployment integrations can alternatively build selected branches or merged pull requests. The exact integration options available depend on the current platform offering.

A successful Git push is not by itself evidence of a healthy application. Teams should also verify build output, release status, process state, health endpoints, and application behavior.

3.2 Buildpacks

A buildpack is executable build logic that identifies a compatible project and transforms its source into a runnable artifact. For a Node.js application, for example, detection may depend on package.json; the build then installs declared dependencies and prepares launch commands.

Heroku supports platform-maintained and third-party buildpacks, while contemporary build systems may use Cloud Native Buildpack concepts. Multiple buildpacks can be applied when an application needs more than one toolchain, but their order matters because earlier outputs may affect later steps.

Good build discipline includes:

  • committing dependency lock files;
  • pinning supported runtime versions where practical;
  • avoiding downloads from untrusted sources;
  • reviewing third-party buildpack code and maintenance status;
  • keeping build output reproducible;
  • excluding unnecessary files to reduce build time and artifact size.

Build caches can accelerate later builds, but a cache is not the deployed artifact and must not be treated as authoritative storage.

4. Process Types and Dynos

4.1 The Procfile

A Procfile maps process-type names to commands:

web: node server.js
worker: node worker.js
release: npm run migrate

The web process type receives routed HTTP traffic. A worker commonly consumes queued background tasks. The release process is not a continuously scaled service; its command runs during release creation before the new release is made current. If it fails, the new release is not promoted to active execution.

Migration commands should be backward-compatible when old and new application processes may briefly overlap. Destructive schema changes are safer when divided into expand-and-contract stages.

4.2 Dyno Properties

A dyno is an isolated execution unit that runs one command from a process type. Dynos are disposable: the platform may restart, replace, or relocate them. Consequently:

  • local filesystems are ephemeral;
  • user uploads should go to durable object storage;
  • sessions should use a shared store or signed client-side mechanism;
  • workers must tolerate interruption;
  • long-running jobs should be idempotent or checkpointed.

A process should also handle termination signals and stop within the platform’s shutdown interval. Ignoring graceful shutdown can interrupt requests or leave jobs partly processed.

One-off dynos execute administrative commands against the current release, for example:

heroku run node scripts/reconcile.js

They are suitable for controlled administration, not permanent background services.

5. Configuration Variables and Secrets

Config vars are app-specific key–value pairs exposed to processes as environment variables:

heroku config:set NODE_ENV=production
heroku config:set API_BASE_URL=https://api.example.org

Applications should read these values at runtime. Configuration should not be compiled into source code or committed to Git.

Config vars frequently contain credentials and therefore require governance. Appropriate controls include least-privilege access, credential rotation, audit review, environment separation, and prevention of secret values appearing in logs. Highly regulated workloads may require an external secrets manager, stronger rotation facilities, or controls beyond the platform’s standard config mechanism.

Changing a config var creates a new release and typically restarts affected processes. A malformed value can therefore cause an outage even when the source artifact is unchanged.

Development, staging, and production apps must have independent configuration. Copying production secrets into lower environments increases the impact of a compromise.

6. Add-Ons and Backing Services

Add-ons provide managed capabilities such as relational databases, caches, monitoring, message queues, email delivery, and error tracking. Provisioning an add-on generally creates attachment configuration, often represented by a URL stored in a config var.

heroku addons:create <service-plan>

The exact service and plan identifiers vary. Application code should treat the service as an attached resource and obtain its location and credentials from configuration.

Operational responsibility remains shared. Teams must understand:

  • backup and restoration procedures;
  • maintenance windows;
  • region and data-residency constraints;
  • encryption and access controls;
  • connection limits;
  • service-level objectives;
  • plan upgrade and deprovisioning consequences.

Removing an add-on can destroy data. Production changes should therefore use change approval, verified backups, and explicit ownership.

7. Releases and Safe Rollback

Heroku records deployment and configuration changes as numbered releases. Useful commands include:

heroku releases
heroku releases:info v42
heroku rollback v41

A rollback creates a new release based on a selected prior release rather than deleting history. Rollback is valuable when a new application version is defective, but it is not equivalent to restoring a database. If the failed version performed an incompatible data migration, restoring an earlier artifact may not restore compatibility.

Safe release engineering therefore includes:

  1. automated tests before deployment;
  2. backward-compatible schema evolution;
  3. a release-phase migration strategy;
  4. post-deployment health checks;
  5. monitoring and rollback criteria;
  6. database backup and recovery procedures.

8. Pipelines, Promotion, and Review Apps

A pipeline groups apps into stages such as review, development, staging, and production. It represents promotion flow, not a shared runtime environment.

The central semantic rule is critical: pipeline promotion transfers the already-built slug or equivalent build artifact to downstream apps. It does not copy the source app’s config vars, secrets, add-ons, domains, or other environment-specific configuration. Each target app retains its own configuration and resources, and creates a release using the promoted artifact with that target environment.

This behavior provides artifact consistency: the code tested in staging can be the same code executed in production. It also means operators must verify production configuration independently. Assuming that promotion transfers staging configuration could lead to missing secrets, wrong service endpoints, or unsafe credentials.

Review apps are temporary applications associated with proposed changes, commonly pull requests. They let reviewers test code in an isolated deployed environment. Automated setup can specify buildpacks, add-ons, config requirements, and post-deployment scripts.

Review-app governance is important because temporary environments can:

  • incur cost;
  • expose test data publicly;
  • consume limited resources;
  • remain active after review;
  • execute untrusted contribution code.

Use synthetic or sanitized data, restrict access where appropriate, minimize credentials, and automate cleanup.

9. Scaling and Capacity Analysis

9.1 Three Distinct Scaling Mechanisms

Heroku scaling decisions should distinguish:

  1. Manual horizontal scaling: changing the number of dynos in a process formation, such as increasing web from two to four dynos.
  2. Dyno-size or vertical scaling: selecting a dyno type with different CPU, memory, performance, isolation, or pricing characteristics.
  3. Supported autoscaling: allowing eligible web formations and plans to vary their dyno count automatically according to platform-supported metrics and configured bounds. Eligibility and available metrics depend on current dyno type, app characteristics, and platform features.

Manual horizontal scaling can be expressed as:

heroku ps:scale web=4 worker=2

Horizontal scaling requires stateless request handling because any request may reach any web dyno. Vertical scaling may help memory-intensive or single-process workloads but cannot compensate for fundamentally unbounded memory growth. Autoscaling is not universal and should not be assumed available for every process type or plan. Background workers are commonly scaled through queue-depth monitoring and operational automation rather than web-response-time autoscaling.

9.2 A Simplified Concurrency Model

Under steady-state conditions, Little’s Law estimates the mean number of requests in service:

L = λW

where:

  • L is mean concurrent work, measured in requests;
  • λ is mean arrival rate, measured in requests per second;
  • W is mean time in the system, measured in seconds per request.

The units are consistent: requests/s × s/request = requests. Little’s Law requires a stable system over the observation interval and does not, by itself, represent burstiness or latency-tail behavior.

If each dyno safely supports C concurrent requests and the desired maximum utilization fraction is ρ, a planning estimate is:

N = ⌈L ÷ (Cρ)⌉

where N is the estimated number of dynos and 0 < ρ < 1. This is a simplified capacity estimate, not a Heroku routing formula. It assumes comparable dynos, reasonably balanced requests, stable average demand, and a measured safe concurrency limit.

Worked Example: Estimating a Web Formation

An API receives an average of 120 requests/s. Mean request time under representative load is 0.25 s. Load testing indicates that one chosen dyno size safely handles 12 concurrent requests. The team targets at most 70% of that tested concurrency.

First calculate mean concurrent work:

L = 120 requests/s × 0.25 s/request = 30 requests

Effective planned concurrency per dyno is:

Cρ = 12 × 0.70 = 8.4 requests

Therefore:

N = ⌈30 ÷ 8.4⌉ = ⌈3.571...⌉ = 4 dynos

The preliminary formation is four web dynos. The result must be validated with burst tests, memory measurements, downstream database limits, error rates, and percentile latency. Average values alone can hide saturation during traffic spikes.

9.3 Cost Model

For process types with hourly rates, an approximate monthly compute cost is:

Cost = ∑i=1k(ni × hi × ri)

where ni is the number of dynos of type i, hi is billable hours per dyno, and ri is price per dyno-hour. Add-ons, data transfer, support, taxes, and other charges must be added separately. Current platform prices should be used rather than values embedded in long-lived design documents.

10. Logs, Monitoring, and Diagnostics

Heroku runtime logging commonly aggregates streams from application processes, platform components, and certain attached services through its runtime log-routing facilities. Applications should write events to standard output or standard error rather than local log files.

Build output must be distinguished from runtime logs. Build logs are generated by the build system and surfaced through build output, deployment integrations, dashboards, or related tooling; they are not necessarily delivered through the same runtime log aggregation path. A developer troubleshooting dependency installation should inspect the build record, whereas a developer troubleshooting a live HTTP failure should inspect runtime application and router logs.

Useful runtime commands include:

heroku logs --tail
heroku logs --source app
heroku ps

A production logging strategy should use structured events and capture, where lawful and appropriate:

  • timestamp;
  • severity;
  • request or correlation identifier;
  • event type;
  • duration;
  • outcome;
  • non-sensitive diagnostic context.

Logs are finite streams, not permanent archival storage. A logging add-on or external drain is normally required for retention, searching, dashboards, and alerts.

Logs must not contain passwords, access tokens, complete payment data, or unnecessary personal information. Observability must be balanced against privacy and regulatory requirements.

11. Domains, DNS, and TLS

Every app receives a platform domain. A custom domain is added to the app, after which DNS is configured using the platform-provided DNS target. The precise record type depends on whether the name is a subdomain or apex domain and on DNS-provider capabilities.

A safe process is:

  1. add the domain to the correct app;
  2. obtain its platform DNS target;
  3. configure the required DNS record;
  4. wait for DNS propagation;
  5. verify routing and certificate status;
  6. redirect HTTP to HTTPS where appropriate;
  7. test certificate renewal monitoring and critical hostnames.

Managed certificate facilities can automate certificate issuance and renewal for supported configurations. Alternatives may be required for unusual certificate, proxy, wildcard, or enterprise key-management requirements.

TLS protects data in transit between the client and the termination point. It does not replace authentication, authorization, secure cookies, input validation, or encryption requirements for stored data.

12. Detailed Applied Case: Campus Placement Portal

Background

This is an illustrative case. Northbridge University develops a Node.js placement portal with a PostgreSQL database. Students submit applications, employers review candidates, and workers generate PDF summaries.

Problem

The original service runs on one manually administered server. Deployments cause downtime, uploaded files are stored locally, secrets are kept in a configuration file, and PDF generation delays web requests. The university wants staging, review environments, repeatable releases, and rapid rollback.

Analysis

The application is mostly stateless, but four concerns conflict with the dyno model:

  • uploaded résumés use the local filesystem;
  • session data is stored in process memory;
  • PDF generation runs synchronously;
  • a database migration removes columns immediately.

The team also handles personal information, requiring restricted access, retention controls, and auditable operational practices.

Approach and Solution

The team adopts the following design:

  1. A web process serves requests, while a worker consumes PDF jobs from a managed queue.
  2. Résumés move to encrypted object storage; only references are stored in PostgreSQL.
  3. Sessions move to a shared store with secure, short-lived cookies.
  4. Secrets become app-specific config vars with limited administrative access.
  5. A pipeline contains staging and production apps with separate databases and credentials.
  6. Review apps use synthetic records and restricted access.
  7. The release command applies backward-compatible migrations.
  8. Pipeline promotion transfers the tested artifact from staging to production; it does not transfer staging configuration. Production retains its own database URL, secrets, add-ons, domain, and scaling formation.
  9. Runtime logs are drained to a retained monitoring service, while failed dependency installations are investigated in build output.
  10. Custom domains use managed TLS, and alerts monitor errors, latency, queue depth, and database capacity.

The database migration follows expand-and-contract practice. A new nullable column is added first. Both old and new application versions can operate while data is backfilled. Only after all code stops using the old column is that column removed in a later release.

Outcome

Deployments become reproducible and normal releases avoid planned server downtime. Web latency improves because PDF generation moves to workers. Review apps improve stakeholder feedback. The design still requires operational work: queue-depth monitoring, restore testing, cost review, access audits, and incident response.

Learning Points

PaaS adoption succeeds when application architecture matches platform assumptions. Pipelines promote artifacts, not environment configuration. Ephemeral compute requires durable external storage, while safe rollback requires compatible data evolution rather than artifact history alone.

13. Limitations and Appropriate Use Cases

13.1 Strengths

Heroku is often appropriate for:

  • web applications and APIs;
  • prototypes and minimum viable products;
  • teaching and student projects;
  • small or medium teams with limited platform-engineering capacity;
  • event-driven workers and scheduled application tasks;
  • services that benefit from standardized deployment conventions.

Its principal advantages are rapid provisioning, low infrastructure-management burden, consistent deployment workflows, managed routing, ecosystem integration, and straightforward release history.

13.2 Limitations

Heroku may be less suitable when a workload requires:

  • extensive operating-system or kernel customization;
  • specialized hardware;
  • complex private-network topology;
  • permanent local storage;
  • unusual long-running network protocols;
  • strict control over every infrastructure component;
  • very large scale where unit economics justify a dedicated platform team;
  • regulatory controls not satisfied by available regions, contracts, or services.

Additional constraints include dyno memory limits, connection limits, request-time constraints, ephemeral filesystems, platform quotas, possible vendor lock-in, and costs that can exceed lower-level infrastructure at sustained scale.

The correct comparison is total cost of ownership, not compute price alone. Engineering labor, security patching, deployment automation, monitoring, incident response, and opportunity cost all matter.

14. Governance, Security, and Professional Practice

Deployment access is production access. Teams should use individual accounts, multifactor authentication where available, least-privilege roles, protected source branches, peer review, and auditable changes.

A mature delivery policy should include:

  • separation of development, staging, and production;
  • dependency and buildpack vulnerability review;
  • automated tests and security scanning;
  • approved release and rollback procedures;
  • secret rotation and incident revocation;
  • backup restoration exercises;
  • data classification and retention rules;
  • cost ownership and unused-resource cleanup;
  • service-provider and add-on risk assessment.

AI-assisted coding and operations tools may help interpret logs, draft configuration, or identify anomalies. Their output must be reviewed because generated deployment commands can be destructive, logs may contain sensitive data, and recommendations may rely on obsolete plan details. Secrets and regulated records should not be sent to an AI service without authorization and appropriate contractual controls.

15. Recommended Deployment Checklist

Before a production release, verify that:

  • the build is reproducible and dependencies are locked;
  • tests and security checks pass;
  • the web process binds to PORT;
  • state is stored in durable external services;
  • release tasks are backward-compatible and repeatable;
  • target-app config vars and add-ons are correct;
  • pipeline promotion uses the intended tested artifact;
  • health, latency, error, queue, and resource metrics are monitored;
  • runtime and build diagnostics are available in their appropriate locations;
  • domains and TLS are valid;
  • rollback and database recovery plans are understood;
  • access, privacy, and retention obligations are satisfied.

Chapter Summary

Heroku provides a PaaS abstraction in which source code is transformed by buildpacks into an immutable artifact, associated with app-specific configuration in a release, and executed by dynos. Process types separate web, worker, release, and administrative responsibilities. Config vars support environment-specific configuration, while add-ons provide managed backing services.

Pipelines enable staged delivery and artifact promotion. Promotion transfers the built artifact, not configuration variables, secrets, add-ons, domains, or scaling settings; each downstream app retains its own environment. Review apps support temporary validation but require cost, security, and data controls.

Scaling may involve manual horizontal formation changes, selection of a different dyno size, or supported autoscaling for eligible formations. Runtime logs and build logs serve different diagnostic purposes and are not necessarily delivered through the same aggregation mechanism. Effective production use also requires stateless design, durable data services, secure configuration, compatible migrations, observability, TLS, governance, and an informed assessment of platform constraints.

Key Terms

Add-on: A managed backing service attached to an application.

Autoscaling: Platform-supported automatic adjustment of eligible dyno counts within configured limits.

Buildpack: Build logic that detects and compiles an application into a runnable artifact.

Config var: An app-specific key–value configuration item exposed as an environment variable.

Dyno: An isolated unit that executes an application process.

Dyno formation: The numbers and types of dynos assigned to declared process types.

Ephemeral filesystem: Local storage whose contents are not durable across dyno replacement or restart.

Horizontal scaling: Increasing or decreasing the number of process instances.

Pipeline: An ordered group of apps representing delivery stages.

Process type: A named command such as web or worker.

Procfile: A file declaring application process types and their commands.

Release: A versioned deployment record associating an artifact with app-specific release state.

Release phase: A command executed before a new release becomes current.

Review app: A temporary deployed environment used to evaluate a proposed code change.

Rollback: Creation of a new release based on a selected earlier release.

Runtime log: An event emitted by application processes or runtime platform components.

Slug: A packaged, immutable application artifact produced by a build.

TLS: A protocol protecting network traffic in transit through encryption and endpoint authentication.

Vertical scaling: Moving a workload to a dyno size with different resource characteristics.

Review Questions

Short Answer Questions

  1. What is the purpose of a buildpack?
  2. Why should an application not store uploads on a dyno filesystem?
  3. What happens when a release-phase command fails?
  4. How do build logs differ from runtime logs?
  5. What must a web application do with the PORT environment variable?

Long Answer Questions

  1. Explain Heroku’s build–release–run model and the responsibilities associated with each stage.
  2. Discuss how process types and dynos support separation of web requests, background work, and administrative tasks.
  3. Explain how config vars and add-ons should be governed in a production environment.
  4. Compare Heroku with self-managed infrastructure in terms of control, operational burden, cost, and suitable workloads.
  5. Describe a secure Git-based deployment workflow from source review to production verification.

Analytical / Application Questions

  1. An application receives 200 requests/s with a mean service time of 0.18 s. Each dyno safely supports 15 concurrent requests, and planned utilization is 80%. Estimate the required dyno count using the chapter’s simplified model, then identify two reasons the estimate must be load-tested.
  2. A team promotes a staging artifact and expects staging database credentials to appear in production. Diagnose the misconception and design a safer configuration-verification procedure.
  3. A deployed application stores sessions and user files locally and performs video conversion inside web requests. Redesign it for Heroku’s dyno model, explaining the required backing services and process types.

Multiple Choice Questions with Answers

Question 1

Which item is transferred to a downstream app during Heroku pipeline promotion?

A. The source app’s config vars

B. The built slug or equivalent artifact

C. The source app’s add-ons

D. The source app’s custom domains

Correct Answer: B. The built slug or equivalent artifact

Question 2

Why should user uploads not be stored permanently on a dyno filesystem?

A. Dyno filesystems are ephemeral

B. Dynos cannot create files

C. Only buildpacks can read files

D. TLS prohibits local storage

Correct Answer: A. Dyno filesystems are ephemeral

Question 3

Which process type normally receives routed HTTP traffic?

A. release

B. worker

C. web

D. build

Correct Answer: C. web

Question 4

What is the expected result if a release-phase command fails?

A. The new release is prevented from becoming current

B. All earlier releases are deleted

C. The production database is automatically restored

D. The failed command becomes a worker process

Correct Answer: A. The new release is prevented from becoming current

Question 5

Which statement correctly distinguishes build and runtime diagnostics?

A. Both are always delivered through exactly the same aggregation path

B. Build output concerns artifact creation, while runtime logs concern executing processes and platform events

C. Runtime logs are available only during Git pushes

D. Build logs are generated only by web dynos

Correct Answer: B. Build output concerns artifact creation, while runtime logs concern executing processes and platform events

Question 6

Which action is an example of manual horizontal scaling?

A. Changing from a smaller to a larger dyno size

B. Increasing the web formation from two dynos to four

C. Adding more memory to an existing dyno process

D. Changing a custom domain’s DNS record

Correct Answer: B. Increasing the web formation from two dynos to four

Question 7

An API receives 100 requests/s and has a mean request time of 0.20 s. According to Little’s Law, what is the mean concurrent work?

A. 5 requests

B. 20 requests

C. 100 requests

D. 500 requests

Correct Answer: B. 20 requests

Question 8

What is the primary purpose of a config var?

A. To store environment-specific configuration outside source code

B. To preserve files across dyno replacement

C. To define DNS propagation time

D. To archive runtime logs permanently

Correct Answer: A. To store environment-specific configuration outside source code

Question 9

Which design best supports safe database evolution when old and new application versions may overlap?

A. Delete old columns before deploying new code

B. Use an expand-and-contract migration strategy

C. Store migrations on the dyno filesystem

D. Copy staging credentials into production

Correct Answer: B. Use an expand-and-contract migration strategy

Question 10

Which workload is least compatible with Heroku’s standard dyno model?

A. A stateless REST API using a managed database

B. A worker consuming jobs from a managed queue

C. An application requiring permanent local filesystem storage

D. A web service storing uploads in object storage

Correct Answer: C. An application requiring permanent local filesystem storage

Cloud Integration & Deployment (Heroku/AWS)
Chapter 3 of 14