Skip to content

Commit

Permalink
cicd: fix production build using import-meta-env
Browse files Browse the repository at this point in the history
  • Loading branch information
chmanie committed Mar 7, 2024
1 parent c8e2810 commit 8442402
Show file tree
Hide file tree
Showing 25 changed files with 380 additions and 615 deletions.
40 changes: 19 additions & 21 deletions .env.development
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
# Environment variables for the frontend in development mode
# # Environment variables for the frontend in development mode
#
NETWORK_ID="ganache"
SAFE_ENABLED="false"
REPUTATION_ORACLE_ENDPOINT="http://localhost:3001/reputation/local"
NETWORK_CONTRACT_ADDRESS=
METATX_ENABLED=true
METATX_BROADCASTER_ENDPOINT="http://localhost:3004"
AUTH_PROXY_ENDPOINT="http://localhost:3005"
BSCSCAN_API_KEY=
ETHERSCAN_API_KEY=
GOOGLE_TAG_MANAGER_ID=
PINATA_API_KEY=
PINATA_API_SECRET=
COINGECKO_API_KEY=

# Network the CDapp is deployed to
VITE_NETWORK="ganache"

# The endpoint of the reputation oracle.
VITE_REPUTATION_ORACLE_ENDPOINT="http://localhost:3001/reputation/local"

# If the network has / or does not have support for metatranasctions
# Ie: contracts deployed, broadcaster service active
VITE_METATX_ENABLED=true
VITE_METATX_BROADCASTER_ENDPOINT="http://localhost:3004"

# The endpoint of the service where etherrouter-addres.json, ganache-accounts.json & safe-addresses.json can be found for frontend
VITE_NETWORK_FILES_ENDPOINT="http://localhost:3006"
VITE_GANACHE_RPC_URL="http://localhost:8545"

# URL where the authentication server is found
VITE_AUTH_PROXY_ENDPOINT="http://localhost:3005"

# For debugging
VITE_DEBUG=true
# Used in development only
DEBUG=true
NETWORK_FILES_ENDPOINT="http://localhost:3006"
GANACHE_RPC_URL="http://localhost:8545"
38 changes: 18 additions & 20 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,46 +1,44 @@
# All possible environment variables for the frontend (set at build time **will end up in source code!!!**)

# Network the CDapp is deployed to
VITE_NETWORK="ganache"
NETWORK_ID="ganache"

# Whether to enable Safe integration
SAFE_ENABLED="false"

# EtherRouter contract address for the network the CDapp is deployed to
# DOES NOT NEED TO BE SET WHEN DEVELOPING LOCALLY
VITE_NETWORK_CONTRACT_ADDRESS="0x0000000000000000000000000000000000000000"
NETWORK_CONTRACT_ADDRESS="0x0000000000000000000000000000000000000000"

# Required for safe control
VITE_BSCSCAN_API_KEY=
VITE_ETHERSCAN_API_KEY=
BSCSCAN_API_KEY=
ETHERSCAN_API_KEY=

# The endpoint of the reputation oracle.
VITE_REPUTATION_ORACLE_ENDPOINT="http://localhost:3001/reputation/local"
REPUTATION_ORACLE_ENDPOINT="http://localhost:3001/reputation/local"

# If the network has / or does not have support for metatranasctions
# Ie: contracts deployed, broadcaster service active
VITE_METATX_ENABLED=true
VITE_METATX_BROADCASTER_ENDPOINT="http://localhost:3004"
METATX_ENABLED=true
METATX_BROADCASTER_ENDPOINT="http://localhost:3004"

# The endpoint of the service where etherrouter-addres.json, ganache-accounts.json & safe-addresses.json can be found for frontend
VITE_NETWORK_FILES_ENDPOINT="http://localhost:3006"
VITE_GANACHE_RPC_URL="http://localhost:8545"
NETWORK_FILES_ENDPOINT="http://localhost:3006"
GANACHE_RPC_URL="http://localhost:8545"

# URL where the authentication server is found
VITE_AUTH_PROXY_ENDPOINT="http://localhost:3005"
AUTH_PROXY_ENDPOINT="http://localhost:3005"

# ID for Google Tag Manager `GTM-XXXXXXX`
VITE_GOOGLE_TAG_MANAGER_ID=
GOOGLE_TAG_MANAGER_ID=

# pinata connection detail from https://app.pinata.cloud/developers/api-keys
# Only needed for production
VITE_PINATA_API_KEY=
VITE_PINATA_API_SECRET=
PINATA_API_KEY=
PINATA_API_SECRET=

# Needed for currency conversion. For testing, see: https://support.coingecko.com/hc/en-us/articles/21880397454233
VITE_COINGECKO_API_KEY=
COINGECKO_API_KEY=

# For debugging
VITE_DEBUG=true

# @NOTE Only on production
# It became apparent that we need a "live" way to check what commit we're running on while debugging issues strait into production
VITE_PROD_COMMIT_HASH=

DEBUG=true
115 changes: 24 additions & 91 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,91 +1,24 @@
FROM node:20.11

# @FIX Allow the nginx service to start at build time, so that the installation will work
# See: https://askubuntu.com/questions/365911/why-the-services-do-not-start-at-installation
# RUN sed -i "s|exit 101|exit 0|g" /usr/sbin/policy-rc.d

# Update the apt cache
RUN apt-get clean
RUN apt-get update

# Apt-utils needs to be in before installing the rest
RUN apt-get install -y \
locales \
apt-utils \
build-essential \
curl \
file \
zip \
nginx

# Reconfigure locales
RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
RUN locale-gen

# Create the app directory
WORKDIR /colonyCDapp

# Copy package.json, package-lock.json and required scripts
COPY package*.json .
COPY scripts/ ./scripts/

# Install node_modules
RUN npm ci

# Copy colonyCDapp
COPY . .

RUN echo "Building commit hash: $(git rev-parse --short HEAD)"

RUN echo "\n\
VITE_PROD_COMMIT_HASH$(git rev-parse --short HEAD)\n\
VITE_SAFE_ENABLED=false\n\
" > .env.production

RUN npm run vite:prod

# Copy the production bundle
RUN mkdir ../colonyCDappProd
RUN cp -R ./dist/* ../colonyCDappProd

# Cleanup the source folder
WORKDIR /
RUN rm -Rf colonyCDapp
WORKDIR /colonyCDappProd

# Setup a basic nginx config
RUN echo "server {\n" \
" listen 80;\n" \
" server_name default_server;\n\n" \
" location / {\n" \
" root /colonyCDappProd;\n" \
" try_files \$uri /index.html;\n" \
" }\n" \
"}" > /etc/nginx/sites-available/default

# Expose the HTTP port
EXPOSE 80

# @NOTE Hack!
# We replace the environment variables in the built bundle with the ones declared in the kubernetes config
# This is necessary since we aren't in a actual node process, they're just files served by nginx
# Doing it like this allows us to use the same image for different deployments
RUN echo "sed -i \"s|import.meta.env.VITE_NETWORK_CONTRACT_ADDRESS|\\\"\$NETWORK_CONTRACT_ADDRESS\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_URL|\\\"\$URL\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_NETWORK|\\\"\$NETWORK\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_AUTH_PROXY_ENDPOINT|\\\"\$AUTH_PROXY_ENDPOINT\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_METATX_ENABLED|\\\"\$METATX_ENABLED\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_METATX_BROADCASTER_ENDPOINT|\\\"\$BROADCASTER_ENDPOINT\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_REPUTATION_ORACLE_ENDPOINT|\\\"\$REPUTATION_ORACLE_ENDPOINT\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_GOOGLE_TAG_MANAGER_ID|\\\"\$GOOGLE_TAG_MANAGER_ID\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_PINATA_API_KEY|\\\"\$PINATA_API_KEY\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_PINATA_API_SECRET|\\\"\$PINATA_API_SECRET\\\"|g\" ./assets/*.js" \
"&& sed -i \"s|import.meta.env.VITE_COINGECKO_API_KEY|\\\"\$COINGECKO_API_KEY\\\"|g\" ./assets/*.js" \
" && nginx -g 'daemon off;'" > ./run.sh

RUN chmod +x ./run.sh

# @NOTE Run the actual command, rather then the service
# so that the docker container won't exit
CMD ./run.sh
# READY TO GO !
# From https://github.com/runtime-env/import-meta-env/blob/main/packages/examples/docker-starter-example/Dockerfile
FROM node:20.11-alpine3.19 as build-stage
RUN apk add git
WORKDIR /app
# To get the git commit hash later
COPY .git ./.git
COPY package.json package-lock.json ./
RUN SKIP_POSTINSTALL=true npm ci

# Package the import-meta-env as single binary as we don't have node on the production container
RUN npx @yao-pkg/pkg ./node_modules/@import-meta-env/cli/bin/import-meta-env.js \
-t node20-alpine-x64 \
-o import-meta-env-alpine
COPY index.html vite.config.mts .env.example ./
COPY src/* ./src/
RUN npm run build

FROM nginx:1.24.0-alpine as production-stage
RUN mkdir /app
COPY --from=build-stage /app/dist/* /app/dist/
COPY --from=build-stage /app/import-meta-env-alpine /app/
COPY .env.example docker/files/frontend/start.sh /app/
COPY docker/files/frontend/nginx.conf /etc/nginx/
ENTRYPOINT ["sh","/app/start.sh"]
10 changes: 3 additions & 7 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ npm install

_Note: at the end of the install there's a post-install script that will recursively install dependencies for all the currently declared lambda functions_

### Create `.env` file

Copy `.env.example` and rename it to `.env`. You should not need to change any of the values to get CDapp running.

## Running the dev environment

```bash
Expand All @@ -44,10 +40,10 @@ On the next start, assuming no key cache files changed, it will skip the image b

## Running the dev web server

Once the above dev environment is up and running, you need to start your dev web server, running through vite:
Once the above dev environment is up and running, you need to start your dev web server:

```bash
npm run vite
npm run frontend
```

You can access it at `http://localhost:9091` _(notice the different port, as to not cause a local storage and cache conflict with the Dapp)_
Expand Down Expand Up @@ -81,7 +77,7 @@ _NOTE: This only works while the environment is running_
If you want to build the bundle locally for production, you can do it via:

```bash
npm run vite:prod
npm run build
```

_Note: It's a straight-up dev build. Just bundled, no code optimizations whatsoever._
Expand Down
9 changes: 9 additions & 0 deletions docker/files/frontend/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
server {
listen 80;
server_name default_server;
location / {
root /app/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
}
8 changes: 8 additions & 0 deletions docker/files/frontend/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

cd /app
# Inject environment variables to index.html
./import-meta-env-alpine -x .env.example -p dist/index.html || exit 1

cd /app/dist
nginx -g "daemon off;"
5 changes: 5 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
</head>
<body>
<div id="root"></div>
<!-- DO NOT CHANGE THE FOLLOWING SCRIPT TAG, used for import-meta-env !!-->
<!-- See https://import-meta-env.org/guide/getting-started/introduction.html#special-expression -->
<script>
globalThis.import_meta_env = JSON.parse('"import_meta_env_placeholder"');
</script>
<script type="module" src="./src/index.ts"></script>
</body>
</html>
Loading

0 comments on commit 8442402

Please sign in to comment.