学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦

几天前在腾讯云买了个最低配置的服务器,开整!
先随便找个教程,简单入门了一下docker,然后在linux服务器上装好docker。心想,我在win10上也装个docker,生成镜像,上传到docker hub,去服务器拉下来直接跑就行。


开启Hyper-V -> 去官网下载安装包(官网链接) -> 安装包告诉我windows版本过低:
学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦_第1张图片
-> 要么升级win系统(不想);要么关掉Hyper-V去安装toolbox虚拟机,太复杂了。去知乎上搜索了一番后悟了:
学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦_第2张图片

遂放弃在windows上安装docker。


将本地代码上传到服务器(腾讯云上Orca Term提供了上传文件功能)
学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦_第3张图片
注意虚拟环境venv文件夹涉及到一个问题:docker容器本身就是一个虚拟环境了,不需要再在里面生成虚拟环境。
我是在解决别的问题时看见评论区得到的启发:
在这里插入图片描述
搜了一下别的资料:Activate python virtualenv in Dockerfile,佐证了这个观点,放弃采用虚拟环境(Dockerfile和boot.sh要做对应的修改,这俩文件的最终完整版在下面)


ps:假如仍然按照书上的做法用虚拟环境,也要注意:venv文件夹不能传过去,本地venv是windows环境下的虚拟环境,和linux不一样。根据linux系统的python版本,选择不同的指令生成虚拟环境(狗书的1.3和1.4章节有介绍),最后服务器的/home/flasky目录结构如下:
在这里插入图片描述


进入到/home/flasky目录,按照书上的命令运行docker build创建image,根据image 创建并运行容器。docker ps -a 查看容器运行状况,容器的STATUS不是预期的Up,而是Exited (127),docker logs 指令查看报错信息:

/bin/sh: 1: flask: not found
/bin/sh: 2: exec: gunicorn: not found

为什么找不到命令?明明在Dockerfile中requirements.txt一个一个安装了这些包。搜了很多方法,也重新装了很多次,都失败。
最终发现在某一次Dockerfile重新生成image的过程中,很快闪过了几个WARNING

 WARNING: The script gunicorn is installed in '/home/flasky/.local/bin' which is not on PATH.
 Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

将这个环境变量写进Dockerfile中:ENV PATH=/home/flasky/.local/bin:$PATH,再重新生成image就行了。参考资料:Default pip package PATH in python:3.8-slim-buster docker image
这个是让docker build过程的输出停留的方式:Why is docker build not showing any output from commands?这么重要的消息一闪而过很不友好,我重装了无数次才发现有这个WARNING…

再根据image生成容器,docker ps -a 查看状态,好歹是up起来了
在这里插入图片描述
docker logs myflasky111查看日志,又遇到了报错

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: posts

docker exec -it 容器id /bin/bash 进入容器内用flask db migrate + flask db upgrade做一下数据迁移,再重启容器。查看logs,又报错

Target database is not up to date.

参考Target database is not up to date 用了三条指令可以解决(flask db stamp head + flask db migrate + flask db upgrade
但是在运行第三条指令flask db upgrade时,没有权限访问最新的迁移文件

PermissionError: [Errno 13] Permission denied: '/home/flasky/migrations/versions/71f743fdbb14_.py'

想了很多办法给flasky用户加权限,什么添加用户组和用户,什么重置密码,最终以不知道root用户的密码告终(所以有谁知道腾讯云服务器root用户的密码是啥,我一进服务器就是root了不需要输入密码啊QAQ)
参考PermissionError: [Errno 13] Permission denied: ‘/manage.py’ 尝试使用
sudo chgrp -R docker /home/flasky/migrations/versions
sudo chmod -R g+rw /home/flasky/migrations/versions
(ps:如果没有docker组,就去创建:groupadd <用户组名称>,将当前用户添加到指定组:usermod -a -G <用户组名称> <用户名称>,如果报错没有权限: usermod: Permission denied.usermod: cannot lock /etc/passwd; try again later.,用root身份进容器( docker exec -u 0 -it 容器id /bin/bash ),再执行usermod -a -G <用户组名称> <用户名称>。命令参考)

它让我输入flasky用户的密码,可是我记得我在Dockerfile中只添加了flasky用户,没给它设置密码啊
查看资料怎么设置flasky用户的密码:How to add users to Docker container?在评论区看到,Dockerfile中加上RUN echo 'newuser:newpassword' | chpasswd

根据参考文章,重新编辑Dockerfile,完整文件如下:(如果不用编辑Dockerfile,遇到Permission denied报错后运行上面两行sudo命令,需要重启容器,权限才能生效,我这里重新编辑Dockerfile重新生成镜像容器,也相当于重启了。)

FROM python:3.7

ENV FLASK_APP flasky.py
ENV FLASK_CONFIG docker

RUN useradd -ms /bin/bash flasky
RUN echo 'flasky:你的密码' | chpasswd
RUN adduser flasky sudo
USER flasky

WORKDIR /home/flasky
ENV PATH=/home/flasky/.local/bin:$PATH
COPY requirements requirements
RUN /usr/local/bin/python -m pip install --upgrade pip
RUN pip install -r requirements/common.txt

COPY app app
COPY migrations migrations
COPY flasky.py config.py boot.sh ./

# run-time configuration
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]

完整boot.sh文件如下

#!/bin/sh
flask deploy
exec gunicorn -b :5000 --access-logfile - --error-logfile - flasky:app

构建image,生成容器,进入容器运行flask db upgrade提示PermissionError: [Errno 13] Permission denied 时,执行sudo chgrp -R docker /home/flasky/migrations/versionssudo chmod -R g+rw /home/flasky/migrations/versions,输入上面在Dockerfile中设置的密码。(根据后来的经验,/home/flasky/app/static/avatars文件夹也会报权限错误,也对它运行一下这两个指令吧!)
exit命令退出容器,docker logs 容器id 查看日志,我的天,终于不报错了,泪目T^T
学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦_第4张图片


ps:

  1. 如果想在容器内部使用vim,而容器内部没安装,apt-get install vim 安装一下,报错:
python List directory /var/lib/apt/lists/partial is missing. -Acquire (13: Permission denied) 

需要 docker exec -u 0 -it 容器id /bin/bash 采用root身份进入容器内再安装

  1. 确保boot.sh有可执行权限,chmod +x boot.sh

接下来研究怎样让我的web app 公开可访问
参考一些:资料0,资料1,资料2,资料3,资料4,资料5,资料6
在腾讯云控制台的防火墙开放对应端口
docker run 的时候指定了端口映射,docker ps -a 可以查看映射细节。
0.0.0.0:8000->5000的意思是,开放容器的5000端口,对接到linux服务器(宿主机)的8000端口
在这里插入图片描述
进入容器内访问app: curl localhost:5000,能返回正确地html
学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦_第5张图片
容器内也能联网
在这里插入图片描述
退出容器,在linux服务器上访问容器内的app,curl localhost:8000,也能正确地返回html
学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦_第6张图片

最后喊你的小伙伴来访问你的app吧!地址:去腾讯云控制台查看服务器的公网ip+8000端口
(ps:docker ps -f 容器名 查看日志,加上-f参数就可以动态显示实时刷新的log,按Ctrl C 退出)
学习狗书flask web :将本地win10系统的flask项目,部署到腾讯云的linux服务器的docker上,然后大家都可以访问啦_第7张图片
最后附上一点参考资料:How To Deploy a Flask App on Docker Containers
Docker container build failed: /bin/sh: 1: flask: not found

你可能感兴趣的:(flask,docker,服务器)