diff --git a/.github/workflows/build_deploy.yml b/.github/workflows/build_deploy.yml index c06b7c8a..350cca78 100644 --- a/.github/workflows/build_deploy.yml +++ b/.github/workflows/build_deploy.yml @@ -46,6 +46,8 @@ jobs: run: npm ci - name: Build run: npm run build --if-present + env: + DATA_SOURCE: development - name: Get directory contents run: ls -la public - name: Lint diff --git a/client/.dockerignore b/client/.dockerignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/client/.dockerignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/client/.env.development b/client/.env.development new file mode 100644 index 00000000..2cfc90a8 --- /dev/null +++ b/client/.env.development @@ -0,0 +1,11 @@ +# WARNING: +# THIS FILE IS CHECKED INTO VERSION CONTROL! DO NOT ADD ANY SECRET INFO. IF SECRETS ARE ADDED, PLEASE ADD TO # GIT IGNORE FILE + +GATSBY_DATA_ROOT_PATH=https://d3jqyw10j8e7p9.cloudfront.net +GATSBY_DATA_PIPELINE_SCORE_PATH=data-pipeline/data/score +GATSBY_SCORE_DOWNLOAD_FILE_PATH=downloadable/Screening+Tool+Data.zip +GATSBY_MAP_TILES_PATH=tiles + +# These may be used in the future: +# WEB_APP_CDN_BASE_URL=https://d2zjid6n5ja2pt.cloudfront.net +# S3_BASE_URL=https://justice40-data.s3.amazonaws.com diff --git a/client/.env.local b/client/.env.local new file mode 100644 index 00000000..f8ca6074 --- /dev/null +++ b/client/.env.local @@ -0,0 +1,11 @@ +# WARNING: +# THIS FILE IS CHECKED INTO VERSION CONTROL! DO NOT ADD ANY SECRET INFO. IF SECRETS ARE ADDED, PLEASE ADD TO # GIT IGNORE FILE + +GATSBY_DATA_ROOT_PATH=http://localhost:5000/data/data-pipeline +GATSBY_DATA_PIPELINE_SCORE_PATH=data_pipeline/data/score +GATSBY_SCORE_DOWNLOAD_FILE_PATH=downloadable/Screening+Tool+Data.zip +GATSBY_MAP_TILES_PATH=tiles + +# These may be used in the future: +# WEB_APP_CDN_BASE_URL=https://d2zjid6n5ja2pt.cloudfront.net +# S3_BASE_URL=https://justice40-data.s3.amazonaws.com diff --git a/client/.gitignore b/client/.gitignore index 1a809502..adb519ff 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -5,3 +5,4 @@ public cypress/screenshots/ cypress/videos/ .DS_Store +.env.* \ No newline at end of file diff --git a/client/Dockerfile b/client/Dockerfile new file mode 100644 index 00000000..71c6024e --- /dev/null +++ b/client/Dockerfile @@ -0,0 +1,22 @@ +FROM node:14 + +# Set working directory like 'cd' command, any subsequent instructions in this docker file, will start from +# this working directory +WORKDIR /client + +# Copy the package.json and package_lock.json files from local to the docker image / container +COPY package*.json ./ + +# install all packages as a layer in the docker image / container +RUN npm install + +# copy all local files from the working directory to the docker image/container however we must use +# dockerignore to ignore node_modules so that the image can use what what was just installed from the above +# step. +COPY . . + +ENV PORT=6000 + +EXPOSE 6000 + +CMD [ "npm", "start"] diff --git a/client/README.md b/client/README.md index 4b81861a..cfcb52e2 100644 --- a/client/README.md +++ b/client/README.md @@ -11,6 +11,7 @@ This README contains the following content: ## Installing and running the client site +### Via npm 1. Confirm you have the base required software installed. See [INSTALLATION](INSTALLATION.md) for more details. 1. Install yarn if you do not have it yet. Open your terminal and run `sudo npm install -global yarn`. This works on MacOS and Win10. To confirm it is installed, run `yarn -v`. A version number should be returned. 1. Navigate to the base directory of this repository, and go to the `client` directory (`cd client`). @@ -20,6 +21,22 @@ This README contains the following content: _Note that while this app uses npm as the package manager, yarn is required to build the [uswds](https://github.com/uswds/uswds) library._ +### Via docker +- Launch VS code in the top level directory (above client) +- Install the Microsoft docker VS code extension +- Type `docker-compose up` +- Running this on MacBook Pro with a 2.6GHz 6-core i7 with 16 GB of memory can take upto 20 minutes to complete. + +#### Changing the source of tile / map layer +If you don't want to use the local data-pipeline location for getting the tile / map layers, you can change the +DATA_SOURCE env variable in the docker-compose.yml file to development and it will point to the CDN for the tile / +map layer. + +#### Troubleshooting docker + +- If an error is thrown about [running out of space](https://medium.com/@wlarch/no-space-left-on-device-when-using-docker-compose-why-c4a2c783c6f6) on device see this for ways to reclaim space. + + ### Viewing data on the map See [VIEW_MAP_DATA](./VIEW_MAP_DATA) for more details on this. diff --git a/client/gatsby-config.js b/client/gatsby-config.js index b25300ec..f8ab423a 100644 --- a/client/gatsby-config.js +++ b/client/gatsby-config.js @@ -1,3 +1,7 @@ +require('dotenv').config({ + path: `.env.${process.env.DATA_SOURCE}`, +}); + module.exports = { siteMetadata: { title: 'Justice40', diff --git a/client/package.json b/client/package.json index c2260399..b65cf071 100644 --- a/client/package.json +++ b/client/package.json @@ -9,8 +9,8 @@ ], "license": "CC0-1.0", "scripts": { - "develop": "gatsby develop", - "start": "gatsby develop", + "develop": "gatsby develop -H 0.0.0.0", + "start": "gatsby develop -H 0.0.0.0", "build": "gatsby build --prefix-paths", "serve": "gatsby serve", "clean": "gatsby clean", diff --git a/client/src/data/constants.tsx b/client/src/data/constants.tsx index 60ed28ac..d24cad52 100644 --- a/client/src/data/constants.tsx +++ b/client/src/data/constants.tsx @@ -2,22 +2,21 @@ import {LngLatBoundsLike} from 'maplibre-gl'; import {isMobile as isMobileReactDeviceDetect} from 'react-device-detect'; import {defineMessages} from 'react-intl'; -// URLS -export const DOWNLOAD_ZIP_URL = 'https://justice40-data.s3.amazonaws.com/data-pipeline/data/score/downloadable/Screening+Tool+Data.zip'; +export const DOWNLOAD_ZIP_URL = [ + process.env.GATSBY_DATA_ROOT_PATH, + process.env.GATSBY_DATA_PIPELINE_SCORE_PATH, + process.env.GATSBY_SCORE_DOWNLOAD_FILE_PATH, +].join('/'); -// This is the URL for the origin S3 bucket: -// export const ORIGIN_BASE_URL = 'https://justice40-data.s3.amazonaws.com'; - -// This is the URL for the CDN that delivers the tile data -export const FEATURE_TILE_BASE_URL = 'https://d3jqyw10j8e7p9.cloudfront.net'; -const FEATURE_TILE_PATH = 'data-pipeline/data/score/tiles'; - -// This is the URL for the CDN that delivers the application -// const APP_BASE_URL = 'https://d2zjid6n5ja2pt.cloudfront.net'; const XYZ_SUFFIX = '{z}/{x}/{y}.pbf'; - export const featureURLForTilesetName = (tilesetName :string ) : string => { - return `${FEATURE_TILE_BASE_URL}/${FEATURE_TILE_PATH}/${tilesetName}/${XYZ_SUFFIX}`; + return [ + process.env.GATSBY_DATA_ROOT_PATH, + process.env.GATSBY_DATA_PIPELINE_SCORE_PATH, + process.env.GATSBY_MAP_TILES_PATH, + tilesetName, + XYZ_SUFFIX, + ].join('/'); }; export const FEATURE_TILE_HIGH_ZOOM_URL = featureURLForTilesetName('high'); export const FEATURE_TILE_LOW_ZOOM_URL = featureURLForTilesetName('low'); diff --git a/data/data-serve/Dockerfile b/data/data-serve/Dockerfile new file mode 100644 index 00000000..e7561fb3 --- /dev/null +++ b/data/data-serve/Dockerfile @@ -0,0 +1,3 @@ +FROM node:latest +RUN npm install -g http-server +CMD http-server ./ --cors diff --git a/docker-compose.yml b/docker-compose.yml index 3fcd4ee7..7f2e63a5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,40 @@ -version: "3.4" -services: - score: - image: j40_data_pipeline - container_name: j40_data_pipeline_1 - build: data/data-pipeline - ports: - - 8888:8888 - volumes: - - ./data/data-pipeline:/data-pipeline - stdin_open: true - tty: true - environment: - ENV_FOR_DYNACONF: development - PYTHONUNBUFFERED: 1 +version: "3.4" +services: + # The j40_data_pipeline service runs the ETL pipeline to create the score + score: + image: j40_data_pipeline + container_name: j40_data_pipeline_1 + build: data/data-pipeline + ports: + - 8888:8888 + volumes: + - ./data/data-pipeline:/data-pipeline + stdin_open: true + tty: true + environment: + ENV_FOR_DYNACONF: development + PYTHONUNBUFFERED: 1 + + # The score_server serves the data-pipeline volume as a URL + j40_score_server: + image: j40_score_server + container_name: j40_score_server_1 + build: data/data-serve/. + volumes: + - ./data/data-pipeline/data_pipeline/data/score:/data/data-pipeline/data_pipeline/data/score + ports: + - 5000:8080 + + #The j40_website service runs the web app / map / site + j40_website: + image: j40_website + container_name: j40_website_1 + build: ./client + environment: + DATA_SOURCE: local + volumes: + - ./client/src:/client/src + ports: + - 8000:6000 + depends_on: + - "j40_score_server"