Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project/alpha nginx serve #1447

Merged
merged 4 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Swap files
*.swp

# Byte-compiled / optimized / DLL files
__pycache__
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env
build
develop-eggs
dist
downloads
eggs
.eggs
lib
lib64
parts
sdist
var
*.egg-info
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build

# PyBuilder
target

#Ipython Notebook
.ipynb_checkpoints

# SASS cache
.sass-cache
media_test

# Rope project settings
.ropeproject

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Typescript v1 declaration files
typings

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env*

# Sensitive Deploy Files
deploy/eb/

# tox
./.tox

# Helm
.helm-charts/
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,19 @@ jobs:
- name: Build
run: yarn build
working-directory: app

validate_helm:
name: Validate Helm
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@main

- name: Install Helm
uses: azure/setup-helm@v4

- name: 🐳 Helm lint
run: helm lint ./nginx-serve/helm --values ./nginx-serve/helm/values-test.yaml

- name: 🐳 Helm template
run: helm template ./nginx-serve/helm --values ./nginx-serve/helm/values-test.yaml
146 changes: 146 additions & 0 deletions .github/workflows/publish-nginx-serve.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: Publish nginx serve image

on:
push:
branches:
- develop
- project/*

permissions:
packages: write


jobs:
publish_image:
name: Publish Docker Image
runs-on: ubuntu-latest

outputs:
docker_image_name: ${{ steps.prep.outputs.tagged_image_name }}
docker_image_tag: ${{ steps.prep.outputs.tag }}
docker_image: ${{ steps.prep.outputs.tagged_image }}

steps:
- uses: actions/checkout@main

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: 🐳 Prepare Docker
id: prep
env:
IMAGE_NAME: ghcr.io/${{ github.repository }}
run: |
BRANCH_NAME=$(echo $GITHUB_REF_NAME | sed 's|:|-|' | tr '[:upper:]' '[:lower:]' | sed 's/_/-/g' | cut -c1-100 | sed 's/-*$//')

# XXX: Check if there is a slash in the BRANCH_NAME eg: project/add-docker
if [[ "$BRANCH_NAME" == *"/"* ]]; then
# XXX: Change the docker image package to -alpha
IMAGE_NAME="$IMAGE_NAME-alpha"
TAG="$(echo "$BRANCH_NAME" | sed 's|/|-|g').$(echo $GITHUB_SHA | head -c7)"
else
TAG="$BRANCH_NAME.$(echo $GITHUB_SHA | head -c7)"
fi

IMAGE_NAME=$(echo $IMAGE_NAME | tr '[:upper:]' '[:lower:]')
echo "tagged_image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "tagged_image=${IMAGE_NAME}:${TAG}" >> $GITHUB_OUTPUT
echo "::notice::Tagged docker image: ${IMAGE_NAME}:${TAG}"

- name: 🐳 Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3

- name: 🐳 Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.ref }}
restore-keys: |
${{ runner.os }}-buildx-refs/develop
${{ runner.os }}-buildx-

- name: 🐳 Docker build
uses: docker/build-push-action@v6
with:
context: .
builder: ${{ steps.buildx.outputs.name }}
file: nginx-serve/Dockerfile
target: nginx-serve
load: true
push: true
tags: ${{ steps.prep.outputs.tagged_image }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
build-args: |
"APP_SENTRY_TRACES_SAMPLE_RATE=0.8"
"APP_SENTRY_REPLAYS_SESSION_SAMPLE_RATE=0.8"
"APP_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=0.8"

- name: 🐳 Move docker cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

publish_helm:
name: Publish Helm
needs: publish_image
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Install Helm
uses: azure/setup-helm@v3

- name: Tag docker image in Helm Chart values.yaml
env:
IMAGE_NAME: ${{ needs.publish_image.outputs.docker_image_name }}
IMAGE_TAG: ${{ needs.publish_image.outputs.docker_image_tag }}
run: |
# Update values.yaml with latest docker image
sed -i "s|SET-BY-CICD-IMAGE|$IMAGE_NAME|" nginx-serve/helm/values.yaml
sed -i "s/SET-BY-CICD-TAG/$IMAGE_TAG/" nginx-serve/helm/values.yaml

- name: Package Helm Chart
id: set-variables
run: |
# XXX: Check if there is a slash in the BRANCH_NAME eg: project/add-docker
if [[ "$GITHUB_REF_NAME" == *"/"* ]]; then
# XXX: Change the helm chart to <chart-name>-alpha
sed -i 's/^name: \(.*\)/name: \1-alpha/' nginx-serve/helm/Chart.yaml
fi

SHA_SHORT=$(git rev-parse --short HEAD)
sed -i "s/SET-BY-CICD/$SHA_SHORT/g" nginx-serve/helm/Chart.yaml
helm package ./nginx-serve/helm -d .helm-charts

- name: Push Helm Chart
env:
IMAGE: ${{ needs.publish_image.outputs.docker_image }}
OCI_REPO: oci://ghcr.io/${{ github.repository }}
run: |
OCI_REPO=$(echo $OCI_REPO | tr '[:upper:]' '[:lower:]')
PACKAGE_FILE=$(ls .helm-charts/*.tgz | head -n 1)
echo "# Helm Chart" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Tagged Image: **$IMAGE**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Helm push output" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
helm push "$PACKAGE_FILE" $OCI_REPO >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,7 @@ generated/
coverage/

# storybook build
storybook-static/
storybook-static/

# Helm
.helm-charts/
7 changes: 5 additions & 2 deletions app/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { defineConfig, Schema } from '@julr/vite-plugin-validate-env';
export default defineConfig({
APP_TITLE: Schema.string(),
APP_ENVIRONMENT: (key, value) => {
const regex = /^production|staging|testing|alpha-\d+|development$/;
const regex = /^production|staging|testing|alpha-\d+|development|APP_ENVIRONMENT_PLACEHOLDER$/;
tnagorra marked this conversation as resolved.
Show resolved Hide resolved
const valid = !!value && (value.match(regex) !== null);
if (!valid) {
throw new Error(`Value for environment variable "${key}" must match regex "${regex}", instead received "${value}"`);
}
return value as ('production' | 'staging' | 'testing' | `alpha-${number}` | 'development');
if (value === 'APP_ENVIRONMENT_PLACEHOLDER') {
console.warn(`Using ${value} for app environment. Make sure to not use this for builds without helm chart`)
}
return value as ('production' | 'staging' | 'testing' | `alpha-${number}` | 'development' | 'APP_ENVIRONMENT_PLACEHOLDER');
},
APP_API_ENDPOINT: Schema.string({ format: 'url', protocol: true, tld: false }),
APP_ADMIN_URL: Schema.string.optional({ format: 'url', protocol: true }),
Expand Down
57 changes: 57 additions & 0 deletions nginx-serve/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
FROM node:18-bullseye AS runtime
tnagorra marked this conversation as resolved.
Show resolved Hide resolved

RUN apt-get update -y \
&& apt-get install -y --no-install-recommends \
git bash g++ make \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /code

RUN git config --global --add safe.directory /code

# ------------------------------------------------------------------------------------
FROM runtime AS nginx-build

# TODO: Add cache with packages.json
# This is not working, will need @samshara help to configure this
# COPY package.json yarn.lock /code/
# COPY app/package.json /code/app/
tnagorra marked this conversation as resolved.
Show resolved Hide resolved
COPY . /code

RUN yarn install --frozen-lockfile --network-concurrency 2

# Dynamic configs. Can be changed with containers. (Placeholder values)
ENV APP_TITLE=APP_TITLE_PLACEHOLDER
ENV APP_ENVIRONMENT=APP_ENVIRONMENT_PLACEHOLDER
ENV APP_MAPBOX_ACCESS_TOKEN=APP_MAPBOX_ACCESS_TOKEN_PLACEHOLDER

Check warning on line 26 in nginx-serve/Dockerfile

View workflow job for this annotation

GitHub Actions / Publish Docker Image

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "APP_MAPBOX_ACCESS_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV APP_TINY_API_KEY=APP_TINY_API_KEY_PLACEHOLDER

Check warning on line 27 in nginx-serve/Dockerfile

View workflow job for this annotation

GitHub Actions / Publish Docker Image

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "APP_TINY_API_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV APP_API_ENDPOINT=https://APP-API-ENDPOINT-PLACEHOLDER.COM/
ENV APP_RISK_API_ENDPOINT=https://APP-RISK-API-ENDPOINT-PLACEHOLDER.COM/
ENV APP_SENTRY_DSN=https://APP-SENTRY-DSN-PLACEHOLDER.COM

# Static configs (Configured when building docker image)
ARG APP_SENTRY_TRACES_SAMPLE_RATE=
ENV APP_SENTRY_TRACES_SAMPLE_RATE=${APP_SENTRY_TRACES_SAMPLE_RATE}
ARG APP_SENTRY_REPLAYS_SESSION_SAMPLE_RATE=
ENV APP_SENTRY_REPLAYS_SESSION_SAMPLE_RATE=${APP_SENTRY_REPLAYS_SESSION_SAMPLE_RATE}
ARG APP_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=
ENV APP_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=${APP_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE}


RUN yarn build \
&& cd app \
&& yarn build
tnagorra marked this conversation as resolved.
Show resolved Hide resolved

# ------------------------------------------------------------------------------------
FROM nginx:1 AS nginx-serve

LABEL maintainer="IFRC"
LABEL org.opencontainers.image.source="https://github.com/IFRCGo/go-web-app"

COPY ./nginx-serve/apply-helm-config.sh /docker-entrypoint.d/
COPY ./nginx-serve/nginx.conf.template /etc/nginx/templates/default.conf.template
COPY --from=nginx-build /code/build /code/build

ENV SOURCE_DIRECTORY=/code/build/
ENV DESTINATION_DIRECTORY=/usr/share/nginx/html/
ENV OVERWRITE_DESTINATION=true
tnagorra marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading