I have a next.js application that requires environment variables, I have included the .env file itself along with adding the variables to beanstalk environment, still the variables are passed to docker host. I use CodePipeline to build and upload to ECR and then deploy to EB
DockerFile
# Base stage to install node deps
FROM --platform=linux/amd64 node:20-alpine AS base
WORKDIR /app
RUN apk add --no-cache libc6-compat
COPY package*.json ./
COPY . ./
RUN npm ci
# Build stage to transpile `src` into `dist`
FROM base AS build
COPY --from=base package*.json ./
COPY --from=base /app/node_modules ./node_modules
COPY . .
RUN npm run build
&& npm prune --production
# Final stage for production app image
FROM base AS production
ENV NODE_ENV="production"
ENV PORT=80
COPY --from=build --chown=node:node package*.json ./
COPY --from=build --chown=node:node /app/node_modules ./node_modules
# Remove if you don't have public files
COPY --from=build --chown=node:node /app/public ./public
COPY --from=build --chown=nextjs:nodejs /app/.next ./.next
RUN mkdir -p /app/shared/public
EXPOSE $PORT
CMD ["npm", "start"]
Docker-Compose
services:
web:
image: image
platform: linux/amd64
restart: always
ports:
- 3000:3000
command:
- /bin/sh
- -c
- |
# Sync shared public files
rm -rf /app/shared/public/*
cp -r /app/public/* /app/shared/public
#
# You can add more commands before startup: compile assets, run migrations, ... if you have
# ...
#
# Start node app
npm run start
environment:
- DB_NAME=${DB_NAME}
- DB_HOSTNAME=${DB_HOSTNAME}
volumes:
- public_assets:/app/shared/public
- /app/node_modules
- /app/.next
nginx:
image: nginx:alpine
platform: linux/amd64
restart: always
ports:
- 80:80
depends_on:
- web
volumes:
- public_assets:/app/public
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- /app/node_modules
- /app/.next
volumes:
public_assets:
my buildspec for CodeBuild
version: 0.2
phases:
pre_build:
commands:
- echo "Logging in to Amazon ECR..."
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- COMMIT_SHA=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_SHA:-latest}
build:
commands:
- echo "Build started on `date`"
- docker build -t $IMAGE_REPOSITORY:$IMAGE_TAG .
- docker tag $IMAGE_REPOSITORY:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPOSITORY:$IMAGE_TAG
- echo "Build completed on `date`"
post_build:
commands:
- echo "Push the docker image to AWS ECR..."
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPOSITORY:$IMAGE_TAG
- echo "Update IMAGE_TAG in docker-compose.yml..."
- sed -i -e "s/${IMAGE_TAG:-latest}/$IMAGE_TAG/g" docker-compose.yml
artifacts:
files:
- .ebextensions/**/*
- docker-compose.yml
- nginx.conf
cache:
paths:
- node_modules