From 99cdff81a073e92fdc98f93ee1f2cd7365320828 Mon Sep 17 00:00:00 2001 From: Loren Buhle <31775445+lorenbuhle@users.noreply.github.com> Date: Wed, 7 Sep 2022 11:50:47 -0400 Subject: [PATCH] Add files via upload --- docker/README.md | 3 + docker/arm64v8.dev.docker-compose.yml | 115 ++++++++++ docker/arm64v8.qa.docker-compose.yml | 67 ++++++ docker/base.services.yml | 94 ++++++++ docker/dev.docker-compose.yml | 57 +++++ docker/entrypoint/docker-test-entrypoint.sh | 8 + .../entrypoint/isolation.docker-entrypoint.sh | 24 ++ docker/entrypoint/sidekiq.entrypoint.sh | 9 + docker/entrypoint/ui_test.entrypoint.sh | 34 +++ docker/entrypoint/web.entrypoint.sh | 12 + docker/external.arm64v8.docker-compose.yml | 20 ++ docker/external.docker-compose.yml | 21 ++ docker/external.services.yml | 29 +++ docker/images/Dockerfile | 9 + docker/images/isolation.Dockerfile | 21 ++ docker/images/isolation.arm64v8.Dockerfile | 19 ++ docker/images/test.Dockerfile | 15 ++ docker/images/ui_test.Dockerfile | 77 +++++++ docker/qa.docker-compose.yml | 56 +++++ docs/DEVELOPMENT_SETUP.md | 197 ++++++++-------- docs/DOCKER_BASED_SETUP.md | 216 ++++++++++++++++++ docs/DOCKER_COMPOSE_GUIDE.md | 84 +++++++ docs/MACOS_ARCHITECTURE_DIFFERENCES.md | 28 +++ docs/OS_BASED_SETUP.md | 178 +++++++-------- docs/REACT_FRONTEND_DEVELOPMENT.md | 156 ++++++------- docs/USEFUL_COMMANDS.md | 85 ++++--- 26 files changed, 1350 insertions(+), 284 deletions(-) create mode 100644 docker/README.md create mode 100644 docker/arm64v8.dev.docker-compose.yml create mode 100644 docker/arm64v8.qa.docker-compose.yml create mode 100644 docker/base.services.yml create mode 100644 docker/dev.docker-compose.yml create mode 100644 docker/entrypoint/docker-test-entrypoint.sh create mode 100644 docker/entrypoint/isolation.docker-entrypoint.sh create mode 100644 docker/entrypoint/sidekiq.entrypoint.sh create mode 100644 docker/entrypoint/ui_test.entrypoint.sh create mode 100644 docker/entrypoint/web.entrypoint.sh create mode 100644 docker/external.arm64v8.docker-compose.yml create mode 100644 docker/external.docker-compose.yml create mode 100644 docker/external.services.yml create mode 100644 docker/images/Dockerfile create mode 100644 docker/images/isolation.Dockerfile create mode 100644 docker/images/isolation.arm64v8.Dockerfile create mode 100644 docker/images/test.Dockerfile create mode 100644 docker/images/ui_test.Dockerfile create mode 100644 docker/qa.docker-compose.yml create mode 100644 docs/DOCKER_BASED_SETUP.md create mode 100644 docs/DOCKER_COMPOSE_GUIDE.md create mode 100644 docs/MACOS_ARCHITECTURE_DIFFERENCES.md diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..dddb1f2af --- /dev/null +++ b/docker/README.md @@ -0,0 +1,3 @@ +# Important note + +Before editing **any** of the `docker-compose.yml` files please read ["docker compose guide"](../docs/DOCKER_COMPOSE_GUIDE.md) \ No newline at end of file diff --git a/docker/arm64v8.dev.docker-compose.yml b/docker/arm64v8.dev.docker-compose.yml new file mode 100644 index 000000000..b8eb983c0 --- /dev/null +++ b/docker/arm64v8.dev.docker-compose.yml @@ -0,0 +1,115 @@ +version: '3.7' + +# NOTE(samuel) - docs - volumes have to always be in leaf docker compose files +volumes: + bundler-deps-cache-ruby: + db-pfda-mysql-volume: + webpack-cache-client: + yarn-network-cache-client: + yarn-network-cache-nodejs-api: + yarn-network-cache-nodejs-worker: + yarn-deps-cache-client: + yarn-deps-cache-nodejs-api: + yarn-deps-cache-nodejs-worker: + +services: + web: + extends: + file: ./base.services.yml + service: web + build: + context: ../ + dockerfile: docker/images/isolation.arm64v8.Dockerfile + environment: + - ARM64V8_DEVELOPMENT_PATCH=1 + - RAILS_ENV=development + - SKIP_RUBY_DEPS_SETUP=${SKIP_RUBY_DEPS_SETUP} + - SKIP_DB_SETUP=${SKIP_DB_SETUP} + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle + - db-pfda-mysql-volume:/var/lib/mysql + frontend: + extends: + file: ./base.services.yml + service: frontend + build: + context: ../client + dockerfile: ./docker/images/isolation.arm64v8.dev.Dockerfile + environment: + - SKIP_FRONTEND_DEPS_SETUP=${SKIP_FRONTEND_DEPS_SETUP} + volumes: + - type: volume + source: webpack-cache-client + target: /precision-fda/.build_cache/ + - type: bind + source: ../client/src + target: /precision-fda/src + - yarn-network-cache-client:${YARNV1_CACHE_DIR} + - yarn-deps-cache-client:/precision-fda/node_modules + nodejs-api: + extends: + file: ./base.services.yml + service: nodejs-api + build: + context: ../ + dockerfile: ./https-apps-api/docker/images/node.isolated-dev.Dockerfile + command: ['make', 'watch'] + environment: + - NODE_ENV=development + - NODE_DATABASE_NAME=precision-fda + - NODE_DATABASE_URL=mysql://root:password@db:3306/precision-fda + - SKIP_NODEJS_DEPS_SETUP=${SKIP_NODEJS_DEPS_SETUP} + volumes: + - type: bind + source: ../https-apps-api/packages + target: /app/packages + - yarn-network-cache-nodejs-api:${YARNV1_CACHE_DIR} + - yarn-deps-cache-nodejs-api:/app/node_modules + + nodejs-worker: + extends: + file: ./base.services.yml + service: nodejs-worker + build: + context: ../ + dockerfile: ./https-apps-api/docker/images/node.isolated-dev.Dockerfile + command: ['make', 'watch-worker'] + environment: + - NODE_ENV=development + - NODE_DATABASE_NAME=precision-fda + - NODE_DATABASE_URL=mysql://root:password@db:3306/precision-fda + - SKIP_NODEJS_DEPS_SETUP=${SKIP_NODEJS_DEPS_SETUP} + volumes: + - type: bind + source: ../https-apps-api/packages + target: /app/packages + - yarn-network-cache-nodejs-worker:${YARNV1_CACHE_DIR} + - yarn-deps-cache-nodejs-worker:/app/node_modules + db: + extends: + file: ./base.services.yml + service: db_emulated + volumes: + - db-pfda-mysql-volume:/var/lib/mysql + redis: + extends: + file: ./base.services.yml + service: redis + sidekiq: + extends: + file: ./base.services.yml + service: sidekiq + build: + context: ../ + dockerfile: docker/images/isolation.arm64v8.Dockerfile + environment: + - ARM64V8_DEVELOPMENT_PATCH=1 + - RAILS_ENV=development + - SKIP_RUBY_DEPS_SETUP=${SKIP_RUBY_DEPS_SETUP} + - SKIP_DB_SETUP=${SKIP_DB_SETUP} + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle diff --git a/docker/arm64v8.qa.docker-compose.yml b/docker/arm64v8.qa.docker-compose.yml new file mode 100644 index 000000000..5a9c5166d --- /dev/null +++ b/docker/arm64v8.qa.docker-compose.yml @@ -0,0 +1,67 @@ +version: '3.7' + +# ! Write a documentation note +# NOTE(samuel): docker volumes cannot be defined in abstract files +volumes: + bundler-deps-cache-ruby: + db-pfda-mysql-volume: + webpack-cache-client: + +services: + web: + extends: + file: ./base.services.yml + service: web + build: + context: ../ + dockerfile: docker/images/isolation.arm64v8.Dockerfile + environment: + - RAILS_ENV=ui_test + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle + - db-pfda-mysql-volume:/var/lib/mysql + + frontend: + extends: + file: ./base.services.yml + service: frontend + build: + context: ../client + dockerfile: ./docker/images/isolation.arm64v8.Dockerfile + volumes: + - type: volume + source: webpack-cache-client + target: /precision-fda/.build_cache/ + nodejs-api: + extends: + file: ./base.services.yml + service: nodejs-api + nodejs-worker: + extends: + file: ./base.services.yml + service: nodejs-worker + db: + extends: + file: ./base.services.yml + service: db_emulated + volumes: + - db-pfda-mysql-volume:/var/lib/mysql + redis: + extends: + file: ./base.services.yml + service: redis + sidekiq: + extends: + file: ./base.services.yml + service: sidekiq + build: + context: ../ + dockerfile: docker/images/isolation.arm64v8.Dockerfile + environment: + - RAILS_ENV=ui_test + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle diff --git a/docker/base.services.yml b/docker/base.services.yml new file mode 100644 index 000000000..e067164a4 --- /dev/null +++ b/docker/base.services.yml @@ -0,0 +1,94 @@ +services: + base_ruby: + build: + context: ../ + dockerfile: docker/images/isolation.Dockerfile + args: + - RUBY_IMAGE_TAG=2.7.5 + environment: + - RAILS_LOG_TO_STDOUT=1 + - LOG_REQUESTS=1 + - NO_FIPS=1 + - REDIS_WORKER_URL=redis://redis:6379/0 + base_nodejs: + build: + context: ../ + dockerfile: ./https-apps-api/docker/images/node.isolated-qa.Dockerfile + args: + - NODEJS_IMAGE_TAG=12.22.10 + + web: + extends: + service: base_ruby + volumes: + - type: bind + source: ../ + target: /precision-fda + working_dir: /precision-fda + ports: + - 3000:3000 + depends_on: + - db + - redis + - sidekiq + entrypoint: ./docker/entrypoint/isolation.docker-entrypoint.sh + + frontend: + build: + context: ../client + dockerfile: ./docker/images/isolation.Dockerfile + args: + - FRONTEND_IMAGE_TAG=12 + volumes: + - type: bind + source: ../app/assets/packs/bundle.js + target: /precision-fda/dist/bundle.js + working_dir: /precision-fda + command: yarn watch:docker + # TODO(samuel) setup correct NODE_ENV here + nodejs-api: + extends: + service: base_nodejs + command: ['make', 'run-dist'] + ports: + - 3001:3001 + depends_on: + - db + - redis + nodejs-worker: + extends: + service: base_nodejs + command: ['make', 'run-worker-dist'] + depends_on: + - db + - redis + sidekiq: + extends: + service: base_ruby + volumes: + - type: bind + source: ../ + target: /precision-fda + entrypoint: docker/entrypoint/sidekiq.entrypoint.sh + depends_on: + - redis + db: + # ! Don't forget to update "db_emulated" image when updating version + image: mysql:5.7 + environment: + - MYSQL_ROOT_PASSWORD=password + ports: + - 32800:3306 + + redis: + image: redis:5.0 + ports: + - 6379:6379 + + # Emulated images + # Note - it's better to keep this in this file as all the versions are at the same place + + db_emulated: + extends: + service: db + image: amd64/mysql:5.7 diff --git a/docker/dev.docker-compose.yml b/docker/dev.docker-compose.yml new file mode 100644 index 000000000..95fc3414a --- /dev/null +++ b/docker/dev.docker-compose.yml @@ -0,0 +1,57 @@ +version: '3.7' + +volumes: + bundler-deps-cache-ruby: + db-pfda-mysql-volume: + webpack-cache-client: + +services: + web: + extends: + file: ./base.services.yml + service: web + environment: + - RAILS_ENV=development + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle + - db-pfda-mysql-volume:/var/lib/mysql + frontend: + extends: + file: ./base.services.yml + service: frontend + volumes: + - type: volume + source: webpack-cache-client + target: /precision-fda/.build_cache/ + command: yarn watch:docker + nodejs-api: + extends: + file: ./base.services.yml + service: nodejs-api + nodejs-worker: + extends: + file: ./base.services.yml + service: nodejs-worker + db: + extends: + file: ./base.services.yml + service: db + volumes: + - db-pfda-mysql-volume:/var/lib/mysql + redis: + extends: + file: ./base.services.yml + service: redis + sidekiq: + extends: + file: ./base.services.yml + service: sidekiq + environment: + - RAILS_ENV=development + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle + diff --git a/docker/entrypoint/docker-test-entrypoint.sh b/docker/entrypoint/docker-test-entrypoint.sh new file mode 100644 index 000000000..8b67b33ef --- /dev/null +++ b/docker/entrypoint/docker-test-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +cp config/database.sample.yml config/database.yml + +service mysql start + +bundle exec rake db:setup +bundle exec rake diff --git a/docker/entrypoint/isolation.docker-entrypoint.sh b/docker/entrypoint/isolation.docker-entrypoint.sh new file mode 100644 index 000000000..97f10aaa5 --- /dev/null +++ b/docker/entrypoint/isolation.docker-entrypoint.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +sed -i '/^#/!s/CipherString = DEFAULT@SECLEVEL=2/#CipherString = DEFAULT@SECLEVEL=2/g' /etc/ssl/openssl.cnf + +dockerize -wait tcp://db:3306 + +cp config/database.sample.yml config/database.yml + +if [[ ! $SKIP_RUBY_DEPS_SETUP || $SKIP_RUBY_DEPS_SETUP = 0 ]]; then + bundle check || bundle install +fi + +if [[ ! $SKIP_DB_SETUP || $SKIP_DB_SETUP = 0 ]]; then + # Runs setup if database does not exist, or runs migrations if it does + bundle exec rake db:prepare + + bundle exec rake user:generate_test_users +fi + +if [[ -f ./key.pem && -f ./cert.pem ]]; then + bundle exec thin --debug start --ssl --ssl-key-file ./key.pem --ssl-cert-file ./cert.pem +else + bundle exec thin --ssl --debug start +fi diff --git a/docker/entrypoint/sidekiq.entrypoint.sh b/docker/entrypoint/sidekiq.entrypoint.sh new file mode 100644 index 000000000..5f90cded2 --- /dev/null +++ b/docker/entrypoint/sidekiq.entrypoint.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +sed -i '/^#/!s/CipherString = DEFAULT@SECLEVEL=2/#CipherString = DEFAULT@SECLEVEL=2/g' /etc/ssl/openssl.cnf + +# Install gems if needed +bundle check || bundle install + +# Run sidekiq +bundle exec sidekiq diff --git a/docker/entrypoint/ui_test.entrypoint.sh b/docker/entrypoint/ui_test.entrypoint.sh new file mode 100644 index 000000000..99564956a --- /dev/null +++ b/docker/entrypoint/ui_test.entrypoint.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +sed -i '/^#/!s/CipherString = DEFAULT@SECLEVEL=2/#CipherString = DEFAULT@SECLEVEL=2/g' /etc/ssl/openssl.cnf + +cp config/database.sample.yml config/database.yml + +service mysql start + +bundle exec rake db:setup +bundle exec rake user:generate_test_users +bundle exec thin --ssl -d start + +#warm up +result=7 +while [[ "$result" == 7 ]] +do + curl -k -o /dev/null https://localhost:3000 + result=$? + sleep 1 +done + +echo "Server up" + +suite=${TEST_SUITE:-fullregression} + +echo "Running suite $suite" + +cd test/functional && mvn -B test -Dsuite=$suite.xml -Dheadless=true -Denv=loc + +#save logs and screenshots +rm -rf /log_storage/docker +mkdir /log_storage/docker +mv /precision-fda/test/functional/target/debug-log/* /log_storage/ +chmod -R 777 /log_storage/docker diff --git a/docker/entrypoint/web.entrypoint.sh b/docker/entrypoint/web.entrypoint.sh new file mode 100644 index 000000000..c46ff0d60 --- /dev/null +++ b/docker/entrypoint/web.entrypoint.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +sed -i '/^#/!s/CipherString = DEFAULT@SECLEVEL=2/#CipherString = DEFAULT@SECLEVEL=2/g' /etc/ssl/openssl.cnf + +# Install gems if needed +bundle check || bundle install + +if [[ -f ./key.pem && -f ./cert.pem ]]; then + bundle exec thin --debug start --ssl --ssl-key-file ./key.pem --ssl-cert-file ./cert.pem +else + bundle exec thin --ssl --debug start +fi diff --git a/docker/external.arm64v8.docker-compose.yml b/docker/external.arm64v8.docker-compose.yml new file mode 100644 index 000000000..90ded6046 --- /dev/null +++ b/docker/external.arm64v8.docker-compose.yml @@ -0,0 +1,20 @@ +volumes: + db-gsrs-mysql-volume: + +services: + web: + depends_on: + - gsrs + environment: + - GSRS_URL=http://gsrs:9000 + - GSRS_ENABLED=true + gsrs: + extends: + file: ./external.services.yml + service: gsrs + gsrsdb: + extends: + file: ./external.services.yml + service: gsrsdb_emulated + volumes: + - db-gsrs-mysql-volume:/var/lib/mysql diff --git a/docker/external.docker-compose.yml b/docker/external.docker-compose.yml new file mode 100644 index 000000000..1de1bbc0f --- /dev/null +++ b/docker/external.docker-compose.yml @@ -0,0 +1,21 @@ +volumes: + db-gsrs-mysql-volume: + +services: + web: + depends_on: + - gsrs + environment: + - GSRS_URL=http://gsrs:9000 + - GSRS_ENABLED=true + gsrs: + extends: + file: ./external.services.yml + service: gsrs + gsrsdb: + extends: + file: ./external.services.yml + service: gsrsdb + volumes: + - db-gsrs-mysql-volume:/var/lib/mysql + diff --git a/docker/external.services.yml b/docker/external.services.yml new file mode 100644 index 000000000..1071c057f --- /dev/null +++ b/docker/external.services.yml @@ -0,0 +1,29 @@ +services: + gsrs: + build: + context: ../ + dockerfile: ./gsrs/docker/images/gsrs.Dockerfile + environment: + - MYSQL_HOST=gsrsdb + - MYSQL_DATABASE=ixginas + - MYSQL_ROOT_PASSWORD=password + - GSRS_PORT=9000 + ports: + - 9000:9000 + depends_on: + - gsrsdb + + gsrsdb: + image: mysql:${MYSQL_IMAGE_TAG:-5.6} + tmpfs: + - /tmp + - /run/mysqld + environment: + - MYSQL_DATABASE=ixginas + - MYSQL_ROOT_PASSWORD=password + ports: + - 32900:3306 + gsrsdb_emulated: + extends: + service: gsrsdb + image: amd64/mysql:${MYSQL_IMAGE_TAG:-5.6} diff --git a/docker/images/Dockerfile b/docker/images/Dockerfile new file mode 100644 index 000000000..b02a4e5c6 --- /dev/null +++ b/docker/images/Dockerfile @@ -0,0 +1,9 @@ +FROM ruby:2.7.5 + +ENV BUNDLER_VERSION 2.3.7 + +RUN apt-get update && apt-get install -y cmake libssl-dev && gem install bundler -v ${BUNDLER_VERSION} + +WORKDIR /precision-fda + +COPY Gemfile Gemfile.lock ./ diff --git a/docker/images/isolation.Dockerfile b/docker/images/isolation.Dockerfile new file mode 100644 index 000000000..5080ac3fa --- /dev/null +++ b/docker/images/isolation.Dockerfile @@ -0,0 +1,21 @@ +ARG RUBY_IMAGE_TAG + +FROM ruby:${RUBY_IMAGE_TAG} + +ENV DOCKERIZE_VERSION v0.6.0 +ENV APP_DIR /precision-fda +ENV BUNDLER_VERSION 2.3.7 + +ARG rails_env=development +ENV RAILS_ENV=$rails_env + +WORKDIR $APP_DIR +RUN apt-get update && \ + apt-get install -y cmake wget libssl-dev nodejs && \ + wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && \ + tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && \ + rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && \ + gem install bundler -v ${BUNDLER_VERSION} +COPY ./docker/entrypoint/isolation.docker-entrypoint.sh $APP_DIR/docker/entrypoint/isolation.docker-entrypoint.sh + +CMD $APP_DIR/docker/entrypoint/isolation.docker-entrypoint.sh diff --git a/docker/images/isolation.arm64v8.Dockerfile b/docker/images/isolation.arm64v8.Dockerfile new file mode 100644 index 000000000..a9f8c2cac --- /dev/null +++ b/docker/images/isolation.arm64v8.Dockerfile @@ -0,0 +1,19 @@ +ARG RUBY_IMAGE_TAG + +FROM amd64/ruby:${RUBY_IMAGE_TAG} +# This dockerfile is required for Apple Silicon M1, otherwise gem installation during build of "web" and "sidekiq" services fails + +ENV DOCKERIZE_VERSION v0.6.0 +ENV APP_DIR /precision-fda +ENV BUNDLER_VERSION 2.3.7 + +WORKDIR $APP_DIR +RUN apt-get update && \ + apt-get install -y cmake wget libssl-dev nodejs && \ + wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && \ + tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && \ + rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && \ + gem install bundler -v ${BUNDLER_VERSION} +COPY ./docker/entrypoint/isolation.docker-entrypoint.sh $APP_DIR/docker/entrypoint/isolation.docker-entrypoint.sh + +CMD $APP_DIR/docker/entrypoint/isolation.docker-entrypoint.sh diff --git a/docker/images/test.Dockerfile b/docker/images/test.Dockerfile new file mode 100644 index 000000000..79bb41396 --- /dev/null +++ b/docker/images/test.Dockerfile @@ -0,0 +1,15 @@ +# Note: This dockerfile should be built from Ruby root directory +# `docker build -f docker/images/test.Dockerfile .` + +FROM ruby:2.7.5 +RUN apt-get update +RUN echo 'mysql-server mysql-server/root_password password password' | debconf-set-selections +RUN echo 'mysql-server mysql-server/root_password_again password password' | debconf-set-selections +RUN apt-get -y install mysql-server +ENV APP_DIR=/precision-fda +WORKDIR $APP_DIR +RUN mkdir -p $APP_DIR +COPY Gemfile Gemfile.lock $APP_DIR/ +RUN bundle install +COPY . $APP_DIR +CMD $APP_DIR/docker/entrypoint/docker-test-entrypoint.sh diff --git a/docker/images/ui_test.Dockerfile b/docker/images/ui_test.Dockerfile new file mode 100644 index 000000000..2e057088b --- /dev/null +++ b/docker/images/ui_test.Dockerfile @@ -0,0 +1,77 @@ +#docker build -f docker/ui_test.Dockerfile -t autoui . +#docker run \ +#-e PFDA_AT_USER_1_PASSWORD_LOC \ +#-e PFDA_AT_USER_2_PASSWORD_LOC \ +#-e PFDA_AT_USER_ADMIN_PASSWORD_LOC \ +#-e PFDA_BASIC_AUTH_DNX_PASSWORD_LOC \ +#--mount type=bind,source="$(pwd)"/tmp/,target=/log_storage \ +#autoui + +ARG FIREFOX_VERSION=57.0 +ARG RUBY_IMAGE_TAG +ARG MAVEN_VERSION=3.3.9 +FROM ruby:${RUBY_IMAGE_TAG} + +RUN echo deb http://http.debian.net/debian jessie-backports main >> /etc/apt/sources.list && \ + apt-get update && \ + apt-get -y -qq install libgtk-3-dev && \ + # Mysql + echo 'mysql-server mysql-server/root_password password password' | debconf-set-selections && \ + echo 'mysql-server mysql-server/root_password_again password password' | debconf-set-selections && \ + apt-get -y -qq install mysql-server && \ + # Firefox + wget -nv -O /tmp/firefox.tar.bz2 https://ftp.mozilla.org/pub/firefox/releases/${FIREFOX_VERSION}/linux-x86_64/en-US/firefox-${FIREFOX_VERSION}.tar.bz2 && \ + tar -C /opt -xjf /tmp/firefox.tar.bz2 && \ + rm /tmp/firefox.tar.bz2 && \ + mv /opt/firefox /opt/firefox-${FIREFOX_VERSION} && \ + ln -fs /opt/firefox-${FIREFOX_VERSION}/firefox /usr/bin/firefox && \ + # Geckodriver + wget -nv https://github.com/mozilla/geckodriver/releases/download/v0.19.1/geckodriver-v0.19.1-linux64.tar.gz && \ + apt-get -y -qq install software-properties-common python-software-properties && \ + # JDK + apt-get install -y -qq -t jessie-backports openjdk-8-jdk && \ + update-alternatives --config java && \ + # Maven + mkdir /usr/share/maven && \ + wget -nv https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz && \ + tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /usr/share/maven --strip-components=1 && \ + ln -s /usr/share/maven/bin/mvn /usr/bin/mvn + +ENV APP_DIR=/precision-fda + +WORKDIR $APP_DIR + +COPY Gemfile Gemfile.lock $APP_DIR/ + +RUN bundle install + +COPY test/functional/pom.xml . + +RUN mvn -B dependency:resolve + +COPY . $APP_DIR +RUN tar -xzf /geckodriver-v0.19.1-linux64.tar.gz -C $APP_DIR/test/functional/drivers/ + +WORKDIR $APP_DIR/test/functional +RUN mvn -B compile test-compile +WORKDIR $APP_DIR + +ENV DATABASE_URL=mysql2://root:password@localhost/precision-fda-uitest +ENV RAILS_ENV=ui_test +ENV PFDA_USER_ORG_HANDLE=alice_org +ENV PFDA_USER_DXUSER=alice +ENV NO_FIPS=1 + +ENV PFDA_AT_USER_1_PASSWORD_DEV="password" +ENV PFDA_AT_USER_2_PASSWORD_DEV="password" +ENV PFDA_AT_USER_ADMIN_PASSWORD_DEV="password" +ENV PFDA_BASIC_AUTH_DNX_PASSWORD_DEV="password" + +ENV PFDA_SERVER_URL_DEV="https://localhost:3000" +ENV PFDA_SERVER_URL_LOC="https://localhost:3000" +ENV PFDA_SERVER_URL_PROD="https://localhost:3000" + +ENV PFDA_PLATFORM_SERVER_URL_LOC="https://staging.dnanexus.com" +ENV PFDA_PLATFORM_SERVER_URL_DEV="https://staging.dnanexus.com" + +ENTRYPOINT $APP_DIR/docker/entrypoint/ui_test.entrypoint.sh diff --git a/docker/qa.docker-compose.yml b/docker/qa.docker-compose.yml new file mode 100644 index 000000000..8057648aa --- /dev/null +++ b/docker/qa.docker-compose.yml @@ -0,0 +1,56 @@ +version: '3.7' + +volumes: + bundler-deps-cache-ruby: + db-pfda-mysql-volume: + webpack-cache-client: + +services: + web: + extends: + file: ./base.services.yml + service: web + environment: + - RAILS_ENV=ui_test + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle + - db-pfda-mysql-volume:/var/lib/mysql + frontend: + extends: + file: ./base.services.yml + service: frontend + volumes: + - type: volume + source: webpack-cache-client + target: /precision-fda/.build_cache/ + nodejs-api: + extends: + file: ./base.services.yml + service: nodejs-api + nodejs-worker: + extends: + file: ./base.services.yml + service: nodejs-worker + db: + extends: + file: ./base.services.yml + service: db + volumes: + - db-pfda-mysql-volume:/var/lib/mysql + redis: + extends: + file: ./base.services.yml + service: redis + sidekiq: + extends: + file: ./base.services.yml + service: sidekiq + environment: + - RAILS_ENV=ui_test + volumes: + - type: volume + source: bundler-deps-cache-ruby + target: /usr/local/bundle + diff --git a/docs/DEVELOPMENT_SETUP.md b/docs/DEVELOPMENT_SETUP.md index 4d04f3677..ef60362ab 100644 --- a/docs/DEVELOPMENT_SETUP.md +++ b/docs/DEVELOPMENT_SETUP.md @@ -1,89 +1,108 @@ -# Development environment configuration -``` -You can skip any furhter section if you already have installed and configured required software. -``` - -To develop on pFDA locally you need to manually add a new user and organization. -Because when you first get started in a new system, -there is no existing user. So you can't log in to provision new accounts. -This requires manually "bootstrapping" the situation in steps described below. - -## New account registration -Register for a new user account at [https://staging.dnanexus.com/register](https://staging.dnanexus.com/register). -Note: the first time you visit this, you will be prompted to enter the credentials -(ask around for what it is). -You must choose an unused email address, but you can use the google "+" trick -to signup with a variable email address, e.g. `your_username+pfdalocal@dnanexus.com`. -Activate your account with the link sent to your email. - -## Create a new organization: -- Download & install the DX Toolkit [https://documentation.dnanexus.com/downloads#dnanexus-platform-sdk](https://documentation.dnanexus.com/downloads#dnanexus-platform-sdk). -- Choose an unused handle, e.g. `{{yourname}}org`. Prepend `pfda..` (two dots), - so that the final handle will be e.g. `pfda..farnsworthorg`. -- Type `dx login --staging` and log in with your new account. -- Type `dx new org --handle pfda..{{yourname}}org "{{Yourname}}'s org"` -- Log into the web UI [https://staging.dnanexus.com](https://staging.dnanexus.com) -with your account, access your profile on the upper right. -- Click __Billing Accounts__ -- Click __Add Billing Info__ in the pfda..floranteorg entry. - - Note: You may need to contact Laura (sales) for the billing info. -- Enter info (it doesn't have to be real, you can type "." in most entries). Enter your real DNAnexus email, however. -- Click __Update Billing Information__ -- Check your email for a new email message asking you to confirm by clicking the link -- Click the link to confirm. - -## MacOS specific prerequisites -* Install XCode - * Search and install XCode from the App Store. - -* Install Apple Command Line Tools - * Open XCode (this just needs to run once to initialize it) and close it. - * Install XCode command line tools by running `xcode-select --install` in - the terminal. - -* Install [Homebrew](http://brew.sh/) - * `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` - * Run `brew update` to make sure all your formulas are current - -* Install git - * `brew install git` - -## Ubuntu Linux specific prerequisites -* Update software packages definitions - * `apt-get update` - -* Install git - * `apt-get install git` - -## Common steps (MacOS and Ubuntu Linux) - -* Set up git ssh - * `ssh-keygen -t rsa -b 4096 -C "your_email@dnanexus.com"` - -* Add generated SSH key to [Github](https://github.com/settings/keys) - -* Set up git config - * `git config --global core.editor "vim"` - * `git config --global user.email “your_email@dnanexus.com”` - * `git config --global user.name “FirstName LastName”` - * `git config --global push.default simple` - -* Clone repo - * `git clone git@github.com:dnanexus/precision-fda.git` - -* Create database config file - * `cp config/database.yml.sample config/database.yml` - -* Create environment config file - * `cp .env.sample .env` - -* Ask Dev team for additional parameters to add into `.env` file - -## Choose further setup mode and proceed with it - -[OS-based setup](OS_BASED_SETUP.md) will require to install some additional software -like MySQL, RVM and required gems directly into your OS. - -[Docker-based setup](DOCKER_BASED_SETUP.md) will require to install docker into your system. Additional -software like MySQL and required gems will be installed into docker containers so your OS -stays clean of them. +# Development Setup +``` +You can skip any section if you have already installed the dependencies. +``` + +## MacOS specific prerequisites +* Install XCode + * Search and install Xcode from the App Store. + + Need different Xcode version? See [list of xip archive links](https://stackoverflow.com/a/10335943) + +* Install Apple Command Line Tools + * Open XCode (this just needs to run once to initialize it) and close it. + * Install XCode command line tools by running `xcode-select --install` in + the terminal. + +* Install [Homebrew](http://brew.sh/) + * `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` + * Run `brew update` to make sure all your formulas are current + +* Install git + * On Mavericks (10.9) or above you can do this simply by trying to run git from the Terminal the very first time: + + `git --version` + + If you don’t have it installed already, it will prompt you to install it. + * Installing via Homebrew: + + `brew install git` + +## Ubuntu/Linux specific prerequisites +* Update software packages definitions + * `apt-get update` + +* Install git + * `apt-get install git` + + +## Common steps (MacOS and Ubuntu Linux) + +* [Set up git ssh](https://docs.github.com/articles/generating-an-ssh-key/) + * `ssh-keygen -t ed25519-sk -C "your_email@dnanexus.com"` + +* Add generated SSH key to [Github](https://github.com/settings/keys) + +* Set up git config + * `git config --global core.editor "vim"` + * `git config --global user.email “your_email@dnanexus.com”` + * `git config --global user.name “FirstName LastName”` + * `git config --global push.default simple` + +* Clone repo + * `git clone git@github.com:dnanexus/precision-fda.git` + +* Create database config file + * `cp config/database.sample.yml config/database.yml` + +* Create environment config file + * `cp .env.sample .env` + +* Ask Dev team for additional parameters to add into `.env` file + + +# Certificate and dev account + +To develop on pFDA locally you need to manually add a new user and organization. +Because when you first get started in a new system, +there is no existing user. So you can't log in to provision new accounts. +This requires manually "bootstrapping" the situation in steps described below. + +## Certificate and Key +- `brew install mkcert` - Install MKCert on your computer: https://github.com/FiloSottile/mkcert +- `mkcert -install` +- From project root run: `mkcert -key-file key.pem -cert-file cert.pem localhost 0.0.0.0 pfda.dev` +- This will create two files `key.pem` and `cert.pem`. They need to be generated on your machine to + get rid of the annoying unprotected site warning in the browser. + +## New account registration +Register for a new user account at [https://staging.dnanexus.com/register](https://staging.dnanexus.com/register). +Note: the first time you visit this, you will be prompted to enter the credentials +(ask around for what it is). +You must choose an unused email address, but you can use the google "+" trick +to signup with a variable email address, e.g. `your_username+pfdalocal@dnanexus.com`. +Activate your account with the link sent to your email. + +## Create a new organization: +- Download & install the DX Toolkit [https://documentation.dnanexus.com/downloads#dnanexus-platform-sdk](https://documentation.dnanexus.com/downloads#dnanexus-platform-sdk). +- Choose an unused handle, e.g. `{{yourname}}org`. Prepend `pfda..` (two dots), + so that the final handle will be e.g. `pfda..farnsworthorg`. +- Type `dx login --staging` and log in with your new account. +- Type `dx new org --handle pfda..{{yourname}}org "{{Yourname}}'s org"` +- Log into the web UI [https://staging.dnanexus.com](https://staging.dnanexus.com) +with your account, access your profile on the upper right. +- Click __Billing Accounts__ +- Click __Add Billing Info__ in the pfda..floranteorg entry. + - Note: You may need to contact Laura (sales) for the billing info. +- Enter info (it doesn't have to be real, you can type "." in most entries). Enter your real DNAnexus email, however. +- Click __Update Billing Information__ +- Check your email for a new email message asking you to confirm by clicking the link +- Click the link to confirm. + + +# Continue setup either using Docker or OS + +[Docker-based setup (preferred)](DOCKER_BASED_SETUP.md) will require to install docker into your system. Dependencies MySQL and required gems will be installed into docker containers to minimize conflicts in the host system with other projects. + +[OS-based setup](OS_BASED_SETUP.md) will require to install some additional software +like MySQL, RVM and required gems directly into your OS. diff --git a/docs/DOCKER_BASED_SETUP.md b/docs/DOCKER_BASED_SETUP.md new file mode 100644 index 000000000..f914169dd --- /dev/null +++ b/docs/DOCKER_BASED_SETUP.md @@ -0,0 +1,216 @@ +# Docker-based setup + + +This guide covers all the steps required to get docker based +development environment. There are also a few _optional_ sections, that are strongly recommended to use for full-stack developer roles + +## Prerequisites + +Make sure that you understand this [Makefile](../Makefile) + +Make sure you know, which configuration to use. Your configuration depends on following + +* role (qa | dev) +* architecture of your workstation + * unless its windows, you can find it using command - `uname -m` + +## Installing docker and docker-compose + +> If you already have docker installed in your system, you can skip this step. + +The first step you have to do is to install [docker](https://docs.docker.com/install/) on your workstation. Instructions are **platform-specific** + +## Makefile and platform differences + +Because of platform differences between M1-silicon and Intel MacOS CPUs and technologies used in our stack, the docker environment setup is **platform-specific**, more on the topic [here](./MACOS_ARCHITECTURE_DIFFERENCES.md). +Summary of all configurations is in top level [Makefile](../Makefile), which contains some basic commands. Feel free to add more according to your own need. + +Note that not all `docker compose` commands are implemented - so when you want to execute `docker compose` command, make sure you have corresponding flags (`-f `) according to [Makefile](../Makefile). + +### Example scenario + +I am a dev using MacBook with `M1-silicon` CPU, and `nodejs-api` container just died (for some reason) + +I can restart it with following command + +```bash +# Edited from "make run-arm64v8-dev" +docker compose -f docker/arm64v8.dev.docker-compose.yml restart nodejs-api +``` +## Minor fixes that it's better to setup in advance + +Majority of the UI is developed as React app - see [client/package.json](../client/package.json). +Compiled react app is served from asset pipeline. For now it requires sharing files between two running containers, which is accomplished with bind mounts (feel free to read through `docker-compose.yml` files for better understanding of topic) + +To keep number of side effects minimal, single file `bundle.js` is mounted instead of whole directory. Although it's cleaner solution, this results in possible issue during initial setup, where source bind mount is missing. Fix it by running following commands + +```bash +mkdir -p app/assets/packs +touch app/assets/packs/bundle.js +``` + +### Minor configuration differences for nodejs-api + +If you're running stack with `make run-arm64v8-dev` configuration, it uses different key paths for `nodejs-api`. Edit `https-apps-api/.env` with following values + +``` +NODE_PATH_CERT=/keys/cert.pem +NODE_PATH_KEY_CERT=/keys/key.pem +``` +## Database setup + +The source of truth for `precision-fda` portal is `mysql` db, which is initialized with +* db migrations, that results in following [schema](../db/schema.rb) + * See `db/migrate` directory, for instance [this file](../db/migrate/20150904202622_create_users.rb) +* `rake ` tasks that prepopulate the database, such as [this one](../lib/tasks/user.rake), that generates dummy users + +### 1. Configure + +* Create a `config/database.yml` file containing the database configuration + ```bash + # Run in 'precision-fda' root directory + # Use 'config/database.sample.yml' as a template + cp config/database.sample.yml config/database.yml + ``` +* Create a `.env` file in the project root with an additional environment variables to be passed into Docker containers. + ```bash + # NOTE - this env file is different from the one defined in "General Setup" section + cp .env.example .env + ``` + * > This part is work in progress + * [`.env.example` file](../.env.example) is a reference file, however, there are a handful of secrets, ask a colleague to provide them + + +### 2. Prepare the database + +The command might vary, depending on your role (dev, qa), or on CPU architecture of the workstation (`x86_64`, `arm64`). You can find more details on the topic [here](./MACOS_ARCHITECTURE_DIFFERENCES.md) + +```bash +# UNTESTED +# intel dev +make prepare-db +# intel qa +make prepare-db-qa +# arm64v8 (Apple M1 Silicon) dev +make prepare-db-arm64v8-dev +# arm64v8 (Apple M1 Silicon) qa +make prepare-db-arm64v8-qa +``` + +## Nodejs API setup + +There are also env variables specific for `nodejs` part of the repository, particularly `nodejs-api` and `nodejs-worker` + +```bash +cp https-apps-api/.env.example https-apps-api/.env +``` + +## (Optional) Account setup + +To use your own account to log-in to the system, run the command to +create database with the environment variables set with your account's data (if you don't have +an account yet, please refer to +[New account registration](DEVELOPMENT_SETUP.md#new-account-registration)): + +```bash +docker compose exec \ + -e PFDA_USER_FIRST_NAME=Florante \ + -e PFDA_USER_LAST_NAME=DelaCruz \ + -e PFDA_USER_EMAIL=fdelacruz+pfdalocal@dnanexus.com \ + -e PFDA_USER_ORG_HANDLE=floranteorg \ + -e PFDA_USER_DXUSER=fdelacruz \ + web bundle exec rake {db:setup,db:migrate,user:generate_test_users} +# ! Don't forget to add respective flags before running this command +# For instance, dev with "arm64v8" +# docker compose +# -f docker/arm64v8.dev.docker-compose.yml \ +# exec \ +# -e PFDA_USER_FIRST_NAME=Florante \ +# -e PFDA_USER_LAST_NAME=DelaCruz \ +# -e PFDA_USER_EMAIL=fdelacruz+pfdalocal@dnanexus.com \ +# -e PFDA_USER_ORG_HANDLE=floranteorg \ +# -e PFDA_USER_DXUSER=fdelacruz \ +# web bundle exec rake {db:setup,db:migrate,user:generate_test_users} +``` + +## Running application + +Running again depends on role and workstation type + +```bash +# intel dev +make run +# intel qa +make run-qa +# arm64v8 (Apple M1 Silicon) dev +make run-arm64v8-dev +# arm64v8 (Apple M1 Silicon) qa +make run-arm64v8-qa +``` + +Once the application is correctly installed & configured, you should be able to access the portal at `https://localhost:3000/`. +In order to log in to the system, ask for shared DEV credentials (ask some1 from the team) + +## Running application with external services + +```bash +# intel dev +make run-all +# intel qa +make run-all-qa +# arm64v8 (Apple M1 Silicon) dev +make run-all-arm64v8-dev +# arm64v8 (Apple M1 Silicon) qa +make run-all-arm64v8-qa +``` + +### GSRS + +GSRS runs as a process on the same instance as pFDA but is completely separate codebase + +_Last updated 14.6.2022_ + +> Atm GSRS local setup is not fully functional, needs various fixes. Contact colleagues to get more information on this topic + +## (Optional) Setup for impatient personalities + +There are a few [docker-related](../docker/arm64v8.dev..docker-compose.yml) [env variables](../docker/.env.example), that are used in `docker-compose.yml` files, such as `SKIP_RUBY_SETUP` +After you run your docker setup successfully, and want to save some time by skipping dependency checks and reinstallations (assuming you've got them correct), feel free to setup + +```bash +# Run in 'precision-fda' root directory +cp docker/.env.example docker/.env +``` + +For obvious reasons these settings aren't versioned, and therefore are kept in separate [docker/.env](../docker/.env.example) file + + +## (Optional) Symlink docker-compose.yml for less typing + +If copy-pasting too many CLI options (such as `-f docker/dev.docker-compose.yml`) is getting frustrating, feel free to symlink your favourite configuration into `docker-compose.yml` + +For instance + +```bash +# Run in 'precision-fda' root directory +# intel dev +ln -s docker/dev.docker-compose.yml docker/docker-compose.yml +# intel qa +ln -s docker/qa.docker-compose.yml docker/docker-compose.yml +# arm64v8 (Apple M1 Silicon) dev +ln -s docker/arm64v8.dev.docker-compose.yml docker/docker-compose.yml +# arm64v8 (Apple M1 Silicon) qa +ln -s docker/arm64v8.qa.docker-compose.yml docker/docker-compose.yml +``` + +This makes use of docker compose more trivial, you can start the stack with simply + +```bash +docker compose up --build +``` + +Note that this part of setup is experimental, potential side effects are suspected with this approach + +## Updating docker-compose files + +Before updating anything related to docker setup, please take a look at [Docker compose guide](./DOCKER_COMPOSE_GUIDE.md), to update according to repo best practices diff --git a/docs/DOCKER_COMPOSE_GUIDE.md b/docs/DOCKER_COMPOSE_GUIDE.md new file mode 100644 index 000000000..af6129d9e --- /dev/null +++ b/docs/DOCKER_COMPOSE_GUIDE.md @@ -0,0 +1,84 @@ +# Docker compose guide + +This guide contains summary and best practices for dockerization in this repo. + +_Last updated: 14.6.2022_ + +## Prerequisites + +Make sure that you understand local configurations, described in [root "Makefike"](../Makefile) and ["docker-based setup" document](./DOCKER_BASED_SETUP.md) + +## `extends` keyword + +Although according to [docker documentation](https://docs.docker.com/compose/extends/#extending-services), `extend`ing is no longer supported in the most recent compose specification-v3, [this update](https://github.com/docker/compose/pull/7588) however makes it possible, to use blend of features from two different compose specifiactions (read through PR comments for more information) - in other words, we can use `extends` keyword + +We use `extends` as primary tool to structure docker configuration with DRY principles + +## Shared vs. specific + +As mentioned in ["docker-based setup" document](./DOCKER_BASED_SETUP.md) and defined in [root "Makefike"](../Makefile), we use 4 specific configurations. There are 2 main reasons for that. Firstly because QAs and devs have different requirements, but also because of bugs in docker for `M1-silicon` apple CPUs - list mentioned on [docker website](https://docs.docker.com/desktop/mac/apple-silicon/) + +Summary of configurations + +* `dev` +* `qa` +* `arm64v8-dev` +* `arm64v8-qa` + +When creating/updating options, you should take into consideration, whether the option impacts colleagues - is it applicable/desired/required for their situation? Or is it only my specific use case? + +In order to retain DRY principles, majority of settings is shared in following files + +* [`base.services.yml`](../docker/base.services.yml) +* [`external.services.yml`](../docker/external.services.yml) + * Details described in section [External services](#external-services) + +Due to maintenance of multiple configurations, that have their own specifics, each configuration has its own `docker-compose` + +If you take a look at [one of docker-compose files](../docker/dev.docker-compose.yml) implementation mostly consists of `extend`ing services defined in `base.services.yml` and applying additional settings. + +### Volumes + +`extends` keyword in `docker compose` works only for services and currently there's no elegant way of reusing `docker` volumes (external volumes don't count) + +_if you happen to find anything, feel free to apply it here_ :) + +## Summary of best practices + +### Secrets + +First and foremost **never** add value that is considered secret into `docker-compose`. Even though kubernetes already has tooling to version secrets and it's possible in terms of technologies, this is not the time and place. + +Environment variables that are considered secrets, shouldn't be versioned and consider defining them in corresponding `.env` file - preferably on service level. If secret value is required during build, consider adding it into [`./docker/.env`](../docker/.env.example), more information in [docker documentation](https://docs.docker.com/compose/environment-variables/#the-env-file) + +### Configuration settings + +Keep as many settings shared as possible in `*.services.yml` files. + +If you encounter +* setting specific only for `M1-silicon` CPU, such as emulated image + * For instance `node-sass` requires emulation on arm64v8 architectures, because of its dependencies on native libs +* qa specific setting +* Workaround, that could have drastic impact + +You should add these type of settings to specific `docker-compose.yml` + +### Versions + +Keep all the versions at single place - preferably [`base.services.yml`](../docker/base.services.yml) (at least for now) + +Updating at multiple places is tedious and is reason why emulated services, such as `db_emulated` remain in [`base.services.yml`](../docker/base.services.yml), even if they could be defined in specific `docker-compose.yml` + +## External services + +Integrated services that aren't considered part of 'standard' stack are defined in `external.services.yml`. +In order to minimize image build and setup parts of container processes, they are excluded by default. +You can run them by merging multiple `docker-compose.yml` files, as mentioned in [docker documentation](https://docs.docker.com/compose/extends/#multiple-compose-files). + +Similar as `base.services.yml`, platform-related specifics are defined in +* [`external.docker-compose.yml`](../docker/external.docker-compose.yml) +* [`external.arm64v8.docker-compose.yml`](../docker/external.arm64v8.docker-compose.yml) + +## (Hopefully) Future simplification + +As mentioned, differences in M1-silicon make the setup difficult. In event, when [here mentioned](https://docs.docker.com/desktop/mac/apple-silicon/) issues get resolved, deprecation of `arm64v8-dev` and `arm64v8-qa` configurations should be taken into consideration. diff --git a/docs/MACOS_ARCHITECTURE_DIFFERENCES.md b/docs/MACOS_ARCHITECTURE_DIFFERENCES.md new file mode 100644 index 000000000..460eb6852 --- /dev/null +++ b/docs/MACOS_ARCHITECTURE_DIFFERENCES.md @@ -0,0 +1,28 @@ +# Summary of Platform Differences + +_Last updated 14.6.2022_ + +## Docker issues + +As stated in [this article](https://docs.docker.com/desktop/mac/apple-silicon/), there are a handful of things that are not fully functional on M1-Silicon CPUs + +* `mysql` docker images aren't available for `arm64v8` docker architecture +* Some libraries are dependant on native libraries writted in C, that don't compile for `arm64v8` architectures + * `therubyracer` for `web` + * `node-sass` for `frontend` + +We solve both of these cases by emulating images, or by building different images + +```yml +# Instead of +# image: mysql +image: amd64/mysql +``` + +## Ruby watch mode + +As stated also in [this article](https://docs.docker.com/desktop/mac/apple-silicon/), `inotify` file system notification API doesn't work on emulated images. This API is used internally by `listen` package and `EventedFileSystemWatcher`. Rails (according to [Rails config](https://guides.rubyonrails.org/configuring.html#config-file-watcher)) ships by default with `FileSystemWatcher`, therefore configuration option for `EventedFileSystemWatcher` is disabled for `arm64v8` with `ARM64V8_DEVELOPMENT_PATCH` env variable. + +[See here](../config/environments/development.rb) + +The env variable `ARM64V8_DEVELOPMENT_PATCH` is defined in arm64v8 docker compose files, such as [this one for arm64v8 dev](../docker/arm64v8.dev.docker-compose.yml). diff --git a/docs/OS_BASED_SETUP.md b/docs/OS_BASED_SETUP.md index 512c8030c..a108b92d0 100644 --- a/docs/OS_BASED_SETUP.md +++ b/docs/OS_BASED_SETUP.md @@ -1,89 +1,89 @@ -# OS-based setup - -## MySQL database - -### MySQL 5.6 on MacOS -At the moment latest MySQL 5.6 (mysql@5.6 or mysql@5.6.46) has a bug that -doesn't allow to build mysql gem, so it's __REQUIRED__ to use version 5.6.43 - -`brew install mysql@5.6.43` - -### MySQL 5.6 on Ubuntu Linux -Since Ubuntu 18.04 doesn't have MySQL 5.6 support out-of-box, you have to add -apt repository in your system and install MySQL from that repo. For more information -look [here](https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/). - -## Installation - -* Install RVM - * `gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3` - * `\curl -sSL https://get.rvm.io | bash -s stable` - -* Install ruby - * `rvm install 2.7.1` - -* Move to project's root directory - * `cd ` - -* Install bundler - * `gem install bundler` - - __OR__ to keep the current bundler version from Gemfile.lock, run - - `gem install bundler -v 2.1.4` - -* (Mac) To overcome `bundle install` errors, you may need to install the following dependencies manually: - * `cmake` (required to build `rugged` gem) - * `brew install cmake` - * V8, libv8 (required to install `therubyracer` gem) - * `brew install v8@3.15` - * `gem install libv8 -v '3.16.14.19' -- --with-system-v8` - * Note: you may need to update the version to match the one bundler's trying to install. - * `therubyracer` - * First, find your V8 directory - look for `/usr/local/opt/v8@*` - * `gem install therubyracer -- --with-v8-dir=/usr/local/opt/v8@3.15` - * Source: https://gist.github.com/fernandoaleman/868b64cd60ab2d51ab24e7bf384da1ca - -* Install the other required gems - * `bundle install` - -## Configure - -See [the Configure section in `DOCKER_BASED_SETUP.md`](./DOCKER_BASED_SETUP.md#1.-configure) for the details. - -### DB setup - -#### Configure local database - -After pointing the application to your local DB (`config/database.yml`), use the same commands to setup the DB as when setting-up a Docker-based DB (see [`DOCKER_BASED_SETUP.md`](./DOCKER_BASED_SETUP.md#3.-prepare-the-database). - -#### Use Databse running in Docker - -Alternatively, you can use a database running inside Docker (see [`DOCKER_BASED_SETUP.md`](./DOCKER_BASED_SETUP.md) for further details). - -To point your local Rails application to the Docker-based DB, set `default.host` to `127.0.0.1` in `config/database.yml`. - -## Run - -To start rails server, run: - * `bundle exec thin --ssl --debug start` - -* Point your browser to [https://localhost:3000](https://localhost:3000), if you're seeing -index page, setup is done. - -## Test - -To run unit & integration tests, use the following commands -* Rails (RSpec): `rspec` or `bundle exec rspec` - * Note: some of these tests require a DB to be configured -* CoffeeScript (Jest): `yarn test` or `yarn test:watch` for watch mode - -### Issues - -On your first `bundle`, you may have issues installing the libv8 and -therubyracer gems. See [here](https://github.com/cowboyd/libv8/issues/205) for -potential solutions. Try `bundle update libv8`. - -## Useful commands - -You can find some useful commands [here](USEFUL_COMMANDS.md). +# OS-based setup + +## MySQL database + +### MySQL 5.6 on MacOS +At the moment latest MySQL 5.6 (mysql@5.6 or mysql@5.6.46) has a bug that +doesn't allow to build mysql gem, so it's __REQUIRED__ to use version 5.6.43 + +`brew install mysql@5.6.43` + +### MySQL 5.6 on Ubuntu Linux +Since Ubuntu 18.04 doesn't have MySQL 5.6 support out-of-box, you have to add +apt repository in your system and install MySQL from that repo. For more information +look [here](https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/). + +## Installation + +* Install RVM + * `gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3` + * `\curl -sSL https://get.rvm.io | bash -s stable` + +* Install ruby + * `rvm install 2.7.5` + +* Move to project's root directory + * `cd ` + +* Install bundler + * `gem install bundler` + + __OR__ to keep the current bundler version from Gemfile.lock, run + + `gem install bundler -v 2.2.33` + +* (Mac) To overcome `bundle install` errors, you may need to install the following dependencies manually: + * `cmake` (required to build `rugged` gem) + * `brew install cmake` + * V8, libv8 (required to install `therubyracer` gem) + * `brew install v8@3.15` + * `gem install libv8 -v '3.16.14.19' -- --with-system-v8` + * Note: you may need to update the version to match the one bundler's trying to install. + * `therubyracer` + * First, find your V8 directory - look for `/usr/local/opt/v8@*` + * `gem install therubyracer -- --with-v8-dir=/usr/local/opt/v8@3.15` + * Source: https://gist.github.com/fernandoaleman/868b64cd60ab2d51ab24e7bf384da1ca + +* Install the other required gems + * `bundle install` + +## Configure + +See [the Configure section in `DOCKER_BASED_SETUP.md`](./DOCKER_BASED_SETUP.md#1.-configure) for the details. + +### DB setup + +#### Configure local database + +After pointing the application to your local DB (`config/database.yml`), use the same commands to setup the DB as when setting-up a Docker-based DB (see [`DOCKER_BASED_SETUP.md`](./DOCKER_BASED_SETUP.md#3.-prepare-the-database). + +#### Use Databse running in Docker + +Alternatively, you can use a database running inside Docker (see [`DOCKER_BASED_SETUP.md`](./DOCKER_BASED_SETUP.md) for further details). + +To point your local Rails application to the Docker-based DB, set `default.host` to `127.0.0.1` in `config/database.yml`. + +## Run + +To start rails server, run: + * `bundle exec thin --ssl --debug start` + +* Point your browser to [https://localhost:3000](https://localhost:3000), if you're seeing +index page, setup is done. + +## Test + +To run unit & integration tests, use the following commands +* Rails (RSpec): `rspec` or `bundle exec rspec` + * Note: some of these tests require a DB to be configured +* CoffeeScript (Jest): `yarn test` or `yarn test:watch` for watch mode + +### Issues + +On your first `bundle`, you may have issues installing the libv8 and +therubyracer gems. See [here](https://github.com/cowboyd/libv8/issues/205) for +potential solutions. Try `bundle update libv8`. + +## Useful commands + +You can find some useful commands [here](USEFUL_COMMANDS.md). diff --git a/docs/REACT_FRONTEND_DEVELOPMENT.md b/docs/REACT_FRONTEND_DEVELOPMENT.md index e9051ff36..c6a4812e3 100644 --- a/docs/REACT_FRONTEND_DEVELOPMENT.md +++ b/docs/REACT_FRONTEND_DEVELOPMENT.md @@ -1,78 +1,78 @@ -# React-based frontend development - -This guide will cover all required steps to start working on -React-based frontend part. - -## Setting up NodeJS -If you already have NodeJS installed in your system, you may use -it, but be careful since it's version can be outdated. - -### Installing NodeJS via NVM -NodeJS can be installed by several ways, but the most preferred -is via [NVM](https://github.com/nvm-sh/nvm). Follow NVM's -guide to get it installed. - -Run this command to install NodeJS: - -``nvm install v12`` - -In order to use installed version run: - -``nvm use`` - -If you want NVM to change node version automatically, please refer -to [this part of NVM manual](https://github.com/nvm-sh/nvm#automatically-call-nvm-use) - -## Installing yarn - -Run this command to install yarn globally: - -`` npm i -g yarn `` - -## Almost there... - -Now change directory to ``client`` of project's root. - -#### ALL THE FOLLOWING COMMANDS TILL THE END OF THIS MANUAL ARE SUPPOSED TO BE RUN FROM ``client`` DIRECTORY - -Install required packages: - -``yarn`` - -After all packages are installed, everything is ready to -start development. - -### Defined yarn commands - -Build production bundle: - -``yarn run build:production`` - -Build development bundle: - -``yarn run build`` - -Run instant rebuilding based on changes: - -``yarn run watch`` - -Run webpack dev server: - -`` yarn run server`` - -Run linter (ESLint): - -`` yarn run lint `` - -Run tests: - -``yarn run test `` - -## Note - -Please run linter and tests before making a pull request, that -will economy other developers' time :) - -##### For those who uses IDEs instead of text editors: -Most of IDEs have built-in support for ESLint, so please configure -them if not already. +# React-based frontend development + +This guide will cover all required steps to start working on +React-based frontend part. + +## Setting up NodeJS +If you already have NodeJS installed in your system, you may use +it, but be careful since it's version can be outdated. + +### Installing NodeJS via NVM +NodeJS can be installed by several ways, but the most preferred +is via [NVM](https://github.com/nvm-sh/nvm). Follow NVM's +guide to get it installed. + +Run this command to install NodeJS: + +``nvm install v12`` + +In order to use installed version run: + +``nvm use`` + +If you want NVM to change node version automatically, please refer +to [this part of NVM manual](https://github.com/nvm-sh/nvm#automatically-call-nvm-use) + +## Installing yarn + +Run this command to install yarn globally: + +`` npm i -g yarn `` + +## Almost there... + +Now change directory to ``client`` of project's root. + +#### ALL THE FOLLOWING COMMANDS TILL THE END OF THIS MANUAL ARE SUPPOSED TO BE RUN FROM ``client`` DIRECTORY + +Install required packages: + +``yarn`` + +After all packages are installed, everything is ready to +start development. + +### Defined yarn commands + +Build production bundle: + +``yarn run build:production`` + +Build development bundle: + +``yarn run build`` + +Run instant rebuilding based on changes: + +``yarn run watch`` + +Run webpack dev server: + +`` yarn run server`` + +Run linter (ESLint): + +`` yarn run lint `` + +Run tests: + +``yarn run test `` + +## Note + +Please run linter and tests before making a pull request, that +will economy other developers' time :) + +##### For those who uses IDEs instead of text editors: +Most of IDEs have built-in support for ESLint, so please configure +them if not already. diff --git a/docs/USEFUL_COMMANDS.md b/docs/USEFUL_COMMANDS.md index a93b284fa..57781986d 100644 --- a/docs/USEFUL_COMMANDS.md +++ b/docs/USEFUL_COMMANDS.md @@ -1,28 +1,57 @@ -# Some useful commands - -If you use [docker-based setup](DOCKER_BASED_SETUP.md), prepend each command -with `docker-compose exec web` (unless it's written that it does not work). - -* Get to rails console - * `bundle exec rails c` - -* Run a migration - * `bundle exec rake db:migrate` - -* Run all tests - * `bundle exec rspec` - -* Run specific test - * `bundle exec rspec spec/` - -* Run rubocop - * `bundle rubocop` - -* Run tests with Rspec Guard (doesn't work in docker container) - * `bundle exec guard` - -* To exit from Guard mode (doesn't work in docker container) - * `exit` - -* Check current code coverage - * `open coverage/index.html` +# Useful commands + +If you use [OS-based setup](OS_BASED_SETUP.md), remove from each command the +`docker compose exec ` portion of the command when applicable. + +## Ruby client + +Get to rails console +`docker compose exec web bundle exec rails c` + +Run database migration +`docker compose exec web bundle exec rake db:migrate` + +Run all Ruby tests +`docker compose exec web bundle exec rspec` + +Run specific test +`docker compose exec web bundle exec rspec spec/` + +Run rubocop +`docker compose exec web bundle exec rubocop` + +Run brakeman +`docker compose exec web brakeman -A --parser-timeout 30 -w2` + +#### A couple commands that don't work in a docker container: + +Run tests with Rspec Guard (doesn't work in docker container) +`bundle exec guard` + +* To exit from Guard mode (doesn't work in docker container) + * `exit` + +* Check current code coverage + * `open coverage/index.html` + + +## React Frontend + +Run lint +`docker compose exec frontend yarn lint .` + +Run all unit tests +`docker compose exec frontend yarn test` + +Run specific unit tests +`docker compose exec frontend yarn test --testNamePattern=Challenge` + +## Database + +```bash +# Hook into db container +docker compose exec -it db bash +# Log in +mysql -uroot -p +# You should be able to find the password depending on your configuration +```