• 构建个人博客网站(基于Python Flask)


    本文由 Ficow Shen 首发于 Ficow Shen's Blog.

    文章概览

    • 前言
    • Sketch
    • HTML, CSS, JavaScript
    • Python & Flask & MySQL & SQLAlchemy
    • Gunicorn & Terminal & Command
    • Domain name
    • Nginx & Certbot

     
     

    前言

    你是否曾经尝试过搭建个人博客网站?
    Hugo, HexoWordPress 这些耳熟能详的产品,你是否也曾经试用过?
    这些产品可以让你极速搭建个人博客网站,而且你不需要了解太多技术细节。

    如果你只是想有一个简单的博客网站只是希望能够进行内容创作、发表,那么我建议你使用那些产品停止阅读这篇文章

    如果你想DIY你的博客想更深入地了解一个博客系统想学习一些Web和后端技术,那么我建议你继续阅读,然后 自己搭建一个博客网站

    为何选择 PythonFlask 进行后端开发?

    • Python 简单易学
    • 对脚本语言感兴趣,通过学习 Python 来熟悉 脚本语言
    • Flask 是一个知名且被广泛应用的后端开发框架,社区非常活跃
    • Python 和 Flask 都有丰富的第三方库

    当然,除了 Python,你也可以选择 PHP, Golang 等作为后端开发语言。

    在学习开始之前,我向你推荐一个网站:Learn X in Y minutes
    正如网站名称说的那样,你可以在Y分钟内学习X。该站可以加快你的学习进程,让你尽快看到内容的全貌。

     
     

    Sketch

    Sketch

    使用 Sketch,主要是为了设计博客页面
    当然,也可以用 PhotoShop 这种类似的软件。
    然后,你就可以参考别人的个人博客页面,然后设计自己的博客页面的版式、配色等等。

    也许有人会问,有很多现成的主题可以用,为什么还要自己设计呢?

    如果你想学习和应用 Web技术,尤其是 CSS 中的 Selector、Flexbox,那么自己写就可以让你的学习效果更好。
    如果你不感兴趣,可以跳过这一步,直接去用别人造好的轮子即可。

    如果你觉得 Sketch 实在太贵,请看这里
    Sketch 是个很优秀的产品,请您支持正版~

     
     

    HTML, CSS, JavaScript

    HTML 示例:

     <!DOCTYPE html>
    <html>
    	<head>
    		<title>Page Title</title>
    	</head>
    	<body>
    		<h1>This is a Heading</h1>
    		<p>This is a paragraph.</p>
    	</body>
    </html> 
    

    CSS 示例:

    body {
      background-color: lightblue;
    }
    h1 {
      color: white;
      text-align: center;
    }
    p {
      font-family: verdana;
      font-size: 20px;
    }
    

    JavaScript 示例:

    document.getElementById("demo").innerHTML = "Hello JavaScript"; 
    

    在开始学习之前,我在知乎了解了 零基础如何迅速学习前端?
    然后,在 菜鸟教程 看完了 HTML, CSS, JavaScript 的基础内容。

    相关的基础知识必须过一遍,甚至几遍!
    要确保自己知道这些技术包含哪些内容,然后你后面需要用到的时候,就可以很容易地找到它们并把它们用起来。

    除此之外,还在 MDN 单独学习了一些技术点,比如:Flexbox.
    以及 阮一峰的网络日志

    看了这些东西之后,就需要实操练习。你可以去找一些博客网站来模仿,通过模仿别人的网站来熟悉前端的布局技术。
    其实,要点就是:看基础知识,然后模仿着写,巩固学习效果

    掌握了这些知识,你就可以写出静态的网页了。

     
     

    Python & Flask & MySQL & SQLAlchemy

    Python 示例:

    # -*- coding: UTF-8 -*-
    
    # 该实例输出 Hello World!
    print('Hello World!')
    

    让静态网页“活”起来的关键是后端提供的数据支持。
    学习 Python & Flask & MySQL 之后,你就可以自己定义后端接口,然后为前端提供数据支持。

    学习 Python3,了解 Python 的基础知识点。

    掌握了 Python 基础知识之后,就可以开始学习 Flask 了。
    点开 Documentation,里面会有 Quickstart,也有 Tutorial。这两个部分,不容错过!

    如果觉得阅读英文文档的难度太高,你可以看 Flask Web开发:基于Python的Web应用开发实战
    这本书的资源仅供参考,请您支持正版~

    另外,Flask Tutorial 中使用的是SQLite,但是我建议你使用更好的关系型数据库,比如:MySQL 或者 PostgreSQL
    如何安装和使用这些数据库,你可以参考官方文档或者去搜索引擎找相关的文章来学习。

    学完这些内容之后,你基本上就已经学会了:
    定义后端接口执行数据库CRUD操作返回网页数据给前端单元测试 以及 基本的网络安全知识

    把前端和后端的内容结合在一起,网页的内容就任由你来定义。

    如果你觉得书写 SQL 语句很烦人,那么我推荐你使用知名的ORM【对象关系映射(Object Relational Mapping)】 框架 SQLAlchemy
    你可以去官方网站找 Tutorial 来快速入门, 比如:SQLAlchemy tutorial

    这里有两个示例可供参考。

    使用 SQL 语句的示例:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    from sqlalchemy import create_engine
    from sqlalchemy.sql import text
    
    eng = create_engine("mysql://testuser:test623@localhost/testdb")
    
    with eng.connect() as con:
    
        con.execute(text('DROP TABLE IF EXISTS Cars'))
        con.execute(text('''CREATE TABLE Cars(Id INTEGER PRIMARY KEY, 
                     Name TEXT, Price INTEGER)'''))
    
        data = ( { "Id": 1, "Name": "Audi", "Price": 52642 },
                 { "Id": 2, "Name": "Mercedes", "Price": 57127 },
                 { "Id": 3, "Name": "Skoda", "Price": 9000 },
                 { "Id": 4, "Name": "Volvo", "Price": 29000 },
                 { "Id": 5, "Name": "Bentley", "Price": 350000 },
                 { "Id": 6, "Name": "Citroen", "Price": 21000 },
                 { "Id": 7, "Name": "Hummer", "Price": 41400 },
                 { "Id": 8, "Name": "Volkswagen", "Price": 21600 }
        )
        
        for line in data:
            con.execute(text("""INSERT INTO Cars(Id, Name, Price) 
                VALUES(:Id, :Name, :Price)"""), **line)
    

    使用 SQLAlchemy ORM 的示例:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String
    from sqlalchemy.orm import sessionmaker
    
    eng = create_engine('sqlite:///:memory:')
    
    Base = declarative_base()
     
    class Car(Base):
        __tablename__ = "Cars"
     
        Id = Column(Integer, primary_key=True)
        Name = Column(String)  
        Price = Column(Integer)
            
    Base.metadata.bind = eng        
    Base.metadata.create_all()        
            
    Session = sessionmaker(bind=eng)
    ses = Session()    
    
    ses.add_all(
       [Car(Id=1, Name='Audi', Price=52642), 
        Car(Id=2, Name='Mercedes', Price=57127),
        Car(Id=3, Name='Skoda', Price=9000),
        Car(Id=4, Name='Volvo', Price=29000),
        Car(Id=5, Name='Bentley', Price=350000),
        Car(Id=6, Name='Citroen', Price=21000),
        Car(Id=7, Name='Hummer', Price=41400),
        Car(Id=8, Name='Volkswagen', Price=21600)])
    ses.commit()
    

    观察后可以发现,使用了 ORM 可以帮助我们专注于业务逻辑。
    不用担心 SQL 语句是否打错字,也不用担心它是否能正常执行并返回预期的结果。

     
     

    Gunicorn & Terminal & Command

    学习完 Flask 之后,你已经知道了开发服务器和生产服务器的区别。
    为了更好的性能以及安全性,在部署博客系统的时候,你需要使用一个生产服务器。

    我选择了 Gunicorn,配置比较简单(入门容易),而且用户群也比较庞大(遇到问题更容易解决)。
    参考 Gunicorn 的教程,你可以很容易地完成相关的配置。

    Gunicorn 配置示例:

    import multiprocessing
    
    bind = '127.0.0.1:8000'
    workers = multiprocessing.cpu_count() * 2 + 1
    
    backlog = 2048
    worker_class = "gevent"
    worker_connections = 1000
    daemon = False
    debug = True
    proc_name = 'gunicorn_demo'
    pidfile = './log/gunicorn.pid'
    errorlog = './log/gunicorn.log'
    

     
    使用 Gunicorn 之后,你可以很容易地配置后端应用的访问地址、进程数、日志路径、运行模式等等。

    在你打算部署服务器时,你会发现你必须使用 命令行工具

    首先,启动 Gunicorn 需要执行命令行指令,比如:gunicorn --paste development.ini -b :8080 --chdir /path/to/project
    然后,连接远程服务器需要使用 SSH, 比如: ssh root@127.0.0.1

    推荐你学习 Linux 教程Shell 教程 。在部署后台系统到远程服务器的过程中,你会反复用到如 cd, ls, vim 等这些命令。所以,学习这些命令是必需的步骤。

    如果你还没有购买云服务器,那我推荐你使用 Vultr 的服务器。
    优点:便宜、不用备案、轻松部署强力爱国上网等等
    缺点:延迟高、经常有黑客来访等等

    当然,你也可以购买知名的 AWS、阿里云、腾讯云、UCloud 等等厂商的云服务器。

     
     

    Domain name

    拥有自己的博客的同时,你是不是也希望能够拥有一个特别的网站域名,比如自己的名字?

    现在以 http://ficow.cn 为例来讲解域名相关的知识。

    你可以访问 http://www.ficow.cn,也可以访问 http://ficow.cn
    但是,如果我访问 http://123.ficow.cn 就无法看到正常的页面。为什么呢?
    因为我在域名解析页面进行了相应的配置,http://ficow.cnhttp://www.ficow.cn 都是我希望别人可以正常访问的网页。

    阿里云 域名注册首页

    我是在 阿里云(原万网) 购买了 ficow.cn 这个域名,当然你也可以选择其他的域名提供商购买域名。

    在购买了域名之后,就可以登录控制台进行域名解析

    控制台 域名解析

    在主机记录这一列,我配置了 wwwblog。这两个均指向了同一个IP,也就意味着目前我是依靠这一台服务器来处理个人首页博客
    关于域名配置的详细内容,你可以参考域名提供商提供的帮助文档,也可以直接通过搜索引擎寻找答案,这里就不赘述了。

    但是,你是不是比较好奇,两个不同的主机记录竟然指向了同一台服务器。服务器是如何对不同的主机记录进行解析的呢? 接下来,Nginx 会告诉你答案~

     
     

    Nginx & Certbot

    Nginx 是一个高性能反向代理服务器,它可以将远程服务器上收到的数据转发给你的后台程序。用它来处理静态文件请求非常方便。

    这是一个 Nginx server 的配置 Demo:

    server
    {
            access_log /home/xxx/path/to/project custom_log;
            server_name blog.ficow.cn;
    
            charset utf-8;
            root /home/xxx/path/to/project;
    
            # Proxy connections to the application servers
            location / {
                proxy_pass         http://0.0.0.0:5000;
                proxy_redirect     off;
                proxy_set_header   Host $host;
                proxy_set_header   X-Forwarded-Proto $scheme;
                proxy_set_header   X-Real-IP $remote_addr;
                proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header   X-Forwarded-Host $server_name;
                client_max_body_size 10M;
            }
    }
    

    你可以通过简单地配置 Nginx 来监听 80 端口,然后让它根据域名来区分以及转发数据给你的后台程序。
    在上面的示例中,Nginx 会把指向 blog.ficow.cn 的访问请求转发给 http://0.0.0.0:5000, 限制客户端请求中body最大为 10M。

    当然,你可以让多个 server_name 都使用这同一套配置。你还可以定义多个 server,然后对不同的 server_name 进行不同的定制化处理,比如:负载均衡

    想了解更多关于如何配置 Nginx 的内容,请参考官网文档。

    如果你希望你的博客网站支持 HTTPS,我推荐你使用 Certbot
    Certbot 的最大优势就是:免费、易用,这对于一个个人博客系统来说,简直完美~

    在 Ubuntu 系统上安装 Certbot 的示例:

    sudo apt-get update
    sudo apt-get install software-properties-common
    sudo add-apt-repository ppa:certbot/certbot
    sudo apt-get update
    sudo apt-get install python-certbot-nginx 
    

    自动配置 Nginx 的 SSL 相关参数:

    certbot --nginx
    

    编辑定时任务,定期调起 Certbot 去更新 SSL 证书:

    crontab -e
    

    插入本行内容,并保存退出,定时任务即可生效

    # 分  时  某月中的几号  几月  星期几  *代表任何时候 ,分隔多个相同类型的参数
    0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
    

    如果系统默认打开的编辑器不是vim,可以修改环境变量
    在~/.profile中加入以下内容,并保存退出

    vim ~/.profile
    export EDITOR="/usr/bin/vim";
    

    加载更新的EDITOR配置:

    source ~/.profile
    

    然后再重新使用crontab -e添加定时更新 SSL 证书的任务即可。

    然后,尝试使用HTTPS来访问你的博客吧!

  • 相关阅读:
    记录一下最近面试的总结
    网络模块相关面试题
    JVM 之类加载器
    一段简单的关于字符串的 Java 代码竟考察了这么多东西
    LeetCode 链表题 ( Java )
    MD5 加盐加密
    SpringMVC 学习笔记
    [redis]dict和rehash
    [redis]SDS和链表
    [go]包和工程管理
  • 原文地址:https://www.cnblogs.com/ficow/p/12679253.html
Copyright © 2020-2023  润新知