Skip to content

Commit

Permalink
image build process improvements (blockscout#1045)
Browse files Browse the repository at this point in the history
* auto-generate .env.production file

* env placeholders congruity check

* refactor yarn dev and docker tasks

* [skip ci] pass git tag and commit sha to dev app

* [skip ci] clean up
  • Loading branch information
tom2drum authored Aug 2, 2023
1 parent c41fef8 commit 6655687
Show file tree
Hide file tree
Showing 23 changed files with 282 additions and 171 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ SENTRY_CSP_REPORT_URI=xxx
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=xxx
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID=UA-XXXXXX-X
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN=xxx
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN=xxx
NEXT_PUBLIC_AUTH0_CLIENT_ID=xxx
80 changes: 0 additions & 80 deletions .env.template

This file was deleted.

3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
node_modules_linux

playwright/envs.js
playwright/envs.js
deploy/tools/envs-validator/index.js
8 changes: 1 addition & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# dependencies
/node_modules
/node_modules_linux
/**/node_modules
/.pnp
.pnp.js

Expand Down Expand Up @@ -48,9 +47,4 @@ yarn-error.log*
/playwright/.browser/
/playwright/envs.js

**.dec**

# tools: envs-validator
/deploy/tools/envs-validator/index.js
/deploy/tools/envs-validator/envs.ts
/deploy/tools/envs-validator/schema.ts
**.dec**
18 changes: 9 additions & 9 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// DEV SERVER
{
"type": "shell",
"command": "yarn dev:${input:devServerConfig}",
"command": "yarn dev:preset ${input:dev_config_preset}",
"problemMatcher": [],
"label": "dev server",
"detail": "start local dev server",
Expand Down Expand Up @@ -243,11 +243,11 @@
}
},
{
"type": "npm",
"script": "start:docker:poa_core",
"type": "shell",
"command": "yarn start:docker:preset ${input:dev_config_preset}",
"problemMatcher": [],
"label": "docker: run poa",
"detail": "run docker container for POA network",
"label": "docker: run",
"detail": "run docker container with env preset",
"presentation": {
"reveal": "always",
"panel": "shared",
Expand Down Expand Up @@ -311,17 +311,17 @@
},
{
"type": "pickString",
"id": "devServerConfig",
"description": "Choose dev server config:",
"id": "dev_config_preset",
"description": "Choose dev server config preset:",
"options": [
"main",
"main:L2",
"main.L2",
"poa_core",
"eth_goerli",
"eth",
"localhost",
],
"default": ""
"default": "main"
},
],
}
57 changes: 34 additions & 23 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,72 @@ FROM node:18-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat

# Install dependencies for App
### APP
# Install dependencies
WORKDIR /app
COPY package.json yarn.lock ./
RUN apk add git
RUN yarn --frozen-lockfile

# Install dependencies for ENVs checker
### ENV VARIABLES CHECKER
# Install dependencies
WORKDIR /envs-validator
COPY ./deploy/tools/envs-validator/package.json ./deploy/tools/envs-validator/yarn.lock ./
RUN yarn --frozen-lockfile


# *****************************
# ****** STAGE 2: Build *******
# *****************************
FROM node:18-alpine AS builder
RUN apk add --no-cache --upgrade libc6-compat bash

# Build app for production
# pass commit sha and git tag to the app image
ARG GIT_COMMIT_SHA
ENV NEXT_PUBLIC_GIT_COMMIT_SHA=$GIT_COMMIT_SHA
ARG GIT_TAG
ENV NEXT_PUBLIC_GIT_TAG=$GIT_TAG

ENV NODE_ENV production

### APP
# Copy dependencies and source code
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
COPY .env.template .env.production
RUN rm -rf ./deploy/tools/envs-validator

# Generate .env.production with ENVs placeholders and save build args into .env file
COPY --chmod=+x ./deploy/scripts/make_envs_template.sh ./
RUN ./make_envs_template.sh ./docs/ENVS.md

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

# Build app for production
RUN yarn build

# Build ENVs checker

### ENV VARIABLES CHECKER
# Copy dependencies and source code, then build
WORKDIR /envs-validator
COPY --from=deps /envs-validator/node_modules ./node_modules
COPY ./deploy/tools/envs-validator .
COPY ./types/envs.ts .
RUN yarn build


# *****************************
# ******* STAGE 3: Run ********
# *****************************
# Production image, copy all the files and run next
FROM node:18-alpine AS runner
WORKDIR /app

# pass commit sha to the app (uses by sentry.io as release version)
ARG GIT_COMMIT_SHA
ENV NEXT_PUBLIC_GIT_COMMIT_SHA=$GIT_COMMIT_SHA
RUN apk add --no-cache --upgrade bash

# pass git tag to the app (for the footer link)
ARG GIT_TAG
ENV NEXT_PUBLIC_GIT_TAG=$GIT_TAG
### APP
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

Expand All @@ -68,20 +82,17 @@ COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /envs-validator/index.js ./envs-validator.js

# Copy scripts and ENV templates file
COPY ./deploy/scripts/entrypoint.sh .
COPY ./deploy/scripts/replace_envs.sh .
COPY .env.template .
# Copy scripts and ENVs file
COPY --chmod=+x ./deploy/scripts/entrypoint.sh .
COPY --chmod=+x ./deploy/scripts/replace_envs.sh .
COPY --from=builder /app/.env.production .
COPY --from=builder /app/.env .

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

RUN apk add --no-cache --upgrade bash
RUN ["chmod", "+x", "./entrypoint.sh"]
RUN ["chmod", "+x", "./replace_envs.sh"]

ENTRYPOINT ["./entrypoint.sh"]

USER nextjs
Expand Down
3 changes: 2 additions & 1 deletion configs/envs/.env.eth_goerli
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=ETH
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_TOKEN_ADDRESS=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_AUTH_URL=http://localhost:3000
NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE=validation
NEXT_PUBLIC_NETWORK_RPC_URL=https://rpc.ankr.com/eth_goerli
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/marketplace/eth-goerli.json
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/shrqUAcjgGJ4jU88C
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_HAS_BEACON_CHAIN=false

# api config
NEXT_PUBLIC_API_HOST=eth-goerli.blockscout.com
Expand Down
3 changes: 2 additions & 1 deletion configs/envs/.env.main
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=ETH
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_TOKEN_ADDRESS=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_AUTH_URL=http://localhost:3000
NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE=validation
NEXT_PUBLIC_NETWORK_RPC_URL=https://rpc.ankr.com/eth_goerli
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/marketplace/eth-goerli.json
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/shrqUAcjgGJ4jU88C
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_HAS_BEACON_CHAIN=false

# api config
NEXT_PUBLIC_API_HOST=blockscout-main.k8s-dev.blockscout.com
Expand Down
2 changes: 1 addition & 1 deletion deploy/scripts/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Check run-time ENVs values integrity
node "$(dirname "$0")/envs-validator.js" "$input"
if [ $? != 0 ]; then
echo ENV integrity check failed. 1>&2 && exit 1
echo 🛑 ENV integrity check failed. 1>&2 && exit 1
fi

# Execute script for replace build-time ENVs placeholders with their values at runtime
Expand Down
45 changes: 45 additions & 0 deletions deploy/scripts/make_envs_template.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

# Check if the number of arguments provided is correct
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <input_file>"
exit 1
fi

input_file="$1"
prefix="NEXT_PUBLIC_"

# Function to make the environment variables template file
# It will read the input file, extract all prefixed string and use them as variables names
# This variables will have placeholders for their values at buildtime which will be replaced with actual values at runtime
make_envs_template_file() {
output_file=".env.production"

# Check if file already exists and empty its content if it does
if [ -f "$output_file" ]; then
> "$output_file"
fi

grep -oE "${prefix}[[:alnum:]_]+" "$input_file" | sort -u | while IFS= read -r var_name; do
echo "$var_name=__PLACEHOLDER_FOR_${var_name}__" >> "$output_file"
done
}

# Function to save build-time environment variables to .env file
save_build-time_envs() {
output_file=".env"

# Check if file already exists and empty its content if it does or create a new one
if [ -f "$output_file" ]; then
> "$output_file"
else
touch "$output_file"
fi

env | grep "^${prefix}" | while IFS= read -r line; do
echo "$line" >> "$output_file"
done
}

make_envs_template_file
save_build-time_envs
2 changes: 1 addition & 1 deletion deploy/scripts/replace_envs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set +x

# config
envFilename='.env.template'
envFilename='.env.production'
nextFolder='./.next/'

# replacing build-stage ENVs with run-stage ENVs
Expand Down
6 changes: 6 additions & 0 deletions deploy/tools/envs-validator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/node_modules
.env
.env.production
index.js
envs.ts
schema.ts
8 changes: 8 additions & 0 deletions deploy/tools/envs-validator/dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

cp ../../../types/envs.ts .
export NEXT_PUBLIC_GIT_COMMIT_SHA=$(git rev-parse --short HEAD)
export NEXT_PUBLIC_GIT_TAG=$(git describe --tags --abbrev=0)
../../scripts/make_envs_template.sh ../../../docs/ENVS.md
yarn build
dotenv -e ../../../configs/envs/.env.main -e ../../../configs/envs/.env.secrets yarn validate
Loading

0 comments on commit 6655687

Please sign in to comment.