diff --git a/README.md b/README.md index eebc7fb6..9c08a7ae 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ There are several template projects that you can download (as a `.zip` file) to This Docker image is based on [**tiangolo/uwsgi-nginx**](https://hub.docker.com/r/tiangolo/uwsgi-nginx/). That Docker image has uWSGI and Nginx installed in the same container and was made to be the base of this image. -## QuickStart +## Quick Start **Note**: You can download the **example-flask-python3.7.zip** project example and use it as the template for your project from the section **Examples** above. @@ -130,338 +130,139 @@ docker run -d --name mycontainer -p 80:80 myimage ...and you have an optimized Flask server in a Docker container. -You should be able to check it in your Docker container's URL, for example: +You should be able to check it in your Docker container's URL, for example: http://192.168.99.100 or http://127.0.0.1 ## Project Generators There are several project generators that you can use to start your project, with everything already configured. -They all include automatic and free HTTPS certificate generation using [Traefik](https://traefik.io/) and [Let's Encrypt](https://letsencrypt.org/), using [a very simple to use Docker cluster configuration with Docker Swarm mode](https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232). - -### [flask-frontend-docker](https://github.com/tiangolo/flask-frontend-docker) - -Minimal project generator with a Flask backend, a modern frontend (Vue, React or Angular), a Traefik load balancer with HTTPS, all based on Docker. - -Features: - -* Full Docker integration (Docker based) -* Docker Swarm Mode deployment -* Docker Compose integration and optimization for local development -* Production ready Python web server using Nginx and uWSGI -* Python Flask backend: - * CORS already configured, to be used by the frontend. -* Vue frontend - * Easily updated to be Angular or React. - * Docker server based on Nginx (configured to play nicely with Vue-router) - * Docker multi-stage building, so you don't need to save or commit compiled code - * Easily enable frontend tests at build time -* Load balancing between frontend and backend with Traefik: - * So you can have both backend and frontend under the same domain, separated by path, but served by the two different containers -* Automatic (free) HTTPS certificate generation with Let's Encrypt and Traefik - - -### [full-stack](https://github.com/tiangolo/full-stack) - -Full stack, modern web application generator. Using Flask, PostgreSQL DB, Docker, Swagger, automatic HTTPS and more. - -Features: - -* Full Docker integration (Docker based) -* Docker Swarm Mode deployment -* Docker Compose integration and optimization for local development -* Production ready Python web server using Nginx and uWSGI -* Python Flask backend with: - * Flask-apispec: Swagger live documentation generation - * Marshmallow: model and data serialization (convert model objects to JSON) - * Webargs: parse, validate and document inputs to the endpoint / route - * Secure password hashing by default - * JWT token authentication - * SQLAlchemy models (independent of Flask extensions, so they can be used with Celery workers directly) - * Basic starting models for users and groups (modify and remove as you need) - * Alembic migrations - * CORS (Cross Origin Resource Sharing) -* Celery worker that can import and use models and code from the rest of the backend selectively (you don't have to install the complete app in each worker) -* REST backend tests based on Pytest, integrated with Docker, so you can test the full API interaction, independent on the database. As it runs in Docker, it can build a new data store from scratch each time (so you can use ElasticSearch, MongoDB, CouchDB, or whatever you want, and just test that the API works) -* Easy Python integration with Jupyter Kernels for remote or in-Docker development with extensions like Atom Hydrogen or Visual Studio Code Jupyter -* Vue frontend: - * Generated with Vue CLI - * JWT Authentication handling - * Login view - * After login, main dashboard view - * Vuex - * Vue-router - * Vuetify for beautiful material design components - * TypeScript - * Docker server based on Nginx (configured to play nicely with Vue-router) - * Docker multi-stage building, so you don't need to save or commit compiled code - * Frontend tests ran at build time (can be disabled too) - * Made as modular as possible, so it works out of the box, but you can re-generate with Vue CLI or create it as you need, and re-use what you want -* PGAdmin for PostgreSQL database, you can modify it to use PHPMyAdmin and MySQL easily -* Swagger-UI for live interactive documentation -* Flower for Celery jobs monitoring -* Load balancing between frontend and backend with Traefik, so you can have both under the same domain, separated by path, but served by different containers -* Traefik integration, including Let's Encrypt HTTPS certificates automatic generation -* GitLab CI (continuous integration), including frontend and backend testing - - -### [full-stack-flask-couchbase](https://github.com/tiangolo/full-stack-flask-couchbase) - -Full stack, modern web application generator. Using Flask, Couchbase as database, Docker, Swagger, automatic HTTPS and more. - -Features: - -* Full Docker integration (Docker based) -* Docker Swarm Mode deployment -* Docker Compose integration and optimization for local development -* Production ready Python web server using Nginx and uWSGI -* Python Flask backend with: - * Flask-apispec: Swagger live documentation generation - * Marshmallow: model and data serialization (convert model objects to JSON) - * Webargs: parse, validate and document inputs to the endpoint / route - * Secure password hashing by default - * JWT token authentication - * Basic starting functionality for users and roles (modify and remove as you need) - * CORS (Cross Origin Resource Sharing) -* Celery worker that can import and use code from the rest of the backend selectively (you don't have to install the complete app in each worker) -* NoSQL Couchbase database that supports direct synchronization via Couchbase Sync Gateway for offline-first applications. -* Full Text Search integrated, using Couchbase. -* REST backend tests based on Pytest, integrated with Docker, so you can test the full API interaction, independent on the database. As it runs in Docker, it can build a new data store from scratch each time (so you can use ElasticSearch, MongoDB, or whatever you want, and just test that the API works). -* Easy Python integration with Jupyter Kernels for remote or in-Docker development with extensions like Atom Hydrogen or Visual Studio Code Jupyter -* Vue frontend: - * Generated with Vue CLI - * JWT Authentication handling - * Login view - * After login, main dashboard view - * Vuex - * Vue-router - * Vuetify for beautiful material design components - * TypeScript - * Docker server based on Nginx (configured to play nicely with Vue-router) - * Docker multi-stage building, so you don't need to save or commit compiled code - * Frontend tests ran at build time (can be disabled too) - * Made as modular as possible, so it works out of the box, but you can re-generate with Vue CLI or create it as you need, and re-use what you want -* Swagger-UI for live interactive documentation -* Flower for Celery jobs monitoring -* Load balancing between frontend and backend with Traefik, so you can have both under the same domain, separated by path, but served by different containers -* Traefik integration, including Let's Encrypt HTTPS certificates automatic generation -* GitLab CI (continuous integration), including frontend and backend testing - - -### [full-stack-flask-couchdb](https://github.com/tiangolo/full-stack-flask-couchdb) - -Full stack, modern web application generator. Using Flask, CouchDB as database, Docker, Swagger, automatic HTTPS and more. - -Features: - -* Full Docker integration (Docker based) -* Docker Swarm Mode deployment -* Docker Compose integration and optimization for local development -* Production ready Python web server using Nginx and uWSGI -* Python Flask backend with: - * Flask-apispec: Swagger live documentation generation - * Marshmallow: model and data serialization (convert model objects to JSON) - * Webargs: parse, validate and document inputs to the endpoint / route - * Secure password hashing by default - * JWT token authentication - * Basic starting functionality for users and roles (modify and remove as you need) - * CORS (Cross Origin Resource Sharing) -* Celery worker that can import and use code from the rest of the backend selectively (you don't have to install the complete app in each worker) -* NoSQL CouchDB database that supports direct synchronization for offline-first applications -* REST backend tests based on Pytest, integrated with Docker, so you can test the full API interaction, independent on the database. As it runs in Docker, it can build a new data store from scratch each time (so you can use ElasticSearch, MongoDB, or whatever you want, and just test that the API works). -* Easy Python integration with Jupyter Kernels for remote or in-Docker development with extensions like Atom Hydrogen or Visual Studio Code Jupyter -* Vue frontend: - * Generated with Vue CLI - * JWT Authentication handling - * Login view - * After login, main dashboard view - * Vuex - * Vue-router - * Vuetify for beautiful material design components - * TypeScript - * Docker server based on Nginx (configured to play nicely with Vue-router) - * Docker multi-stage building, so you don't need to save or commit compiled code - * Frontend tests ran at build time (can be disabled too) - * Made as modular as possible, so it works out of the box, but you can re-generate with Vue CLI or create it as you need, and re-use what you want -* Swagger-UI for live interactive documentation -* Flower for Celery jobs monitoring -* Load balancing between frontend and backend with Traefik, so you can have both under the same domain, separated by path, but served by different containers -* Traefik integration, including Let's Encrypt HTTPS certificates automatic generation -* GitLab CI (continuous integration), including frontend and backend testing - -## QuickStart for SPAs * - -### * Deprecation Notice +### Server set up -If you are building modern frontend applications (e.g. [Vue](https://vuejs.org/), [React](https://reactjs.org/), [Angular](https://angular.io/)) you would most probably be compiling a modern version of JavaScript (ES2015, TypeScript, etc) to a less modern, more compatible version. +All these project generators include automatic and free HTTPS certificates generation provided by: +* [Traefik](https://traefik.io/) and +* [Let's Encrypt](https://letsencrypt.org/) -If you want to serve your (compiled) frontend code by the same backend (Flask) Docker container, you would have to copy the code to the container after compiling it. +...using [a very simple to use Docker cluster configuration with Docker Swarm mode](https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232). -That means that you would need to have all the frontend tools installed on the building machine (it might be your computer, a remote server, etc). +It would take about 20 minutes to read that guide and have a Docker cluster (of one or more servers) up and running ready for your projects. -That also means that you would have to, somehow, always remember to compile the frontend code right before building the Docker image. +You can have several projects in the same cluster, all with automatic HTTPS, even if they have different domains or sub-domains. -And it might also mean that you could then have to add your compiled frontend code to your `git` repository (hopefully you are using Git already, or [learning how to use `git`](https://www.atlassian.com/git)). +### Generate a project -Adding your compiled code to Git is a very bad idea for several reasons, some of those are: +Then you can use one of the following project generators. -* You don't have a single, ultimate source of truth (the source code). -* The compiled code might be stale, even when your source code is new, which might make you spend a lot of time debugging. -* You might run into a lot of code conflicts when interacting with multiple team members with different Git branches, and spend a lot of time solving irrelevant code conflicts in the compiled code. - * This might also ruin automatic branch merging in pull requests from other team members. +It would take about 5 extra minutes to generate one of these projects. -For these reasons, it is not recommended that you serve your frontend code from the same backend (Flask) Docker container. +### Deploy +And it would take about 3 more minutes to deploy them in your cluster. -### Better alternative +--- -There's a much better alternative to serving your frontend code from the same backend (Flask) Docker container. +In total, about 28 minutes to start from scratch and get an HTTPS Docker cluster with your full application(s) ready. -You can have another Docker container with all the frontend tools installed (Node.js, etc) that: +--- -* Takes your source frontend code. -* Compiles it and generates the final "distributable" frontend. -* Uses Docker "multi-stage builds" to copy that compiled code into a pure Nginx Docker image. -* The final frontend image only contains the compiled frontend code, directly from the source, but has the small size of an Nginx image, with all the performance from Nginx. +These are the project generators: -To learn the specifics of this process for the frontend building in Docker you can read: +### flask-frontend-docker -* [React in Docker with Nginx, built with multi-stage Docker builds, including testing](https://medium.com/@tiangolo/react-in-docker-with-nginx-built-with-multi-stage-docker-builds-including-testing-8cc49d6ec305) -* [Angular in Docker with Nginx, supporting configurations / environments, built with multi-stage Docker builds and testing with Chrome Headless](https://medium.com/@tiangolo/angular-in-docker-with-nginx-supporting-environments-built-with-multi-stage-docker-builds-bb9f1724e984) +Project link: [https://github.com/tiangolo/flask-frontend-docker](https://github.com/tiangolo/flask-frontend-docker) -After having one backend (Flask) container and one frontend container, you need to serve both of them. +Minimal project generator with a Flask backend, a modern frontend (Vue, React or Angular) using Docker multi-stage building and Nginx, a Traefik load balancer with HTTPS, Docker Compose (and Docker Swarm mode) etc. -And you might want to serve them under the same domain, under a different path. For example, the backend (Flask) app at the path `/api` and the frontend at the "root" path `/`. -You can then use [Traefik](https://traefik.io/) to handle that. +### full-stack -And it can also automatically generate HTTPS certificates for your application using Let's Encrypt. All for free, in a very easy setup. +Project Link: [https://github.com/tiangolo/full-stack](https://github.com/tiangolo/full-stack) -If you want to use this alternative, [check the project generators above](#project-generators), they all use this idea. +Full stack project generator with Flask backend, PostgreSQL DB, PGAdmin, SQLAlchemy, Alembic migrations, Celery asynchronous jobs, API testing, CI integration, Docker Compose (and Docker Swarm mode), Swagger, automatic HTTPS, Vue.js, etc. -In this scenario, you would have 3 Docker containers: -* Backend (Flask) -* Frontend (Vue.js, Angular, React or any other) -* Traefik (load balancer, HTTPS) +### full-stack-flask-couchbase +Project Link: [https://github.com/tiangolo/full-stack-flask-couchbase](https://github.com/tiangolo/full-stack-flask-couchbase) -### Deprecated technique for SPAs in a single container +✨ This project generator is the most feature-complete. ✨ -**Notice**: this technique is deprecated, as it can create several issues with modern frontend frameworks. For the details and better alternatives, read the section above. +Full stack project generator with Flask backend, Couchbase, Couchbase Sync Gateway, Celery asynchronous jobs, API testing, CI integration, Docker Compose (and Docker Swarm mode), Swagger, automatic HTTPS, Vue.js, etc. -This section explains how to configure the image to serve the contents of `/static/index.html` directly when the browser requests `/`. +Similar to the one above (`full-stack`), but with Couchbase instead of PostgreSQL, and some more features. -This is specially helpful (and efficient) if you are building a Single-Page Application (SPA) with JavaScript ( [Vue](https://vuejs.org/), [React](https://reactjs.org/), [Angular](https://angular.io/), etc.) and you want the `index.html` to be served directly, without modifications by Python or Jinja2 templates. And you want to use Flask mainly as an API / back end for your SPA front end. -**Note**: You can download the example project **example-flask-python3.7-index.zip** and use it as the template for your project in the **Examples** section above. +### full-stack-flask-couchdb ---- +Project Link: [https://github.com/tiangolo/full-stack-flask-couchdb](https://github.com/tiangolo/full-stack-flask-couchdb) -Or you may follow the instructions to build your project from scratch (it's very similar to the procedure above): +Full stack project generator with Flask backend, CouchDB, Celery asynchronous jobs, API testing, CI integration, Docker Compose (and Docker Swarm mode), Swagger, automatic HTTPS, Vue.js, etc. -* Go to your project directory -* Create a `Dockerfile` with: +Similar to `full-stack-flask-couchbase`, but with CouchDB instead of Couchbase (or PostgreSQL). -```Dockerfile -FROM tiangolo/uwsgi-nginx-flask:python3.7 -ENV STATIC_INDEX 1 +## Quick Start for SPAs * -COPY ./app /app -``` +### Modern Single Page Applications -* Create an `app` directory and enter in it -* Create a `main.py` file (it should be named like that and should be in your `app` directory) with: +If you are building modern frontend applications (e.g. [Vue](https://vuejs.org/), [React](https://reactjs.org/), [Angular](https://angular.io/)) you would most probably be compiling a modern version of JavaScript (ES2015, TypeScript, etc) to a less modern, more compatible version. -```python -import os -from flask import Flask, send_file -app = Flask(__name__) +If you want to serve your (compiled) frontend code by the same backend (Flask) Docker container, you would have to copy the code to the container after compiling it. +That means that you would need to have all the frontend tools installed on the building machine (it might be your computer, a remote server, etc). -@app.route("/hello") -def hello(): - return "Hello World from Flask" +That also means that you would have to, somehow, always remember to compile the frontend code right before building the Docker image. +And it might also mean that you could then have to add your compiled frontend code to your `git` repository (hopefully you are using Git already, or [learning how to use `git`](https://www.atlassian.com/git)). -@app.route("/") -def main(): - index_path = os.path.join(app.static_folder, 'index.html') - return send_file(index_path) +Adding your compiled code to Git is a very bad idea for several reasons, some of those are: +* You don't have a single, ultimate source of truth (the source code). +* The compiled code might be stale, even when your source code is new, which might make you spend a lot of time debugging. +* You might run into a lot of code conflicts when interacting with multiple team members with different Git branches, and spend a lot of time solving irrelevant code conflicts in the compiled code. + * This might also ruin automatic branch merging in pull requests from other team members. -# Everything not declared before (not a Flask route / API endpoint)... -@app.route('/') -def route_frontend(path): - # ...could be a static file needed by the front end that - # doesn't use the `static` path (like in `