这里列出的平台都是可以永久免费使用的,不包含需要收费的比如heroku等,也不包括只能免费体验一段时间的平台比Azure/AWS等。
这个github仓库 heroku-free-alternatives 里面列出一些类似heroku的平台,如果感兴趣的话,可以自己去尝试。
创建项目
打开 google cloud ,创建一个项目。
Shell部署
在同一个页面的右上角有一个图标 "激活 Cloud shell", 点击它,打开 cloud shell, 拷贝粘贴以下命令(请保持多行命令格式),根据提示不停的按 "y" 即可完成部署。
部署和更新都使用同样一条命令。
rm -rf kindleear && \
git clone --depth 1 https://github.com/cdhigh/kindleear.git && \
chmod +x kindleear/tools/gae_deploy.sh && \
kindleear/tools/gae_deploy.sh
注1: 默认配置为B2实例,1个工作进程,2个工作线程,20分钟超时,如果需要其他配置,可以修改最后一行代码
#instance_class: B1 (384MB/600MHz)
#max_instances: 1
#threads: 2 (2 thread per instance)
#idle_timeout: 15m (minutes)
kindleear/tools/gae_deploy.sh B1,1,t2,15m
github页面上下载KindleEar的最新版本,在页面的右下角有一个按钮"Download ZIP",点击即可下载一个包含全部源码的ZIP文档,然后解压到你喜欢的目录,比如D:\KindleEar。
安装 gloud CLI,并且执行
gcloud components install app-engine-python app-engine-python-extras # Run as Administrator
gcloud init
gcloud auth login
gcloud auth application-default set-quota-project your_app_id
gcloud config set project your_app_id
python kindleear/tools/update_req.py gae
gcloud beta app deploy --version=1 app.yaml worker.yaml
gcloud beta app deploy --version=1 cron.yaml
gcloud beta app deploy --version=1 queue.yaml
gcloud beta app deploy --version=1 dispatch.yaml
gcloud beta app deploy --version=1 app.yaml worker.yaml
Updating config [cron]...API [cloudscheduler.googleapis.com] not enabled on project [xxx]. Would you like to enable and retry (this will take a few minutes)
Updating config [queue]...API [cloudtasks.googleapis.com] not enabled on project [xxx]. Would you like to enable and retry (this will take a few minutes)
如果出现部署失败并且多次尝试后仍然无法解决,比如"Timed out fetching pod."之类的错误,可以关停此id,然后重建一个,部署时选择其他区域。
部署成功后先到 GAE后台 将你的发件地址添加到 "Mail API Authorized Senders",否则投递会出现 "Unauthorized sender" 错误。
如果你之前已经部署过Python2版本的KindleEar,建议新建一个项目来部署Python3版本,因GAE不再支持Python2部署,所以覆盖后无法恢复原先的版本。
GAE的计算资源是可伸缩配置的,一般情况下,只有后台实例(worker.yaml)需要修改,默认为B2(768MB/1.2GHz),根据你的推送量调整这个配置,如果推送量大,调整为B4,如果推送量小,缩小为B1。额外的,如果后台出现 " [CRITICAL] WORKER TIMEOUT",则需要增加 entrypoint 里面的 –timeout 参数。
Docker是什么?如果你不了解,就把它类比为Windows平台的绿色软件的增强版。
Docker不限平台,只要目标平台支持Docker,资源足够就可以部署。
wget -O - https://raw.githubusercontent.com/cdhigh/KindleEar/master/docker/ubuntu_docker.sh | bash
http://example.com
修改为你自己的值)。wget https://raw.githubusercontent.com/cdhigh/KindleEar/master/docker/ke-docker.sh
chmod +x ke-docker.sh
ke-docker.sh http://example.com
注1:KindleEar更新后,重新执行最后一行命令可以自动拉取并启动更新后的版本。
注2:脚本会在当前目录创建data子目录(如果不存在)。
注3:如果需要https支持,将 fullchain.pem/privkey.pem 拷贝到data目录,再执行此命令。
注4:默认镜像的配置:
如果连不上,请确认80/443端口是否已经开放,不同的平台开放80/443端口的方法不一样,可能为iptables或ufw。 比如:
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT 7 -m state --state NEW -p tcp --dport 443 -j ACCEPT
sudo netfilter-persistent save
或者开放所有端口
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F
3.1 推荐使用Caddy做为web服务器,可以自动申请和续期SSL证书(一定要先正确填写DOMAIN)
mkdir data #for database and logs
wget https://raw.githubusercontent.com/cdhigh/KindleEar/master/docker/docker-compose.yml
wget https://raw.githubusercontent.com/cdhigh/KindleEar/master/docker/Caddyfile
#important!!! Change the environ variables APP_DOMAIN/DOMAIN
vim ./docker-compose.yml
sudo docker compose up -d
3.2 如果更喜欢Nginx
mkdir data #for database and logs
wget https://raw.githubusercontent.com/cdhigh/KindleEar/master/docker/docker-compose-nginx.yml
wget https://raw.githubusercontent.com/cdhigh/KindleEar/master/docker/default.conf
#Change the environ variables APP_DOMAIN/DOMAIN
vim ./docker-compose-nginx.yml
sudo docker compose -f docker-compose-nginx.yml up -d
使用Nginx时如果需要https,预先将ssl证书 fullchain.pem/privkey.pem 拷贝到data目录,取消default.conf/docker-compose-nginx.yml里面对应的注释即可。
sudo docker compose pull && \
sudo docker compose up -d --remove-orphans && \
sudo docker image prune -f
tail -n 100 ./data/gunicorn.error.log
tail -n 100 ./data/gunicorn.access.log
sudo usermod -aG docker your-username
/data
,比如 /docker/data
映射到 /data
,权限为"读取/写入"APP_DOMAIN
。这是手动在一个 Oracle VPS 上部署的步骤,比较复杂,一般不建议,如果没有特殊要求,推荐使用docker镜像。
DATABASE_URL = "sqlite:////home/ubuntu/site/kindleear/database.db"
TASK_QUEUE_SERVICE = "apscheduler"
TASK_QUEUE_BROKER_URL = "redis://127.0.0.1:6379/"
KE_TEMP_DIR = "/tmp"
DOWNLOAD_THREAD_NUM = "3"
然后测试ping对应的IP,能ping通说明实例配置完成。
使用自己喜欢的SSH工具远程连接对应IP。 3.1 如果使用puTTY,需要先使用puttyGen将key格式的私钥转换为ppk格式。 打开puTTY,Host格式为username@IP,端口号22,用户名在"实例信息"中可以找到,在Connection|SSH|Auth|Credentials导入私钥文件。
3.2 如果使用Xshell,身份验证选择Public Key,并导入之前保存的私钥文件。
登录进去后建议先修改root密码
sudo -i
passwd
sudo apt update
sudo apt upgrade
sudo apt install nginx
sudo apt install git python3.10 python3-pip
sudo pip3 install virtualenv
sudo apt install redis-server
sudo systemctl start nginx
sudo systemctl start redis-server
sudo systemctl enable nginx
sudo systemctl enable redis-server
curl localhost #test if nginx works well
sudo apt install vim-common
mkdir -p ~/site
cd ~/site
#fetch code from github, or you can upload code files by xftp/scp
git clone --depth 1 https://github.com/cdhigh/kindleear.git
chmod -R 775 ~ #nginx user www-data read static resource
sudo usermod -aG ubuntu www-data #or add nginx www-data to my group ubuntu
cd kindleear
virtualenv --python=python3 venv #create virtual environ
vim ./config.py #start to modify some config items
python3 ./tools/update_req.py docker #update requirements.txt
source ./venv/bin/activate #activate virtual environ
pip install -r requirements.txt #install dependencies
python3 ./main.py db create #create database tables
#open port 80/443
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT 7 -m state --state NEW -p tcp --dport 443 -j ACCEPT
sudo netfilter-persistent save
mkdir -p /var/log/gunicorn/
chown ubuntu:ubuntu /var/log/gunicorn/ #current user have right to write log
sudo cp ./tools/nginx/gunicorn_logrotate /etc/logrotate.d/gunicorn #auto split log file
#modify nginx configuration
vim ./tools/nginx/nginx_default #optional, change server_name if you want
sudo cp -rf ./tools/nginx/nginx_default /etc/nginx/sites-enabled/default
sudo nginx -t #test if nginx config file is correct
#set gunicorn auto start
sudo cp ./tools/nginx/gunicorn.service /usr/lib/systemd/system/gunicorn.service
sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl status gunicorn
sudo systemctl enable gunicorn
sudo systemctl restart nginx
sudo systemctl status nginx
#先更新代码,不管是git/ftp/scp等,注意要保留数据库文件
sudo systemctl restart gunicorn
sudo systemctl status gunicorn #确认running
现在你就可以在浏览器中使用 "http://ip" 来确认是否已经部署成功。如果有证书的话,也可以继续配置nginx来使用SSL。
如果已有域名,也可以绑定自己的域名,没有的话,随便找一个免费域名注册商申请一个就好,比如 FreeDomain.One 或 freenom 等,我就在 FreeDomain.One 申请了一个域名,特别简单,在申请成功后的页面直接填入Oracle cloud的instance对应的IP就行,没有复杂的配置。
出现错误后,查询后台log的命令
tail -n 100 /var/log/nginx/error.log
tail -n 100 /var/log/gunicorn/error.log
tail -n 100 /var/log/gunicorn/access.log
DATABASE_URL = "mysql://name:pass@name.mysql.pythonanywhere-services.com/name$default"
TASK_QUEUE_SERVICE = ""
TASK_QUEUE_BROKER_URL = ""
登录 pythonanywhere,转到 "Web" 选项卡,点击左侧 "Add a new web app",创建一个Flask应用。
转到 "Databases" 选项卡,初始化mysql并创建一个数据库。
在 "Files" 选项卡打开一个 Bash console,执行bash命令 pip install -r requirements.txt
创建定时任务。PythonAnywhere不支持代码中自由设置定时任务,并且免费用户只能设置一个定时时间,限制较大,不过如果要勉强使用,可以到 "Tasks" 选项卡,根据你希望推送订阅的时间创建一个Task,命令行为: python /home/yourname/yourdirectory/main.py deliver now
如果部署在PythonAnywhere,则网页上的投递时间设置无效,投递时间就是这个Task的执行时间。
注:经过测试,除非付费,否则PythonAnywhere不适合我们的应用部署,因为其限制较多,最致命的限制就是其对免费用户能访问的网站实施白名单措施,不在其 列表中的网站 无法访问。