Skip to content

Commit

Permalink
Merge pull request #17 from ricardogsilva/specify-backend-urls-via-env
Browse files Browse the repository at this point in the history
Specify backend urls via env
  • Loading branch information
sirmmo authored Dec 13, 2024
2 parents 29a9ac2 + 80aaf33 commit f1ed35b
Show file tree
Hide file tree
Showing 26 changed files with 124 additions and 127 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
build/
build/
public/injectedEnv.js
11 changes: 0 additions & 11 deletions .env.example

This file was deleted.

3 changes: 0 additions & 3 deletions .env.local

This file was deleted.

5 changes: 0 additions & 5 deletions .env.production

This file was deleted.

5 changes: 0 additions & 5 deletions .env.staging

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ node_modules
stats.json
.pnp
.pnp.js
public/injectedEnv.js

# misc
.DS_Store
Expand Down
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
24 changes: 14 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
FROM node:16-alpine AS builder
ENV NODE_ENV production
ENV \
NODE_ENV=production \
GENERATE_SOURCEMAP=false
# Add a work directory
WORKDIR /app
# Cache and Install dependencies
COPY package.json .
COPY yarn.lock .
RUN yarn install --production
RUN yarn install --production --frozen-lockfile
# Copy app files
COPY . .
# Build the app
RUN yarn build

# Bundle static assets with nginx
FROM nginx:1.21.0-alpine as production
ENV NODE_ENV production
# Copy built assets from builder
COPY --from=builder /app/build /usr/share/nginx/html
# Add your nginx.conf
FROM nginx:1.21.0-alpine AS production
ENV \
NODE_ENV=production \
ARPAV_BACKEND_API_BASE_URL=http://localhost:8877 \
ARPAV_TOLGEE_BASE_URL=http://localhost:8899
WORKDIR /usr/share/nginx/html
COPY --from=builder /app/build .
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose port
COPY docker-entrypoint.sh .
COPY injectEnv.sh .
EXPOSE 80
# Start nginx
CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT [ "sh", "docker-entrypoint.sh" ]
41 changes: 31 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,35 @@ This work is licensed under a <a rel="license" href="https://creativecommons.org
Commissioned by & Data credits to <br/>
<a href="https://www.arpa.veneto.it/"><img src="https://github.com/inkode-it/Arpav-PPCV/raw/main/public/img/logo_arpav.png" alt="ARPAV" style="background-color:white;padding:4px"></a>

Designed and developed in Italy by <br/>
<a rel="author" href="mailto:[email protected]"><img src="https://avatars.githubusercontent.com/u/64135645" alt="INKODE soc coop"></a>

Current version was designed and developed in Italy by <br/>
<a rel="author" href="mailto:[email protected]"><img src="https://avatars.githubusercontent.com/u/1163234?s=200&v=4" alt="Geobeyond"></a>

A previous version had originally been developed by [inkode](http://inkode.it)


## Install & development

This project uses the [Yarn Package Manager](https://yarnpkg.com) .
This project uses node version 16. It uses the [Yarn Package Manager](https://yarnpkg.com) and is known to work
with yarn v1.22.22. Start by ensuring you meet these conditions (install node and yarn).

Install dependencies
Now for installing this project:

```shell
yarn install
yarn install --frozen-lockfile
```

Before launching the application, copy the contents of `.env.example` file to `.env` and edit Environment variables.
Before launching the application, ensure you have the following environment variables:

- `ARPAV_BACKEND_API_BASE_URL` - base URL of the backend. Example: `http://localhost:8877`
- `ARPAV_TOLGEE_BASE_URL` - base URL of the tolgee service. Example: `http://localhost:8899`

Create the `public/injectedEnv.js` file by running:

```shell
yarn inject-env public
```

Launch application in development mode
Then launch application in development mode:

```shell
yarn start
Expand Down Expand Up @@ -64,10 +74,21 @@ http://localhost:3000
- `src/app/pages/MapPage/slice`: Redux and Redux-Saga management;
- `src/utils`: Utility functions.

## Docker build command for production
# Running in production

Build the docker image:

```shell
docker build -t ppcv_frontend -f production.Dockerfile .
docker build -t ppcv_frontend -f Dockerfile .
```

Run the built container with:

```shell
docker run \
-e ARPAV_BACKEND_API_BASE_URL=http://localhost:8877 \
-e ARPAV_TOLGEE_BASE_URL=http://localhost:8899 \
-p 3000:80 \
ppcv_frontend
```

6 changes: 6 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

cd /usr/share/nginx/html
sh injectEnv.sh

[ -z "$@" ] && nginx -g 'daemon off;' || "$@"
25 changes: 25 additions & 0 deletions injectEnv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
output_dir="${1:-.}"

output_file="${output_dir}/injectedEnv.js"

echo "(Re)generating '${output_file}' by writing environment variables starting with 'ARPAV_' into it..."

# Start writing the JavaScript file
cat > "$output_file" << EOL
// This file is autogenerated
window.injectedEnv = {
EOL

# Process only environment variables starting with ARPAV_
env | grep "^ARPAV_" | while IFS='=' read -r key value; do
# Clean the value: escape quotes and backslashes
cleaned_value=$(echo "$value" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')

# Write the key-value pair as a JavaScript property
echo " \"$key\": \"$cleaned_value\"," >> "$output_file"
done

cat >> "$output_file" << EOL
};
EOL
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@
"extract-messages": "i18next-scanner --config=internals/extractMessages/i18next-scanner.config.js",
"build:production": "docker build -t ppcv_frontend -f production.Dockerfile .",
"ghpredeploy": "npm run build",
"ghdeploy": "gh-pages -b gh-pages -d build"
"ghdeploy": "gh-pages -b gh-pages -d build",
"inject-env": "sh ./injectEnv.sh"
},
"eslintConfig": {
"extends": "react-app"
Expand Down
24 changes: 0 additions & 24 deletions production.Dockerfile

This file was deleted.

1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<script src="%PUBLIC_URL%/injectedEnv.js" defer="defer"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!--
Expand Down
4 changes: 2 additions & 2 deletions src/app/Services/API/Http/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { API_URL } from '../../../../utils/constants';
import { BACKEND_API_URL } from '../../../../utils/constants';

import { getCookie, removeCookie } from '../../../../utils/cookie';

Expand Down Expand Up @@ -39,7 +39,7 @@ abstract class HttpClient {
}

const AxiosConf: AxiosRequestConfig = {
baseURL: API_URL,
baseURL: BACKEND_API_URL,
};

export class Http extends HttpClient {
Expand Down
25 changes: 13 additions & 12 deletions src/app/Services/API/Requests/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AxiosResponse } from 'axios';
import { Http } from '../Http';
import { P } from 'app/pages/NotFoundPage/P';
import { BACKEND_API_URL } from '../../../../utils/constants'

export interface AuthResponse {
[key: string]: {};
Expand Down Expand Up @@ -56,7 +57,7 @@ export class RequestApi extends Http {
}
return this.instance
.get<any>(
'https://arpav.geobeyond.dev/api/v2/coverages/forecast-data?',
BACKEND_API_URL + '/coverages/forecast-data?',
{
params: { offset: 0, limit: 100, ...innerConf },
paramsSerializer: { indexes: null },
Expand Down Expand Up @@ -120,7 +121,7 @@ export class RequestApi extends Http {
} else {
this.instance
.get<any>(
'https://arpav.geobeyond.dev/api/v2/municipalities/municipality-centroids',
BACKEND_API_URL + '/municipalities/municipality-centroids',
)
.then((x: any) => x.features)
.then(x => {
Expand Down Expand Up @@ -288,7 +289,7 @@ export class RequestApi extends Http {
}

const fullUrl =
'https://arpav.geobeyond.dev/api/v2/coverages/coverage-identifiers?' +
BACKEND_API_URL + '/coverages/coverage-identifiers?' +
filter;

console.log(fullUrl);
Expand All @@ -310,7 +311,7 @@ export class RequestApi extends Http {
// Make the request to the API.
return this.instance
.get<any>(
'https://arpav.geobeyond.dev/api/v2/coverages/coverage-identifiers?' +
BACKEND_API_URL + '/coverages/coverage-identifiers?' +
filter,
)
.then((x: any) => {
Expand Down Expand Up @@ -462,7 +463,7 @@ export class RequestApi extends Http {
smoothing: boolean = true,
uncertainty: boolean = true,
) => {
let url = `https://arpav.geobeyond.dev/api/v2/coverages/time-series/${serie}?coords=POINT(${lng.toFixed(
let url = `${BACKEND_API_URL}/coverages/time-series/${serie}?coords=POINT(${lng.toFixed(
4,
)} ${lat.toFixed(
4,
Expand Down Expand Up @@ -501,7 +502,7 @@ export class RequestApi extends Http {
lng: number,
year: number,
) => {
let url = `https://arpav.geobeyond.dev/api/v2/coverages/time-series/${serie}?coords=POINT(${lng.toFixed(
let url = `${BACKEND_API_URL}/coverages/time-series/${serie}?coords=POINT(${lng.toFixed(
4,
)} ${lat.toFixed(4)})&datetime=${year + 1}%2F${
year - 1
Expand All @@ -511,14 +512,14 @@ export class RequestApi extends Http {
};

public getBarometroClimatico = () => {
let url = `https://arpav.geobeyond.dev/api/v2/coverages/time-series/climate-barometer?data_smoothing=MOVING_AVERAGE_11_YEARS&include_uncertainty=true`;
let url = `${BACKEND_API_URL}/coverages/time-series/climate-barometer?data_smoothing=MOVING_AVERAGE_11_YEARS&include_uncertainty=true`;
console.log(url);
return this.instance.get<any>(url);
};

public findMunicipality = (lat, lng) => {
return this.instance.get<any>(
`https://arpav.geobeyond.dev/api/v2/municipalities/municipalities?coords=POINT(${lng} ${lat})`,
`${BACKEND_API_URL}/municipalities/municipalities?coords=POINT(${lng} ${lat})`,
);
};

Expand All @@ -543,7 +544,7 @@ export class RequestApi extends Http {
}
return this.instance
.get<any>(
'https://arpav.geobeyond.dev/api/v2/coverages/configuration-parameters?offset=0&limit=100',
`${BACKEND_API_URL}/coverages/configuration-parameters?offset=0&limit=100`,
)
.then((d: any) => {
return d.items;
Expand All @@ -562,20 +563,20 @@ export class RequestApi extends Http {

const ret = this.instance
.get<any>(
'https://arpav.geobeyond.dev/api/v2/coverages/configuration-parameters?offset=0&limit=100',
`${BACKEND_API_URL}/coverages/configuration-parameters?offset=0&limit=100`,
)
.then((d: any) => {
return d.items;
});
reqs.push(ret);
if (mode === 'forecast') {
const cret = this.instance.get<any>(
'https://arpav.geobeyond.dev/api/v2/coverages/forecast-variable-combinations',
`${BACKEND_API_URL}/coverages/forecast-variable-combinations`,
);
reqs.push(cret);
} else {
const cret = this.instance.get<any>(
'https://arpav.geobeyond.dev/api/v2/coverages/historical-variable-combinations',
`${BACKEND_API_URL}/coverages/historical-variable-combinations`,
);
reqs.push(cret);
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/DownloadDataDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import MapDlData from './mapDlData';
import UserDlData from '../UserDlData/userDlData';
import { saveAs } from 'file-saver';
import { useMapSlice } from '../../pages/MapPage/slice';
import { API_URL } from '../../../utils/constants';
import { BACKEND_API_URL } from '../../../utils/constants';
import { RequestApi } from 'app/Services/API/Requests';
import { Icon, LinkList, LinkListItem } from 'design-react-kit';

Expand Down Expand Up @@ -92,7 +92,7 @@ const DownloadDataDialog = (props: DownloadDataDialogProps) => {
...dataSet.current,
...values,
};
const url = `${API_URL}/maps/ncss/netcdf/?${new URLSearchParams(
const url = `${BACKEND_API_URL}/maps/ncss/netcdf/?${new URLSearchParams(
params,
).toString()}`;
setDownloadUrl(url);
Expand Down
1 change: 0 additions & 1 deletion src/app/components/Map/LegendBar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useEffect } from 'react';
import { Box, Typography } from '@mui/material';
import { useSelector } from 'react-redux';
import { WMS_PROXY_URL, V2_WMS_PROXY_URL } from '../../../utils/constants';
import { useTranslation } from 'react-i18next';

export interface LegendBarProps {
Expand Down
Loading

0 comments on commit f1ed35b

Please sign in to comment.