I am trying to migrate from Elastic Beanstalk to AWS App Runner, but AWS App Runner does not seem to consider the environment variable during it's build phase.
Troubleshooting:
- npm run build (next build) - Works successfully locally and references my .env vars successfully.
- My existing elastic beanstalk implementation (shared below successfully gets the .env vars from github actions and are included in the build process).
- AppRunner the environment variables are currently set as plain-text, but language around around the build and start steps indicate that the variables are only available in the start phase, not the build phase.
- This works without issue on vercel.
Would really like to use AWS AppRunner out of the box, part of the reason of migrating to app runner was ease of use and quickly pushing code and having it published.
References:
Elastic Beanstalk:
name: Deploy to Elastic Beanstalk
on:
push:
branches:
- main
- dev
workflow_dispatch:
env:
BUCKET_NAME: marketbase-web
DEV_APP_NAME: Marketbase-web-dev
MAIN_APP_NAME: marketbase-web-prod-2
DEV_ENV_NAME: Marketbase-web-dev-env
MAIN_ENV_NAME: marketbase-web-prod-2-env
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Generate Last Updated Timestamp
run: echo "NEXT_PUBLIC_LAST_UPDATED=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" > .env.local
working-directory: ./
- name: Log environment variables
run: |
echo "NEXT_PUBLIC_API_URL=${{ secrets.NEXT_PUBLIC_API_URL }}"
echo "NEXT_PUBLIC_STANDARD_PRICE_ID=${{ secrets.NEXT_PUBLIC_STANDARD_PRICE_ID }}"
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build Next.js project
run: |
if [ "${{ github.ref }}" == "refs/heads/dev" ]; then
export NEXT_PUBLIC_API_URL=${{ secrets.DEV_NEXT_PUBLIC_API_URL }}
export NEXT_PUBLIC_STANDARD_PRICE_ID=${{ secrets.DEV_NEXT_PUBLIC_STANDARD_PRICE_ID }}
export NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${{ secrets.DEV_NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY }}
export NEXT_PUBLIC_M_API_KEY=${{ secrets.DEV_NEXT_PUBLIC_M_API_KEY }}
export NEXT_PUBLIC_CLOUDFRONT_URL=${{secrets.DEV_NEXT_PUBLIC_CLOUDFRONT_URL}}
export NEXT_PUBLIC_ENVIRONMENT=${{secrets.DEV_NEXT_PUBLIC_ENVIRONMENT}}
else
export NEXT_PUBLIC_API_URL=${{ secrets.PROD_NEXT_PUBLIC_API_URL }}
export NEXT_PUBLIC_STANDARD_PRICE_ID=${{ secrets.PROD_NEXT_PUBLIC_STANDARD_PRICE_ID }}
export NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${{ secrets.PROD_NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY }}
export NEXT_PUBLIC_M_API_KEY=${{ secrets.PROD_NEXT_PUBLIC_M_API_KEY }}
export NEXT_PUBLIC_CLOUDFRONT_URL=${{secrets.PROD_NEXT_PUBLIC_CLOUDFRONT_URL}}
export NEXT_PUBLIC_ENVIRONMENT=${{secrets.PROD_NEXT_PUBLIC_ENVIRONMENT}}
fi
npm run build
env:
NEXT_PUBLIC_API_URL: ${{ env.NEXT_PUBLIC_API_URL }}
NEXT_PUBLIC_STANDARD_PRICE_ID: ${{ env.NEXT_PUBLIC_STANDARD_PRICE_ID }}
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: ${{ env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY }}
NEXT_PUBLIC_M_API_KEY: ${{ env.NEXT_PUBLIC_M_API_KEY }}
NEXT_PUBLIC_CLOUDFRONT_URL: ${{ env.NEXT_PUBLIC_CLOUDFRONT_URL }}
NEXT_PUBLIC_ENVIRONMENT: ${{ env.NEXT_PUBLIC_ENVIRONMENT }}
- name: Cache
uses: actions/cache@v3
with:
# See here for caching with `yarn` https://github.com/actions/cache/blob/main/examples.md#node---yarn or you can leverage caching with actions/setup-node https://github.com/actions/setup-node
path: |
~/.npm
${{ github.workspace }}/.next/cache
# Generate a new cache whenever packages or source files change.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
# If source files changed but packages didn't, rebuild from a prior cache.
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
- name: Generate version label
run: echo "VERSION_LABEL=$(git rev-parse --short HEAD)-$(date +%s)" >> $GITHUB_ENV
- name: Zip the application
run: zip -r ${VERSION_LABEL}.zip . -x '*.git*' 'node_modules/*'
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1 # Change to your desired region
- name: Deploy to Dev Elastic Beanstalk on commit to dev branch
if: github.ref == 'refs/heads/dev'
run: |
aws s3 cp ${VERSION_LABEL}.zip s3://$BUCKET_NAME/dev/${VERSION_LABEL}.zip
aws elasticbeanstalk create-application-version --application-name $DEV_APP_NAME --version-label ${VERSION_LABEL} --source-bundle S3Bucket="$BUCKET_NAME",S3Key="dev/${VERSION_LABEL}.zip"
aws elasticbeanstalk update-environment --environment-name $DEV_ENV_NAME --version-label ${VERSION_LABEL}
- name: Deploy to Main Elastic Beanstalk on commit to main branch
if: github.ref == 'refs/heads/main'
run: |
aws s3 cp ${VERSION_LABEL}.zip s3://$BUCKET_NAME/main/${VERSION_LABEL}.zip
aws elasticbeanstalk create-application-version --application-name $MAIN_APP_NAME --version-label ${VERSION_LABEL} --source-bundle S3Bucket="$BUCKET_NAME",S3Key="main/${VERSION_LABEL}.zip"
aws elasticbeanstalk update-environment --environment-name $MAIN_ENV_NAME --version-label ${VERSION_LABEL}
Config in AWS AppRunner:
next.config.js:
module.exports = {
env: {
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL || 'default',
NEXT_PUBLIC_CLOUDFRONT_URL: process.env.NEXT_PUBLIC_CLOUDFRONT_URL || 'default',
NEXT_PUBLIC_ENVIRONMENT: process.env.NEXT_PUBLIC_ENVIRONMENT || 'default',
NEXT_PUBLIC_LAST_UPDATED: process.env.NEXT_PUBLIC_LAST_UPDATED || 'default',
NEXT_PUBLIC_M_API_KEY: process.env.NEXT_PUBLIC_M_API_KEY || 'default',
NEXT_PUBLIC_STANDARD_PRICE_ID: process.env.NEXT_PUBLIC_STANDARD_PRICE_ID || 'default',
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || 'default',
},
};
I've even tried using a manual apprunner file and it still will not include the environment variables in the build (they actually disappear from the AppRunner UI until I switch back to the configuration as opposed to apprunner.yaml file.
