FRED (Flask + REact + Docker): An End-to-End Boilerplate for Full Stack Development
Demo: harrywang.me/fred
Tools and packages used in this project:
- Flask: a micro web framework written in Python
- React: a JavaScript library for building user interfaces
- Docker: a set of platform as a service products that uses OS-level virtualization to deliver software in packages called containers
- Postgres: a free and open-source relational database management system
- SQLAlchemy: an open-source SQL toolkit and object-relational mapper for Python
- Flask-RESTX:an Flask extension for building REST APIs
- PyTest: a Python testing framework
- Jest: a JavaScript testing framework
- Python Linting and Formatting: flake8, black, isort
- JS Linting and Formatting: ESLint and Prettier
- JSON Web Tokens (JWT) via flask-bcrypt and pyjwt
- Bulma: a free, open source, and modern CSS framework
- Fresh: a beautiful Bulma template by CSSNinja
- Illustrations from UnDraw.co
- Images from Unsplash
- Heroku: a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud.
- CircleCI (TODO)
- AWS (TODO)
Data: I use the data scraped from http://quotes.toscrape.com/. Check out my tutorial A Minimalist End-to-End Scrapy Tutorial if you are interested in learning web scraping.
Special Thanks: many parts of this repo are based on the open-source code and related courses offered by Michael Herman from testdriven.io - highly recommended! Please show your support by buying the courses - I am not affiliated with testdriven.io - just really enjoyed the courses :).
I recommend the following materials, which can greatly help you understand the code in this repo.
- Flask and SQLAlchemy: The Flask Mega-Tutorial by Miguel Grinberg
- React: Intro to React and Step-by-Step Guide
- Docker and Docker Compose: Getting started with Docker and Get started with Docker Compose
You need to install the followings:
- Python 3
- Node
- Docker
- Clone the repo:
git clone https://github.com/harrywang/fred.git
- Switch to
fred
folder and rundocker-compose up -d --build
- Setup database and load data:
$ docker-compose exec backend python manage.py reset_db
$ docker-compose exec backend python manage.py load_data
- Visit http://localhost:3007 to check the app and visit http://127.0.0.1:5001/docs/ to check API docs
Other useful commands:
$ docker-compose stop # stop containers
$ docker-compose down # stop and remove containers
$ docker-compose down -v # stop and remove containers and volumes
If something does not work, you can try to use:
$ docker-compose down -v
$ docker-compose up -d --build
Other docker commands:
$ docker image ls # check images
$ docker system prune -a --volumes # delete everything
Run backend tests:
$ docker-compose exec backend python -m pytest "app/tests" -p no:warnings
$ docker-compose exec backend pytest "app/tests" -p no:warnings --cov="app"
$ docker-compose exec backend pytest "app/tests" -p no:warnings --cov="app" --cov-branch
$ docker-compose exec backend python -m pytest "app/tests" -p no:warnings --cov="app" --cov-branch --cov-report html
$ docker-compose exec backend python -m pytest "app/tests" -p no:warnings --cov="app" --cov-report html
$ docker-compose exec backend flake8 app
$ docker-compose exec backend black app
$ docker-compose exec backend /bin/sh -c "isort app/**/*.py"
Run frontend tests:
$ docker-compose exec frontend npm test
$ docker-compose exec frontend npm run prettier:check
$ docker-compose exec frontend npm run prettier:write
$ docker-compose exec frontend npm run lint
Access the database via psql:
$ docker-compose exec db psql -U postgres
# \c app_dev
# select * from user;
# select * from author;
# \q
SSH to containers:
$ docker-compose exec backend /bin/sh
$ docker-compose exec backend-db /bin/sh
Some notes:
- If you add new API endpoints - don't forget to add them to
services/nginx/default.conf
- setup nginx by adding
services/nginx/default.conf
. Note that nginx listens at$PORT
- add Dockerfile.deploy file. Note that
sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && \
maps$PORT
inservices/nginx/default.conf
by the environmental variable PORT supplied by Heroku - you will supply this port when running the container later. - create a Heroku account and setup Heroku CLI
- create a new app
heroku create getfred
, note that the app namegetfred
has to be unique
$ heroku create getfred
Creating ⬢ getfred... done
https://getfred.herokuapp.com/ | https://git.heroku.com/getfred.git
Empty app is created:
No Config Vars so far:
- Start a new Postgres database with the hobby-dev plan:
$ heroku addons:create heroku-postgresql:hobby-dev
dami:fred harrywang$ heroku addons:create heroku-postgresql:hobby-dev
Creating heroku-postgresql:hobby-dev on ⬢ getfred... free
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Created postgresql-triangular-16372 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
Database is attached:
DATABASE_URL configuration variable has been generated:
- get the database URL
$ heroku config:get DATABASE_URL
postgres://some_random_username:[email protected]:5432/some_random_db_name
- Export local environment variable DATABASE_URL - NOTE: the Heroku image we are going to build using
Dockerfile.deploy
reads from this local environment variable.
$ export DATABASE_URL=postgres://some_random_username:[email protected]:5432/some_random_db_name
- Set security key on remote Heroku App:
heroku config:set SECRET_KEY=you_should_choose_your_key --app getfred
- add .circleci/config.yml
- add Docker Hub environment variables