FASTAPI官方项目(一)-项目启动、初始化

将官方生成的项目直接跑在服务器上大概率是跑不起来的

强烈建议想学习这个项目的同学通读生成的README,注意,是通读,很有用

前言

Fastapi 官方的文档还是不错的,上手也比较快,但是我们学这个框架,还是需要以一个稍大一点的项目来结合学习,官网的 demo 太简单了,我们很难从一个简单的 demo 扩展出更完整的后台接口。

我们选择的是官方的项目生成器:full-stack-fastapi-postgresql

按照readme,我们可以生成对应自己环境的项目

整个文档详细的讲了项目的生成,都没遇到什么坑,除了要填的东西出乎意料的多之外。

生成的脚本如下:

1
2
pip install cookiecutter
cookiecutter https://github.com/tiangolo/full-stack-fastapi-postgresql

生成部分略过,这部分基本没坑,有坑你可以评论区留言。

因个人电脑环境不同,你遇到的问题我可能并没有遇到,还请见谅

而且很多教程都在讲如何用 docker compose 启动,花了大晚上时间躺一晚上的坑。
比着 readme 来各种报错,比着文章来各种报错,最后终于启动了,结果并不知道启动了个啥。

相关框架以及包管理器介绍

对一个客户端来看,后端很多的概念都是陌生的,只有见一个不会的技术搜一个。

其实其他的很多东西,我们这些野路子,可能只想要个简介。

NPM

这个应该了解的还是挺多的,但是还是贴一下

NPM是随同 NodeJS 一起安装的包管理工具,能解决 NodeJS 代码部署上的很多问题,常见的使用场景有以下几种:

  • 允许用户从 NPM 服务器下载别人编写的第三方包到本地使用。
  • 允许用户从 NPM 服务器下载并安装别人编写的命令行程序到本地使用。
  • 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

Docker

这玩意我至今只会简单用用,并不知道如何封装一个自定义的 Docker 镜像。

  • Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
  • Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
  • 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker Compose

这个我表示没听过

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
如果你还不了解 YML 文件配置,可以先阅读 YAML 入门教程。
Compose 使用的三个步骤:

  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

下载 Docker

这个可以直接百度,mac 下 docker desktop 比较方便。

ubuntu 就使用 apt 安装。

启动 docker

1
systemctl restart docker

换源

我们是国内用户,npm 换源,docker 换源,有的时候本地有梯子并且也能代理到 docker 去,但是得考虑这个我们之后是需要部署到服务器的。

修复 flower 版本兼容

相关链接
flower这个玩意不兼容新版docker
查 issue 后解决,更改 docker-compose.yml 中的 flower 的版本如下:

1
2
flower:
image: mher/flower:0.9.7

替换 python 包管理器

仓库使用 poetry 作为 python 的包管理器,这个需要梯子,我们换回 pip 作为包管理器。

在 backend/app 下新建 requirments.txt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
uvicorn==0.11.3
fastapi==0.54.1
python-multipart==0.0.5
email-validator==1.0.5
requests==2.23.0
celery==4.4.2
passlib==1.7.2
tenacity==6.1.0
pydantic==1.4
emails==0.5.15
raven==6.10.0
gunicorn==20.0.4
jinja2==2.11.2
psycopg2-binary==2.8.5
alembic==1.4.2
sqlalchemy==1.3.16
pytest==5.4.1
python-jose==3.1.0
mypy==0.770
black==19.10b0
isort==4.3.21
autoflake==1.3.1
flake8==3.7.9
pytest==5.4.1
sqlalchemy-stubs==0.3
pytest-cov==2.8.1
bcrypt==3.2.0

修改 backend/app/backend.dockerfile 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7

WORKDIR /app/

COPY ./app/requirments.txt /app/

RUN pip config set global.index-url http://mirrors.aliyun.com/pypi/simple && \
pip config set install.trusted-host mirrors.aliyun.com && \
pip install -U pip &&\
pip install -r requirments.txt

# # Install Poetry
# RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \
# cd /usr/local/bin && \
# ln -s /opt/poetry/bin/poetry && \
# poetry config virtualenvs.create false

# # Copy poetry.lock* in case it doesn't exist in the repo
# COPY ./app/pyproject.toml ./app/poetry.lock* /app/

# # Allow installing dev dependencies to run tests
# ARG INSTALL_DEV=false
# RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then poetry install --no-root ; else poetry install --no-root --no-dev ; fi"

# For development, Jupyter remote kernel, Hydrogen
# Using inside the container:
# jupyter lab --ip=0.0.0.0 --allow-root --NotebookApp.custom_display_url=http://127.0.0.1:8888
ARG INSTALL_JUPYTER=false
RUN bash -c "if [ $INSTALL_JUPYTER == 'true' ] ; then pip install jupyterlab ; fi"

COPY ./app /app
ENV PYTHONPATH=/app

修改 backend/app/celeryworker.dockerfile 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
FROM python:3.7

WORKDIR /app/
COPY ./app/requirments.txt /app/

RUN pip config set global.index-url http://mirrors.aliyun.com/pypi/simple && \
pip config set install.trusted-host mirrors.aliyun.com && \
pip install -U pip && \
pip install -r requirments.txt

# Install Poetry
# RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \
# cd /usr/local/bin && \
# ln -s /opt/poetry/bin/poetry && \
# poetry config virtualenvs.create false

# # Copy poetry.lock* in case it doesn't exist in the repo
# COPY ./app/pyproject.toml ./app/poetry.lock* /app/

# Allow installing dev dependencies to run tests
# ARG INSTALL_DEV=false
# RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then poetry install --no-root ; else poetry install --no-root --no-dev ; fi"

# For development, Jupyter remote kernel, Hydrogen
# Using inside the container:
# jupyter lab --ip=0.0.0.0 --allow-root --NotebookApp.custom_display_url=http://127.0.0.1:8888
ARG INSTALL_JUPYTER=false
RUN bash -c "if [ $INSTALL_JUPYTER == 'true' ] ; then pip install jupyterlab ; fi"

ENV C_FORCE_ROOT=1

COPY ./app /app
WORKDIR /app

ENV PYTHONPATH=/app

COPY ./app/worker-start.sh /worker-start.sh

RUN chmod +x /worker-start.sh

CMD ["bash", "/worker-start.sh"]

解决端口占用

我们服务器可能已经使用了80端口,后端接口与对应的前端客户端都会因为端口已经使用而无法启动容器
更改 docker-compose.override.yml 如下
关键行- "8000:80",目的是将 docker 的80端口映射到服务器的8000端口上。

1
2
3
4
proxy:
ports:
- "8000:80"
- "8090:8080"

启动

1
docker-compose up -d

正常运行输出如下,我第一次看到这的时候其实还是比较懵,以为会打印一些信息,比如打开啥 url 是啥,其实就是对
docker 相关的东西陌生导致的。

1
2
3
4
5
6
7
8
9
WARNING: Some services (backend, db, flower, frontend, pgadmin, proxy) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.
Starting user_center_frontend_1 ... done
Starting user_center_queue_1 ... done
Starting user_center_flower_1 ... done
Starting user_center_proxy_1 ... done
Starting user_center_db_1 ... done
Starting user_center_backend_1 ... done
Starting user_center_celeryworker_1 ... done
Starting user_center_pgadmin_1 ... done

这个时候可能会记不得某个项目的端口,用 docker ps命令可以看,输出如下:

1
2
3
4
5
6
7
8
9
CONTAINER ID   IMAGE                 COMMAND                  CREATED        STATUS         PORTS                                                                              NAMES
273a3718ecd2 backend:latest "/start-reload.sh" 18 hours ago Up 8 minutes 80/tcp, 0.0.0.0:8888->8888/tcp, :::8888->8888/tcp user_center_backend_1
b1e83b1588b1 dpage/pgadmin4 "/entrypoint.sh" 39 hours ago Up 8 minutes 80/tcp, 443/tcp, 0.0.0.0:5050->5050/tcp, :::5050->5050/tcp user_center_pgadmin_1
4e247a6c36b9 celeryworker:latest "bash /worker-start.…" 39 hours ago Up 8 minutes user_center_celeryworker_1
8a1a34f474f6 mher/flower:0.9.7 "flower --broker=amq…" 39 hours ago Up 9 minutes 0.0.0.0:5555->5555/tcp, :::5555->5555/tcp user_center_flower_1
669842cbebac traefik:v2.2 "/entrypoint.sh --pr…" 39 hours ago Up 9 minutes 0.0.0.0:8000->80/tcp, :::8000->80/tcp, 0.0.0.0:8090->8080/tcp, :::8090->8080/tcp user_center_proxy_1
ba15d3e197b0 frontend:latest "nginx -g 'daemon of…" 39 hours ago Up 9 minutes 80/tcp user_center_frontend_1
cc6b4f18fcda rabbitmq:3 "docker-entrypoint.s…" 39 hours ago Up 9 minutes 4369/tcp, 5671-5672/tcp, 15691-15692/tcp, 25672/tcp user_center_queue_1
b33c3ac40a51 postgres:12 "docker-entrypoint.s…" 39 hours ago Up 9 minutes 5432/tcp user_center_db_1

需要查看某个 docker container 的 log ,可以直接在 vs code 安装 docker 查看,左边侧栏就会多出一个菜单,右键对应的容器就可以看 log。

这个时候慢慢感觉到了docker-compose 的强大。

跨域问题

如果是本地开发,运行成功后,别用127.0.0.1去打开,用 localhost,因为只有这个配置了跨域,127.0.0.1会访问不到,虽然网页能打开,但是登录只会提示密码错误,但其实就是跨域的问题。

当然你可以修改.env文件,添加新的跨域规则。

相关命令

mac 请用客户端操作
启动进入某个容器的 sh

相关 URL

host:8000可以打开对应的客户端
host:8000/docs可以查看 swagger 文档,
host:8000/redoc可以查看新版文档
host:5050可以打开 pgadmin 界面,这个是一个 web 的数据库客户端,非常方便
我起初还去下了一堆破解的 navicat,其实没太多必要,而且在我的电脑上用 navicat 连接上看不到表。

前端项目单独启动

注意上面的操作结束后,前端项目已经启动成功了,以下是讲没有经过以上步骤单独启动前端项目

这个文件夹下有一个非常简洁的 readme,读一下

1
2
3
# frontend

## Project setup

npm install

1
2

### Compiles and hot-reloads for development

npm run serve

1
2

### Compiles and minifies for production

npm run build

1
2

### Run your tests

npm run test

1
2

### Lints and fixes files

npm run lint

1
2

### Run your unit tests

npm run test:unit

1

运行npm install

报错,血压一下就上来了…

一堆ERR

使用淘宝源

1
2
npm --registry https://registry.npm.taobao.org i express
npm install

还是报错
一句一句读吧,定位到缺什么.pc,

1
Perhaps you should add the directory containing `pangocairo.pc' to the PKG_CONFIG_PATH environment

然后我是 macOS ,去 /usr/local/Celler 找 pkgconfig 那个文件夹并引入到环境变量。

1
export PKG_CONFIG_PATH="/usr/local/Cellar/cairo/1.16.0_5/lib/pkgconfig"

再安装 cairo,pango

1
2
brew install cairo
brew install pango

npm install 正常了。

启动

执行

1
npm run serve

报错~

1
2
3
4
5
6
npm run serve
> frontend@0.1.0 serve
> vue-cli-service serve

INFO Starting development server...
ERROR Error: When you use `tslint` option, make sure to install `tslint`.

执行npm install tslint

终于能跑了,能看到页面,登录肯定是没用的,因为现在咱后端 api 都还没启动。

如果 api 也同时启动成功的话,就能玩了。

作者

梦魇兽

发布于

2022-05-30

更新于

2023-03-11

许可协议

评论