DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk6 min

How to Deploy a MERN App on EC2 with a Safer Setup

A practical blueprint for deploying a MERN app on EC2 with Compose, Terraform, and GitHub Actions—while handling production configuration, credentials, and state safely.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Deploying a MERN app on EC2 with Docker Compose, Terraform, and GitHub Actions is a single-server deployment pattern: Terraform provisions the infrastructure, Compose runs the application services, and GitHub Actions can automate tests and deployment. The right configuration depends on details a generic guide cannot safely assume—especially where MongoDB lives, which ports your app uses, and how the frontend is served. Decide and document those before applying infrastructure or opening network access.

How the deployment pieces fit together

Docker describes a single server as the easiest way to deploy an application with Compose. That is a useful starting model, not a guarantee of availability, capacity, or suitability for every production workload. In this pattern, EC2 is the host, Docker Compose defines the application services on that host, Terraform manages the AWS infrastructure, and GitHub Actions automates the workflow.

As an Amazon Associate I earn from qualifying purchases.

Before writing deployment configuration, map the actual application:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • React: establish whether the frontend is built into a production image or served another way, and which service receives external traffic.
  • Express and Node.js: identify the API service, its listening port, and how it connects to MongoDB.
  • MongoDB: choose whether it runs in Compose, on another host, or as a managed database. The choice affects networking, persistence, backups, and which services can reach it.
  • Persistent data: identify what must survive container replacement and where it is stored. Do not assume a container’s writable layer is durable storage.

Those are application-specific decisions, not defaults established by the single-server deployment model. Likewise, a working deployment cannot be inferred from a diagram or a generic workflow: verify the configuration, security boundaries, and results for your own project.

Separate production Compose configuration

Docker recommends separating production settings from the base Compose configuration, commonly by using a production override. Development settings often differ: production may need to remove source-code bind mounts, set different environment variables, choose host-port bindings, apply a restart policy, or add supporting services. Keep the production changes explicit so developers can understand which behavior differs and why.

Review the effective production configuration against the topology you documented. Confirm that each service uses the intended image or build, that only the required ports are exposed, and that credentials are supplied securely rather than committed in Compose files or repository examples. Define how MongoDB data persists if the database runs in Compose; if it does not, document the actual connection and access path instead.

Compose on one EC2 host keeps the deployment model comparatively simple, but all services placed there share that host’s operational boundary. The approach does not, by itself, provide multi-host orchestration, a scaling policy, or an availability guarantee.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Provision EC2 and manage Terraform state

Use Terraform to describe the infrastructure your application actually needs. Record the selected AWS region and network assumptions, and avoid implying a particular subnet, address, domain, TLS terminator, or set of AWS resources unless your implementation defines them.

For shared automation, use a remote Terraform backend rather than treating a developer’s local state file as the deployment record. With the S3 backend, configure the bucket and state key for your project, enable bucket versioning to aid recovery, and protect access to the state. Terraform state can contain sensitive values, so access to the bucket and its history matters.

For Terraform 1.10.0 or later, the S3 backend supports native state locking when configured with use_lockfile = true. HashiCorp marks DynamoDB-based locking as deprecated; do not present it as the current preferred setup. Confirm the Terraform version used by both local operators and automation before relying on native locking.

Do not hardcode AWS credentials in Terraform configuration or backend arguments. HashiCorp warns that credentials provided through backend configuration can be written into the .terraform directory and plan files. Use a suitable credential mechanism for the environment running Terraform, and restrict who or what can access state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Limit network access and choose an administration path

Set EC2 security group rules to the minimum traffic the application and its operators need. Derive the allowed application ports from the real service topology; do not open a port simply because an example commonly uses it. Keep database access limited to the components that require it.

AWS identifies Systems Manager Session Manager as an option for remote instance management without opening inbound SSH or managing SSH key pairs. If you choose SSH instead, protect the private key and never commit it to the application repository. A person who obtains that key may be able to connect to instances associated with it.

Keep the credentials for managing EC2 distinct from those used by CI. When Terraform runs on EC2, AWS recommends using an IAM role attached through an instance profile to provide temporary credentials rather than storing long-lived keys on the instance. When Terraform or deployment runs in GitHub-hosted Actions, use a separate federation and permissions design.

Give GitHub Actions AWS access through OIDC

GitHub Actions can request an OpenID Connect token and exchange it for AWS credentials, avoiding long-lived AWS access keys stored as GitHub secrets. Set id-token: write at the workflow or job scope that needs to request the token. That permission allows token issuance; it does not grant permission to change AWS resources. The assumed IAM role’s permissions determine what the workflow can do.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Restrict the IAM role trust policy’s subject condition so only the intended repository and branch, tag, or GitHub environment can assume the role. If the workflow uses a GitHub environment, the subject refers to that environment; use environment protection rules to limit which branches or tags may deploy.

There is an important date-sensitive detail: GitHub’s OIDC subject format is changing for repositories created after July 15, 2026, and for repositories that opt into immutable subject claims. Before copying a trust-policy condition, inspect the actual subject claim format for your repository and make the IAM condition match it. An older example may not match a newer repository’s claim.

Build a workflow that reflects the real deployment

Make the workflow’s steps describe what your project actually does. A typical sequence to consider is checkout, tests, image build, registry push if your design uses a registry, and deployment to EC2. These are possible stages, not a verified pipeline for every MERN app. Choose and document the actual image source and remote deployment mechanism rather than presenting an untested generic workflow as a working implementation.

Keep workflow permissions narrow and grant the AWS role only the access required for its job. Separate infrastructure changes from application releases if that better matches your review and approval process; regardless of the workflow shape, its AWS trust and permissions should align with the repository and deployment target.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Redeploy a changed service correctly

When application code changes, rebuilding an image and recreating its service is different from merely restarting the existing container. Docker’s production guidance gives this example for a service named web:

  1. docker compose build web
  2. docker compose up --no-deps -d web

Replace web with the service name in your Compose configuration. The --no-deps option avoids recreating dependencies as part of this command; decide whether that is appropriate for your change and service relationships. Confirm that the replacement container is running the intended image and that the application behaves as expected.

Choose the deployment model for its trade-offs

A single EC2 host with Compose gives you direct control over the server and a compact way to run related containers. In exchange, you are responsible for host administration and for designing the deployment, access controls, persistence, and recovery around that host. A larger orchestration setup or managed platform changes those operational responsibilities and usually introduces additional resources and configuration. The available official guidance does not establish a fair price, throughput, or availability comparison, so choose based on your requirements rather than an unsupported performance claim.

Terraform’s S3 backend is one way to keep shared infrastructure state remotely; HCP Terraform is another managed-workflow option, not a requirement for an EC2-and-Compose deployment. Whichever approach you choose, make the state location, access boundaries, and credential flow explicit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.