Next in Docker

Plus de détail sur les layers

L'exemple Unify

Qu'est-ce qui se passe dans la CD ?

 - apk add --no-cache -q jq python3 py3-pip bash make g++ && pip3 install awscli
 - yarn install --frozen-lockfile
 - cd $BASE_PATH/$service && mv .env.$STAGE .env && rm -f .env.* && yarn build
 - cd $CI_PROJECT_DIR
 # Login to nuage registry to login to Nuage ECR which hosts the base image used by the dockerfile
 - aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin $NUAGE_REGISTRY
 - mkdir temp-package-json
 - find . -name "package.json" -not -path "./**/node_modules/*" -not -path "./node_modules/**" -exec cp --parents "{}" temp-package-json \;
 - node remove-all-dev-deps-from-all-package-jsons-and-backend-deps.js
 - export UNO_REGISTRY="$(aws sts get-caller-identity --query Account --output text).dkr.ecr.eu-west-1.amazonaws.com"
 - docker build --network=host -t $UNO_REGISTRY/$REPOSITORY:$image_tag -f Dockerfile_frontend --build-arg SITE=${SITE} --build-arg STAGE=${env} --build-arg SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN} .
 # Login to uno registry which hosts the image we just built for the frontend
 - aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin $UNO_REGISTRY
 - docker push $UNO_REGISTRY/$REPOSITORY:$image_tag
 - rm -rf temp-package-json
 - cd $BASE_PATH/$service/ecs/service

Le Docker file

FROM 322816562783.dkr.ecr.eu-west-1.amazonaws.com/unify/node:12-alpine
ARG SITE
ARG STAGE
ARG SENTRY_AUTH_TOKEN

ENV SITE=$SITE
ENV STAGE=$STAGE
ENV PORT=80
ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
ENV NEXT_TELEMETRY_DISABLED=1

SHELL ["/bin/ash", "-eo", "pipefail", "-c"]

WORKDIR /usr/src/app/
COPY ./temp-package-json .
COPY yarn.lock yarn.lock
COPY lerna.json lerna.json

RUN NODE_ENV=production yarn install --prod && yarn cache clean --all && rm -rf /root/.cache /root/.npm

WORKDIR /usr/src/app/frontend/sites/${SITE}

# Copy .env and optionnal files
COPY ./frontend/sites/${SITE}/.env ./frontend/sites/${SITE}/src/services/sentry.j[s] ./frontend/sites/${SITE}/src/routes.jso[n] ./
COPY ./frontend/sites/${SITE}/next.config.js next.config.js
COPY ./frontend/sites/${SITE}/server.js server.js
RUN mkdir src && mkdir src/services

# Move optionnal files in the correct folder
RUN cp routes.json src/routes.json 2>/dev/null || :
RUN cp sentry.js src/services/sentry.js 2>/dev/null || :

# Continue copying files
COPY ./frontend/sites/${SITE}/public ./public
COPY ./frontend/sites/${SITE}/.next .next

EXPOSE ${PORT}
CMD ["yarn", "start"]

Les bonnes pratiques générales

  • Faire les choses dans l'ordre, du changé le moins fréquemment au changé le plus fréquemment
  • Faire le plus de choses possible hors de Docker (gain de perf + profiter du cache)
  • Si vous avez besoin d'élement pour un seul layer, faites un oneliner

Les apprentissages

  • Installer uniquement les dépendances de prod avec lerna n'est pas évident
  • Un seul DockerFile dans un monorepo c'est possible mais ça fait du code moche

Le bonus

deck

By Léo Anesi

deck

  • 228