docker-flask-example

授权协议 MIT License
开发语言 JavaScript
所属分类 Web应用开发、 常用JavaScript包
软件类型 开源软件
地区 不详
投 递 者 贡可人
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

An example Flask + Docker app

CI

You could use this example app as a base for your new project or as a guide toDockerize your existing Flask app.

The example app is minimal but it wires up a number of things you might use ina real world Flask app, but at the same time it's not loaded up with a millionpersonal opinions.

For the Docker bits, everything included is an accumulation of Docker bestpracticesbased on building and deploying dozens of assorted Dockerized web apps sincelate 2014.

This app is using Flask 2.0.2 and Python 3.10.0. The screenshot doesn't getupdated every time I bump the versions:

Table of contents

Tech stack

If you don't like some of these choices that's no problem, you can swap themout for something else on your own.

Back-end

Front-end

But what about JavaScript?!

Picking a JS library is a very app specific decision because it depends onwhich library you like and it also depends on if your app is going to bemostly Jinja templates with sprinkles of JS or an API back-end.

This isn't an exhaustive list but here's a few reasonable choices depending onhow you're building your app:

On the bright side with Webpack being set up you can use any (or none) of thesesolutions very easily. You could follow a specific library's Webpackinstallation guides to get up and running in no time.

Personally I'm going to be using Hotwire Turbo + Stimulus in most newerprojects.

Notable opinions and extensions

Flask is a very unopinionated framework but I find in most apps I'm adding thesame things over and over. Here's a few (but not all) note worthy additionsand changes.

  • Packages and extensions:
    • gunicorn for an app server in both development and production
    • Flask-DB to help manage, migrate and seed your database
    • Flask-Static-Digest to md5 tag and gzip your static files (and add optional CDN support)
    • Flask-Secrets to quickly generate secure random tokens you can use for various things
    • Flask-DebugToolbar to show useful information for debugging
  • Linting, formatting and testing:
    • flake8 is used to lint the code base
    • black is used to format the code base
    • pytest and pytest-cov for writing tests and reporting test coverage
  • Blueprints:
    • Add page blueprint to render a / page and /up health check endpoint
  • Config:
    • Log to STDOUT so that Docker can consume and deal with log output
    • Extract a bunch of configuration settings into environment variables
    • config/settings.py and the .env file handles configuration in all environments
  • Front-end assets:
    • assets/ contains all your CSS, JS, images, fonts, etc. and is managed by Webpack
    • Custom 502.html and maintenance.html pages
    • Generate favicons using modern best practices
  • Flask defaults that are changed:
    • public/ is the static directory where Flask will serve static files from
    • static_url_path is set to "" to remove the /static URL prefix for static files
    • ProxyFix middleware is enabled (check hello/app.py)

Besides the Flask app itself:

  • Docker support has been added which would be any files having *docker* inits name
  • GitHub Actions have been set up
  • A requirements-lock.txt file has been introduced using pip3. Themanagement of this file is fully automated by the commands found in the runfile. We'll cover this in more detail when we talk about updatingdependencies.

Running this app

You'll need to have Docker installed.It's available on Windows, macOS and most distros of Linux. If you're new toDocker and want to learn it in detail check out the additional resourceslinks near the bottom of thisREADME.

If you're using Windows, it will be expected that you're following along insideof WSL or WSL2.That's because we're going to be running shell commands. You can always modifythese commands for PowerShell if you want.

Clone this repo anywhere you want and move into the directory:

git clone https://github.com/nickjj/docker-flask-example helloflask
cd helloflask

# Optionally checkout a specific tag, such as: git checkout 0.7.0

Copy a few example files because the real files are git ignored:

cp .env.example .env
cp docker-compose.override.yml.example docker-compose.override.yml

Build everything:

The first time you run this it's going to take 5-10 minutes depending on yourinternet connection speed and computer's hardware specs. That's because it'sgoing to download a few Docker images and build the Python + Yarn dependencies.

docker-compose up --build

Now that everything is built and running we can treat it like any other Flaskapp.

Did you receive an error about a port being in use? Chances are it's becausesomething on your machine is already running on port 8000. Check out the docsin the .env file for the DOCKER_WEB_PORT_FORWARD variable to fix this.

Setup the initial database:

# You can run this from a 2nd terminal. It will create both a development and
# test database with the proper user / password credentials.
./run flask db reset --with-testdb

We'll go over that ./run script in a bit!

Check it out in a browser:

Visit http://localhost:8000 in your favorite browser.

Not seeing any CSS? That means Webpack is still compiling. Give ita few more seconds and reload. It should self resolve.

Linting the code base:

# You should get no output (that means everything is operational).
./run flake8

Formatting the code base:

# You should see that everything is unchanged (it's all already formatted).
./run black

Running the test suite:

# You should see all passing tests. Warnings are typically ok.
./run pytest

Stopping everything:

# Stop the containers and remove a few Docker related resources associated to this project.
docker-compose down

You can start things up again with docker-compose up and unlike the firsttime it should only take seconds.

Files of interest

I recommend checking out most files and searching the code base for TODO:,but please review the .env and run files before diving into the rest of thecode and customizing it. Also, you should hold off on changing anything untilwe cover how to customize this example app's name with an automated script(coming up next in the docs).

.env

This file is ignored from version control so it will never be commit. There's anumber of environment variables defined here that control certain options andbehavior of the application. Everything is documented there.

Feel free to add new variables as needed. This is where you should put all ofyour secrets as well as configuration that might change depending on yourenvironment (specific dev boxes, CI, production, etc.).

run

You can run ./run to get a list of commands and each command hasdocumentation in the run file itself.

It's a shell script that has a number of functions defined to help you interactwith this project. It's basically a Makefile except with lesslimitations.For example as a shell script it allows us to pass any arguments to anotherprogram.

This comes in handy to run various Docker commands because sometimes thesecommands can be a bit long to type. Feel free to add as many conveniencefunctions as you want. This file's purpose is to make your experience better!

If you get tired of typing ./run you can always create a shell alias withalias run=./run in your ~/.bash_aliases or equivalent file. Then you'll beable to run run instead of ./run.

Running a script to automate renaming the project

The app is named hello right now but chances are your app will be a differentname. Since the app is already created we'll need to do a find / replace on afew variants of the string "hello" and update a few Docker related resources.

And by we I mean I created a zero dependency shell script that does all of theheavy lifting for you. All you have to do is run the script below.

Run the rename-project script included in this repo:

# The script takes 2 arguments.
#
# The first one is the lower case version of your app's name, such as myapp or
# my_app depending on your preference.
#
# The second one is used for your app's module name. For example if you used
# myapp or my_app for the first argument you would want to use MyApp here.
bin/rename-project myapp MyApp

The bin/rename-projectscriptis going to:

  • Remove any Docker resources for your current project
  • Perform a number of find / replace actions
  • Optionally initialize a new git repo for you

Afterwards you can delete this script because its only purpose is to assist inhelping you change this project's name without depending on any complicatedproject generator tools or 3rd party dependencies.

If you're not comfy running the script or it doesn't work for whatever reasonsyou can check itoutand perform the actions manually. It's mostly running a find / replace acrossfiles and then renaming a few directories and files.

Start and setup the project:

This won't take as long as before because Docker can re-use most things. We'llalso need to setup our database since a new one will be created for us byDocker.

docker-compose up --build

# Then in a 2nd terminal once it's up and ready.
./run flask db reset --with-testdb

Sanity check to make sure the tests still pass:

It's always a good idea to make sure things are in a working state beforeadding custom changes.

# You can run this from the same terminal as before.
./run flake8
./run black
./run pytest

If everything passes now you can optionally git add -A && git commit -m "Initial commit" and start customizing your app. Alternatively you can waituntil you develop more of your app before committing anything. It's up to you!

Tying up a few loose ends:

You'll probably want to create a fresh CHANGELOG.md file for your project. Ilike following the style guide at https://keepachangelog.com/ but feel freeto use whichever style you prefer.

Since this project is MIT licensed you should keep my name and email address inthe LICENSE file to adhere to that license's agreement, but you can also addyour name and email on a new line.

If you happen to base your app off this example app or write about any of thecode in this project it would be rad if you could credit this repo by linkingto it. If you want to reference me directly please link to my site athttps://nickjanetakis.com. You don't have to do this, but it would be verymuch appreciated!

Updating dependencies

Let's say you've customized your app and it's time to make a change to yourrequirements.txt or package.json file.

Without Docker you'd normally run pip3 install -r requirements.txt or yarn install. With Docker it's basically the same thing and since these commandsare in our Dockerfile we can get away with doing a docker-compose build butdon't run that just yet.

In development:

You can run ./run pip3:outdated or ./run yarn:outdated to get a list ofoutdated dependencies based on what you currently have installed. Once you'vefigured out what you want to update, go make those updates in yourrequirements.txt and / or assets/package.json file.

Then to update your dependencies you can run ./run pip3:install or ./run yarn:install. That'll make sure any lock files get copied from Docker's image(thanks to volumes) into your code repo and now you can commit those files toversion control like usual.

You can check out therun file to seewhat these commands do in more detail.

As for the requirements' lock file, this ensures that the same exact versionsof every package you have (including dependencies of dependencies) get used thenext time you build the project. This file is the output of running pip3 freeze. You can check how it works by looking atbin/pip3-install.

You should never modify the lock files by hand. Add your top level Pythondependencies to requirements.txt and your top level JavaScript dependenciesto assets/package.json, then run the ./run command(s) mentioned earlier.

In CI:

You'll want to run docker-compose build since it will use any existing lockfiles if they exist. You can also check out the complete CI test pipeline inthe run fileunder the ci:test function.

In production:

This is usually a non-issue since you'll be pulling down pre-built images froma Docker registry but if you decide to build your Docker images directly onyour server you could run docker-compose build as part of your deploypipeline.

See a way to improve something?

If you see anything that could be improved please open an issue or start a PR.Any help is much appreciated!

Additional resources

Now that you have your app ready to go, it's time to build something cool! Ifyou want to learn more about Docker, Flask and deploying a Flask app here's acouple of free and paid resources. There's Google too!

Learn more about Docker and Flask

Official documentation

Courses

Deploy to production

I'm creating an in-depth course related to deploying Dockerized web apps. Ifyou want to get notified when it launches with a discount and potentially getfree videos while the course is being developed then sign up here to getnotified.

About the author

I'm a self taught developer and have been freelancing for the last ~20 years.You can read about everything I've learned along the way on my site athttps://nickjanetakis.com.

There's hundreds of blog posts and a coupleof video courses on web development anddeployment topics. I also have a podcastwhere I talk with folks about running web apps in production.

  • 本文主要讲解以下两块内容:环境配置的作用及常规使用、服务配置文件的解析以及常规使用 必备知识: 在讲解服务配置文件和环境配置文件之前,首先要对docker以及编排工具compose有一定的了解,然后,才能结合服务配置文件编排整个项目的服务以及其依赖关系等。 环境变量:在容器中生效的全局变量值 环境配置文件:可以替换compose服务配置文件中的属性变量。compose默认读取环境配置文件为“.en

  • 目录 1.Compose介绍 2.Compose和Docker兼容性 3.安装docker 4.安装docker-compose 1.从github上下载docker-compose二进制文件安装 2.pip安装 5.docker-compose文件结构和示例 docker-compose文件结构 docker-compose使用示例 6.compose常用服务配置参考 build image c

  • 1、简介 Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。 Compose 使用的三个步骤: 使用 Dockerfile 定义应用程序的环境。 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境

  • docker-compose用于定义和运行多个docker容器。采用YAML文件配置应用服务,可从配置文件启动相关服务,一条命令可以启动多个容器。 docker-compose应用 compose将所管理的容器分为三层:工程(project)、服务(service)、容器(container)。compose运行目录下的所有文件组成一个工程,一个工程包含多个服务,每个服务中定义了容器运行的镜像、参

 相关资料
  • Dockerizing Flask with Postgres, Gunicorn, and Nginx Want to learn how to build this? Check out the post. Want to use this project? Development Uses the default Flask development server. Rename .env.d

  • Docker Flask Celery Redis A basic Docker Compose template for orchestrating a Flask application & a Celery queue with Redis Installation git clone https://github.com/mattkohl/docker-flask-celery-redis

  • Supported tags and respective Dockerfile links python3.9, latest (Dockerfile) python3.8, (Dockerfile) python3.7, (Dockerfile) python3.6 (Dockerfile) Discouraged tags python3.9-alpine3.13 (Dockerfile)

  • Supported tags and respective Dockerfile links python3.9, latest (Dockerfile) python3.8, (Dockerfile) python3.7, (Dockerfile) python3.6 (Dockerfile) Discouraged tags python3.8-alpine (Dockerfile) To l

  • 我有两个容器 - 一个包含 react 应用程序,另一个包含烧瓶应用程序。 我可以使用下面的docker-compose文件和它们各自的Dockerfile构建两者,并且能够通过指定端口上的浏览器访问每个。但是,我的React应用程序对Flask的API调用没有被检索(它们在图片中没有Docker的情况下工作)。 任何建议都非常感谢! Docker-撰写 用于烧瓶应用程序的Dockerfile D

  • 本文向大家介绍使用Docker部署Nginx+Flask+Mongo的应用,包括了使用Docker部署Nginx+Flask+Mongo的应用的使用技巧和注意事项,需要的朋友参考一下 Nginx做为服务器,Mongo为数据库支持,Flask为Python语言的Web框架,利用Docker的容器特性,可以简单地部署在linux服务器上 项目准备 项目主要目录如下 简要说明 docker-file目录