diff --git a/.dockerignore b/.dockerignore index af7f909..613af6c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,9 +2,11 @@ .git/ .github/ .gitignore +.vs +.vscode CHANGELOG.md Dockerfile Makefile README.md deployment.yaml -log/ +log/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4964bf4..748fc79 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,28 @@ # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile '~/.gitignore_global' -# Ignore bundler config. +!/log/.keep +.byebug_history +.github-token +.npmrc +.tags +.yarn-integrity /.bundle - -# Ignore all logfiles and tempfiles. /log/* -!/log/.keep +/node_modules +/public/packs +/public/packs-test /tmp -.byebug_history +coverage +fc.json +fc_simple.json +index-names.txt +index.json +node_modules/ public/assets +tags +yarn-debug.log* +yarn-error.log + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a98c40..f2d5c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ This app presents the landing page experience for landregistry.data.gov.uk, including the SPARQL Qonsole +## 1.5.6 - 2021-12-15 + +- (Mairead) Added deployment sub repo and assisting deployment files + ## 1.5.5 - 2021-06-25 - (Joseph) Small config change to allow linking to privacy notice. diff --git a/Dockerfile b/Dockerfile index 3eefaed..c7d1a26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,36 +1,47 @@ +ARG ALPINE_VERSION=3.10 ARG RUBY_VERSION=2.6.6 -# Defining ruby version -FROM ruby:$RUBY_VERSION-alpine +# Defines base image which builder and final stage use +FROM ruby:$RUBY_VERSION-alpine$ALPINE_VERSION as base -# Set working dir and copy app -WORKDIR /usr/src/app -COPY . . +# Change this if Gemfile.lock bundler version changes +ARG BUNDLER_VERSION=2.2.22 # Prerequisites for gems install RUN apk add build-base \ npm \ tzdata \ - git + git \ + && rm -rf /var/cache/apk/* \ + && gem install bundler:$BUNDLER_VERSION \ + && bundle config --global frozen 1 + +FROM base as builder -ARG BUNDLER_VERSION=2.1.4 +RUN apk add --update build-base -# Install bundler and gems -RUN gem install bundler:$BUNDLER_VERSION -RUN bundle install +# Set working dir and copy app +WORKDIR /usr/src/app +COPY . . -# Params -ARG RAILS_ENV="production" -ARG RAILS_SERVE_STATIC_FILES="true" -ARG RELATIVE_URL_ROOT="/app/root" +# Install gems +RUN bundle install \ + && RAILS_ENV=production bundle exec rake assets:precompile \ + && mkdir -p 777 /usr/src/app/coverage + +# Start a new build stage to minimise the final image size +FROM base + +RUN addgroup -S app && adduser -S -G app app -# Set environment variables and expose the running port -ENV RAILS_ENV=$RAILS_ENV -ENV RAILS_SERVE_STATIC_FILES=$RAILS_SERVE_STATIC_FILES -ENV RELATIVE_URL_ROOT=$RELATIVE_URL_ROOT -ENV SCRIPT_NAME=$RELATIVE_URL_ROOT EXPOSE 3000 -# Precompile assets and add entrypoint script -RUN rake assets:precompile -ENTRYPOINT [ "sh", "./entrypoint.sh" ] +WORKDIR /usr/src/app + +COPY --from=builder --chown=app /usr/local/bundle /usr/local/bundle +COPY --from=builder --chown=app /usr/src/app . + +USER app + +COPY entrypoint.sh /app/entrypoint.sh +ENTRYPOINT [ "sh", "/app/entrypoint.sh" ] diff --git a/Gemfile.lock b/Gemfile.lock index 489ef25..5a9e329 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -178,6 +178,8 @@ GEM nokogiri (1.12.3) mini_portile2 (~> 2.6.1) racc (~> 1.4) + nokogiri (1.12.3-x86_64-linux) + racc (~> 1.4) parallel (1.20.1) parser (3.0.2.0) ast (~> 2.4.1) @@ -280,6 +282,7 @@ GEM websocket-extensions (0.1.5) PLATFORMS + ruby x86_64-linux DEPENDENCIES diff --git a/Makefile b/Makefile index f21eb12..47d103a 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,69 @@ -.PHONY: image publish +.PHONY: assets clean image lint modules publish realclean run tag test vars ACCOUNT?=$(shell aws sts get-caller-identity | jq -r .Account) +GRP_OWNER?=epimorphics +AWS_REGION?=eu-west-1 STAGE?=dev -NAME?=$(shell awk -F: '$$1=="name" {print $$2}' deployment.yaml | sed -e 's/\s//g') +NAME?=$(shell awk -F: '$$1=="name" {print $$2}' deployment.yaml | sed -e 's/[[:blank:]]//g') ECR?=${ACCOUNT}.dkr.ecr.eu-west-1.amazonaws.com -TAG?=$(shell if git describe > /dev/null 2>&1 ; then git describe; else git rev-parse --short HEAD; fi) +PAT?=$(shell read -p 'Github access token:' TOKEN; echo $$TOKEN) +API_SERVICE_URL?= http://localhost:8080 + +COMMIT=$(shell git rev-parse --short HEAD) +VERSION?=$(shell /usr/bin/env ruby -e 'require "./app/lib/version" ; puts Version::VERSION') +TAG?=${VERSION}-${COMMIT} + +${TAG}: + @echo ${TAG} IMAGE?=${NAME}/${STAGE} REPO?=${ECR}/${IMAGE} -all: publish +GITHUB_TOKEN=.github-token +NPMRC=.npmrc +BUNDLE_CFG=${HOME}/.bundle/config +YARN_LOCK=yarn.lock + +all: image + +${BUNDLE_CFG}: ${GITHUB_TOKEN} + @./bin/bundle config set rubygems.pkg.github.com ${GRP_OWNER}:`cat ${GITHUB_TOKEN}` + +${GITHUB_TOKEN}: + @echo ${PAT} > ${GITHUB_TOKEN} + +${NPMRC}: ${GITHUB_TOKEN} + @echo "@epimorphics:registry=https://npm.pkg.github.com/" > ${NPMRC} + @echo "//npm.pkg.github.com/:_authToken=`cat ${GITHUB_TOKEN}`" >> ${NPMRC} -image: assets test +assets: + @./bin/bundle config set --local without 'development' + @./bin/bundle install + @./bin/rails assets:clean assets:precompile + +auth: ${GITHUB_TOKEN} ${NPMRC} ${BUNDLE_CFG} + +clean: + @[ -d public/assets ] && ./bin/rails assets:clobber || : + +image: auth lint test @echo Building ${REPO}:${TAG} ... @docker build --tag ${REPO}:${TAG} . @echo Done. +lint: assets + @./bin/bundle exec rubocop + +modules: ${NPMRC} + @yarn install + publish: image @echo Publishing image: ${REPO}:${TAG} ... @docker push ${REPO}:${TAG} 2>&1 @echo Done. -assets: - @./bin/bundle config set --local without 'development' - @./bin/bundle install - @./bin/rails assets:clean assets:precompile +realclean: clean + @rm -f ${GITHUB_TOKEN} ${NPMRC} ${BUNDLE_CFG} run: @-docker stop lr_landing @@ -35,11 +74,7 @@ tag: @echo ${TAG} test: assets - @./bin/bundle exec rubocop @./bin/rake test -clean: - @[ -d public/assets ] && ./bin/rails assets:clobber || : - vars: @echo "Docker: ${REPO}:${TAG}" diff --git a/README.md b/README.md index baabd6c..2a95c7c 100644 --- a/README.md +++ b/README.md @@ -28,16 +28,21 @@ There aren't very many tests as this is a very simple app. rails -t -### Deployment +## Deployment -At the present time (this may change in future), the development, -staging (aka pre-production) and production deployments are -built by Chef scripts from the `dev` `staging` and `production` -branches respectively. +To mimic running the application in a deployed state you can run +`make image` and this will run through the assets precompilation, linting and testing before creating a Docker image. To view the Docker container you can run `make run` -To add a new feature or fix, create an appropriate branch, -make a pull request, merge the code then use the DMS to update -that particular deployment environment. +To bypass the need for running locally AWS you can pass a global variable to the command with `ECR=local make image` + +You can run `make help` to view a list of other make commands available + +## Entrypoint.sh + +* The Rails Framework requires certain values to be set as a Global environment variable when starting. To ensure the `RAILS_RELATIVE_URL_ROOT` is only set in one place per application we have added this to the Entrypoint file along with the `SCRIPT_NAME`. +* The Rails secret is also created here. +* There is a workaround to removing the PID lock of the Rails process in the event of the application crashing and not releasing the process. +* We have to pass the `API_SERVICE_URL` so that it is available in the Entrypoint.sh or the application will throw an error and exit before starting ## Issues diff --git a/app/lib/version.rb b/app/lib/version.rb index edeafef..68efcb5 100644 --- a/app/lib/version.rb +++ b/app/lib/version.rb @@ -3,6 +3,6 @@ module Version MAJOR = 1 MINOR = 5 - REVISION = 5 + REVISION = 6 VERSION = "#{MAJOR}.#{MINOR}.#{REVISION}" end diff --git a/config/environments/production.rb b/config/environments/production.rb index f93cc0e..9ad1f15 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -24,7 +24,7 @@ # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. - config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'] || true # Compress JavaScripts and CSS. config.assets.js_compressor = :uglifier @@ -78,7 +78,7 @@ config.logger = JsonRailsLogger::Logger.new($stdout) - config.relative_url_root = ENV['RELATIVE_URL_ROOT'] || '/' + config.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] || '/' config.accessibility_document_path = '/accessibility' config.privacy_document_path = '/privacy' diff --git a/deployment.yaml b/deployment.yaml index 9eaae0b..b81976b 100644 --- a/deployment.yaml +++ b/deployment.yaml @@ -5,9 +5,6 @@ deployments: - tag: "v{ver}" deploy: "prod" publish: "prod" - - tag: "v{ver}-rc" - deploy: "preprod" - publish: "preprod" - branch: "dev-infrastructure" deploy: "dev" publish: "dev" diff --git a/entrypoint.sh b/entrypoint.sh index a037315..5d15cd5 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,4 +1,9 @@ #!/bin/bash +set -e + +# Remove a potentially pre-existing server.pid for Rails. +rm -f ./tmp/pids/server.pid +mkdir -pm 1777 ./tmp # Set the environment if [ -z "$RAILS_ENV" ] @@ -12,5 +17,8 @@ then export SECRET_KEY_BASE=`./bin/rails secret` fi -# Run the rails app -exec ./bin/rails server +export RAILS_RELATIVE_URL_ROOT=${RAILS_RELATIVE_URL_ROOT:-'/app/root'} +export SCRIPT_NAME=${RAILS_RELATIVE_URL_ROOT} + +exec ./bin/rails server -e ${RAILS_ENV} -b 0.0.0.0 +