Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ yarn-error.log*

#deployment
/deployment/payara/target

#dev environment
/dev-env/docker-dev-volumes
/dev-env/dataverse
/dev-env/dataverse-sample-data
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,43 @@ Launches the prettier formatter. We recommend you to configure your IDE to run p
Runs the Storybook in the development mode.
Open [http://localhost:6006](http://localhost:6006) to view it in your browser.

## Local development environment

A containerized environment, oriented to local development, is available to be run from the repository.

This environment contains a dockerized instance of the Dataverse backend with its dependent services (database, mailserver, etc), as well as an npm development server running the SPA frontend (With code autoupdating).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wanted to note that the autoupdating is working great!

I added "FOOBAR" to the Hello Dataverse page and as soon as I saved the file the text appeared, like this:

Screen Shot 2023-05-09 at 12 06 28 PM

Here was the change:

$ git diff
diff --git a/src/sections/hello-dataverse/HelloDataverse.tsx b/src/sections/hello-dataverse/HelloDataverse.tsx
index 52091d7..a4bb4f5 100644
--- a/src/sections/hello-dataverse/HelloDataverse.tsx
+++ b/src/sections/hello-dataverse/HelloDataverse.tsx
@@ -8,6 +8,7 @@ export function HelloDataverse() {
   return (
     <section className={styles.container}>
       <h2 className={styles.title}>{t('title')}</h2>
+      <h1>FOOBAR</h1>
       <img src={logo} className={styles.logo} alt={t('altImage')} />
       <p>
         <Trans t={t} i18nKey="description" components={{ 1: <code /> }} />


This environment is intended for locally testing any functionality that requires access to the Dataverse API from the SPA frontend.

There is an Nginx reverse proxy container on top of the frontend and backend containers to avoid CORS issues while testing the application.

### Run the environment

Inside the `dev-env` folder, run the following command:

```
./run-env <dataverse_branch_name>
```

As the script argument, add the name of the Dataverse backend branch you want to deploy.

Note that both the branch and the associated tag in the docker registry must to be pre pushed, otherwise the script will fail.

If you are running the script for the first time, it may take a while, since `npm install` has to install all the dependencies. This can also happen if you added new dependencies to package.json.

Once the script has finished, you will be able to access Dataverse via:

- [http://localhost:8000/spa](http://localhost:8000/spa): SPA Frontend
- [http://localhost:8000](http://localhost:8000): Dataverse Backend and JSF Frontend

### Remove the environment

To clean up your environment of any running environment containers, as well as any associated data volumes, run this script inside the `dev-env` folder:

```
./rm-env
```

## Deployment

Once the site is built through the `npm run build` command, it can be deployed in different ways to different types of infrastructure, depending on installation needs.
Expand Down
4 changes: 4 additions & 0 deletions dev-env/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
POSTGRES_VERSION=13
DATAVERSE_DB_USER=dataverse
SOLR_VERSION=8.11.1
REGISTRY=ghcr.io
137 changes: 137 additions & 0 deletions dev-env/docker-compose-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
version: '2.4'

services:
dev_nginx:
container_name: 'dev_nginx_proxy'
image: nginx:stable
ports:
- '8000:80'
networks:
- dataverse
depends_on:
- dev_dataverse
- dev_frontend
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./docker-dev-volumes/nginx/logs:/var/log/nginx/

dev_frontend:
container_name: 'dev_frontend'
hostname: frontend
build:
context: ../
dockerfile: ./dev.Dockerfile
network: host
expose:
- '5173'
stdin_open: true
networks:
- dataverse
depends_on:
- dev_dataverse
environment:
- VITE_DATAVERSE_BACKEND_URL=http://localhost:8000
volumes:
- ../:/usr/src/app
- /usr/src/app/dev-env
- /usr/src/app/node_modules

dev_dataverse:
container_name: 'dev_dataverse'
hostname: dataverse
image: ${REGISTRY}/gdcc/dataverse:${DATAVERSE_BRANCH_NAME}
restart: on-failure
user: payara
environment:
- DATAVERSE_DB_HOST=postgres
- DATAVERSE_DB_PASSWORD=secret
- DATAVERSE_DB_USER=${DATAVERSE_DB_USER}
- DATAVERSE_FEATURE_API_SESSION_AUTH=1
# We open 8080, rather than just expose, so that the docker-final-setup.sh script works from the run-env.sh script
ports:
- '8080:8080'
networks:
- dataverse
depends_on:
- dev_postgres
- dev_solr
volumes:
- ./docker-dev-volumes/app/data:/dv
- ./docker-dev-volumes/app/secrets:/secrets
tmpfs:
- /dumps:mode=770,size=2052M,uid=1000,gid=1000
- /tmp:mode=770,size=2052M,uid=1000,gid=1000
mem_limit: 2147483648 # 2 GiB
mem_reservation: 1024m
privileged: false

dev_postgres:
container_name: 'dev_postgres'
hostname: postgres
image: postgres:${POSTGRES_VERSION}
restart: on-failure
environment:
- POSTGRES_USER=${DATAVERSE_DB_USER}
- POSTGRES_PASSWORD=secret
ports:
- '5432:5432'
networks:
- dataverse
volumes:
- ./docker-dev-volumes/postgresql/data:/var/lib/postgresql/data

dev_solr_initializer:
container_name: 'dev_solr_initializer'
image: alpine
restart: 'no'
command:
- sh
- -c
- 'chown 8983:8983 /conf /var/solr && cp *.xml /conf'
volumes:
- ./docker-dev-volumes/solr/data:/var/solr
- ./docker-dev-volumes/solr/conf:/conf
- ./dataverse/conf/solr/8.11.1/schema.xml:/schema.xml
- ./dataverse/conf/solr/8.11.1/solrconfig.xml:/solrconfig.xml

dev_solr:
container_name: 'dev_solr'
hostname: 'solr'
image: solr:${SOLR_VERSION}
depends_on:
- dev_solr_initializer
restart: on-failure
expose:
- '8983'
networks:
- dataverse
command:
- bash
- -c
- 'cd /opt/solr-${SOLR_VERSION}/server/solr/configsets/_default/conf && cp -R -n . /template && solr-precreate collection1 /template'
volumes:
- ./docker-dev-volumes/solr/data:/var/solr
- ./docker-dev-volumes/solr/conf:/template

dev_smtp:
container_name: 'dev_smtp'
hostname: 'smtp'
image: maildev/maildev:2.0.5
restart: on-failure
expose:
- '25' # smtp server
ports:
- '1080:1080' # web ui
environment:
- MAILDEV_SMTP_PORT=25
- MAILDEV_MAIL_DIRECTORY=/mail
networks:
- dataverse
#volumes:
# - ./docker-dev-volumes/smtp/data:/mail
tmpfs:
- /mail:mode=770,size=128M,uid=1000,gid=1000

networks:
dataverse:
driver: bridge
16 changes: 16 additions & 0 deletions dev-env/dvconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
base_url = 'http://localhost:8000'
api_token = '<DATAVERSE_API_TOKEN>'
sample_data = [
'data/dataverses/pums/pums.json',
'data/dataverses/pums/datasets/2000pums5/2000pums5.json',
'data/dataverses/dataverseno/dataverseno.json',
'data/dataverses/open-source-at-harvard/open-source-at-harvard.json',
'data/dataverses/open-source-at-harvard/dataverses/dataverse-project/dataverse-project.json',
'data/dataverses/open-source-at-harvard/dataverses/dataverse-project/datasets/dataverse-irc-metrics/dataverse-irc-metrics.json',
'data/dataverses/ubiquity-press/ubiquity-press.json',
'data/dataverses/ubiquity-press/dataverses/jopd/jopd.json',
'data/dataverses/ubiquity-press/dataverses/jopd/datasets/flynn-effect-in-estonia/flynn-effect-in-estonia.json',
'data/dataverses/ubiquity-press/dataverses/jopd/datasets/bafacalo/bafacalo.json',
'data/dataverses/king/king.json',
'data/dataverses/king/datasets/cause-of-death/cause-of-death.json',
]
18 changes: 18 additions & 0 deletions dev-env/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
events {}
http {
server {
listen 80;
server_name localhost;

location / {
proxy_pass http://dataverse:8080;
}

location /spa {
proxy_pass http://frontend:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
}
4 changes: 4 additions & 0 deletions dev-env/rm-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

docker-compose -f "./docker-compose-dev.yml" down
rm -rf ./docker-dev-volumes
62 changes: 62 additions & 0 deletions dev-env/run-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash

export DATAVERSE_BRANCH_NAME=$1

# To avoid timeout issues on frontend container startup
export COMPOSE_HTTP_TIMEOUT=200

DATAVERSE_API_BASE_URL=http://localhost:8000/api

echo "INFO - Setting up Dataverse on branch ${DATAVERSE_BRANCH_NAME}..."

echo "INFO - Removing current environment if exists..."
./rm-env.sh

echo "INFO - Cloning Dataverse backend repository..."
git clone -b ${DATAVERSE_BRANCH_NAME} git@github.com:IQSS/dataverse.git

echo "INFO - Running docker containers..."
docker-compose -f "./docker-compose-dev.yml" up -d --build

echo "INFO - Waiting for containers to be ready..."
Comment on lines +18 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, I had an existing containerized dev env so I'm getting these errors:

 => [3/4] COPY package.json ./                                                                                    0.0s
 => [4/4] RUN npm install                                                                                       155.4s
 => exporting to image                                                                                           32.3s
 => => exporting layers                                                                                          32.3s
 => => writing image sha256:a74728f7351267800afd342ddfa2ce75cd075bab2dda9cc8a1414a7136cca1aa                      0.0s
 => => naming to docker.io/library/dev-env_dev_frontend                                                           0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Pulling dev_nginx (nginx:stable)...
stable: Pulling from library/nginx
9e3ea8720c6d: Pull complete
ee7feb8b89d4: Pull complete
3726de4affbb: Pull complete
4b5188c33a72: Pull complete
3c90f9dd7b85: Pull complete
2246bda193a8: Pull complete
Digest: sha256:b1a2c7bcc61be621eae24851a976179bfbc72591e43c1fb340f7497ff72128ff
Status: Downloaded newer image for nginx:stable
Creating dev_postgres ... 
Creating dev_smtp             ... error
Creating dev_solr_initializer ... 

Creating dev_postgres         ... error
in use by container "625132d69842de36ceb48e97802bf572c09cebad36fc180c680448707339c268". You have to remove (or rename) that container to be able to reuse that name.

ERROR: for dev_postgres  Cannot create container for service dev_postgres: Conflict. The container name "/dev_postgres" is already in use by container "cbf5acc6b793fa032268eb2371f934af8603ec094c0e03a371985cbec507db46". You have to remove Creating dev_solr_initializer ... error

ERROR: for dev_solr_initializer  Cannot create container for service dev_solr_initializer: Conflict. The container name "/dev_solr_initializer" is already in use by container "991489f935adac2e3bf6dd129f561e10de097fd493319c6606480463237671dd". You have to remove (or rename) that container to be able to reuse that name.

ERROR: for dev_smtp  Cannot create container for service dev_smtp: Conflict. The container name "/dev_smtp" is already in use by container "625132d69842de36ceb48e97802bf572c09cebad36fc180c680448707339c268". You have to remove (or rename) that container to be able to reuse that name.

ERROR: for dev_postgres  Cannot create container for service dev_postgres: Conflict. The container name "/dev_postgres" is already in use by container "cbf5acc6b793fa032268eb2371f934af8603ec094c0e03a371985cbec507db46". You have to remove (or rename) that container to be able to reuse that name.

ERROR: for dev_solr_initializer  Cannot create container for service dev_solr_initializer: Conflict. The container name "/dev_solr_initializer" is already in use by container "991489f935adac2e3bf6dd129f561e10de097fd493319c6606480463237671dd". You have to remove (or rename) that container to be able to reuse that name.
ERROR: Encountered errors while bringing up the project.
INFO - Waiting for containers to be ready...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this:

$ ./rm-env.sh 
WARNING: The DATAVERSE_BRANCH_NAME variable is not set. Defaulting to a blank string.
Removing network dev-env_dataverse
Removing network dev-env_default

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that didn't help. I think I need to docker rm these three manually:

ERROR: for dev_smtp  Cannot create container for service dev_smtp: Conflict. The container name "/dev_smtp" is already in use by container "625132d69842de36ceb48e97802bf572c09cebad36fc180c680448707339c268". You have to remove (or rename) Creating dev_postgres         ... error

ERROR: for dev_postgres  Cannot create container for service dev_postgres: Conflict. The container name "/dev_postgres"Creating dev_solr_initializer ... error
(or rename) that container to be able to reuse that name.

ERROR: for dev_solr_initializer  Cannot create container for service dev_solr_initializer: Conflict. The container name "/dev_solr_initializer" is already in use by container "991489f935adac2e3bf6dd129f561e10de097fd493319c6606480463237671dd". You have to remove (or rename) that container to be able to reuse that name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running docker rm on these manually fix it. I was able to bring up the dev env.

# Up to ~5 minutes
max_attempts=30
n_attempts=0
until $(curl --output /dev/null --silent --head --fail ${DATAVERSE_API_BASE_URL}/info/version); do
if [ ${n_attempts} -eq ${max_attempts} ];then
echo "ERROR - Timeout reached while waiting for containers to be ready"
./rm-env.sh
rm -rf dataverse
exit 1
fi
n_attempts=$(($n_attempts+1))
sleep 10
done

echo "INFO - Bootstrapping dataverse..."
cd dataverse
./scripts/dev/docker-final-setup.sh

echo "INFO - Cleaning up repository..."
cd ..
rm -rf dataverse

echo "INFO - Cloning Dataverse sample data repository..."
git clone git@github.com:IQSS/dataverse-sample-data.git

echo "INFO - Configuring Dataverse sample data repository..."
cd dataverse-sample-data
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp ../dvconfig.py ./dvconfig.py
curl -X PUT -d 'true' ${DATAVERSE_API_BASE_URL}/admin/settings/:AllowApiTokenLookupViaApi
dataverse_api_token=$(python3 get_api_token.py)
sed -i '' "s/<DATAVERSE_API_TOKEN>/${dataverse_api_token}/g" dvconfig.py

echo "INFO - Creating sample data..."
python3 create_sample_data.py
Comment on lines +57 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some sample data was created (screenshot below, honestly this is probably enough) but then the script exited early with this error:

Creating dataset cause-of-death.json in dataverse king
Dataset doi:10.5072/FK2/J3IUDU created.
<Response [201]>
data/dataverses/king/datasets/cause-of-death/files
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  391k  100   496  100  391k    370   292k  0:00:01  0:00:01 --:--:--  294k
{'status': 'OK', 'data': {'files': [{'description': '', 'label': 'adjacency_subset.sav', 'restricted': False, 'version': 1, 'datasetVersionId': 5, 'dataFile': {'id': 18, 'persistentId': '', 'filename': 'adjacency_subset.sav', 'contentType': 'application/x-spss-sav', 'filesize': 400569, 'description': '', 'storageIdentifier': 'local://1880138b119-b5ae7b172c21', 'rootDataFileId': -1, 'md5': '719388b2dfe326bd926a81cce8621211', 'checksum': {'type': 'MD5', 'value': '719388b2dfe326bd926a81cce8621211'}, 'creationDate': '2023-05-09'}}]}}
Lock found for dataset id 17... sleeping...
<Response [200]>
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0 4842k  100   183    0     0   7878      0 --:--:-- --:--:-- --:--:-- 12200
Traceback (most recent call last):
  File "/Users/pdurbin/github/iqss/dataverse-frontend/dev-env/dataverse-sample-data/create_sample_data.py", line 76, in <module>
    resp = api.upload_file(dataset_pid, "'" + filepath + "'")
  File "/Users/pdurbin/github/iqss/dataverse-frontend/dev-env/dataverse-sample-data/venv/lib/python3.10/site-packages/pyDataverse/api.py", line 1035, in upload_file
    resp = json.loads(result.stdout)
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
INFO - Cleaning up repository...
HMDC-beamish:dev-env pdurbin$ 

Screenshot 2023-05-09 at 11-56-35 Root

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


echo "INFO - Cleaning up repository..."
cd ..
rm -rf dataverse-sample-data
6 changes: 6 additions & 0 deletions dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM node:19.6.1
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
EXPOSE 5173
CMD ["npm", "start"]
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "vite",
"start": "vite --base=/spa",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "vitest watch",
Expand Down
8 changes: 8 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@ export default defineConfig({
plugins: [react()],
preview: {
port: 5173
},
server: {
//https://github.com/vitejs/vite/discussions/3396
host: true,
port: 5173,
hmr: {
clientPort: 8000 // nginx reverse proxy port
}
}
})