我正在尝试从 Elastic Beanstalk 迁移到 AWS App Runner,但 AWS App Runner 在其
build
阶段似乎没有考虑环境变量。
真的很想立即使用 AWS AppRunner,迁移到应用程序运行器的部分原因是易于使用以及快速推送代码并发布。
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}
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',
},
};
我什至尝试使用手动 apprunner 文件,但它仍然不会在构建中包含环境变量(它们实际上从 AppRunner UI 中消失,直到我切换回配置而不是 apprunner.yaml 文件。
虽然我无法直接回答上述问题,但我在 AppRunner 上部署 Next.JS 的解决方法是将 github 操作部署到 ECR,然后使用 AppRunner 中的容器而不是源存储库。
GH Actions 和 Dockerfile 供参考。
name: Build and Push Docker Image to ECR
on:
push:
branches:
- main
- dev
workflow_dispatch:
env:
AWS_REGION: us-east-1 # Change to your AWS region
ECR_REPOSITORY_NAME_DEV: your-ecr-name-space/your-service-dev ECR_REPOSITORY_NAME_MAIN: your-ecr-name-space/your-service-main
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
# 1. Checkout the repository
- name: Checkout code
uses: actions/checkout@v2
# 2. Generate Last Updated Timestamp
- name: Generate Last Updated Timestamp
run: echo "NEXT_PUBLIC_LAST_UPDATED=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" > .env.local
# 3. Set environment variables based on branch using repository variables
- name: Set environment variables based on branch
run: |
if [ "${{ github.ref }}" == "refs/heads/dev" ]; then
echo "NEXT_PUBLIC_VAR=${{ vars.DEV_NEXT_PUBLIC_VAR}}" >> $GITHUB_ENV
else
echo "NEXT_PUBLIC_VAR=${{ vars.PROD_NEXT_PUBLIC_VAR }}" >> $GITHUB_ENV
fi
# 4. Set up Node.js
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
# 5. Install dependencies
- name: Install dependencies
run: npm install
# 6. Build Next.js project
- name: Build Next.js project
run: npm run build
# 7. Configure AWS Credentials
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
# 8. Get AWS Account ID
- name: Get AWS Account ID
id: aws_account
run: echo "AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)" >> $GITHUB_ENV
# 9. Set ECR repository URI
- name: Set ECR repository URI
run: |
echo "ECR_REPOSITORY_URI=${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY_NAME }}" >> $GITHUB_ENV
# 10. Login to Amazon ECR
- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v1
# 11. Build Docker image
- name: Build Docker image
run: |
docker build -t $ECR_REPOSITORY_URI:${{ github.sha }} \
.
# 12. Push Docker image to Amazon ECR
- name: Push Docker image to Amazon ECR
run: |
docker push $ECR_REPOSITORY_URI:${{ github.sha }}
# 13. (Optional) Tag the image as 'latest'
- name: Tag and push latest Docker image
run: |
docker tag $ECR_REPOSITORY_URI:${{ github.sha }} $ECR_REPOSITORY_URI:latest
docker push $ECR_REPOSITORY_URI:latest
# Use the official Node.js 18 image as the base
FROM node:18
# Set the working directory inside the container
WORKDIR /app
# Accept build arguments for environment-specific configurations
ARG NEXT_PUBLIC_VAR
# Set environment variables based on the build arguments
ENV NEXT_PUBLIC_VAR=${NEXT_PUBLIC_VAR}
# Copy package.json and package-lock.json to leverage Docker cache
COPY package*.json ./
# Install project dependencies
RUN npm install
# Copy the rest of the application code to the container
COPY . .
# Build the Next.js application for production
RUN npm run build
# Expose port 3000 to allow external access
EXPOSE 3000
# Define the default command to run the application
CMD ["npm", "start"]