Deploy a Next.js App to AWS Amplify

Deploy a full-stack Next.js 14 app to AWS Amplify with CI/CD and SSR.

Introduction

30 Second Summary

You have built a full-stack application that works perfectly on your local machine. For the people who need SafeConnect Rwanda, that is not enough. They need to reach it from any browser, anywhere.

In this project, you will deploy your Next.js 14 application to AWS Amplify Hosting. You will connect your GitHub repository, configure environment variables, and get a live HTTPS URL with automatic redeployments on every push.

What You'll Build

A production deployment of SafeConnect Rwanda on AWS Amplify with CI/CD from GitHub, Prisma database migrations, and full server-side rendering support.

By the end of this project, you'll have:

  • An AWS Amplify app connected to your GitHub repository with automatic CI/CD deployments on every push to master.
  • A custom build specification handling Prisma client generation and database migrations against your Supabase database.
  • Securely configured environment variables and a live production URL with HTTPS and CDN support.
  • Secret Mission: Connect a custom domain to your Amplify app so users access SafeConnect Rwanda at your own URL.

Are there any prerequisites?

This project assumes you already have an AWS account, a GitHub repository containing your Next.js 14 app, and a Supabase PostgreSQL database with your connection credentials.

You also need your local .env file with DATABASE_URL, NEXTAUTH_SECRET, NEXTAUTH_URL, and CONTACT_ENCRYPTION_KEY ready to paste into the Amplify console.

Connect Your GitHub Repository to Amplify

SafeConnect Rwanda is a full-stack Next.js application that currently lives in your GitHub repository. To make it accessible to real users, you need to deploy it to a hosting service that supports server-side rendering, API routes, and automatic HTTPS.

AWS Amplify Hosting is purpose-built for Next.js deployments. In this step, you'll connect your GitHub repository to Amplify so it knows where to pull your code from.

What is AWS Amplify Hosting?

AWS Amplify Hosting is a fully managed AWS service that deploys and hosts web applications. It provides a global CDN, automatic HTTPS certificates, and managed compute for server-side rendering.

For Next.js apps, it handles SSR, API routes, middleware, and internationalization without you managing any servers. Every push to your connected branch triggers an automatic rebuild and deploy.

In this step, get ready to:
  • Sign in to the AWS Management Console and open the Amplify console.
  • Connect your GitHub repository to a new Amplify app.
  • Create an IAM service role so Amplify can deploy your app.
Open the Amplify console
  • Sign in to the AWS Management Console at https://console.aws.amazon.com.
  • In the search bar at the top of the page, type Amplify and select AWS Amplify from the results.
  • On the All apps page, click Create new app.
Connect your GitHub repository

Amplify needs access to your GitHub repository so it can pull your source code for every build. You will authorize it through the Amplify GitHub App.

  • On the Start building with Amplify page, select GitHub as your Git provider.
  • Click Next.
  • GitHub opens a new page asking you to authorize AWS Amplify to access your account. Grant the requested permissions and install the Amplify GitHub App.
  • You are redirected back to the Amplify console. In the Recently updated repositories list, select techservices-munezrohill/mytools.
  • For Branch, select master.
  • Click Next.

Not seeing your repository?

  • Make sure you authorized Amplify to access the correct GitHub account. If you have multiple accounts, the Amplify GitHub App may have been installed on the wrong one.
  • During authorization, select Only select repositories and confirm techservices-munezrohill/mytools is included in the list.
  • Why can't Amplify see my GitHub repository?
Create a service role

Amplify needs an IAM service role to deploy your SSR app. This role gives Amplify permission to create and manage AWS resources on your behalf during the build and deployment process.

  • On the App settings page, find the service role section.
  • Select Create and use a new service role.
  • Amplify creates and assigns the role automatically. You do not need to configure anything else here.

What is an IAM service role?

An IAM service role is a set of permissions that allows an AWS service to act on your behalf. In this case, the role lets Amplify provision compute resources, manage your deployment artifacts, and connect to other AWS services needed to run your Next.js SSR application.

Do not click Save and deploy yet

You are not ready to deploy. The build settings and environment variables still need to be configured in the next two steps. Stay on the App settings page and proceed to Step 2.

Your GitHub repository is connected and Amplify knows where to find your code. Next, you'll configure a custom build specification so Amplify knows how to build your Next.js app with Prisma migrations.

Configure the Build Specification

Your GitHub repository is connected and AWS Amplify has a service role ready to deploy on your behalf. Now Amplify needs to know how to build your app.

A standard Next.js build won't work here because your app uses Prisma ORM, which needs extra steps before the build can run. In this step, you'll write a custom build specification that handles Prisma setup and environment variable injection.

In this step, get ready to:
  • Understand why a custom build specification is needed.
  • Enter the custom amplify.yml build spec into the Amplify editor.
  • Verify the key build phases are correct.
Understand why you need a custom build spec

Your app uses Prisma ORM to talk to your Supabase PostgreSQL database. Prisma requires two extra commands before a Next.js build can succeed.

  • npx prisma generate creates the Prisma client library that your app imports to query the database.
  • npx prisma migrate deploy applies any pending database schema changes to your Supabase instance.

There's a second problem too. Amplify makes your environment variables available during the build, but the Next.js SSR runtime does NOT automatically receive them after deployment.

Why inject env vars into .env.production?

When your Next.js app runs server-side code after deployment (API routes, middleware, SSR pages), it looks for variables in a .env.production file. Amplify's build container has those variables, but won't pass them to the runtime automatically.

The documented solution is to write them into .env.production during the build phase using env | grep. This bundles the variables into the deployment artifact so the SSR runtime can read them.

Edit the build settings
  • On the App settings page, scroll down to the Build settings section.
  • Click Edit on the build specification.
  • Select all the existing content in the editor and delete it.
  • Paste the following custom amplify.yml configuration into the editor:
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
        - npx prisma generate
        - npx prisma migrate deploy
    build:
      commands:
        - env | grep -e DATABASE_URL -e NEXTAUTH_SECRET -e NEXTAUTH_URL -e CONTACT_ENCRYPTION_KEY >> .env.production
        - env | grep -e NEXT_PUBLIC_ >> .env.production
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*
      - .next/cache/**/*

What does this build spec do?

This spec tells Amplify exactly how to build your app in three phases:

  • preBuild installs dependencies (npm ci), generates the Prisma client, and applies database migrations to Supabase.
  • build writes your server-side environment variables into .env.production so the SSR runtime can access them, then runs npm run build to compile your Next.js app.
  • artifacts tells Amplify that the compiled output lives in the .next directory.
  • cache stores node_modules and the Next.js build cache between deployments so future builds are faster.

✔️ Awesome, I've got everything!

Great. Double check the YAML is pasted correctly in the Amplify editor before moving on.

ⓧ I'd like to double check the full code

Here's the complete amplify.yml build spec. Make sure your editor matches this exactly:

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
        - npx prisma generate
        - npx prisma migrate deploy
    build:
      commands:
        - env | grep -e DATABASE_URL -e NEXTAUTH_SECRET -e NEXTAUTH_URL -e CONTACT_ENCRYPTION_KEY >> .env.production
        - env | grep -e NEXT_PUBLIC_ >> .env.production
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*
      - .next/cache/**/*
Verify the key elements

Before moving on, scan through your build spec in the editor and confirm these key elements are present.

  • Confirm that npx prisma generate and npx prisma migrate deploy appear in the preBuild phase.
  • Confirm the two env | grep lines write your server-side variables to .env.production in the build phase.
  • Confirm baseDirectory: .next appears in the artifacts section.
  • Confirm both node_modules/**/* and .next/cache/**/* appear in the cache paths.

Build spec editor not showing?

  • Make sure you're still on the App settings page from Step 1. If you navigated away, go back to the Amplify console and find your in-progress app.
  • Look for the Build settings section. If you see a collapsed panel, expand it before clicking Edit.
  • If your YAML looks garbled after pasting, check that indentation uses spaces (not tabs). YAML is whitespace-sensitive.

Why isn't my Amplify build spec saving correctly?

Your build spec is locked in. Next up, you'll add the environment variables that this spec references so Prisma can connect to Supabase and NextAuth can secure your admin panel.

Set Up Environment Variables

Your build specification is ready, but it references environment variables that do not exist yet. The env | grep commands in your build phase will write empty values to .env.production unless you configure the actual variables in the Amplify console.

In this step, you will add each environment variable that your Next.js app needs at runtime. This includes your database connection string, authentication secrets, and a special Prisma binary target for the Amplify build environment.

In this step, get ready to:
  • Add your four application environment variables (database, auth, encryption).
  • Add the Prisma binary target for the Amplify build container.
  • Deploy your app by clicking Save and deploy.
Add your application environment variables

Your app needs four secrets to function: a database connection string, an authentication secret, a production URL for NextAuth, and an encryption key. You will add each one to the Amplify console so the build process can inject them into the SSR runtime.

  • On the App settings page (you should still be on it from the previous step), scroll down to the Environment variables section.
  • Click Add new to add your first variable.
  • For Variable, enter DATABASE_URL. For Value, paste your Supabase connection string from your local .env file.
  • Click Add new again. For Variable, enter NEXTAUTH_SECRET. For Value, paste your NextAuth secret from your local .env file.
  • Click Add new again. For Variable, enter NEXTAUTH_URL. For Value, enter https://placeholder.amplifyapp.com as a temporary value.
  • Click Add new one more time. For Variable, enter CONTACT_ENCRYPTION_KEY. For Value, paste your AES-256-GCM key from your local .env file.

Why is NEXTAUTH_URL a placeholder?

NextAuth requires a NEXTAUTH_URL that matches your production domain exactly. You do not know your Amplify URL yet because the app has not been deployed.

You will come back and update this to the real URL after your first successful deploy in the next step.

Why are environment variables encrypted?

All environment variables that you add are encrypted to prevent rogue access. The values are only exposed inside the build container during deployment and written into the deployment artifact via your build spec's env | grep commands.

Add the Prisma binary target

Amplify's build container runs Amazon Linux, which needs a specific Prisma binary to compile the database client correctly. Without this variable, Prisma will generate a binary that does not match the server's operating system.

  • Click Add new to add one more variable.
  • For Variable, enter PRISMA_CLI_BINARY_TARGETS.
  • For Value, enter native,rhel-openssl-3.0.x.

What does this binary target do?

The native target tells Prisma to compile for the current machine (the build container). The rhel-openssl-3.0.x target ensures Prisma also generates a binary compatible with the Amazon Linux runtime that serves your SSR app after deployment.

Review and deploy your app

You have configured all five environment variables. It is time to submit your app for its first build.

  • Confirm you see all five variables listed: DATABASE_URL, NEXTAUTH_SECRET, NEXTAUTH_URL, CONTACT_ENCRYPTION_KEY, and PRISMA_CLI_BINARY_TARGETS.
  • Click Next to proceed to the review page.
  • On the review page, verify your repository, branch, build settings, and environment variables all look correct.
  • Click Save and deploy.

Amplify will start your first build immediately. You should see the build pipeline appear with stages like Provision, Build, Deploy, and Verify.

Don't see your environment variables listed?

Double-check that you clicked Add new for each variable separately. Each variable needs its own row with both the Variable name and Value filled in.

Also verify that none of your variable names start with AWS as a prefix. That prefix is reserved by Amplify and will be rejected.

help me troubleshoot my Amplify environment variables

Your first build is now running. Next up, you will monitor the build progress, grab your real production URL, and update NEXTAUTH_URL so authentication works correctly.

Monitor Your First Build and Fix NEXTAUTH_URL

Your environment variables are saved and Amplify has started building your app for the first time.

In this step, you will watch the build pipeline complete, grab your live production URL, and then update the NEXTAUTH_URL placeholder with the real address so NextAuth authentication works correctly in production.

In this step, get ready to:
  • Monitor the build pipeline and confirm a successful deployment.
  • Get your live production URL.
  • Update NEXTAUTH_URL to the real Amplify URL and trigger a second build.
Watch the build progress

Amplify runs your deployment through a multi-stage pipeline. Each stage handles a different part of getting your app live.

  • Return to the Amplify console. You should see your app's build in progress with stages displayed: Provision, Build, Deploy, and Verify.
  • Click into the build to open the real-time logs.
  • Watch for the Build stage specifically. In the logs, you will see your amplify.yml commands running: npm ci installs dependencies, npx prisma generate creates the Prisma client, npx prisma migrate deploy applies database migrations to Supabase, and npm run build compiles the Next.js app.
  • Wait for all four stages to show green checkmarks. This first build typically takes 3-5 minutes.

What are these build stages?

Amplify's pipeline has four stages for your app. Provision spins up a Docker-based build environment. Build clones your repo and runs the commands from your amplify.yml (preBuild, then build).

Deploy uploads your build artifacts and provisions the SSR compute. Verify checks that your app renders correctly at the deployed URL.

Build failed with a red X?

Click into the failed stage to read the error log. The most common issues at this point are:

  • Prisma migration error: your DATABASE_URL environment variable may have a typo. Double check it matches your Supabase connection string exactly.
  • Build command failure: if npm run build fails, the error is likely in your app code, not Amplify. Read the log output for the specific TypeScript or Next.js error.
  • Help me debug my failed Amplify build.
Get your production URL

Once all four stages show green checkmarks, your app is live on the internet with HTTPS automatically configured.

  • Look for the generated URL displayed on the build summary page. It follows the format https://master.d<id>.amplifyapp.com where <id> is a unique identifier for your app.
  • Click the URL to open your live app in a new tab.
  • Copy this URL and save it somewhere (a text file or sticky note). You will need it in the next substep.

Why does this URL use HTTPS?

AWS Amplify automatically provisions a free public SSL certificate for every deployed app. You do not need to configure HTTPS yourself. The certificate is managed by AWS Certificate Manager at no additional cost.

Update NEXTAUTH_URL to your real Amplify URL

Right now, NEXTAUTH_URL is set to https://placeholder.amplifyapp.com which means NextAuth cannot validate callback URLs correctly. You need to replace it with the real URL you just obtained.

  • In the left sidebar of the Amplify console, click Hosting, then click Environment variables.
  • Click Manage variables.
  • Find NEXTAUTH_URL in the list.
  • Replace the value https://placeholder.amplifyapp.com with your actual Amplify URL (the one you copied in the previous substep).
  • Click Save.

Saving the updated variable triggers a new build automatically. Wait for this second build to complete with green checkmarks.

Why does changing a variable trigger a rebuild?

Your amplify.yml build spec writes environment variables into .env.production at build time. The old build still has the placeholder baked in. Amplify triggers a fresh build so the new NEXTAUTH_URL value gets written into the deployment artifact.

Second build taking too long?

Subsequent builds are often faster because Amplify caches node_modules and .next/cache from the first build. If it still takes more than 5 minutes, click into the logs to check for errors.

Help me figure out why my second build is slow.

Your app is now fully deployed with the correct NEXTAUTH_URL. Next up, you will verify that every part of SafeConnect Rwanda works in production.

Verify Your Live App

Your build is green and your NEXTAUTH_URL is pointing to the real production URL. A successful build means the code compiled without errors. It does not guarantee that SSR, database connections, and authentication all work together in production.

In this step, you will verify that SafeConnect Rwanda is fully functional end-to-end. You will test the public homepage, log into the admin panel to confirm the database connection, and trigger an automatic deployment to prove your CI/CD pipeline works.

In this step, get ready to:
  • Test the public-facing homepage loads with all features working.
  • Verify the admin panel, authentication, and database connection.
  • Confirm automatic deployments trigger on every push to master.
Test the public-facing app

The first thing to check is whether your homepage renders correctly for any visitor. This confirms that Next.js SSR is working and that static assets are being served through the CDN.

  • Open a new browser tab.
  • Paste your Amplify production URL into the address bar (it looks like https://master.d1234abcdef.amplifyapp.com) and press Enter.
  • Verify you see the SafeConnect Rwanda homepage with the neutral "MyTools" branding.
  • Confirm the Quick Exit button is visible and functional.
  • Check that the PWA install prompt appears correctly.

What should I see?

Your homepage should load with full styling, the neutral MyTools branding (not a development placeholder), the Quick Exit safety button, and no console errors. The address bar should show a padlock icon confirming HTTPS is active.

Seeing a blank page or error?

  • Go back to the Amplify console and check that your latest build shows a green checkmark. If it failed, click into the build logs to see what went wrong.
  • Make sure you are using the full URL including https:// at the start.
  • If you see a generic Amplify placeholder page, the second build (triggered by the NEXTAUTH_URL update) may still be in progress. Wait for it to complete.

My Amplify app shows a blank page or error instead of the homepage. What should I check?

Test the admin panel

The admin panel is the most demanding part of your stack. It requires SSR for page rendering, API routes for data fetching, NextAuth for authentication, and a live Prisma-to-Supabase database connection. If this works, everything works.

  • In your browser address bar, add /admin/login to the end of your Amplify URL and press Enter.
  • Log in with your seeded admin credentials.
  • Verify you can see the admin dashboard.
  • Navigate to the directory listings and confirm data loads from the database.
  • Test the CRUD functionality by creating or editing a listing to confirm write access works.

What does this confirm?

  • The login page loading confirms SSR and middleware are working (the admin route is gated by NextAuth middleware).
  • Logging in successfully confirms your NEXTAUTH_SECRET and NEXTAUTH_URL environment variables are correctly configured.
  • Seeing directory listings confirms the Prisma client is generated, the DATABASE_URL connects to Supabase, and API routes are functioning.
  • CRUD working confirms full read and write access to your production database.

Can't log in or seeing a server error?

  • If the login page shows a "CSRF" or "callback" error, your NEXTAUTH_URL does not match your actual Amplify URL. Double-check it in Hosting > Environment variables.
  • If directory listings are empty, confirm your Prisma migrations ran successfully by checking the build logs for the npx prisma migrate deploy output.
  • If you see "Internal Server Error," check that DATABASE_URL in your Amplify environment variables matches the connection string from your Supabase dashboard exactly.

My admin panel won't load or I can't log in. How do I troubleshoot NextAuth on Amplify?

Test automatic deployments

The final piece to verify is your CI/CD pipeline. Every push to your master branch should trigger a fresh build and deploy automatically.

  • Open your GitHub repository in a new browser tab: https://github.com/techservices-munezrohill/mytools.
  • Click on the README.md file to open it.
  • Click the pencil icon (edit button) in the top right of the file view.
  • Add a small change, such as a new line at the bottom of the file.
  • Click Commit changes.
  • In the commit dialog, leave the defaults and click Commit changes again to commit directly to the master branch.
  • Switch back to the AWS Amplify console tab in your browser.
  • Watch the build pipeline. Within seconds, a new build should appear with the "Provision" stage starting.

You should see a new build triggered in the Amplify console. The build card shows the commit message from your README edit.

Why does this matter?

This automatic deployment pipeline means you never have to manually deploy again. Every code change you push to master goes through the full build process (including Prisma migrations) and deploys to production automatically.

If a build fails, Amplify keeps your previous successful deployment live. Your users never see a broken site.

Build not triggering?

  • Confirm you committed to the master branch, not a different branch. Amplify only watches the branch you connected.
  • Check that GitHub authorization is still active. In the Amplify console, if you see a warning about repository access, re-authorize.
  • Give it 30 seconds. There can be a short delay between the push and when Amplify picks up the webhook.

My Amplify app is not picking up new commits. How do I fix the webhook connection?

Secret mission

Add a Custom Domain

Your app is live, but the URL is a long string of characters like master.d1234abcdef.amplifyapp.com. In this secret mission, you will connect your own domain name so users can access SafeConnect Rwanda at a memorable, professional URL with automatic HTTPS.

Clean Up Your Resources

Clean Up Your Resources

Your AWS Amplify app runs within the always-free tier, so ongoing costs are $0 for a low-traffic application. Decide whether to keep your resources running, pause deployments to come back later, or delete them entirely.

What about your GitHub repo and Supabase database?

Deleting the Amplify app only removes the hosting and compute layer. Your GitHub repository and Supabase PostgreSQL database are completely unaffected.

Resources you used:

  • AWS Amplify app (hosting your Next.js SSR application).
  • IAM service role (created automatically by Amplify for deployment permissions).

Keep everything running

No action needed. Choose this if you are still actively building or want SafeConnect Rwanda to stay live.

  • Your app stays live at your Amplify URL (and custom domain if configured).
  • Every push to master continues to trigger automatic builds and deploys.
  • Amplify's always-free tier covers 1,000 build minutes, 15 GB data transfer, 500,000 SSR requests, and 100 GB-hours of SSR compute per month. A small NGO app is unlikely to exceed these limits.

Pause - I'll come back to this later

Stop automatic deployments to avoid unnecessary builds while keeping your site live.

  • Open the Amplify console and select your app.
  • In the left sidebar, go to Hosting > Branch settings.
  • Disable auto-build for the master branch.
  • Your site remains accessible at its current URL, but new pushes to GitHub will not trigger builds.

Delete - I don't want to use this again

Remove all Amplify hosting resources and start fresh. This does not affect your GitHub repository or Supabase database.

  • Open the Amplify console and select your app.
  • Choose Actions > Delete app.
  • Confirm the deletion when prompted.
  • (Optional) Delete the IAM service role: open the IAM console, choose Roles in the left navigation, select the check box next to the Amplify service role, choose Delete, enter the role name to confirm, then choose Delete. IAM roles are free, so keeping the role has no cost impact.
  • (If you added a custom domain) Log in to your domain registrar and remove the CNAME records you added for Amplify. This prevents dead DNS entries pointing at a deleted app.

That's a Wrap!

That's a Wrap!

Nice work! You just deployed SafeConnect Rwanda as a production full-stack application on AWS.

Your Next.js 14 app is now live on a public HTTPS URL, backed by a global CDN, and automatically redeploying every time you push to master.

Here's what you accomplished:

  • Connected a GitHub repository to AWS Amplify with automatic CI/CD deployments on every push.
  • Configured a custom amplify.yml build specification that handles Prisma client generation and database migrations during deployment.
  • Deployed a live Next.js 14 SSR application with API routes, middleware, and securely injected environment variables for database connectivity and authentication.
  • Connected a custom domain with automatic SSL certificate provisioning via AWS Certificate Manager.

Ready to quiz yourself?