技术教程
技术教程
10-03
若确认是 权限问题 导致 SQLite 数据库「无法打开」或「无法读写」,核心解决思路是:确保运行应用的用户(如 wzf)对数据库文件、数据库所在目录拥有完整的「访问权限」和「所有权」,同时排除系统级权限限制(如 SELinux/AppArmor)。以下是分场景的精准解决方案: 一、先明确「关键角色」 在解决权限问题前,需先确认两个核心信息: 运行应用的用户:你用 (venv) wzf@sweet:/var/www/blog$ 启动 Gunicorn,因此运行用户是 wzf; 数据库路径:假设你的数据库文件是 /var/www/blog/app.db(绝对路径),所在目录是 /var/www/blog。 二、基础权限修复:文件 + 目录权限 + 所有权 这是最常见的权限问题场景,需同时修复「文件权限」「目录权限」和「所有权」(三者缺一不可)。 1. 修复「数据库文件」的权限和所有权 数据库文件需要 wzf 有 读写权限(rw-),且所有者必须是 wzf(避免其他用户占用): bash # 1. 强制将文件所有权改为 wzf(关键!避免 root 等其他用户占用) sudo chown wzf:wzf /var/www/blog/app.db # 2. 赋予文件读写权限(所有者可读写,其他用户只读,安全合规) sudo chmod 644 /var/www/blog/app.db # 3. 验证结果(必须确保所有者是 wzf,权限是 -rw-r--r--) ls -l /var/www/blog/app.db # 正确输出示例: # -rw-r--r-- 1 wzf wzf 16384 Sep 27 10:00 /var/www/blog/app.db 2. 修复「数据库所在目录」的权限和所有权 SQLite 会在数据库所在目录创建临时文件(如 app.db-journal),因此目录需要 wzf 有 执行 + 写入权限(rwx): bash # 1. 强制将目录所有权改为 wzf(递归,子目录也生效) sudo chown -R wzf:wzf /var/www/blog # 2. 赋予目录读写执行权限(所有者可操作,其他用户只读执行) sudo chmod -R 755 /var/www/blog # 3. 验证结果(所有者是 wzf,权限是 drwxr-xr-x) ls -ld /var/www/blog # 正确输出示例: # drwxr-xr-x 2 wzf wzf 4096 Sep 27 10:00 /var/www/blog 3. 测试基础权限是否生效 修复后,用 wzf 用户直接读写数据库文件,验证权限是否正常: bash # 1. 用 wzf 用户创建一个测试文件(验证目录写入权限) touch /var/www/blog/test.txt # 2. 用 wzf 用户读写数据库文件(验证文件权限) cat /var/www/blog/app.db # 即使乱码,无「Permission denied」即正常 # 3. 若以上命令无报错,说明基础权限已修复 rm /var/www/blog/test.txt # 删除测试文件 三、进阶权限修复:排除系统级限制(SELinux/AppArmor) 若基础权限修复后仍报错,大概率是 系统级安全工具(SELinux 或 AppArmor) 阻止了进程访问文件(常见于 CentOS、RHEL、Ubuntu Server)。 场景 1:SELinux 限制(CentOS/RHEL 为主) SELinux 会强制管控进程对文件的访问,即使文件权限是 777,也可能被阻止。 1. 验证是否是 SELinux 问题 临时关闭 SELinux(重启后失效,仅用于测试): bash # 临时关闭 SELinux sudo setenforce 0 # 重新启动 Gunicorn 测试 /var/www/blog/venv/bin/gunicorn --bind 0.0.0.0:8888 app:app 若关闭后数据库正常访问,确认是 SELinux 限制,需添加永久规则; 若仍报错,跳过此节,检查 AppArmor。 2. 添加 SELinux 永久规则(允许访问数据库目录) 临时关闭 SELinux 不安全,需添加规则允许 Gunicorn(识别为 httpd 进程)访问 /var/www/blog: bash # 1. 为数据库目录添加 SELinux 标签(httpd_sys_rw_content_t 表示 httpd 可读写) sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/blog(/.*)?" # 2. 应用标签到目录(让规则生效) sudo restorecon -Rv /var/www/blog # 3. 重新启用 SELinux(恢复系统安全) sudo setenforce 1 # 4. 验证规则是否生效(输出包含 httpd_sys_rw_content_t 即正常) ls -Z /var/www/blog | grep app.db # 正确输出示例: # -rw-r--r--. wzf wzf unconfined_u:object_r:httpd_sys_rw_content_t:s0 app.db # 5. 启动 Gunicorn 验证 /var/www/blog/venv/bin/gunicorn --bind 0.0.0.0:8888 app:app 场景 2:AppArmor 限制(Ubuntu Server 为主) AppArmor 类似 SELinux,会限制进程的文件访问范围,默认可能阻止 Gunicorn 访问非标准目录。 1. 验证是否是 AppArmor 问题 临时停止 AppArmor 服务(仅测试): bash # 临时停止 AppArmor sudo systemctl stop apparmor # 重新启动 Gunicorn 测试 /var/www/blog/venv/bin/gunicorn --bind 0.0.0.0:8888 app:app 若停止后正常,确认是 AppArmor 限制; 若仍报错,需检查是否有其他进程占用数据库文件(如旧 Gunicorn 进程)。 2. 添加 AppArmor 规则(允许访问数据库目录) bash # 1. 为 Gunicorn 创建 AppArmor 配置文件 sudo nano /etc/apparmor.d/usr.local.bin.gunicorn # 路径需匹配你的 Gunicorn 实际路径 # 2. 在文件中添加以下内容(允许访问数据库目录和文件) #include <tunables/global> /usr/local/bin/gunicorn { # 替换为你的 Gunicorn 路径(用 which gunicorn 查看) # 原有规则... /var/www/blog/ r, # 允许读取目录 /var/www/blog/* rw, # 允许读写目录下所有文件(含数据库) /tmp/ rw, # 允许读写临时文件(SQLite 可能用到) } # 3. 重新加载 AppArmor 规则 sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.gunicorn # 4. 启动 AppArmor 服务 sudo systemctl start apparmor # 5. 启动 Gunicorn 验证 /var/www/blog/venv/bin/gunicorn --bind 0.0.0.0:8888 app:app 四、终极验证:确保权限完全生效 修复后,通过以下步骤确认权限无问题: 重启 Gunicorn:确保加载最新的权限配置; 访问文章页面:如 http://服务器IP:8888/post/12,观察日志是否有「unable to open」错误; 检查数据库临时文件:访问后,查看数据库目录是否生成 app.db-journal(有则说明写入权限正常): bash ls -l /var/www/blog | grep journal # 若显示类似 -rw-r--r-- 1 wzf wzf 0 Sep 27 10:30 app.db-journal,说明正常 总结 权限问题的核心是「谁(用户)能访问什么(文件 / 目录),能做什么(读 / 写 / 执行)」,按以下优先级排查: 先修复 文件 + 目录的所有权和基础权限(最常见问题); 再排查 SELinux/AppArmor 系统级限制(次之); 最后确认 无其他进程占用数据库文件(如旧 Gunicorn 进程,用 pkill -f gunicorn 终止)。 按此流程操作,即可彻底解决 SQLite 数据库的权限问题。
技术教程
10-03
案例一 这是一个Flask应用程序,包含以下关键文件和目录: - app.py - 主应用程序文件 - models.py - 数据模型 - requirements.txt - 项目依赖 - templates/ - HTML模板 - static/ - 静态资源 - lottery.db - SQLite数据库 ## 一、系统要求 - Linux服务器(推荐Ubuntu 20.04或CentOS 7/8) - Python 3.8或更高版本 - 网络连接 - 基本的Linux命令知识 ## 二、准备Linux环境 ### 1. 更新系统包 ``` # Ubuntu/Debian系统 sudo apt update && sudo apt upgrade -y # CentOS/RHEL系统 sudo yum update -y ``` ### 2. 安装必要的软件包 ``` # Ubuntu/Debian系统 sudo apt install -y python3 python3-pip python3-venv git nginx curl # CentOS/RHEL系统 sudo yum install -y python3 python3-pip git nginx curl ``` ## 三、克隆项目代码 ``` # 创建项目目录 mkdir -p /var/www/lottery_app cd /var/www/lottery_app # 克隆项目代码(假设您的代码在Git仓库中) git clone <您的项目Git地址> . # 如果没有Git仓库,可以使用FTP/SCP等方式 上传代码 ``` ## 四、创建虚拟环境并安装依赖 ``` # 在项目目录中创建虚拟环境 python3 -m venv venv # 激活虚拟环境 source venv/bin/activate # 安装项目依赖 pip install --upgrade pip pip install -r requirements.txt # 安装Gunicorn作为WSGI服务器 pip install gunicorn ``` ## 五、配置环境变量 创建 .env 文件(如果不存在)或修改现有的环境变量配置: ``` # 在项目根目录创建.env文件 touch .env nano .env ``` 添加以下内容(根据实际情况修改): ``` SECRET_KEY=your_secure_secret_key_here DATABASE_URL=sqlite:////var/www/ lottery_app/lottery.db ``` ## 六、准备数据库 ``` # 激活虚拟环境 source venv/bin/activate # 运行Python shell创建数据库表 python ``` 在Python shell中执行: ``` from app import app, db from models import Admin with app.app_context(): db.create_all() # 检查是否存在管理员账户,如果不存在则 创建 if not Admin.query.filter_by (username='admin').first(): admin = Admin (username='admin') admin.set_password ('your_secure_password_here') db.session.add(admin) db.session.commit() exit() ``` ## 七、配置Gunicorn ### 1. 测试Gunicorn能否正常运行 ``` source venv/bin/activate gunicorn --bind 0.0.0.0:8000 app:app ``` 如果一切正常,您应该能看到Gunicorn启动成功的信息。按 Ctrl+C 停止。 ### 2. 创建Gunicorn配置文件 ``` mkdir -p /var/www/lottery_app/logs touch /var/www/lottery_app/ gunicorn_config.py nano /var/www/lottery_app/ gunicorn_config.py ``` 添加以下内容: ``` import multiprocessing import os # 绑定的地址和端口 bind = '127.0.0.1:8000' # 工作进程数量 workers = multiprocessing.cpu_count() * 2 + 1 # 工作方式 worker_class = 'sync' # 每个工作进程的最大并发数 worker_connections = 1000 # 请求超时时间 timeout = 30 # 保持连接时间 keepalive = 2 # 日志文件 errorlog = '/var/www/lottery_app/logs/ gunicorn_error.log' accesslog = '/var/www/lottery_app/ logs/gunicorn_access.log' # 日志级别 loglevel = 'info' # 进程ID文件 pidfile = '/var/www/lottery_app/ gunicorn.pid' ``` ## 八、配置Systemd服务 创建Systemd服务文件,以便系统可以自动启动Gunicorn服务: ``` sudo nano /etc/systemd/system/ lottery_app.service ``` 添加以下内容: ``` [Unit] Description=Gunicorn instance to serve lottery_app After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/lottery_app Environment="PATH=/var/www/ lottery_app/venv/bin" ExecStart=/var/www/lottery_app/venv/ bin/gunicorn -c gunicorn_config.py app:app Restart=on-failure [Install] WantedBy=multi-user.target ``` 启用并启动服务: ``` sudo systemctl daemon-reload sudo systemctl start lottery_app sudo systemctl enable lottery_app ``` 检查服务状态: sudo systemctl status lottery_app 九、配置Nginx作为反向代理 1. 创建Nginx配置文件 sudo nano /etc/nginx/sites-available/lottery_app 添加以下内容(替换 your_domain.com 为您的域名或服务器IP): server { listen 80; server_name your_domain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static { alias /var/www/lottery_app/static; expires 30d; } location /uploads { alias /var/www/lottery_app/static/uploads; expires 30d; } } 2. 启用Nginx配置 sudo ln -s /etc/nginx/sites-available/lottery_app /etc/nginx/sites-enabled sudo nginx -t # 测试配置是否正确 sudo systemctl restart nginx 十、配置文件权限 sudo chown -R www-data:www-data /var/www/lottery_app sudo chmod -R 755 /var/www/lottery_app sudo chmod -R 775 /var/www/lottery_app/static/uploads sudo chmod -R 775 /var/www/lottery_app/backups 十一、配置防火墙 # Ubuntu/Debian系统 sudo ufw allow 'Nginx Full' sudo ufw allow OpenSSH sudo ufw enable # CentOS/RHEL系统 sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --reload 十二、获取SSL证书(可选但推荐) 使用Let's Encrypt获取免费的SSL证书: # 安装Certbot sudo apt install certbot python3-certbot-nginx # Ubuntu/Debian sudo yum install certbot python3-certbot-nginx # CentOS/RHEL # 获取证书 sudo certbot --nginx -d your_domain.com # 设置自动续期 sudo certbot renew --dry-run 十三、部署后的维护 1. 查看应用日志 tail -f /var/www/lottery_app/logs/gunicorn_error.log tail -f /var/www/lottery_app/logs/gunicorn_access.log sudo journalctl -u lottery_app sudo journalctl -u nginx 2. 重启服务 sudo systemctl restart lottery_app sudo systemctl restart nginx 3. 更新代码 cd /var/www/lottery_app git pull source venv/bin/activate pip install -r requirements.txt sudo systemctl restart lottery_app 十四、项目特性说明 ## 十四、项目特性说明 部署完成后,您的Flask应用将包含以下功能: 1. 1. 黄历查询功能 :通过 /huangli 路由访问,数据处理逻辑在前端JavaScript中实现 2. 2. 开奖结果展示 :通过 /results 路由访问 3. 3. 新闻管理系统 :包括新闻列表和详情页 4. 4. 后台管理中心 :包含开奖设置、新闻管理、数据备份等功能 5. 5. 安全特性 :包含CSRF保护、管理员认证等 通过以上步骤,您的Flask项目应该已经成功部署到Linux服务器上,并且可以通过您的域名或服务器IP地址访问。 ---------------------------------------------------------------------------------------------------------- 案例二 # Flask博客项目CentOS部署详细步骤 下面是将您的Flask博客项目部署到CentOS系统的完整步骤: 准备CentOS环境 更新系统包 # 更新系统包 sudo yum update -y # 安装必要的系统依赖 sudo yum install -y gcc python3 python3-devel python3-pip nginx git 创建项目目录并克隆代码 # 创建项目目录 sudo mkdir -p /var/www/blog # 设置目录权限 sudo chown -R $USER:$USER /var/www/blog # 克隆或上传项目代码到该目录 # 如果使用git:git clone <your-repo-url> /var/www/blog # 或使用scp/sftp等工具上传项目文件 创建并激活Python虚拟环境 # 进入项目目录 cd /var/www/blog # 创建虚拟环境 python3 -m venv venv # 激活虚拟环境 source venv/bin/activate # 升级pip pip install --upgrade pip 安装项目依赖 # 安装项目依赖 pip install -r requirements.txt # 安装WSGI服务器(用于生产环境) pip install gunicorn 配置环境变量 # 在项目目录创建.env文件 cp .env.example .env # 如果没有.env.example,则直接创建.env # 编辑.env文件,根据实际情况修改配置 nano .env .env文件应包含以下关键配置(根据您的实际情况修改): # 邮件服务器配置 MAIL_SERVER=smtp.qq.com MAIL_PORT=587 MAIL_USE_TLS=True MAIL_USERNAME=your-email@qq.com MAIL_PASSWORD=your-email-password MAIL_DEFAULT_SENDER=your-email@qq.com # 应用密钥(建议修改为随机生成的字符串) SECRET_KEY=your-secure-secret-key # 数据库配置(SQLite使用绝对路径) DATABASE_URL=sqlite:///blog.db 初始化数据库 # 确保虚拟环境处于激活状态 # 运行Python交互环境 python 在Python交互环境中执行: from app import app, db with app.app_context(): db.create_all() # 如果需要创建管理员用户,可以在这里添加代码 quit() 配置Gunicorn服务 # 创建Gunicorn配置文件 nano /var/www/blog/gunicorn_config.py 添加以下内容: bind = '127.0.0.1:8000' workers = 3 accesslog = '/var/log/blog/access.log' errorlog = '/var/log/blog/error.log' user = 'your_username' # 替换为您的用户名 创建日志目录: sudo mkdir -p /var/log/blog sudo chown -R $USER:$USER /var/log/blog 创建Systemd服务文件 sudo nano /etc/systemd/system/blog.service 添加以下内容(ini): [Unit] Description=Gunicorn instance to serve Flask blog application After=network.target [Service] User=your_username # 替换为您的用户名 Group=nginx WorkingDirectory=/var/www/blog Environment="PATH=/var/www/blog/venv/bin" ExecStart=/var/www/blog/venv/bin/gunicorn --config /var/www/blog/gunicorn_config.py app:app Restart=always [Install] WantedBy=multi-user.target 配置Nginx作为反向代理 sudo nano /etc/nginx/conf.d/blog.conf 添加以下内容(nginx): server { listen 80; server_name your_domain.com www.your_domain.com; # 替换为您的域名或服务器IP location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static { alias /var/www/blog/static; } # 错误页面 error_page 404 /404.html; error_page 500 502 503 504 /500.html; } 配置防火墙 # 允许HTTP和HTTPS流量 sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd –reload 启动服务并设置开机自启 # 启动Gunicorn服务 sudo systemctl start blog sudo systemctl enable blog # 检查Gunicorn服务状态 sudo systemctl status blog # 测试Nginx配置 sudo nginx -t # 启动Nginx服务 sudo systemctl start nginx sudo systemctl enable nginx 配置SELinux(如果启用) # 如果SELinux处于enforcing模式,需要设置以下规则 sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/blog(/.*)?' sudo restorecon -Rv /var/www/blog/ # 允许Nginx连接到Gunicorn sudo setsebool -P httpd_can_network_connect 1 13. 监控和维护 - 查看应用日志: sudo journalctl -u blog - 查看Nginx日志: sudo tail -f /var/log/nginx/error.log - 查看Gunicorn日志: sudo tail -f /var/log/blog/error.log ## 其他注意事项 1. 1. 数据库备份 :定期备份 blog.db 文件 2. 2. 安全优化 : - 考虑配置HTTPS(使用Let's Encrypt证书) - 修改 SECRET_KEY 为随机生成的强密码 - 定期更新系统和依赖包 3. 3. 性能优化 :根据访问量调整Gunicorn的worker数量 4. 4. 静态文件 :确保static目录权限正确,以便Nginx能访问 完成以上步骤后,您的Flask博客应用应该已成功部署到CentOS系统上并可以通过浏览器访问了。 ------------------------------------------------------------------------------------------- 在 CentOS 系统中搭建第二个 Flask 应用,与搭建第一个的流程类似,但需要注意端口占用和服务配置的隔离。以下是具体步骤: 1. 准备独立的环境 为第二个 Flask 应用创建独立的目录和虚拟环境,避免依赖冲突: bash # 创建应用目录 mkdir -p /var/www/flask_app2 cd /var/www/flask_app2 # 创建并激活虚拟环境 python3 -m venv venv source venv/bin/activate # 安装Flask(可指定版本) pip install flask 2. 编写第二个 Flask 应用代码 创建应用主文件(如app.py),注意使用与第一个应用不同的端口: python 运行 from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "这是第二个Flask应用!" if __name__ == '__main__': # 使用不同于第一个应用的端口(如5001) app.run(host='0.0.0.0', port=5001) 3. 配置服务(使用 systemd) 创建服务文件,确保与第一个应用的服务名不同: bash sudo vim /etc/systemd/system/flask-app2.service 服务文件内容: ini [Unit] Description=Second Flask Application After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/flask_app2 Environment="PATH=/var/www/flask_app2/venv/bin" ExecStart=/var/www/flask_app2/venv/bin/python app.py [Install] WantedBy=multi-user.target 4. 启动并设置开机自启 bash # 重新加载systemd配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start flask-app2 # 设置开机自启 sudo systemctl enable flask-app2 # 检查服务状态 sudo systemctl status flask-app2 5. 配置 Nginx 反向代理(可选) 如果需要通过域名区分两个应用,可配置 Nginx: bash sudo vim /etc/nginx/conf.d/flask-app2.conf 配置内容: nginx server { listen 80; server_name app2.yourdomain.com; # 第二个应用的域名 location / { proxy_pass http://127.0.0.1:5001; # 对应第二个应用的端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } 重启 Nginx: bash sudo systemctl restart nginx 关键注意事项 端口冲突:确保两个应用使用不同的端口(默认 5000,可改为 5001、5002 等) 服务名区分:systemd 服务文件名称需不同,避免冲突 目录隔离:应用文件和虚拟环境应完全独立 防火墙设置:如果启用了 firewalld,需开放第二个应用的端口 bash sudo firewall-cmd --add-port=5001/tcp --permanent sudo firewall-cmd --reload 通过以上步骤,你就可以在同一台 CentOS 服务器上运行多个独立的 Flask 应用了。 ................................................................................................................................................. 为第二个 Flask 应用配置 Gunicorn 的步骤如下: 1. 在虚拟环境中安装 Gunicorn bash # 激活第二个应用的虚拟环境 cd /var/www/flask_app2 source venv/bin/activate # 安装Gunicorn pip install gunicorn 2. 测试 Gunicorn 运行 bash # 用Gunicorn启动Gunicorn启动应用(指定不同端口) gunicorn -w 4 -b 0.0.0.0:5001 app:app -w 4:指定 4 个工作进程 -b 0.0.0.0:5001:绑定到 5001 端口(与第一个应用不同) app:app:表示从 app.py 文件中导入 app 实例 3. 修改 systemd 服务配置 编辑之前创建的服务文件: bash sudo vim /etc/systemd/system/flask-app2.service 将ExecStart行修改为使用 Gunicorn: ini [Unit] Description=Second Flask Application with Gunicorn After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/flask_app2 Environment="PATH=/var/www/flask_app2/venv/bin" # 使用Gunicorn启动,而不是直接运行python ExecStart=/var/www/flask_app2/venv/bin/gunicorn -w 4 -b 0.0.0.0:5001 app:app [Install] WantedBy=multi-user.target 4. 重启服务 bash sudo systemctl daemon-reload sudo systemctl restart flask-app2 使用 Gunicorn 的优势 性能更好:支持多进程处理,能同时处理更多请求 更稳定:相比 Flask 开发服务器,更适合生产环境 资源控制:可以灵活配置工作进程数量 安全性:提供更好的安全特性,适合暴露在公网环境 如果后续需要进一步优化,还可以结合 Nginx 作为反向代理,处理静态文件并转发动态请求给 Gunicorn,形成更完善的生产环境部署架构。 ------------------------------------------------------------------------------------------------------------------------------ 第一步:重新创建 Gunicorn 服务配置文件 bash # 1. 确保在任意目录下,执行以下命令创建服务文件 sudo nano /etc/systemd/system/gunicorn.service 粘贴以下内容(根据你的实际路径修改): ini [Unit] Description=Gunicorn daemon for blog project After=network.target [Service] User=wzf Group=wzf WorkingDirectory=/var/www/blog ExecStart=/var/www/blog/venv/bin/gunicorn \ --workers 3 \ --bind unix:/var/www/blog/blog.sock \ app:app [Install] WantedBy=multi-user.target 保存文件:按 Ctrl+O → 回车确认 → 按 Ctrl+X 退出。 第二步:重载系统服务配置(关键步骤) bash # 让系统识别新创建的服务文件 sudo systemctl daemon-reload 第三步:验证服务是否存在并启动 bash # 1. 查看服务是否已被识别 sudo systemctl list-unit-files | grep gunicorn # 若输出 `gunicorn.service enabled` 或 `static`,说明已识别 # 2. 启动服务 sudo systemctl start gunicorn # 3. 查看服务状态(确认是否启动成功) sudo systemctl status gunicorn 若仍提示 “Unit not found” 检查服务文件路径是否完全正确: bash # 确认文件存在且路径正确 ls -l /etc/systemd/system/gunicorn.service 若输出 “没有那个文件或目录”,说明第一步的文件创建失败,重新执行第一步(建议用 nano )。 检查文件权限: bash # 确保服务文件有正确权限 sudo chmod 644 /etc/systemd/system/gunicorn.service 再次重载配置并尝试启动: bash sudo systemctl daemon-reload sudo systemctl restart gunicorn 核心问题是系统未识别到服务文件,通过 “重新创建文件 + 重载配置” 即可解决。只要 /etc/systemd/system/gunicorn.service 存在且格式正确,systemctl 就能找到并管理该服务。 # Gunicorn 配置文件: bind = "0.0.0.0:8888" # 绑定地址和端口 workers = 3 # 工作进程数(建议设为 CPU 核心数×2 + 1) accesslog = "/var/www/blog/logs/access.log" # 访问日志路径 errorlog = "/var/www/blog/logs/error.log" # 错误日志路径 loglevel = "info" # 日志级别(debug/info/warning/error/critical) 注意:若指定日志路径(如 logs/access.log),需先创建 logs 目录,否则启动会报错 bash mkdir -p /var/www/blog/logs # 创建日志目录 .................................................................................................. 创建Systemd服务文件 sudo nano /etc/systemd/system/blog.service 添加以下内容(ini): [Unit] Description=Gunicorn daemon for blog project After=network.target [Service] User=wzf Group=wzf WorkingDirectory=/var/www/blog ExecStart=/var/www/blog/venv/bin/gunicorn \ --config /var/www/blog/gunicorn_config.py \ app:app [Install] WantedBy=multi-user.target ......................................................................................................... sudo systemctl start gunicorn # 启动服务 sudo systemctl stop gunicorn # 停止服务 ........................................................................................................ # 重载配置(推荐,不中断服务) sudo systemctl reload nginx # 或重启服务(会短暂中断) sudo systemctl restart nginx # 停止服务 sudo systemctl stop nginx
技术教程
10-02
Linux系统命令是管理和操作Linux系统的核心工具,涵盖文件管理、系统监控、进程控制等多个方面。以下分类总结常用命令及其功能: 一、系统信息查询 架构与内核 arch:显示处理器架构 uname -r:查看内核版本 cat /proc/cpuinfo:获取CPU详细信息 cat /proc/meminfo:检查内存使用情况 日期时间 date:显示或设置当前日期时间 二、文件与目录操作 基础命令 ls:列出目录内容(-l显示详情,-a包含隐藏文件) cd:切换目录(cd ~返回家目录,cd -返回上一目录) pwd:显示当前工作目录路径 增删改查 mkdir:创建目录(-p递归创建多级目录) rm:删除文件或目录(-rf强制递归删除) cp/mv:复制或移动文件/目录 find:搜索文件(如find /usr -name 'a*') 三、进程管理 查看与终止 ps:查看进程状态(ps -aux显示所有用户进程) kill:终止进程(kill -9 PID强制终止) 四、帮助与手册 man:查看命令手册(如man ls) --help:获取命令简要帮助(如ls --help) 五、其他实用命令 clear:清屏2 alias:设置命令别名(如alias ll='ls -l') df -Th:查看文件系统格式及磁盘空间 如需更详细的功能参数,可通过man命令查阅具体手册。 -------------------------------------------------------------------- cp -r ./* /var/www/lottery_app/ # 复制当前目录下的所有文件于是别一目录 cp models.py /var/www/lottery_app # 将当前目录下的models.py文件复制到/var/www/lottery_app目录 # 若目标目录不存在会报错 # 若目标目录已存在同名文件会被覆盖 rm -rfv /var/www/lottery_app/lottery_app # 具有破坏性的Linux文件删除操作 -rfv组合参数: -r:递归删除目录及其内容 -f:强制删除不提示确认 -v:显示详细删除过程 cp -r /var/www/lottery_app /backup/ # 将 /var/www/lottery_app 目录及其所有子目录和文件 递归复制到 /backup/ (数据执行备份),/var/www/lottery_app:源目录路径,/backup/:目标目录路径 ps -aux 是一个常用的Linux/Unix命令,用于查看系统中正在运行的进程信息。以下是详细解析: 命令组成: ps:process status的缩写 -a:显示所有用户的进程 -u:以用户为主的格式显示 -x:显示没有控制终端的进程 输出列说明: USER:进程所有者 PID:进程ID %CPU:CPU占用率 %MEM:内存占用率 VSZ:虚拟内存用量(KB) RSS:常驻内存用量(KB) TTY:终端设备 STAT:进程状态(S-休眠,R-运行等) START:启动时间 TIME:CPU占用时间 COMMAND:启动命令 常用组合: 查找特定进程:ps -aux | grep [进程名] 按CPU排序:ps -aux --sort=-%cpu 按内存排序:ps -aux --sort=-%mem 注意事项: 在BSD系统上应使用ps aux(无横线) 会显示系统所有进程,可能输出较长 普通用户只能看到自己的进程,root可查看全部 该命令是系统监控的基础工具,常用于检查异常进程或分析资源占用情况。如需实时监控,可改用top命令。 ********************************************************************************************************* 附:虚拟环境相关操作: # 先退出当前虚拟环境 deactivate # 进入项目目录 cd /www/wwwroot/lottery_app # 删除有问题的旧虚拟环境 rm -rf venv # 使用支持 SSL 的 Python 重新创建虚拟环境 /usr/local/python3.9/bin/python3.9 -m venv venv # 激活新的虚拟环境 source venv/bin/activate # 验证虚拟环境中的 Python 是否支持 SSL python -c "import ssl; print('虚拟环境 SSL 模块正常')" ------------------------------------------------------------------------------------------------ # 先删除现有虚拟环境 rm -rf /var/www/blog/venv # 重新创建虚拟环境 python3 -m venv /var/www/blog/venv # 激活虚拟环境 source /var/www/blog/venv/bin/activate # 重新安装需要的包 pip install <需要的包> --------------------------------------------------------------------------------------------------- # 切换到应用目录 cd /var/www/blog # 确保已激活虚拟环境(终端显示 (venv)) source venv/bin/activate # 如果尚未激活 # 再次尝试启动(此时 gunicorn 能找到当前目录下的 app.py) gunicorn --bind 0.0.0.0:8888 app:app # 虚拟环境 Python 路径 + -m gunicorn + 启动参数 /var/www/blog/venv/bin/python -m gunicorn --bind 0.0.0.0:8888 app:app ----------------------------------------------------------------------------- 从 ps aux 输出可以看到,你当前同时运行了 两个 Gunicorn 服务: 绑定 8000 端口 的服务(主进程 PID: 15232,工作进程 PID: 15235); 绑定 8888 端口 的服务(主进程 PID: 16180,工作进程 PID: 16183)。 这就是你执行命令 “没有反应” 的原因 —— 旧的服务(8000/8888 端口)已经占用了终端,新的启动命令被阻塞或端口冲突。 第一步:停止所有旧的 Gunicorn 进程(避免冲突) 先终止这两个服务的所有进程,清理环境: bash # 终止 8000 端口的主进程(PID: 15232)和工作进程(PID: 15235) kill -9 15232 15235 # 终止 8888 端口的主进程(PID: 16180)和工作进程(PID: 16183) kill -9 16180 16183 验证是否停止成功: bash ps aux | grep gunicorn 如果只显示 grep --color=auto gunicorn 这一行,说明所有旧进程已终止。 第二步:重新启动指定端口的 Gunicorn 服务 根据你的需求(使用 8888 端口),重新在项目目录启动服务: bash # 1. 切换到项目目录 cd /var/www/lottery_app # 2. 激活虚拟环境(确保命令行前有 (venv)) source venv/bin/activate # 3. 启动 Gunicorn 并绑定 8888 端口(推荐后台运行,不占用终端) nohup gunicorn --bind 0.0.0.0:8888 app:app > gunicorn.log 2>&1 & 第三步:确认新服务是否正常运行 查看进程: bash ps aux | grep gunicorn 应显示新的 8888 端口服务进程(主进程 + 工作进程)。 测试端口响应: bash curl -I http://127.0.0.1:8888 若返回 HTTP/1.1 200 OK 或其他状态码,说明服务完全正常。 为什么推荐后台运行(nohup)? 前台启动(直接 gunicorn ...)会占用终端,关闭终端或按 Ctrl+C 会导致服务停止; 后台启动(nohup ... &)会让服务在后台持续运行,日志输出到 gunicorn.log,方便后续排查问题。 若需停止新服务 后续若需重启 / 停止,只需终止新的主进程: bash # 找到新的主进程 PID ps aux | grep "gunicorn --bind 0.0.0.0:8888" # 终止进程(替换为新的 PID) kill -9 新主进程PID 现在你的环境已清理干净,新的 Gunicorn 服务会在 8888 端口稳定运行,且不会占用终端。 ---------------------------------------------------- 终止主进程,停止服务。 1.检查所有 Gunicorn 的进程 ps aux | grep gunicorn 2.使用 kill -9 命令终止主进程(替换为你找到的 PID) # 替换为实际的主进程 PID(如 27738) kill -9 27738 ---------------------------------------------------------------------- 启动新的 Gunicorn 进程: 若使用 8888 端口(确保已释放): bash # 后台启动,日志输出到 gunicorn.log nohup gunicorn --bind 0.0.0.0:8888 app:app > gunicorn.log 2>&1 & 你可以通过以下命令进一步确认服务是否正常: 查看日志文件:tail -f gunicorn.log 检查 8888 端口是否被监听:netstat -tuln | grep 8888 或 ss -tuln | grep 8888 如果需要停止这些进程,可以使用: kill -9 主进程 工作进程 ----------------------------------------------------------------------------------- # 一次性杀死所有 gunicorn 相关进程 pkill gunicorn # 或者更精确地杀死特定应用的 gunicorn 进程 pkill -f "/var/www/lottery_app/venv/bin/gunicorn"
技术教程
10-02
初始化本地仓库(如果还没有 Git 仓库): bash # 进入项目文件夹 cd /path/to/your/project # 初始化Git仓库 git init 将文件添加到暂存区: bash # 添加单个文件 git add 文件名 # 添加所有文件 git add . 提交文件到本地仓库: bash git commit -m "提交说明,描述你做了什么修改" 关联远程仓库(如果是第一次):首先在 Git 平台(如 GitHub)创建一个新仓库,然后执行: bash git remote add origin 远程仓库地址 # 例如: git remote add origin https://github.com/你的用户名/仓库名.git 推送到远程仓库: bash # 第一次推送需要加上-u参数 git push -u origin main # 后续推送可以简化为 git push 如果是第一次使用 Git,可能需要先配置用户名和邮箱: bash git config --global user.name "你的用户名" git config --global user.email "你的邮箱" 这些命令将帮助你把本地文件上传到 Git 远程仓库。如果遇到权限问题,可能需要配置 SSH 密钥或使用个人访问令牌进行认证。 -------------------------------------------------------------------------------------------------------------------------- 注意: 你的 .env 文件被 .gitignore 文件列入了忽略名单,Git 默认不会跟踪这类文件。 如果你确实需要将 .env 文件添加到 Git 仓库中(通常不建议,因为 .env 常包含敏感信息如密钥),可以使用强制添加的方式: bash git add -f .env 其中 -f 是 --force 的缩写,表示强制添加被忽略的文件。 添加后,你可以正常提交: bash git commit -m "添加.env文件" ⚠️ 注意:.env 文件通常包含数据库密码、API 密钥等敏感信息,将其上传到公共仓库可能存在安全风险。如果是多人协作项目,更推荐使用环境变量模板文件(如 .env.example),只包含变量名而不包含实际值,然后将 .env 保持在 .gitignore 中。 Git 会自动转换换行符以适应不同系统,如果所以出现了 "LF will be replaced by CRLF" 的提示,这是正常现象,不会影响文件内容或版本控制功能。 你可以忽略这个警告,继续执行提交操作: bash git commit -m "添加.env文件" 如果希望关闭这类换行符转换警告,可以配置 Git 的 autocrlf 设置: bash # Windows 系统推荐设置 git config --global core.autocrlf true 这个设置会让 Git 在检出文件时自动将 LF 转换为 CRLF,在提交时再转换回 LF,确保跨平台协作时的一致性。 -------------------------------------------------------------------------------------------------------- 用Git Bash 操作 如果你想将本地已有的项目与远程仓库关联: 首先进入你的项目目录(你的博客项目在D:\blog): bash cd /d/blog 确认这是一个 Git 仓库后,添加远程仓库地址: bash git remote add origin https://gitee.com/huang2025h/blog.git 如果之前已经添加过远程仓库,可以先移除再添加: bash git remote remove origin git remote add origin https://gitee.com/huang2025h/blog.git 推送代码: bash git push -u origin master 如果你想从远程仓库克隆项目到本地: bash # 克隆仓库 git clone https://gitee.com/huang2025h/blog.git # 进入克隆下来的目录 cd blog 关键是要先确保你在正确的项目目录下,并且该目录已经初始化为 Git 仓库(包含.git文件夹)。 --------------------------------------------------------------------------------------------------------- 更新Git仓库里的文件通常涉及以下几个步骤,具体取决于你希望进行的操作类型(比如添加新文件、修改现有文件、删除文件等)。以下是一些基本的Git命令,可以帮助你更新仓库中的文件: 1. 修改文件 如果你已经修改了本地文件,首先需要将这些修改添加到暂存区(stage)中: bash git add <文件名> 或者,如果你想添加所有修改过的文件,可以使用: bash git add . 2. 提交更改 将修改从暂存区提交到仓库中: bash git commit -m "提交信息" 3. 推送更改到远程仓库 将本地的更改推送到远程仓库: bash git push origin <分支名> 例如,如果你在main分支上工作,你应该使用: bash git push origin main 4. 添加新文件 如果你添加了一个新文件,首先使用git add命令将其添加到暂存区,然后按照上述步骤进行提交和推送。 5. 删除文件 如果你想从仓库中删除一个文件,首先从你的工作目录中删除该文件: bash rm <文件名> 然后,你需要告诉Git也要删除这个文件: bash git rm <文件名> 之后,你可以提交和推送更改。 6. 重命名文件或移动文件 如果你需要重命名或移动文件,可以使用git mv命令: bash git mv <旧文件名> <新文件名> 然后,像处理新文件一样提交和推送更改。 7. 拉取最新更改并解决冲突(如果有) 在推送之前,确保你的本地仓库是最新的。你可以先拉取远程仓库的最新更改: bash git pull origin <分支名> 如果在拉取过程中出现冲突,你需要手动解决这些冲突。Git会标记冲突的文件,你需要打开这些文件,解决冲突,然后再次提交你的更改。 通过遵循这些步骤,你可以有效地更新Git仓库中的文件。记得频繁地提交和推送你的更改,以避免丢失任何工作
技术教程
10-02
基础语法 1、注释:# 单行注释,多行注释" 2、变量:直接赋值,如x=5 3、数据类型:int,float,str,bool 4、类型转换:int(),float(), str(),bool() 5、运算符:+,-, *, /, //, %, ** 6、比较运算符:==,!=,>, <,>=,<= 7、逻辑运算符:and, or, not 8、位运算符:&,|,^,~,<<,>> 数据结构 9、列表:【],如my_list= [1,2, 3] 10、元组:(),如my_tuple= (1, 2, 3) 11、字典:{},如my_dict = {'key': 'value'} 12、集合:set (),如my_set= {1,2, 3} 13、列表解析:[xfor xin iterable] 14、字典解析:{k:v for k,vin iterable} 15、集合解析:{xfor xin iterable} 控制流 16、if语句:if,elif,else 17、for 循环:for item in iterable 18、while 循环:while condition 19、break:提前结束循环 20、continue:跳过本次循环剩余部分 21、pass:占位符,什么也不做 函数 22、定义函数:def function_name(parameters): 23、参数:位置参数,默认参数,关键字参数,不定长参数 24、返回值:return 25、匿名函数:lambda x:x+1 26、函数文档字符串:"""docstring""" 模块和包 27、导入模块:import module_name 28、导入模块中某个部分:from module_nameimport function_name 29、导入模块井重命名:import module_name as mn 30、检查模块属性:dir(module_name) 文件操作 31、打开文件:open('filename', 'mode') 32、读文件:file.read() 33、写文件:file.write('text') 34、逐行读文件:for line in file 35、关闭文件:file.close() 36、with语句:with open('filename','mode')as file 异常处理 38、except:except ExceptionType as e 39、else: else 40、finally:finally 41、自定义异常:class MyException(Exception): 面向对象编程 42、类:class ClassName: 43、初始化方法:definit (self): 44、类方法:def method name(self): 45、类变量:ClassName.variab1e 46、实例变量:self.variable 47、继承:classSubClassName (BaseClassName) : 48、方法重写:def method name(self): 49、多继承:class SubClassName(Class1,Class2) : 50、特殊方法:_str_,repr_,len_,_eq_, -lt_ 常用标准库 51、0s:操作系统接口 52、sys:Python 解释器接口 53、math:数学函数 54、datetime:日期和时间处理 55、re:正则表达式 56、json:JSON 解析与生成 57、csv:CSV文件读写 58、random:随机数生成 59、time:时间访问和转换 60、collections:高效数据结构 61、itertools:迭代器函数 62、functools:高阶函数和操作 63、operator:函数形式的标准操作符 进阶主题 64、生成器:yield生成器函数 65、装饰器:@decorator 66、上下文管理器:with 语句和enter_,exit方法 67、迭代器:iter,_next_ 68、元类:class Meta(type): 69、协程:async, await 70、异步编程:asynci0 71、多线程:threading 72、多进程:multiprocessing 73、锁和同步:Lock,RLock,Semaphore 数据科学和机器学习 74、numpy:数值计算库 75、pandas:数据分析库 76、matplotlib:数据可视化库 77、scikit-learn:机器学习库 78、tensorflow/keras:深度学习框架 Web 开发 79、Flask:轻量级 Web 框架 80、Django:全功能Web 框架 81、requests:HTTP 请求库 82、beautifulsoup4:HTML和XML 解析库 83、scrapy:爬虫框架 其他 84、虚拟环境:venv 85、包管理:pip 86、命令行参数:argparsP 87、单元测试:unittest 88、日志记录:logging 89、配置文件:configparser 90、数据类:dataclasses 91、路径操作:pathlib 92、类型注解:typing 93、并发执行:concurrent.futures 94、缓存:functools.lru_cache 95、单例模式:class singleton: 96、上下文变量:contextvars 97、数据库操作:sqlite3 98、信号处理:signal 99、垃圾回收:gc 100、序列化:pickle