This is a boilerplate that has the following stack:
- React - frontend
- Laravel - backend
- Docker - development and deployment container tool
- Jenkins - CI/CD
- Xdebug - debugging
- Codeception - backend testing
- Jest & Enzyme - frontend testing
- AWS - deployment platform All setup steps are described below so that you can easily start developing.
- Go to docker and run
docker-compose upand if you want to rebuild php container add--build
- Your starting point is
./src/App.js. Here you have to Context API Providers:
ThemeProvider- allows you to pass theme data to all componentsUserProvider- allows you to pass user data to all components. User can be changed viareducerProtected Routes authorize users based onallowedRolesprop. Don't worry authorization is done on backend as well.
- All other elements are in
Components,Containers&Contextfolders. Signin&Signupcontainers allow to create and authenticate user
React - core of the project, JS library ReactDOM - allows to render DOM in React
Axios - AJAX request tool
Webpack - JS bundler, collect js, html, css etc. into one or several bundles for lazy loading Webpack CLI - CLI utility for Webpack
Lodash - TO BE CHECKED
Babel-core - Transforms your ES6 code into ES5 Babel-loader - Webpack helper to transform your JavaScript dependencies (for example, when you import your components into other components) with Babel Babel-preset-env - Determines which transformations/plugins to use and polyfills (provide modern functionality on older browsers that do not natively support it) based on the browser matrix you want to support Babel-preset-react - Babel preset for all React plugins, for example turning JSX into functions Babel-plugin-proposal-class-properties - allows to use state = {} in React
styled-components - used for styling components instead of CSS. Adds auto prefixing of CSS classes & implements CSS-in-JS logic
babel-plugin-styled-components - allows to use css prop for styled components, so you can write like <div css="padding: 5px"></div>
CSS-loader - process css style-loader - injects css to html sass-loader - process sass file-loader - process images & icons
html-webpack-plugin - dev dependency inserts <script> to /dist/index.html
jest - testing tools. Jest acts as a test runner, assertion library, and mocking library [
jest-svg-transformer - allows jest to parse svg
jest-styled-components - allows to test styled components and ignore their auto generated
className
identity-obj-proxy - allows jest to parse css|styl|less|sass|scss|png|jpg|ttf|woff|woff2
react-test-renderer - for rendering snapshots
enzyme - adds some great additional utility methods for rendering a component (or multiple components), finding elements, and interacting with elements.
enzyme-to-json - provides a better component format for snapshot comparison than Enzyme’s internal component representation.
snapshotSerializers allows you to minimise code duplication when working with snapshots.
Without the serializer each time a component is created in a test it must have the enzyme-to-json method .toJson() used individually before it can be passed to Jest’s snapshot matcher, with the serializer you never use it individually.
enzyme-adapter-react-16 - allows Enzyme to work with React
babel-jest - allow jest usage with babel
dotenv - allows to use .env to set environment variable. Read here how it should be written in Webpack https://medium.com/@trekinbami/using-environment-variables-in-react-6b0a99d83cf5.
notistack - used for snackbars
- Routes are protected with middleware that is fired when route is used doing checks that are required. For example, check that HTTP request contains all required fields.
- Controller actions are protected by Gates that are registered in
AuthServiceProvider.php
- Find your local IP address with
ipconfig getifaddr en0 - Add it to
Dockerfile_devxdebug.remote_host=10.0.1.11. All the other configurations are already there - Remote port should be equal to debug port in IDE (Preferences->Languages & Frameworks->Debug)
xdebug.remote_port - Add this host to
DBGp Proxytoo - Add the host to
Serverswith ip of the backend. For example,localhost:8001 - Add configuration with remote debug
- You can debug though REST API call only direct call in browser or Postman
Codeception is used for testing.
- It has a general configuration file
codeception.yml& separate file acceptanceacceptance.suite.yml, functionalfunctional.suite.yml& unitunit.suite.ymltests - Acceptance test uses Selenium with Google WebDriver that is run in Docker. It allows to test web application as if
it was a real user, so it is useful for JS SPA. Command to start Selenium
docker run -p 4444:4444 -d selenium/standalone-chrome - To run tests use the following command
php vendor/bin/codecept run --steps - For testing purpose you should change Axios base url in
.envto host machine IP as Selenium is in Docker -10.0.1.11:8001. (!) Currently it is change directly in Axios file. - For third party API
donatj\MockWebServeris used and that's whysocketsextension is install in the container. As well asprocpsso that ps command can be used. Indocker-composeforcomposercontainer we also addcommand: composer update --ignore-platform-reqs --no-scriptsbecause it should ignore phpsocketsdependency which os in a separate container.
Commands:
- Create test:
php vendor/bin/codecept generate:cest api CreateUser
(!) Very important to use swap for small AWS instances
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile
https://linuxize.com/post/create-a-linux-swap-file/
- Install Docker
apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" && apt-get update && apt-cache policy docker-ce && apt-get install -y docker-ce - Download docker image
docker pull jenkinsci/blueocean - Put AWS access key to
/home/ubuntu/.aws - Launch container in interactive mode, so you can see admin password and copy it.
-v /var/run/docker.sock:/var/run/docker.sockis used so you can run Docker inside Dockerdocker run -p 8080:8080 -p 50000:50000 -v /var/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean - Then run container in detached mode
docker run --name jenkins -d -p 8080:8080 -p 50000:50000 -v /var/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v /home/ubuntu/.aws:/root/.aws jenkinsci/blueocean. Here we put the following volumes:
- jenkins_home - contains all data about jenkins, so when container is restarted you don't have to set up all over again
- docker.sock - allows to use docker inside Jenkins container without additional installation
- .aws - aws access key that is used to authenticate before pushing to ECR
- Install Python
apk add --no-cache --update python3 - Install AWS CLI as non root
pip3 install awscli --upgrade --user - Get AWS Credentials
$(/root/.local/bin/aws ecr get-login --no-include-email --region eu-central-1) - Give rights to
ubuntuuser on remote host forvar/run/docker.sock - Install AWS CLI on remote host
- Start mysql
docker run -p 3306:3306 --name mysql -v /db_volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=ueXXrisTgqP2I-1TmOYU2myQS1TCeVuVL0xZNOxNbXX= -e MYSQL_DATABASE=database -e MYSQL_USER=user -e MYSQL_PASSWORD=ueOQrisTgqP2I+9TmOYU2myQS1TCeVuVL0xZNOxNb44= -d mysql:5.7
##How to get AWS CLI key
- Go to AWS IAM
- Create a new user and attach rights: AmazonEC2FullAccess, SecretsManagerReadWrite, AmazonEC2ContainerRegistryFullAccess, AmazonEC2ContainerRegistryPowerUser
- Download .csv file
- Run command
aws configure --profile produserand enter data from the .csv. Do the same in Jenkins. - If you use several AWS profiles follow the instruction
##How to get secret credentials Description is here In sshort:
- Get the credentials hash with inspector
- Insert it to
http://52.59.247.1:8080/scriptlike thisprintln hudson.util.Secret.decrypt("{AQAAABAAAABANx7Sofv4K/ThU0BIB8oUS0bOtZ0xu9UT6sHdHk9lb18+RYF1kcdMhSJ6uKLBd5UFOWX4KDAkZV7HBD8WGabER+qn9rEDlHqeLwrJO69YsvI=}")
- Backend build is clear
- Frontend contains
--build-arg 'arg=.env.test'that is passed to the Dockerfile where it is used inARG arg ENV env_file=$argto replace.envfiles. - Test part is more interesting and described in the Jenkinsfile
- Build backend & frontend. Backend is the same & to front we just push a different
.env - Push image to ECR a. Get credentials for AWS b. Apply tag that contains data about the registry c. Delete image
- Deploy quite clear