群晖最新版(DSM 7.2) 下使用 Web Station 部署 flask 项目

goocheez 2024-10-12 17:03:05 阅读 52

0. 需求由来

为了在 DSM 7.2 版本下的群晖 NAS 里运行我基于 flask 3.0.2 编写的网页应用程序,我上网查了非常多资料,也踩了很多坑。最主要的就是 7.2 版本的界面与旧版略有不同,而网络上的资料大多基于旧版界面,且大部分仅仅说明了 How to do,而没有解释 Why to do。因此本人随手记录一下。

DSM 7.2 下的 web staton 主界面

1. 新建虚拟环境

最开始的一步,自然是建设虚拟环境,用以支撑 Flask 的项目运行:

从自己的 Flask 项目中导出所需的软件包: <code>pip freeze > requirements.txt在 DSM 的管理界面下:web station ➡️ 脚本语言设置 ➡️ python ➡️ 新增 ➡️ 名称设为 flask_venv ➡️ uWSGI 可保持默认 ➡️ 模块页面,点击上传 requirements.txt

本步骤要点:

DSM 7.2 里的 web station,其脚本语言设置,其实就是搭建一个可以复用的虚拟环境。无需自行远程登录 DSM 去手动安装 pip。自 python 3.4 版本以来,pip 已经被内置到官方版本内部了,仅需一个 python -m ensurepip --upgrade 命令,完整安装的 python 即可离线安装好 pip。因此,我们在 DSM 上面的配置过程,全程无需后台登录操作,仅需在 web 页面下足以。

2. 上传代码

上传代码到 DSM 有很多种方式,最简单的是通过 File Station 的 web 界面,将项目代码拖进去,比如 web 下的一个子目录。也可以通过开启 DSM 的 ftp、sftp 等协议进行上传

关于 flask 的代码有一个注意点,即若 flask 的实例是采用工厂模式创建的,则必须添加一个独立的文件,名称随意(一般叫 wsgi.py),内容如下:

from hello import create_app

app = create_app()

本步骤要点:

需要对 wsgi 协议有一定了解,知道 wsgi 的程序跑起来需要哪些设置,特别是工厂模式下的 flask 如何支持 wsgi 需要了解。DSM 下的 sftp 服务,其根目录就是 File Station 见到的根目录,可以依据此设置自动脚本,实现文件的自动上传,以便后期部署过程中的不断修正。为确保安全,建议使用公钥体系,避免使用密码,不赘述。

3. 设置网页服务

设置网页服务: web station ➡️ 网页服务 ➡️ 新增 ➡️ 本机脚本语言网站服务项选择 python3.9 以及 flask_venv ➡️ 文档根目录指向第2步上传的代码所在目录,指定 wsgi 文件及 Callable

本步骤要点:

wsgi 文件:即 flask 的主程序所在的 python 文件,一般就是初始化了 Flask 对象的那个。若是工厂模式,则指定前述新增的那个 wsgi.py 文件Callable:即 wsgi 文件中,代表被初始化的 Flask 对象的那个变量,一般都是 app需要理解,DSM 语境下的网页服务,实际意思就是基于虚拟环境与代码实现的一套网页应用。到了这一步,代码其实已经运行起来了,只是尚未对外提供服务而已(详见 <code>/usr/local/etc/nginx/sites-enabled)。DSM 使用 uwsgi 支持 python,并通过 nginx 反向代理,对外提供服务。

4. 对外提供服务

现在到了最后一步,我们需要设置网络门户,以便我们可以面向互联网提供我们前面配置好的网页服务:web station ➡️ 网络门户 ➡️ 网页服务门户

服务:选择我们刚新增的那个 flask 网页服务门户类型:有三个选择,分别是基于端口、基于名称,和别名门户。

若是只有一个域名,一般选择基于端口,然后选择一个不冲突的端口即可。若拥有额外的域名,则此时可以选择基于名称并复用 80/443 端口,且要确保该域名设置了正确的解析,指向 NAS 的公网地址。至于别名门户,就是在 URL 末端用一个子目录,指向你的网站。比如我们如果设置了名称为 myapp 的别名,则访问地址可能为 yourname.synology.me/myapp (前面的 yourname.synology.me 依据你注册使用的地址不同而略有不同)。

如果要使用这一项,则必须确保你的 flask 项目能够部署在子目录,比如我通过重写 flask.url_for 函数,实现 url 子目录前缀,最终实现 flask 项目部署的子目录化。(关于如何重写 flask.url_for 函数,详见 这篇)

我个人倾向于使用别名门户,看起来正经,而且无需额外的域名,使用群晖自带的服务即可。

若是出现 Internal Server Error 的错误提示,则一般都是你的 flask 代码有问题,在本地测试修改,并确认第1步建立的虚拟环境内的各模块正确,一般都可以解决了。

至此,flask 应用已经正常跑起来了。

参考

flask 官方文档: https://flask.palletsprojects.com/en/3.0.x/ensurepip 的官方文档: https://docs.python.org/zh-cn/dev/library/ensurepip.html群晖nas中使用python的Flask框架搭建网站(用Web Station): https://www.cnblogs.com/yaoyue68/p/17587070.html群晖NAS中Web Station使用Flask作为后端服务教程: https://www.bilibili.com/read/cv17483317/



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。