diff --git a/.env.prod b/.env.prod new file mode 100644 index 0000000..b77ec81 --- /dev/null +++ b/.env.prod @@ -0,0 +1,2 @@ +NEXT_PUBLIC_BASE_PATH="/selfservice" +NEXT_PUBLIC_BASE_API_PATH="/v1/selfservice" diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 71573dd..6e17adf 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest env: NAMESPACE: ${{ secrets.docker_hub_organisation }} - SELFSERVICE_SERVICE_NAME: "openg2p-selfservice-ui" + SERVICE_NAME: "openg2p-beneficiary-portal-ui" steps: - uses: actions/checkout@v3 - name: Setup branch and env @@ -25,22 +25,17 @@ jobs: echo "VERSION=$VERSION" >> $GITHUB_ENV - name: Build docker run: | - SELFSERVICE_IMAGE_ID=$NAMESPACE/$SELFSERVICE_SERVICE_NAME + IMAGE_ID=$NAMESPACE/$SERVICE_NAME # Change all uppercase to lowercase - SELFSERVICE_IMAGE_ID=$(echo $SELFSERVICE_IMAGE_ID | tr '[A-Z]' '[a-z]') + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo SELFSERVICE_IMAGE_ID=$SELFSERVICE_IMAGE_ID + echo IMAGE_ID=$IMAGE_ID echo VERSION=$VERSION - echo "SELFSERVICE_IMAGE_ID=$SELFSERVICE_IMAGE_ID" >> $GITHUB_ENV + echo "IMAGE_ID=$IMAGE_ID" >> $GITHUB_ENV - docker build . \ - --file Dockerfile \ - --tag $SELFSERVICE_IMAGE_ID:$VERSION - docker build . \ - --file Dockerfile.no-runtime-build \ - --tag $SELFSERVICE_IMAGE_ID:$VERSION-no-runtime-build + docker build . --file Dockerfile --tag $IMAGE_ID:$VERSION - name: Docker login run: | echo "${{ secrets.docker_hub_token }}" | docker login -u ${{ secrets.docker_hub_actor }} --password-stdin @@ -50,5 +45,4 @@ jobs: fi - name: Docker Push images run: | - docker push $SELFSERVICE_IMAGE_ID:$VERSION - docker push $SELFSERVICE_IMAGE_ID:$VERSION-no-runtime-build + docker push $IMAGE_ID:$VERSION diff --git a/Dockerfile b/Dockerfile index 78e3d6e..77e5903 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,48 @@ FROM node:18-alpine AS base +RUN apk add bash + +FROM base AS builder # 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 -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs +WORKDIR /app + +COPY package.json package-lock.json* ./ + +RUN npm ci + +COPY . . +RUN ./docker-env-replace.sh .env.prod .env.local +ENV NEXT_TELEMETRY_DISABLED 1 +RUN npm run build + +FROM base AS runner WORKDIR /app -RUN chown -R nextjs:nodejs /app +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs -USER nextjs +RUN mkdir .next +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +COPY --from=builder --chown=nextjs:nodejs /app/.env.prod . +COPY --from=builder --chown=nextjs:nodejs /app/docker-entrypoint.sh . -# Install dependencies based on the preferred package manager -COPY --chown=nextjs:nodejs package.json package-lock.json* ./ -RUN npm ci +RUN npm i sharp + +RUN chown nextjs:nodejs /app -COPY --chown=nextjs:nodejs . . +USER nextjs -# 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 -ENV NODE_ENV=production -ENV HOSTNAME="0.0.0.0" -ENV PORT=3000 +ENV NEXT_TELEMETRY_DISABLED 1 +ENV NODE_ENV production +ENV PORT 3000 +ENV HOSTNAME 0.0.0.0 EXPOSE 3000 -CMD npm run build && npm run start \ No newline at end of file +ENTRYPOINT [ "./docker-entrypoint.sh" ] +CMD node server.js diff --git a/Dockerfile.no-runtime-build b/Dockerfile.no-runtime-build deleted file mode 100644 index 307c9dc..0000000 --- a/Dockerfile.no-runtime-build +++ /dev/null @@ -1,34 +0,0 @@ -FROM node:18-alpine AS base - -# 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 - -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs - -WORKDIR /app - -RUN chown -R nextjs:nodejs /app - -USER nextjs - -# Install dependencies based on the preferred package manager -COPY --chown=nextjs:nodejs package.json package-lock.json* ./ -RUN npm ci - -COPY --chown=nextjs:nodejs . . - -# 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. -ARG NEXT_TELEMETRY_DISABLED=1 -ARG NODE_ENV=production -ARG HOSTNAME="0.0.0.0" -ARG PORT=3000 -ARG NEXT_PUBLIC_BASE_PATH=/selfservice -ARG NEXT_PUBLIC_BASE_API_PATH=/selfservice/v1 - -EXPOSE 3000 - -RUN npm run build -CMD npm run start \ No newline at end of file diff --git a/README.md b/README.md index 7eebe84..ddb1a32 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,22 @@ # OpenG2P Beneficiary Portal OpenG2P beneficiary self service portal + +## Developer Notes + +- For local development. + - Install Node, Npm, Npx. + - Install dependencies + ```sh + npm ci + ``` + - Create a `.env.local` file with the following content. Edit the below API base path appropriately. + ```sh + NEXT_PUBLIC_BASE_PATH="" + NEXT_PUBLIC_BASE_API_PATH="http://localhost:8000/" + ``` + - Run the following to start the app + ```sh + npm run dev + ``` + - Open [http://localhost:3000](http://localhost:3000) on browser. diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000..ad20bbe --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +WORKDIR="/app" +ENV_FILE=$WORKDIR/.env.prod + +IFS=$'\n' next_env_vars=($(awk 'BEGIN{for(v in ENVIRON) print v}' | grep "^NEXT_PUBLIC_")) +for env_var in ${next_env_vars[@]}; do + file_env_var_line=$(grep "${env_var}=" $ENV_FILE) + if ! [ -z $file_env_var_line ]; then + sed -i "s|$file_env_var_line||g" $ENV_FILE + fi +done + +set -a +source $ENV_FILE +set +a + +IFS=$'\n' next_env_vars=($(awk 'BEGIN{for(v in ENVIRON) print v}' | grep "^NEXT_PUBLIC_")) +for env_var in ${next_env_vars[@]}; do + for file in $(find $WORKDIR -name "node_modules" -prune -o -type f -exec grep -l "/@$env_var@" {} \;); do + sed -i "s|/@$env_var@|${!env_var}|g" $file + done +done + +exec "$@" diff --git a/docker-env-replace.sh b/docker-env-replace.sh new file mode 100755 index 0000000..43b29e5 --- /dev/null +++ b/docker-env-replace.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +input_file=$1 +output_file=$2 + +while read line; do + # Skip empty lines and comments + if [[ -z "$line" ]] || [[ "$line" =~ ^# ]]; then + echo "$line" >> $output_file + continue + fi + + key=$(echo "$line" | cut -d'=' -f1) + echo "$key=/@$key@" >> $output_file +done < $input_file diff --git a/next.config.js b/next.config.js index 66e280d..7da9dee 100644 --- a/next.config.js +++ b/next.config.js @@ -5,6 +5,7 @@ const withNextIntl = createNextIntlPlugin(); /** @type {import('next').NextConfig} */ const nextConfig = { basePath: process.env.NEXT_PUBLIC_BASE_PATH || "", + output: "standalone", }; module.exports = withNextIntl(nextConfig); diff --git a/package-lock.json b/package-lock.json index b0a9651..25f6e61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "openg2p-selfservice-ui", - "version": "0.1.0", + "name": "openg2p-beneficiary-portal-ui", + "version": "1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "openg2p-selfservice-ui", - "version": "0.1.0", + "name": "openg2p-beneficiary-portal-ui", + "version": "1.0", "dependencies": { "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", diff --git a/package.json b/package.json index b053367..4a14142 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "openg2p-selfservice-ui", - "version": "0.1.0", + "name": "openg2p-beneficiary-portal-ui", + "version": "1.0", "private": true, "scripts": { "dev": "next dev", diff --git a/src/app/[locale]/login/loginbox.tsx b/src/app/[locale]/login/loginbox.tsx index 679f655..cd78f7c 100644 --- a/src/app/[locale]/login/loginbox.tsx +++ b/src/app/[locale]/login/loginbox.tsx @@ -99,7 +99,7 @@ export default function LoginBox() { {t("Password")}
- {t("Reset Password")} + {t("Reset Password")}