<?xml version="1.0" encoding="UTF-8"?>        <rss version="2.0"
             xmlns:atom="http://www.w3.org/2005/Atom"
             xmlns:dc="http://purl.org/dc/elements/1.1/"
             xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
             xmlns:admin="http://webns.net/mvcb/"
             xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:content="http://purl.org/rss/1.0/modules/content/">
        <channel>
            <title>
									Programer/IT Automation - ITProSec Resources Forum				            </title>
            <link>https://itprosec.com/community/programer/</link>
            <description>ITProSec Resources Discussion Board</description>
            <language>en-US</language>
            <lastBuildDate>Wed, 03 Jun 2026 22:57:25 +0000</lastBuildDate>
            <generator>wpForo</generator>
            <ttl>60</ttl>
							                    <item>
                        <title>Ansible新手从这些文章开始</title>
                        <link>https://itprosec.com/community/programer/ansible%e6%96%b0%e6%89%8b%e4%bb%8e%e8%bf%99%e4%ba%9b%e6%96%87%e7%ab%a0%e5%bc%80%e5%a7%8b/</link>
                        <pubDate>Thu, 20 Aug 2020 14:16:15 +0000</pubDate>
                        <description><![CDATA[如果你是 Ansible 的新手，那么就从这些文章开始着手吧：

《Ansible 快速入门指南》拥有一些对新手非常有用的信息，同时还介绍了一些更高级的话题。
《你需要知道的 10 个 Ansible 模块》和《5 个 Ansible 运维任务》（译文）这两篇文章有每一位 Ansible 管理员都应该熟悉并认真研习的一些最基础的 Ansible 功能。
《如何使用 An...]]></description>
                        <content:encoded><![CDATA[<div>
<div>
<p>如果你是 Ansible 的新手，那么就从这些文章开始着手吧：</p>
<ul>
<li>《<a href="https://opensource.com/article/19/2/quickstart-guide-ansible" target="_blank" rel="nofollow noopener noreferrer">Ansible 快速入门指南</a>》拥有一些对新手非常有用的信息，同时还介绍了一些更高级的话题。</li>
<li>《<a href="https://opensource.com/article/19/9/must-know-ansible-modules" target="_blank" rel="nofollow noopener noreferrer">你需要知道的 10 个 Ansible 模块</a>》和《<a href="https://linux.cn/article-11312-1.html" target="_blank" rel="nofollow noopener noreferrer">5 个 Ansible 运维任务</a>》（译文）这两篇文章有每一位 Ansible 管理员都应该熟悉并认真研习的一些最基础的 Ansible 功能。</li>
<li>《<a href="https://opensource.com/article/19/4/ansible-procedures" target="_blank" rel="nofollow noopener noreferrer">如何使用 Ansible 记录流程</a>》这篇文章是对一些额外话题的纵览，我猜你一定会感到很有趣。</li>
</ul>
<p>剩余的这些文章包含了更多高级的话题，比如 Windows 管理、测试、硬件、云和容器，甚至包括了一个案例研究，如何管理那些对技术有兴趣的孩子的需求。</p>
<p>我希望你能像我一样好好享受 Ansible 带来的乐趣。不要停止学习哦！</p>
<ol>
<li>《<a href="https://opensource.com/article/19/9/ansible-documentation-kids-laptops" target="_blank" rel="nofollow noopener noreferrer">Ansible 如何为我的家庭带来和平</a>》这个异想天开的案例，你能看到如何利用 Ansible 为孩子们快速部署一个新的笔记本（或者重装旧笔记本）</li>
<li>Taz Brown 和 Abner Malivert 的《<a href="https://opensource.com/article/19/2/ansible-windows-admin" target="_blank" rel="nofollow noopener noreferrer">适用于 Windows 管理员的 Ansible</a>》：你知道 Ansible 也可以管理 Windows 的节点吗？这篇文章以部署一个 IIS 为案例，阐述了基础的 Ansible 服务器和 Windows 客户端的安装。</li>
<li>Shashank Hegde 的《<a href="https://opensource.com/article/19/9/must-know-ansible-modules" target="_blank" rel="nofollow noopener noreferrer">你需要知道的 10 个 Ansible 模块</a>》是个学习你最应该知道的那些最常见、最基础的 Ansible 模块的好文章。运行命令、安装软件包和操作文件是许多有用的自动化工作的基础。</li>
<li>Marco Bravo 的《<a href="https://opensource.com/article/19/4/ansible-procedures" target="_blank" rel="nofollow noopener noreferrer">如何使用 Ansible 记录流程</a>》：Ansible 的 YAML 文件易于阅读，因此它们可以被用于记录完成任务所需的手动步骤。这一特性可以帮助你调试与扩展，这令工作变得异常轻松。同时，这篇文章还包含关于测试和分析等 Ansible 相关主题的指导。</li>
<li>Clement Verna 的《<a href="https://linux.cn/article-10943-1.html" target="_blank" rel="nofollow noopener noreferrer">使用 Testinfra 和 Ansible 验证服务器状态</a>》（译文）：测试环节是任何一个 CI/CD DevOps 流程不可或缺的一部分。所以为什么不把测试 Ansible 的运行结果也纳入其中呢？这个测试架构 Testinfra 的入门级文章可以帮助你检查配置结果。</li>
<li>Mark Phillips 的《<a href="https://opensource.com/article/19/5/hardware-bootstrapping-ansible" target="_blank" rel="nofollow noopener noreferrer">Ansible 硬件起步</a>》：这个世界并不是完全已经被容器和虚拟机所占据。许多系统管理员仍然需要管理众多硬件资源。通过 Ansible 与一点 PXE、DHCP 以及其他技巧的结合，你可以创建一个方便的管理框架使硬件易于启动和运行。</li>
<li>Jairo da Silva Junior 的《<a href="https://opensource.com/article/19/3/developing-ansible-modules" target="_blank" rel="nofollow noopener noreferrer">你需要了解的关于 Ansible 模块的知识</a>》：模块给 Ansible 带来了巨大的潜力，已经有许多模块可以拿来利用。但如果没有你所需的模块，那你可以尝试给自己打造一个。看看这篇文章吧，它能让你了解如何从零开始打造自己所需的模块。</li>
<li>Mark Phillips 的《<a href="https://linux.cn/article-11312-1.html" target="_blank" rel="nofollow noopener noreferrer">5 个 Ansible 运维任务</a>》（译文）：这是另一个有关于如何使用 Ansible 来管理常见的系统操作任务的文章。这里描述了一系列可以取代命令行操作的 Tower（或 AWX）的案例。</li>
<li>Chris Short 的《<a href="https://opensource.com/article/19/2/quickstart-guide-ansible" target="_blank" rel="nofollow noopener noreferrer">Ansible 快速入门指南</a>》是个可以下载的 PDF 文档。它可以作为一本随时拿来翻阅的手册。这篇文章的开头有助于初学者入门。同时，还包括了一些其他的研究领域，比如模块测试、系统管理任务和针对 K8S 对象的管理。</li>
<li>Mark Phillips 的《<a href="https://opensource.com/article/19/7/ansible-news-edition-one" target="_blank" rel="nofollow noopener noreferrer">Ansible 参考指南，带有 Ansible Tower 和 GitHub 的 CI/CD，等等</a>》：这是一篇每月进行总结更新的文章，充满了有趣的链接。话题包括了 Ansible 的基础内容、管理 Netapp 的 E 系列存储产品、调试、打补丁包和其他一些相关内容。文章中还包括了一些视频以及一些聚会的链接。请查看详情。</li>
</ol>
</div>
<br />作者：Linux中国<br />链接：https://juejin.im/post/6844904041177153550<br />来源：掘金<br />著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</div>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/ansible%e6%96%b0%e6%89%8b%e4%bb%8e%e8%bf%99%e4%ba%9b%e6%96%87%e7%ab%a0%e5%bc%80%e5%a7%8b/</guid>
                    </item>
				                    <item>
                        <title>企业级 IT 系统运维怎么搞?</title>
                        <link>https://itprosec.com/community/programer/%e4%bc%81%e4%b8%9a%e7%ba%a7-it-%e7%b3%bb%e7%bb%9f%e8%bf%90%e7%bb%b4%e6%80%8e%e4%b9%88%e6%90%9e/</link>
                        <pubDate>Sat, 18 Jul 2020 18:41:19 +0000</pubDate>
                        <description><![CDATA[谈起运维工作，估计很多人会下意识的认为就是修电脑的、网管（上不去网，第一个被召唤的那种）。其实不能说这是错误的理解，IT 运维人员的工作小到修电脑、理网线，大到部署整个数据中心。负责运维的设备，小的从个人电脑，大的到数以亿计的高精尖计算设备（比如 IBM 的大型机 Z13）。
从运维的工作层次来分，又分为硬件运维、桌面运维、系统运维、数据库运维和应用运维。几乎所有的和系统相关...]]></description>
                        <content:encoded><![CDATA[<header id="header" class="header is-hide"></header>
<div id="body" class="body">
<div class="container">
<div class="row">
<div id="main" class="main">
<article class="article">
<div id="article-box" class="article-box card">
<div id="post-text2speech" class="post__text2speech" title="用声音感受世界"> </div>
<div id="article-content" class="article-content">
<p>谈起运维工作，估计很多人会下意识的认为就是修电脑的、网管（上不去网，第一个被召唤的那种）。其实不能说这是错误的理解，IT 运维人员的工作小到修电脑、理网线，大到部署整个数据中心。负责运维的设备，小的从个人电脑，大的到数以亿计的高精尖计算设备（比如 IBM 的大型机 Z13）。</p>
<p>从运维的工作层次来分，又分为硬件运维、桌面运维、系统运维、数据库运维和应用运维。几乎所有的和系统相关的问题，都与 IT 运维人员有关。根据公司 IT 系统规模的不同，有的运维团队不到 10 人，有的甚至达到数百人。每晚通宵达旦，为 IT 系统保驾护航。</p>
<p>但是始终还是有很多的人和同事会质疑：为什么我的电脑还这么卡？网络速度还这么慢？某某系统还是上不去，很影响业务运营等等。这些质疑让运维人员很尴尬也很无语，有些问题甚至类似客户没有插网线，抱怨上不去网。有时候甚至会胡思乱想，究竟运维的意义是什么？这么努力怎么还这么受气？</p>
<p>前段时间与运维方面的朋友一起交流的时候，大家总是时不时的诉苦，抱怨运维苦逼，没有成就感，甚至经常成为“窦娥”、“背锅侠”的代名词。种种抱怨和不满，也促使我更加的想表达一下如何做好 IT 运维方面的经验和个人见解（不一定对，欢迎拍砖），尤其是企业级的 IT 系统运维。因为企业级的 IT 系统运维不但系统分支多，而且够复杂。业务频繁变更，要求 IT 系统必须随需应变。</p>
<p>本文作者将分为如下几个部分剖析企业级IT系统运维者如何才能体现真正价值？</p>
<h2 id="article-header-0">运维的价值</h2>
<p>我毕业后就一直从事 IT 系统运维方面的工作，从当初的桌面技术人员到现在的运维总监，一路荆棘，回想起来已有超过 10 年的运维经验了。虽然谈不上老道，更说不上是大咖，但是也总结了一些自己对运维工作的理解，对运维价值的理解。多年的摸爬滚打，我对运维总结成了两句话：“技术只是手段，业务才是王道”。运维的好坏评定标准其实就是你给公司及业务带来了哪些价值及哪些影响。</p>
<p>业内有很多的运维专场，每年不下数十场。从之前传统运维到现在的敏捷运维甚至 AIOps，这些都是在说运维的方法。通过这些方法让运维变得更灵敏、让运维人员更好的理解用户的需求。但是万变不离其宗的道理是，这些行为都是围绕着不同的业务需求而展开，为了满足不同阶段业务的发展而设计。</p>
<p>无论是小企业还是大企业，很多时候，运维人员的确做了很多的事情，处理了很多紧急的事件，甚至都是在凌晨才动手，确实非常辛苦，真所谓是“累成狗，起的比鸡早，睡得比猪晚”。但是这些事情真正为业务创造了多少价值呢？老板知道吗？可能这个就是运维人员该好好思考一下的了。</p>
<p>当然，我并不是否定我们运维在做的事情，毕竟我也是做运维出身的。这些事情的确是运维人员必须要做的。但是我的观点是不能陷在这个自我感觉良好的漩涡中——自认为运维做了很多的事情，非常的辛苦，甘做幕后英雄。如果有这样的想法，那一定是运维人员自己的问题了。运维不光是需要技术上的不断改进与创新，更需要思维观念的改变，学会站在业务的角度思考问题。往往在这个改变的过程中，运维的价值就会逐步的得到体现。</p>
<p>在这里，我总结了一下多年来自己做运维的经验分享给大家，踩过的坑，背过的锅，还历历在目。希望大家可以避开这些问题，做好企业 IT 系统的运维，体现运维的真正价值给公司。</p>
<h2 id="article-header-1">什么是运维</h2>
<p>运维是一件对知识面要求很高的工作，它要求运维者不仅要懂得基本的系统与网络知识，还要对运维的业务系统有较深的理解，知道整套业务系统的工作模式与工作原理。这也是对运维人员学习能力的一种考验。一听到故障描述，就可以大概知道问题的故障点所在。同时知道如何通过技术手段及清晰的逻辑方法去发现和解决问题。</p>
<p>运维是一件对自动化要求很高的工作，随着 IT 技术的不断发展，越来越多的方便运维的技术应运而生。从互联网时代开始，业务系统的交付和迭代也变得越来越频繁，从每月的迭代一次，甚至到了每天迭代多次的场景。如果没有自动化的手段快速响应与处理，对用户的影响可想而知。自动化的主要目的个人认为主要有三个：效率提升、可控、降低依赖。</p>
<h3 id="article-header-2">效率提升</h3>
<p>初期自动化主要解决的是和日常运维例行工作相关的操作。比如各种平台的资源分配&amp;回收、统一配置管理、CI&amp;CD（持续集成&amp;发布）、操作系统的部署、系统空间的扩容与缩容、简单应用部署、文件分发等等，这些都是运维最基础的工作，也是自动化最容易实现和集中的领域。</p>
<p>个人觉得凡是那些偏日常和重复的工作都应该自动化，解放运维的生产力，提升运维效率，降低人为失误，让运维的同事可以有更多的精力去学习更多的技能。做更有价值的事情，无论互联网时代还是大数据时代，人才毕竟是最贵的。</p>
<p>目前自动化的解决方案都相对完善了很多，所以可以放心的去实践和应用。对于重要的领域和操作，一定要经过严谨的测试才能应用，否则自动化带来的灾难也是不可估量的。</p>
<h3 id="article-header-3">可靠可控</h3>
<p>可控对于运维人员来说是再重要不过的了，自身经验是，如果运维一套不可控的系统，无疑是攥着一颗不知道什么时候会爆炸的定时炸弹，时刻担心它会产生不可预知的后果。可控要细说我觉得大致可以分为稳定性可控、性能可控和安全可控。</p>
<h3 id="article-header-4">稳定性可控</h3>
<p>作为企业级的运维人员，我们要运维的系统不但数量多，而且网络架构复杂。包括的硬件更是多样，除了熟知的服务器、存储、网络设备、负载均衡设备等，可能还有很多是运维人员没有接触过的新玩意。而这些硬件又承载了各种应用，组成了各类不同的系统供用户访问，复杂程度不言而喻。如何让这些设备在损坏的情况下也不影响业务，不影响运维人员陪女朋友看电影。做到心中有数，掌控硬件损坏会对系统有什么影响，需要多少时间来修复等等。</p>
<h3 id="article-header-5">性能可控</h3>
<p>合理的分配系统资源产生合理的性能对系统的稳定性起到了至关重要的作用。一个系统慢与快并不是运维人员最担心的，而是时快时慢是最可怕的，因为那种状态是最不可控的状态，这样的系统是不可能承载企业核心或者重要的业务的。最典型的应用场景就是云计算平台的资源分配。一旦平台资源被错误的分配，对业务的影响是不可估量的，排错过程也是运维人员最头疼的。</p>
<h3 id="article-header-6">安全可控</h3>
<p>现在运维圈子流行的模块化管理、运维自动化、可视化甚至是基于大数据决策的运维，本质上都是希望达到运维可控的目标。安全是唯一一个贯穿运维全部过程的模块。</p>
<p>所以运维人员每日都会花费特别多的精力在系统的安全建设和防御上，比如防止哪些未授权行为，所有的操作必须通过堡垒机，关键操作必须通过审计等等。IT 运维安全方面的内容还是相当复杂的，比如应用交付可控，各种变更可控以及效率可控都是值得特别关注的。</p>
<p>为什么我们熟悉的工作往往是最容易出问题的工作。简单分析一下就是因为我们平常一直在周而复始的做一件事，产生了麻痹。同理，IT 运维大部分都是一些重复性的操作与工作，但是又是必须的。合理的通过自动化代替人工操作，可以非常有效的避免低级错误的发生。</p>
<p>这对于企业级的复杂系统是至关重要的，可以明显提高可靠性，减轻运维人员繁琐的人工任务。</p>
<h3 id="article-header-7">降低人员依赖</h3>
<p>运维工作是个很有意思的工作，他不是靠人多堆出来的工种。运维工作对人员的技能要求还是比较高的，可谓是要精不要多，多培养精兵强将。任何问题的处理都要避免靠堆人来解决，这种方式不一定会解决问题，但是一定会增加运维的成本。</p>
<p>运维是一件对精细化要求很高的工作，那么什么是精细化管理呢？</p>
<p>引用一段官方解释：“精细化管理是源于发达国家的一种企业管理理念，它是社会分工的精细化，以及服务质量的精细化对现代管理的必然要求，是建立在常规管理的基础上，并将常规管理引向深入的基本思想和管理模式，是一种以最大限度地减少管理所占用的资源和降低管理成本为主要目标的管理方式”。</p>
<p>现在的 IT 运维已经进入了精细化管理的时代，而不是以前的大锅饭年代了。分工明确，注重细节、注重过程、注重质量。通过技术手段对全部的信息进行收集，管理员可以随时知道目前系统的运行状态。从而提高运维管理的整体水平和效果，实现了灵活的弹性扩容能力。</p>
<p>运维是一件对责任心要求很高的工作，各行各业都对责任心有很强的要求，运维也是如此。因为不同系统的应用等级不同，影响范围也会不同。如果运维人员因为疏忽大意导致业务系统崩溃，所带来的影响可能是灾难性的。比如银行的结算系统、股票的交易系统等等。</p>
<p>我认为一个运维人员技术可以不是那么精深，做事可以不是那么敏捷，但是一定要有一颗较强的责任心，否则一切归零。</p>
<h2 id="article-header-8">运维方法浅谈</h2>
<p>随着信息技术的发展以及企业业务的不断扩张，运维人员所面临的系统架构越发的复杂，关联度越发紧密。从技术角度上，对运维人员的要求也会越来越高，需要个个都是精兵强将，对业务系统了如指掌。现在的运维已经不像 N 年前那种被动式的运维了，需要运维人员快速转变观念，学会通过主动运维的方式应对复杂多变的 IT 问题，保证业务系统的稳定。需要更多的站在客户的角度思考问题，解决问题。当然，每个人的经历不同，职责不同。</p>
<p>所以对运维的理解也会有不同，我们可以将运维说的高大上、高精尖，也可以将运维说的稀疏平常、平易近人。高精尖、高大上是在于运维使用了很多非常牛 X 的技术，在业务系统没有感知的情况下实现了业务的变更、升级。终端用户可以在无感知的情况下继续进行自己的支付操作、游戏操作等等。稀疏平常是在于用户每天都有机会和运维人员打交道，或多或少，或深或浅都会有不同程度的交集。哪天不和运维人员发个牢骚、抱怨一下就会觉得自己没有来上班一样。</p>
<p>以下是我总结归纳的一些不成规律的运维经验，不成方法的运维手段。正如前文所述，不同的人就会有不同的见解，不同的经验就会碰撞出不同的火花。欢迎运维爱好者一起讨论、拍砖。结合自己多年的经验，总结了一些运维经验，希望可以抛砖引玉得到更多爱好者甚至专家的指点，促使我不断的进步。</p>
<p>下文方法主要分为五大类：文档、流程、技术、监控和备份。</p>
<p><img src="https://vircloud.net/usr/uploads/2020/07/2844954162.jpg" alt="运维方法" /></p>
<h3 id="article-header-9">文档</h3>
<p>正所谓兵马未动，粮草先行。一个好的系统或者项目，必定有很多的文档进行支撑。比如系统建设前期，一定要做好系统的需求文档、设计文档、实施文档。在系统建设中要依据前期的文档进行实施和设计，并生成系统相关的问题总结文档和更新实施文档。系统建设完成后，要基于系统的业务能力和使用对象编写操作手册和运维手册等。有些业务在交付的过程中，并未按照要求提供相关的文档，系统上线后问题层出不穷，导致运维人员手忙脚乱，不知道从何下手处理，往往会让运维人员绕很多的弯路，错失良机。文档也分好多种，比如配置文档、实施文档、设计文档、系统规范性文档、项目管理文档等等。基于种种，所以要求运维人员一定要具备相应的文档编写能力和整理能力。同时一定要严格按照之前的文档进行实施，有问题要学会及时沟通，并把修正后的问题更新到文档中。</p>
<p>以前文档的管理大多数是放在用户的本地，高级点是放在共享的 NFS 或者 FTP 中。但是很多的功能受到技术限制，不能满足高效、敏捷、互动的要求。通过知识库的一个文档管理功能，不仅可以解决如上问题，还可以将不同运维人员的经验和知识转化为生产力，协同办公。类似的软件比如 Confluence、Wiki 等。</p>
<h3 id="article-header-10">流程</h3>
<p>正所谓无规矩不成方圆。随着 IT 环境的不断扩大，业务变更的频繁度越来越高，就要求运维人员一定要基于一个既定的规则来干活。而不是完全按照业务的要求，被扯来扯去，拆东墙补西墙，毕竟业务人员专注点与运维人员的专注点不同，责任也不同。这规则就称为流程。</p>
<p>在 IT 界最有名也最实用的流程莫过于英国政府部门 CCTA 在 20 世纪 80 年代末制定的 ITIL 了（即 IT 基础架构库(Information Technology Infrastructure Library，ITIL，信息技术基础架构库)。当然现在由英国商务部 OGC(Office of Government Commerce)负责管理，版本也从当初的 V1 到了现在的 V3。ITIL 为企业的 IT 服务管理实践提供了一个客观、严谨、可量化的标准和规范。这次我不是要细讲 ITIL 的内容，有兴趣的朋友可以 Google、Baidu 一下，认真研读 ITIL，一定会让你受益匪浅，尤其是运维人员。</p>
<p><img src="https://vircloud.net/usr/uploads/2020/07/3576407249.png" /></p>
<p>在整个系统的运维过程中，流程由始至终贯穿整条链路。它是对运维人员的保障，同时也是对所做变更合规可控的保证。合理的流程设置不仅节约了运维成本，也可以推进事情有序的进行，达到预期效果。那么如何制定符合实际需求的流程呢？这个就仁者见仁，智者见智了。</p>
<p>我把整个过程分成三个阶段：</p>
<ul>
<li>要做啥？就是说这个流程要完成什么任务，目的是什么，切记一定是一个或者唯一的任务，不是多个任务。比如要安装软件、要变更配置、要发布程序等等。</li>
<li>谁来做？就是说要完成这个事情，需要涉及到哪些部门的哪些人。请切记，流程一定要落实到人，否则就是空谈。</li>
<li>多长时间？一个流程从开始到结束一定是有个时间约束的，也就是说这个流程被要求多长时间内必须完成。</li>
</ul>
<p>一般这个往往和业务系统的 SLA 有关，达不到要求可能会扣银子，那就不好玩了。当然流程不是固定不变的。随着 IT 业务和人员的变更，要学会对流程进行优化和改进，以适应最新的 IT 环境和业务要求。</p>
<h3 id="article-header-11">技术</h3>
<p>正所谓工欲善其事，必先利其器。如今是一个知识爆炸的时代，想获取什么知识只需要打开浏览器即可。不像以前还要频繁的出入图书馆，我记得当年自己经常去的就是新华书店啦（主要是因为那里可以坐下来慢慢的看书，而且还可以将其抄录下来），暴露年龄啦！现如今很多的企业都在强化以用户服务为中心，专业技术为驱动的理念，可见拥有过硬的技术是多么的重要。</p>
<p>这里所说的技术，我主要想从两个方面入手，一个是指人员自身所掌握的技能，另一个是指对主流技术的剖析与实践能力。</p>
<h4>人员自身技能</h4>
<p>运维对技术的要求还是很高的，不是谁都可以做运维的。首先运维人员要对自己所负责的系统有较深的理解，全程参与系统的设计、实施与运维。正所谓打铁还需自身硬，就像武侠名著所说，每个武侠人物都会有个看家本领，比如乔峰的“降龙十八掌”，段誉的“六脉神剑“。</p>
<p>运维人员也是如此，一定要具备相关领域的技术积累，有较丰富的设计或者排错经验。同时要具备较为灵敏的技术嗅觉，不敢说需要十八般武艺样样精通，但是也要对相关辅助技能略知一二，此称为硬实力。光有硬技能其实只能证明你可以解决系统的硬性问题，但是不具备更好的解决问题的能力。很多重大的问题几乎都与外界系统相关联，甚至是强关联。</p>
<p>这个时候单纯的技术能力就很难解决了，需要运维人员具备以下软实力：</p>
<h5>1、首先要具备的就是沟通能力</h5>
<p>记得刚工作的时候，我们部门的技术人员被戏称为“傻、呆、倔”，脑子里装的都是代码和命令，什么风花雪月、人情世故都成功的过滤了我们。随着困难增多，坑踩多了后，才知道沟通是多么的重要。良好的沟通可以很快与多部门协同工作，了解大家的共同点和痛点，对症下药，可以更快速的解决问题。</p>
<h5>2、合作心态很重要</h5>
<p>这么多年，我一直认为团队作战远比孤军奋战要强，效率要高。尤其现在很多的公司都有分公司，IT 运维人员往往也是分布式的。总部与分公司员工之间只有保持合作心态才可以高效、快速的发现问题、解决问题。</p>
<h5>3、同理心让沟通事半功倍</h5>
<p>很多人认为同理心是企业中负责用户体验部门的技能，实际上随着互联网技术的发展，IT 与业务的紧密融合，运维人员是非常需要同理心的。当运维人员接到故障报告或者通知，需要及时与客户沟通，站在客户的角度理解问题，解决问题，避免无谓的抱怨与投诉，提高运维满意度。</p>
<h5>4、善于写作的基础</h5>
<p>无论是系统还是项目从孵化到交付都离不开文档的支持。运维人员应该具备良好的文档写作能力，可以将系统设计说明清晰，问题描述清晰，解决方案条理清晰。运维人员如果每天都往机房跑，一定是有问题的。多数时间应该是在学习、探索，自我提升、总结问题，避免二次发生。这些都需要文档的记录与支撑。</p>
<h5>5、认真做事的态度</h5>
<p>认真做事的态度在任何的行业都是通用的好模板。记得一本书上说过“你做事的态度，决定你的高度”对于运维人员来说，一定要高度热爱自己的工作，如果你不热爱它，肯定不会认真的去做。这不是一句口号，而是要以结果为导向，具备不达目的不罢休的精神。有些运维上的问题，就是某个细节所决定的，只有认真才能从众多乱麻中，找到线索，解决问题。</p>
<h4>主流技术的剖析与实践</h4>
<p>运维人员一定要对现在的主流技术有一定的涉猎（云计算、边缘计算、大数据、AIOps、人工智能、深度学习等等），要与时俱进。经常参与线上或者线下的相关讨论和交流学习。了解目前流行的 IT 技术，并学习它，思考如何将其用于企业的业务中，为企业创造价值，提升运维效率。所以具备主流技术的捕捉能力，也是运维人员的必修课之一。</p>
<h3 id="article-header-12">监控</h3>
<p>正所谓与其后悔于已然，不如防患于未然，监控的目的就是防患于未然。通过监控，运维人员能够及时了解到企业网络的运行状态。一旦出现安全隐患，可以及时预警或者是以其他方式通知运维人员，让运维监控人员有时间处理和解决，避免影响业务系统的正常使用，将一切问题的根源扼杀在摇篮当中。</p>
<p>监控的方式很多，软件更多。如何选择监控对象、设计监控指标就需要运维人员根据不同业务的实际情况自己去实践了。但是一定要记住，现在的监控工具可以在监控指标触发时，自动修复一些故障，但是它最多帮你做些简单的自动化任务，更高阶的自动化任务需要运维人员具备较深的脚本和系统知识。</p>
<p>所以监控作为运维人员的眼睛，要时刻保持 12 分精神，运维人员要定期对监控系统进行“照料”，避免“视觉疲劳”，影响监控效果。</p>
<h3 id="article-header-13">备份</h3>
<p>正所谓天有不测风云，人有旦夕祸福。备份是一种保障机制，一般用不到，用到就是大事。备份可以说是运维人员的最后一根救命稻草，用好这最后一根稻草可以起死回生，用不好就会死无葬身之地呀。其实一点也不夸张，公司将重资产都交给运维来做，是对运维的信任，运维人员自然要对这些资产和数据负责，对公司负责，这也是运维价值的一种体现。</p>
<p>现在备份软件很多，国产的、国外的，所以选择一款适合自己业务需要的备份软件很重要。不是什么数据都需要备份，要首先甄别出哪些数据需要备份，确定备份范围。制定好备份策略，不同的数据需要不同的策略设定。选择靠谱的备份介质，到底是选择磁带、硬盘还是光介质等，这些都是需要运维人员根据业务需求而制定。</p>
<h2 id="article-header-14">总结</h2>
<p>以上这些算是自己对这十年运维经验的小小总结，很多内容不可能一次说完，也不可能全部写下来，毕竟运维这东西很多还是看自己的感悟和直觉。在运维方法浅谈章节中，我仅仅是总结了自己做运维用到的一些主要方法，并未涉及具体的技术。</p>
<p>可能有些朋友会问，为啥没有体现当下流行的 CMDB、可视化运维、ITSM 等。其实这些都只是工具，一种让运维更透明，让运维人员更轻松，让老板更放心的运维工具。在实际工作中，可以根据需要自行采购或者自己开发，满足业务要求。</p>
<p>最后和运维的朋友分享一段心里话：“运维是一件细致的工作，不允许一丝马虎。运维人员一定要富有勇于创新的精神和对工作的激情，有了这些东西，我相信，你一定是个非常优秀的运维人员。”</p>
<p>结尾祝做运维的朋友在运维的道路上越走路越宽，技术更上一层楼。也祝自己在以后的工作中学习到更多，分享更多给大家。</p>
</div>
</div>
</article>
</div>
</div>
</div>
</div>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/%e4%bc%81%e4%b8%9a%e7%ba%a7-it-%e7%b3%bb%e7%bb%9f%e8%bf%90%e7%bb%b4%e6%80%8e%e4%b9%88%e6%90%9e/</guid>
                    </item>
				                    <item>
                        <title>运维经验总结</title>
                        <link>https://itprosec.com/community/programer/%e8%bf%90%e7%bb%b4%e7%bb%8f%e9%aa%8c%e6%80%bb%e7%bb%93/</link>
                        <pubDate>Mon, 13 Jul 2020 02:56:07 +0000</pubDate>
                        <description><![CDATA[这几天对这一年的运维工作做了一些总结，然后有一些思考，整理出来发一篇，希望2020年工作可以更轻松
多做计划
墨菲定律其实是一种心理学效应， 原文为：如果有两种或两种以上的方式去做某件事情，而其中一种选择方式将导致灾难，则必定有人会做出这种选择。根本内容是：如果事情有变坏的可能，不管这种可能性有多小，它总会发生
在运维工作中，这种情况很多，晚上做网络割接，心里一定会想，千...]]></description>
                        <content:encoded><![CDATA[<p><span>这几天对这一年的运维工作做了一些总结，然后有一些思考，整理出来发一篇，希望2020年工作可以更轻松</span></p>
<p>多做计划</p>
<p><span>墨菲定律其实是一种心理学效应， </span><span>原文为：如果有两种或两种以上的方式去做某件事情，而其中一种选择方式将导致灾难，则必定有人会做出这种选择。根本内容是：如果事情有变坏的可能，不管这种可能性有多小，它总会发生</span></p>
<p><span>在运维工作中，这种情况很多，晚上做网络割接，心里一定会想，千万别出问题，结果网络切断了</span></p>
<p><span>服务器需要重启，一定会担心会不会起不来，结果就会起不来</span></p>
<p><span>担心网站挂掉，总会在半夜的时候挂掉</span></p>
<p><span>……</span></p>
<p><span>运维工作中，很多这种情况，总会有“意向到的意外”，所以需要有更多的plan</span></p>
<p><span>很多公众号写文章说使用某某监控某某架构不做救火运维，扯犊子呢，我就没见过不救火的运维</span></p>
<p><span>运维工作要保证可用性，所以很多意想到的可能性很小的事情，也需要提前做好计划来应对，这也是运维工作中要做的应急响应计划</span></p>
<p>一定有原因</p>
<p><span>运维工作中，很多时候会有很奇怪的故障或者问题出现</span></p>
<p><span>一个脚本从这个服务器复制到另外一个服务器就不能执行了</span></p>
<p><span>一份配置，在配置一样的两台服务器，却有一台不能用</span></p>
<p><span>上一秒还在检查的故障，突然自己好了</span></p>
<p><span>……</span></p>
<p><span>很多人在群里会这样问，觉得很神奇，反复对比两个环境，一模一样，其中一个就是不能运行，其实神奇，是因为你对这个东西不了解，你没有找到关键的地方，既然不能运行，肯定还是有不一样的地方</span></p>
<p><span>你可以去strace查看它的执行过程，你可以去抓包查看每个数据包对比，总能找到问题的关键，找问题的过程，是你熟悉这个知识的过程，找出问题的结果，是你对这个故障的一个宝贵经验，所以一定要去探索问题最根本的原因，即便最后你查不到最根本的原因</span></p>
<p>多做尝试</p>
<p><span>运维这个工作，就是个技术工人，技术高的就是高级运维，有自己技术创新的就是运维专家，初入门的，跟着师傅的，就是搬砖运维</span></p>
<p><span>初级技术工人，要成为专家，就是要不断的去做相应的工作，积累经验，经验积累到一定程度，就可以是专家，</span></p>
<p><span>很多人遇到问题喜欢群里、知乎、知识星球这些地方去问，比如监控用zabbix好还是 Prometheus好，还是open-falcon更好，系统用CentOS好用还是Ubuntu好用，k8s好用还是k3s更适合你</span></p>
<p><span>为什么不自己去搭建，去测试，抛开每个人的业务情况、系统配置不说，群里的人说的你就相信吗？有多少文技术文章是抄来抄去，错误都不改的。现在有虚拟机、有按量付费的公有云，花十几块钱、花一些时间把你想要了解的东西，搭建一遍，你会在这个过程中得到比你在微信群里得到的一个不一定对你来说正确的答案更多的东西</span></p>
<p><span>你想了解的东西也好，你维护别人的环境也好，处理故障也好，多去实践、尝试你的想法，在这个过程中，你会这个东西有更深入的了解，对你的技术提升有很大的帮助</span></p>
<p>别人说的不一定是对的</p>
<p><span>接上一个问题，你不去尝试，直接从搜索引擎或群里获得一个结果，对于运维这种环境复杂的情况来说，别人的结果是在别人的业务和配置情况下的一个结果，虽然很多情况下，我们都可以参考别人的配置、别人的脚本，改个参数就可以用，但只适合参考，很多时候，你去测试别人的配置，发现在你的环境下竟然是完全不同的结果</span></p>
<p><span>参考别人的，只是在自己解决问题，没有思路的时候，去找到一个方向，但是不要固化的认为别人这么配置就可以用，就得这么配置才是对 的 ，你按这种方式配置了，你一定是搞错了</span></p>
<p><span>程序为什么会有bug，就是因为开发的人没有想到这个问题，所以不管是官方的文档，还是有经验的人给你说的经验，你都只能当作一个参考，更重要的是去实践，勇于怀疑，并去探索验证</span></p>
<p>了解每个配置的意义</p>
<p><span>运维工作，基本就是用命令工具和中间件工具去支持和维护服务正常运行，天天在和命令打交道、天天安装配置各种中间件，每个命令每个中间件，每个开源工具都有自己的一套“说明书”，对每个参数都有详细的解释</span></p>
<p><span>在使用前尽可能去了解、学习并实践每个参数的意义，或者说作用，对你的工作效率或者说做出的运维工作会有很大的不同</span></p>
<p><span>比如Dockerfile中，ADD和COPY，你要不了解的话，会觉得，都是往容器里面加文件，无所谓，那你觉得人家开发设计的时候，为啥要设置两个参数呢，他闲的没事干，玩呢？</span></p>
<p><span>你发现你COPY构建的镜像比别人ADD构建的镜像要大，因为你COPY把压缩包放进去，还需要RUN去解压，而ADD直接解压了</span></p>
<p><span>当你去下载个包，然后再通过COPY复制进去的时候，人家早就通过ADD加载链接的方式直接打包进去了，当然这里更推荐再打包的时候用curl或wget去下载远程文件</span></p>
<p><span>所以说，要尽量去了解更多配置项和参数的作用或意义，很大程度上能提高你的效率</span></p>
<p>思路很重要</p>
<p><span>运维过程中，经常遇到各种各样，摸不着头脑的问题，而且很多时候，你所看到的问题，并不是你所看到出现问题的这个中间件或者工具引起的，报错日志也不会给到直接的错误原因，这个时候你去排查问题，就是看你思路的时候</span></p>
<p><span>你需要根据你的经验及知识，去理清思路，根据自己的思路去检查、排错、尝试，而不是像无头苍蝇一样，胡乱的尝试，很多人根据别人的建议胡乱尝试，最后把系统重要组件卸载，服务器挂掉，这种例子很常见</span></p>
<p><span>他能知道你什么情况吗，他能比你更了解你的环境吗，你需要有自己的思路，自己去思考问题可能的原因，否则你连搜索引擎你都不会用</span></p>
<p><span>比如你的网站，使用nginx前后端分离，请求的时候，提示跨域，你去搜索引擎怎么搜？ ”nginx跨域如何配置“，搜出来一堆，然后你按照别人的配置， 在 nginx配置文件中添加了add_header，允许所有跨域请求，结果发现request_header中根本都没加上这个header，然后你开始查”nginx跨域配置不生效“，结果别人各种方法，加在http里面，加在server里面，加在location里面，你跟着尝试了一遍，发现仍然没有效果，最后你才发现，你的静态资源加了CDN，CDN那边没做跨域处理</span></p>
<p><span>你要自己先脑子里有个你自己系统的拓扑图，你可以脑子里，也可以画出来，然后你感觉哪里会引起目前的问题，你去解决，不是跟着别人的思路去尝试</span></p>
<p>持续关注新技术</p>
<p><span>我是做互联网运维的，不是传统的运维(那种机房看监控的)，对于互联网的快速发展，大家是有目共睹的，各种开源项目不断涌现，各种新的开发语言应接不暇，好多人调侃说，学不动了，是真的学不动了，新出一个东西，有些人还没听说，就已经过时了，这就是互联网速度</span></p>
<p><span>但是，不要做井底之蛙，我的建议是持续关注新技术，不管是开发的也好、产品相关也好、网络相关等等，现在信息时代，获取信息很方便，你可以每天上下班的时间，去订阅一些公众号，把一些娱乐的新闻换成这些技术公众号，你可以不去详细学习每个出来的新技术，但是你要知道有这些新的技术，为啥？</span></p>
<p><span>这又接上面一个话题了，思路，为什么出个故障，别人定位问题很快，你半天定位不到问题，别人处理问题的时候花样百出，你只能花式百度，关注各种新技术，能让你的视野更开阔，定位问题的时候，能够更全面的去思考，而不是仅限于你自己管理的那个中间件上面</span></p>
<p><span>新的技术，一定是为解决就得痛点而诞生 的 ，所以，当你不断得关注新的技术的时候，你会发现很多你之前遇到的问题，你可能花了好长时间，费了很大的成本才解决的问题，别人一个命令就搞定了</span></p>
<p><span>比如我之前搭建ffmpeg去处理图片，大家都知道，CentOS系统的源码库的项目都很旧，更新没有ubuntu那么快，这也是为什么服务器都选CentOS系统，选Ubuntu少的原因，因为旧的相对来说要稳定一些，在CentOS7还好，ffmpeg已经可以yum装到2.8的版本吧，大概，但是CentOS6的话yum只能到0.6的版本，很多格式不支持，怎么搞，编译安装，最开始我用了半周的时间去搞这个，因为他要的以来太多了，以来版本还不能又差，但是现在怎么样，我写个dockerfile，用alpine系统，把最新的4.x的ffmpeg装进去，然后docker run一条命令我就可以剪辑音视频</span></p>
<p><span>所以，你可以不去学习每个新的技术，但一定要关注新的技术</span></p>
<p>新技术不要急于上生产</p>
<p><span>接着上面一个话题，你要持续关注新的技术，但是在生产环境不要急于引入新技术，为什么？</span></p>
<p><span>你看政府单位，为什么系统还在用winxp、win7，是win10不好用吗，还是他们没钱换，都不是，是稳定，更换风险系数高</span></p>
<p><span>互联网时代，我们都讲快速交付，很多项目，都是demo的时候就交付使用了，然后边使用，边迭代，但是，这有个问题就是，增加了软件或者项目的不确定和不可控性，不说那么高端的东西，就说我们用的很多开源工具，很多刚上线觉得很好的工具，你觉得应该上到线上，提高工作效率，没几天，你发现，别人开发了同类型的项目，是大厂开发的，比这个要更好，你怎么办，天天换吗？</span></p>
<p><span>有大厂开源了个项目，你觉得应该没问题，大厂的项目，后期很多又很多人维护，很多人使用，Tengine中间都一度不更新了，你觉得还有什么是不可能的吗？</span></p>
<p><span>况且，觉得你有能力作为开源项目的第一批踩坑者吗？你有能力，你觉得公司有成本陪你踩坑吗？在网上没有任何别人经验可以借鉴的情况下，你能处理你用于生产环境的这个新技术的故障吗？</span></p>
<p><span>不是不可以上生产环境，是需要等别人坑踩实了，你在上，你可以在测试环境去学习，去了解，不要再给自己找不必要的麻烦，你可以问问你自己，是不是很多时候的加班，都是自找的，明明之前的项目架构很稳定，非要改个中间件，引发了一系列问题，加了一个月班，还被老板骂，下班健个身不好吗？</span></p>
<p>极简主义</p>
<p><span>不管是做架构、是做优化、写脚本、写管理后台、做服务器管理，最好极简化</span></p>
<p><span>为什么要极简化呢，因为复杂的架构或脚本，会让运维处理故障更加困难</span></p>
<p><span>最近DevOps很火，带动Jenkins很火，自动化构建发布，于是很多运维就开始着手把自己的项目进行一个改造，本身就是小公司，原本就2台服务器，一台web，一台数据库，项目用git直接发布，也很省事</span></p>
<p><span>然后通过gitlab+jenkins一通改造之后，服务器成本加了两台不说，还搭了好几个加班，jenkins他又不熟悉，每次发布出问题，都要等他处理半天，有时候拖延了发布时间，最终还是用git发布上去</span></p>
<p><span>有时候架构简单点也是好事，不一定非要复杂，运维工作中，最重要的是实用，实用才是王道</span></p>
<p><span>当然该要添加优化的时候，还是要添加，但是不要盲目，比如你想session存redis，本身项目也不大，那你单redis节点就够了，redis也够稳定，也不会经常掉线，你完全没必要去搭建个redis sentinel模式</span></p>
<p><span>再一个极简就是，服务器上不要放太多乱七八糟的东西，很多人备份会在web目录下存放打好的tar包，不说你占用资源，备份的时候备份文件大不说，从安全角度，你这是”开源“了啊，你是怕别人不知道你写了多少bug吗？</span></p>
<p>数据最重要</p>
<p><span>对于一个公司来说，数据是最重要的东西，所以数据库是重中之重</span></p>
<p><span>从两个方面来说：数据的安全性和数据的可用性</span></p>
<p><span>作为运维人员，这两个问题是一定需要去考虑的，数据的安全性来说，可能不光涉及到运维的环境，及安全运维的防护工作，还涉及到开发的代码安全，需要做代码安全的审计，但从运维的角度来讲，需要通过一些常见能做的手段去保障数据的安全，当然是根据业务及成本考量的，不能说你就一个几千块的网站，上个几十万的防火墙，这肯定没必要</span></p>
<p><span>单从运维来说，要做到运维规范，配置规范，异常请求日志检测及告警、权限最小化、web数据库分离，数据库安全模式等常见方式，根据不同的业务情况有所不同，更多的可以关注公众号，加好友探讨</span></p>
<p><span>数据的可用性，是运维日常工作中接触更多的，解决方案就是备份，备份的方式很多种，快照、脚本备份、异地备份、实时备份、热备、冷备等等，根据自己的需要选择</span></p>
<p><span>备份有个问题就是，要确保备份的可用性，所以要经常定期去做数据可用性检查，用测试环境或预生产环境，去测试数据的可用性</span></p>
<p><span>还有一个就是运维操作的可恢复，很多运维命令是危险的，比如rm -rf，echo &gt;，drop等，没有人是不犯错的，所以，除了敲下回车键的等待1s，做个检查外，最好的方式就是操作前的备份，对于心里没底的事情，更是要谨慎操作，因为有些时候，你的一个回车，是一个公司不能承担的</span></p>
<p>最后</p>
<p><span>以上就是今年的一些总结吧，可能写的不是那么好，但是都是一些谏言，与各位运维朋友共勉吧，2020，早点实现运维自动化</span></p>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/%e8%bf%90%e7%bb%b4%e7%bb%8f%e9%aa%8c%e6%80%bb%e7%bb%93/</guid>
                    </item>
				                    <item>
                        <title>Hexo on CI/CD 本地部署实战攻略</title>
                        <link>https://itprosec.com/community/programer/hexo-on-ci-cd-%e6%9c%ac%e5%9c%b0%e9%83%a8%e7%bd%b2%e5%ae%9e%e6%88%98%e6%94%bb%e7%95%a5/</link>
                        <pubDate>Sat, 27 Jun 2020 16:46:22 +0000</pubDate>
                        <description><![CDATA[在此之前，每次安装调试博客，基本上都是要经历N个流程……
你需要先安装个LAMP/LNMP环境，然后还需要调试大量的参数；
这还没完；你需要选择个合适的博客程序（比如Wordpress、Typecho等），然后又是一番折腾……
好不容易折腾完了，这些基于PHP语言的程序，总归是有点0day漏洞的吧……
然后又开始无限的防御加固之旅，直到最后，折腾到筋疲力竭，纵使再有灵感...]]></description>
                        <content:encoded><![CDATA[<p>在此之前，每次安装调试博客，基本上都是要经历N个流程……</p>
<p>你需要先安装个LAMP/LNMP环境，然后还需要调试大量的参数；</p>
<p>这还没完；你需要选择个合适的博客程序（比如Wordpress、Typecho等），然后又是一番折腾……</p>
<p>好不容易折腾完了，这些基于PHP语言的程序，总归是有点0day漏洞的吧……</p>
<p>然后又开始无限的防御加固之旅，直到最后，折腾到筋疲力竭，纵使再有灵感，也无力去写博文……</p>
<p>其实上面这些就是我的真实写照：装个环境调试就要2个小时，然后还需要各种各样的迁移调试，服务器还需要做加固防止被洞穿了，等费神费力的搬好家，连想写Blog的力气都没有了（<del>这就是你咕了1年半没更新Blog的借口？</del>）</p>
<p>后来也是经过各路大神推荐，从Typecho搬到了Hexo，但发现一个最最最头大的问题：</p>
<p>那就是这玩意没有后台！</p>
<p>没有后台也就意味着，你每更新一次文章，你就需要手动去部署一次文件，然后部署过程中，你总会忘点什么事情或者手残删错文件，然后……一切重来。（</p>
<p>毕竟在座的各位都是有Github账号的人，你说什么，没有？</p>
<p>那你总归知道 git clone 怎么用吧（苦笑</p>
<p>所以今天给Blog除草的同时，也给大家带来一篇基于CI/CD实现自动化博客本地构建更新的教程。</p>
<h2 id="Chapter-01-前言">Chapter 01: 前言</h2>
<p>首先，想要让Hexo实现自动化构建，你需要：</p>
<ul>
<li>一个Git仓库（可以是公有的如GitHub，也可以是私有的如Gitlab CE、Gitea）</li>
<li>一个CI平台（可以是公有的如Travis CI，也可以是私有的如Drone CI）</li>
<li>一个存放生成的静态网页文件的服务器</li>
</ul>
<p>由于国内访问GitHub Pages的速度实在太过感人，故本教程将这些服务全部放在同一台VM上完成。</p>
<p>本教程将使用如下组合方案作为演示环境：</p>
<ul>
<li>系统： Debian 10 (amd64)</li>
<li>Web服务器：Nginx 1.17.10</li>
<li>Node.JS版本：v12.16.4 （<strong>注意暂时不要使用v14版本，可能会导致生成的文件均为0KB，也就是无效文件</strong>）</li>
<li>Git服务器：Gitea</li>
<li>CI服务器：Drone CI</li>
</ul>
<p>准备好了吗？那么现在就开始部署！</p>
<p><strong>小提示：</strong></p>
<p><strong>如果你使用 Linux / macOS 作为你的写作平台，请跳转 Chapter 02.01 ；</strong></p>
<p><strong>如果你使用 Windows 作为你的写作平台，请跳转 Chapter 02.02。</strong></p>
<h2 id="Chapter-02-01-博客撰写平台的准备工作-For-Linux">Chapter 02.01: 博客撰写平台的准备工作 (For Linux)</h2>
<p>首先，Hexo首先作为使用Node.JS语言的博客程序，自然你需要先安装Node.JS和<del>垃圾制造者</del>NPM。</p>
<p>这里推荐使用nvm安装，这样可以无视不同系统之间，自带Node.JS版本不一致的问题。</p>
<p>执行以下命令，安装nvm：</p>
<figure id="code-1593273731167348" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.3/install.sh | bash</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>之后会出现以下提示：</p>
<blockquote>
<p>=&gt; Downloading nvm from git to ‘/root/.nvm’<br />=&gt; 正克隆到 ‘/root/.nvm’…<br />remote: Enumerating objects: 290, done.<br />remote: Counting objects: 100% (290/290), done.<br />remote: Compressing objects: 100% (257/257), done.<br />remote: Total 290 (delta 35), reused 97 (delta 20), pack-reused 0<br />接收对象中: 100% (290/290), 163.27 KiB | 5.44 MiB/s, 完成.<br />处理 delta 中: 100% (35/35), 完成.<br />=&gt; Compressing and cleaning up git repository</p>
<p>=&gt; Appending nvm source string to /root/.bashrc<br />=&gt; Appending bash_completion source string to /root/.bashrc<br />=&gt; Close and reopen your terminal to start using nvm or run the following to use it now:</p>
<p>export NVM_DIR=”$HOME/.nvm”<br /> &amp;&amp; . “$NVM_DIR/nvm.sh” # This loads nvm<br /> &amp;&amp; . “$NVM_DIR/bash_completion” # This loads nvm bash_completion</p>
</blockquote>
<p>出现这样的提示，表示nvm已经安装完成，可以继续下一步的操作了。</p>
<p>之后执行命令，安装<span> </span><code>v12.16.3</code><span> </span>版本的Node.JS：</p>
<figure id="code-1593273731168224" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">nvm install v12.16.3</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>出现以下结果：</p>
<blockquote>
<p>Downloading and installing node v12.16.3…<br />Downloading<span> </span><a href="https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.xz" target="_blank" rel="noopener">https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.xz</a>…<br />################################################################################################################################# 100.0%<br />Computing checksum with sha256sum<br />Checksums matched!<br />Now using node v12.16.3 (npm v6.14.4)<br />Creating default alias: default -&gt; v12.16.3</p>
</blockquote>
<p>到这里，Node.JS已经安装完成了。我们可以尝试验证下Node.JS是否安装成功。</p>
<p>执行命令：</p>
<figure id="code-1593273731168905" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">node -v</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>返回结果：</p>
<blockquote>
<p>v12.16.3</p>
</blockquote>
<p>执行命令：</p>
<figure id="code-1593273731168913" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">npm -v</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>返回结果：</p>
<blockquote>
<p>6.14.4</p>
</blockquote>
<p>如果两条命令都返回了正确的结果，说明Node.JS安装成功。</p>
<p>之后，执行命令，安装Hexo CLI：</p>
<figure id="code-1593273731168933" class="highlight plain hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">npm install hexo-cli -g</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>返回结果：</p>
<blockquote>
<p>/root/.nvm/versions/node/v12.16.3/bin/hexo -&gt; /root/.nvm/versions/node/v12.16.3/lib/node_modules/hexo-cli/bin/hexo<br />npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules/hexo-cli/node_modules/chokidar/node_modules/fsevents):<br />npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for<span> </span><a href="mailto:fsevents@2.1.3">fsevents@2.1.3</a>: wanted {“os”:”darwin”,”arch”:”any”} (current: {“os”:”linux”,”arch”:”x64”})</p>
<p>+ hexo-cli@3.1.0<br />added 81 packages from 322 contributors in 5.927s</p>
</blockquote>
<p>Hexo CLI安装成功。</p>
<p>之后安装 Git ：</p>
<figure id="code-1593273731169909" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">apt-get install git -y</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>到这里，博客撰写平台已经准备好了，我们先放在一旁，稍后继续使用。</p>
<h2 id="Chapter-02-02-博客撰写平台的准备工作-For-Windows">Chapter 02.02: 博客撰写平台的准备工作 (For Windows)</h2>
<p>不过不是每个人都会拥有一台MacBook，也不是每个人都会用Linux作为桌面环境。</p>
<p>大部分人其实都在用Windows的（</p>
<p>所以如果你用的是Windows平台的话，看这里 xD</p>
<p>相对来讲的话，Windows平台上的准备工作会简单很多，</p>
<p>毕竟图形化嘛，点点点就好了，敲命令是什么，听起来就头疼（</p>
<p>首先，你需要下载并安装一堆东西（敲黑板，请准备好下载工具，比如IDM什么的</p>
<p>下载安装Node.JS v12：</p>
<p>如果你人在海外，或者你的网速很好：</p>
<blockquote>
<p><a href="https://nodejs.org/dist/v12.16.3/node-v12.16.3-x64.msi" target="_blank" rel="noopener">https://nodejs.org/dist/v12.16.3/node-v12.16.3-x64.msi</a></p>
</blockquote>
<p>如果你人在国内：</p>
<blockquote>
<p><a href="https://npm.taobao.org/mirrors/node/v12.16.3/node-v12.16.3-x64.msi" target="_blank" rel="noopener">https://npm.taobao.org/mirrors/node/v12.16.3/node-v12.16.3-x64.msi</a></p>
</blockquote>
<p>安装过程取默认值即可。</p>
<p>向导中有个Chocolatey的选择，不用勾选，用不到，反而会让你多花一个小时安装这一个东西的（</p>
<p>安装完成后，打开命令提示符（也就是cmd）</p>
<p>如果你人在海外，或者网速很好，请继续往下看（</p>
<p>如果你人在国内，执行以下命令，将NPM镜像源切换到国内，加速NPM安装过程：</p>
<figure id="code-1593273731169187" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">npm config <span class="hljs-built_in">set</span> registry https://registry.npm.taobao.org</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>然后执行命令，安装Hexo CLI：</p>
<figure id="code-1593273731169986" class="highlight plain hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">npm install -g hexo-cli</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>安装完成后，执行命令，确认安装状态：</p>
<figure id="code-1593273731169339" class="highlight plain hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">hexo version</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>如果你能得到的东西大概长这个样子的：</p>
<blockquote>
<p>hexo-cli: 3.1.0<br />os: Windows_NT 10.0.19041 win32 x64<br />node: 12.16.3<br />v8: 7.8.279.23-node.35<br />uv: 1.34.2<br />zlib: 1.2.11<br />brotli: 1.0.7<br />ares: 1.16.0<br />modules: 72<br />nghttp2: 1.40.0<br />napi: 5<br />llhttp: 2.0.4<br />http_parser: 2.9.3<br />openssl: 1.1.1g<br />cldr: 36.0<br />icu: 65.1<br />tz: 2019c<br />unicode: 12.1</p>
</blockquote>
<p>安装成功。</p>
<p>然后接下来安装Git：</p>
<p>如果你人在海外，或者你的网速很好：</p>
<blockquote>
<p><a href="https://github.com/git-for-windows/git/releases/download/v2.26.2.windows.1/Git-2.26.2-64-bit.exe" target="_blank" rel="noopener">https://github.com/git-for-windows/git/releases/download/v2.26.2.windows.1/Git-2.26.2-64-bit.exe</a></p>
</blockquote>
<p>如果你人在国内：</p>
<blockquote>
<p><a href="https://npm.taobao.org/mirrors/git-for-windows/v2.26.2.windows.1/Git-2.26.2-64-bit.exe" target="_blank" rel="noopener">https://npm.taobao.org/mirrors/git-for-windows/v2.26.2.windows.1/Git-2.26.2-64-bit.exe</a></p>
</blockquote>
<p>安装过程中一路默认值即可<del>（妈妈说过，不要什么东西都往C盘装（</del></p>
<p>到这里，博客撰写平台已经准备好了，我们先放在一旁，稍后继续使用。</p>
<h2 id="Chapter-03-关于博客撰写工具">Chapter 03: 关于博客撰写工具</h2>
<p>Hexo作为使用Markdown语言的博客程序（和Typecho一样），趁手的撰写工具非常重要。</p>
<p>如果你使用 Windows/macOS 平台，个人推荐使用Typora，绝对舒适的Markdown写作体验：</p>
<blockquote>
<p><a href="https://www.typora.io/" target="_blank" rel="noopener">https://www.typora.io/</a></p>
</blockquote>
<p>如果你使用 Linux 平台，什么都别说了，vim天下第一！<del>（被打死</del></p>
<p>总之，萝卜白菜，各有所爱；</p>
<p>别人推荐的不一定是最好的，适合自己的才是（</p>
<h2 id="Chapter-04-Gitea-Git服务器安装">Chapter 04: Gitea - Git服务器安装</h2>
<p>从现在开始，才算是进入了重头戏：CI/CD平台的搭建与调试。</p>
<p>首先，你需要一个前端Web服务器作为反代工具：</p>
<p>至于用什么，看你使用习惯了（</p>
<p>本文以Nginx为例，安装过程不在本文的范围内<del>（什么，你问我怎么装？宝塔/LAMP/AppNode/Oneinstack它们不香么（被榨汁</del></p>
<p>然后我们安装Git服务器：Gitea。</p>
<p><strong>（小提示：从此处开始，所有涉及到的路径非固定值，如果你有较强的动手能力，可以尝试手动更换到你喜欢的路径）</strong></p>
<p>首先下载Gitea：</p>
<figure id="code-1593273731169569" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span><br /><span class="line">3</span></pre>
</td>
<td class="code">
<pre><span class="line">mkdir -p /data/gitea/{bin,<span class="hljs-built_in">log</span>}</span><br /><span class="line">wget -O /data/gitea/bin/gitea https://dl.gitea.io/gitea/1.11.5/gitea-1.11.5-linux-amd64</span><br /><span class="line">chmod +x /data/gitea/bin/gitea</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>然后安装后台服务管理器supervisor：</p>
<figure id="code-1593273731170609" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">apt-get install supervisor -y</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p><strong>（小提示：你也可以选择其他喜欢的方式托管后台服务，具体请参考Gitea官方文档：<span> </span><a href="https://docs.gitea.io/zh-cn/linux-service/" target="_blank" rel="noopener">https://docs.gitea.io/zh-cn/linux-service/</a><span> </span>）</strong></p>
<p>之后，新建服务项目：</p>
<figure id="code-1593273731170603" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">vim /etc/supervisor/conf.d/Gitea.conf</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>里面写入如下内容：</p>
<figure id="code-15932737311704" class="highlight properties hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span><br /><span class="line">3</span><br /><span class="line">4</span><br /><span class="line">5</span><br /><span class="line">6</span><br /><span class="line">7</span><br /><span class="line">8</span></pre>
</td>
<td class="code">
<pre><span class="line"><span class="hljs-meta"></span></span><br /><span class="line"><span class="hljs-attr">directory</span> = <span class="hljs-string">/data/gitea/</span></span><br /><span class="line"><span class="hljs-attr">command</span> = <span class="hljs-string">/data/gitea/bin/gitea --config /data/gitea/conf/app.ini --custom-path /data/gitea/custom --work-path /data/gitea/</span></span><br /><span class="line"><span class="hljs-attr">autostart</span> = <span class="hljs-string">true</span></span><br /><span class="line"><span class="hljs-attr">autorestart</span> = <span class="hljs-string">true</span></span><br /><span class="line"><span class="hljs-attr">startsecs</span> = <span class="hljs-string">3</span></span><br /><span class="line"><span class="hljs-attr">user</span> = <span class="hljs-string">gitea</span></span><br /><span class="line"><span class="hljs-attr">environment</span> = <span class="hljs-string">HOME="/data/gitea/home", USER="gitea"</span></span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>之后保存退出。</p>
<p>新建一个专门用来跑Gitea的用户：</p>
<figure id="code-1593273731170212" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span></pre>
</td>
<td class="code">
<pre><span class="line">addgroup --system --quiet gitea</span><br /><span class="line">adduser --quiet --system --disabled-login --ingroup gitea --home /data/gitea/home --no-create-home gitea</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p><strong>（小提示：如果你不喜欢单独新建用户运行程序，或者想要简化部署，完全可以使用root用户运行，但这样安全性会稍微降低）</strong></p>
<p>调整Gitea目录的用户权限：</p>
<figure id="code-1593273731171557" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">chown -R gitea:gitea /data/gitea/</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>之后重启Supervisor，将Gitea跑起来：</p>
<figure id="code-1593273731171295" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">service supervisor restart</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>或者可以执行命令，先测试是否能够正常启动，然后再重启Supervisor：</p>
<figure id="code-1593273731171627" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">/data/gitea/bin/gitea --config /data/gitea/conf/app.ini --custom-path /data/gitea/custom --work-path /data/gitea/</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>确认能够正常启动后，访问<span> </span><strong>http://你的IP地址:3000/</strong><span> </span>，打开Gitea页面：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/1.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/1.png" alt="" /></a></p>
<p>如果能看到这个页面，说明Gitea启动成功，可以继续配置过程。</p>
<p>点击右上角的注册（点登录也可以），会来到初始化配置向导：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/2.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/2.png" alt="" /></a></p>
<p>如果你的部署规模不太大的话，数据库类型选择SQLite3即可。</p>
<p>如果部署在大规模的环境（比如你需要用Gitea装其他的东西，或者多人协作使用），建议使用MySQL部署。</p>
<p>一般设置中的<span> </span><strong>Gitea 基本 URL</strong><span> </span>请填写公网可达的URL：</p>
<ul>
<li>如果你使用公网IP访问，填写格式为<span> </span><code>http://你的IP地址:3000</code><span> </span>（端口号请和<span> </span><strong>HTTP 服务端口</strong><span> </span>保持一致）</li>
<li>如果你使用域名访问（前置反代），请填写实际可访问的域名</li>
</ul>
<p>其他的参数，按需填写。</p>
<p>之后下面的<span> </span><strong>管理员账号设置</strong><span> </span>中，输入用户名密码邮箱，作为Gitea系统的第一个账号，也同时作为Gitea的管理员账号。（不能是admin）</p>
<p>在配置成功后，点击最下方的<span> </span><strong>立即安装</strong><span> </span>完成配置向导。</p>
<p>如果一切顺利，将会来到Gitea的控制面板：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/3.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/3.png" alt="" /></a></p>
<p>到此Gitea的初始配置完成，我们继续来配置Drone CI。</p>
<h2 id="Chapter-05-Drone-CI-CI服务器搭建">Chapter 05: Drone CI - CI服务器搭建</h2>
<p>在我们完成Gitea搭建后，我们已经拥有了属于我们自己的Git服务器。</p>
<p>那么接下来，为了实现CI/CD的伟大目标（不是），我们继续开始CI服务器的搭建。</p>
<p>首先点击右上角的头像，下拉列表选择<span> </span><strong>设置</strong><span> </span>，打开用户设置面板：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/4.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/4.png" alt="" /></a></p>
<p>之后导航栏点击<span> </span><strong>应用</strong><span> </span>，打开应用授权设置：</p>
<p>拉到最下方，我们可以看到<span> </span><strong>管理 OAuth2 应用程序</strong><span> </span>一项：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/5.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/5.png" alt="" /></a></p>
<p>在此，我们需要为Drone CI创建OAuth2应用授权：</p>
<ul>
<li>应用名称填写任意名称即可 （比如<span> </span><code>Drone</code><span> </span>）</li>
<li>重定向URI请填写<span> </span><strong>可以访问到你的Drone CI</strong><span> </span>的地址，具体填写方法接下来讲解</li>
</ul>
<p>如果使用公网IP直接访问你的Drone CI，请填写<span> </span><code>http://你的IP地址:6080</code><span> </span>（地址和端口号非唯一，可根据实际需要修改，具体参考下文）；</p>
<p>如果使用反代访问（域名访问）请填写<span> </span><code>https://drone.example.com/login</code><span> </span>（示例域名，请根据实际需要填写）</p>
<p><strong>（小提示：Drone不支持Path访问，例如<span> </span><code>https://myserver.example.com/drone/login</code><span> </span>，请使用二级域名访问，例如<span> </span><code>https://drone.example.com/login</code><span> </span>）</strong></p>
<p>输入完成后，点击<span> </span><strong>创建应用</strong><span> </span>，完成配置。</p>
<p>创建完成后，会跳转到<span> </span><strong>编辑 OAuth2 应用程序</strong><span> </span>页面，<strong>请在此使用记事本类的工具立即保存 客户端ID 和 客户端密钥 信息</strong>，这一组密钥你将只有这一次能看见，刷新或者重新打开页面，客户端密钥都会消失，忘记密钥只能点击<span> </span><strong>重新生成密钥</strong><span> </span>以进行重置！</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/6.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/6.png" alt="" /></a></p>
<p>保存好密钥信息后，我们回到Shell终端，继续部署Drone CI。</p>
<p>接下来，我们使用命令，来生成Drone使用的Token：</p>
<figure id="code-1593273731171581" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">openssl rand -hex 16</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>生成如下结果：</p>
<blockquote>
<p>bea26a2221fd8090ea38720fc445eca6</p>
</blockquote>
<p>这32位Token同样非常重要，同样保存下来。</p>
<p>在此之后，因为Drone CI是Docker-Based CI，所以我们需要安装Docker。</p>
<p>执行一下命令，安装Docker：</p>
<figure id="code-1593273731171315" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">curl -fsL get.docker.com | bash</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>会得到如下的结果</p>
<blockquote>
<p># Executing docker install script, commit: 26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c<br />+ sh -c ‘apt-get update -qq &gt;/dev/null’<br />+ sh -c ‘DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl &gt;/dev/null’<br />+ sh -c ‘curl -fsSL “<a href="https://download.docker.com/linux/debian/gpg%22" target="_blank" rel="noopener">https://download.docker.com/linux/debian/gpg"</a><span> </span>| apt-key add -qq - &gt;/dev/null’<br />Warning: apt-key output should not be parsed (stdout is not a terminal)<br />+ sh -c ‘echo “deb <span> </span><a href="https://download.docker.com/linux/debian" target="_blank" rel="noopener">https://download.docker.com/linux/debian</a><span> </span>buster stable” &gt; /etc/apt/sources.list.d/docker.list’<br />+ sh -c ‘apt-get update -qq &gt;/dev/null’<br />+ ‘’<br />+ sh -c ‘apt-get install -y -qq –no-install-recommends docker-ce &gt;/dev/null’</p>
</blockquote>
<p>稍后即可完成Docker的安装。</p>
<p>我们现在开始正式部署Drone CI：</p>
<p>首先，我们收集部署Drone所需要的信息：</p>
<ul>
<li>DRONE_GITEA_SERVER: Gitea服务器的<strong>公网可达地址</strong></li>
<li>DRONE_GITEA_CLIENT_ID: OAuth2 应用程序中的客户端ID</li>
<li>DRONE_GITEA_CLIENT_SECRET: OAuth2 应用程序中的客户段密钥</li>
<li>DRONE_RPC_SECRET: Drone CI Token (就是刚才生成的32位Token)</li>
<li>DRONE_SERVER_HOST: Drone CI的公网可达地址（完整的URL）</li>
<li>DRONE_SERVER_PROTO: Drone CI访问使用的协议 (http/https)</li>
</ul>
<p>这些参数看起来很头疼？别急，慢慢来（</p>
<p>我给几个示例：</p>
<ul>
<li>Example 1: 所有的服务都使用Nginx反代（Behind Nginx）</li>
</ul>
<blockquote>
<p>Gitea服务器地址：<code>https://gitea.example.com/</code></p>
<p>Drone服务器地址：<code>https://drone.example.com/</code></p>
<p>DRONE_GITEA_SERVER:<span> </span><code>https://gitea.example.com/</code></p>
<p>DRONE_GITEA_CLIENT_ID:<span> </span><code>ce2260d6-f800-4dbe-96d2-194778574814</code></p>
<p>DRONE_GITEA_CLIENT_SECRET:<span> </span><code>wIfoK0ZZ1UclmODEtoom0MQIqvBbw-RNAW0eHqjGd9g=</code></p>
<p>DRONE_SERVER_HOST:<span> </span><code>drone.example.com</code></p>
<p>DRONE_SERVER_PROTO:<span> </span><code>https</code></p>
</blockquote>
<ul>
<li>Example 2: 所有服务都使用IP+端口</li>
</ul>
<blockquote>
<p>Gitea服务器地址：<code>http://100.100.100.100:3000/</code></p>
<p>Drone服务器地址：<code>http://100.100.100.100:6080/</code></p>
<p>DRONE_GITEA_SERVER:<span> </span><code>http://100.100.100.100:3000/</code></p>
<p>DRONE_GITEA_CLIENT_ID:<span> </span><code>ce2260d6-f800-4dbe-96d2-194778574814</code></p>
<p>DRONE_GITEA_CLIENT_SECRET:<span> </span><code>wIfoK0ZZ1UclmODEtoom0MQIqvBbw-RNAW0eHqjGd9g=</code></p>
<p>DRONE_SERVER_HOST:<span> </span><code>100.100.100.100:6080</code></p>
<p>DRONE_SERVER_PROTO:<span> </span><code>http</code></p>
</blockquote>
<p>执行以下命令，部署Drone CI：（请将对应的变量替换为实际值）</p>
<figure id="code-1593273731172466" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span><br /><span class="line">3</span><br /><span class="line">4</span><br /><span class="line">5</span><br /><span class="line">6</span><br /><span class="line">7</span><br /><span class="line">8</span><br /><span class="line">9</span><br /><span class="line">10</span><br /><span class="line">11</span><br /><span class="line">12</span><br /><span class="line">13</span><br /><span class="line">14</span></pre>
</td>
<td class="code">
<pre><span class="line">docker run \</span><br /><span class="line">  --volume=/var/lib/drone:/data \</span><br /><span class="line">  --env=DRONE_GITEA_SERVER=<span class="hljs-string">"<span class="hljs-variable">$DRONE_GITEA_SERVER</span>"</span> \</span><br /><span class="line">  --env=DRONE_GITEA_CLIENT_ID=<span class="hljs-string">"<span class="hljs-variable">$DRONE_GITEA_CLIENT_ID</span>"</span> \</span><br /><span class="line">  --env=DRONE_GITEA_CLIENT_SECRET=<span class="hljs-string">"<span class="hljs-variable">$DRONE_GITEA_CLIENT_SECRET</span>"</span> \</span><br /><span class="line">  --env=DRONE_RPC_SECRET=<span class="hljs-string">"<span class="hljs-variable">$DRONE_RPC_SECRET</span>"</span> \</span><br /><span class="line">  --env=DRONE_SERVER_HOST=<span class="hljs-string">"<span class="hljs-variable">$DRONE_SERVER_HOST</span>"</span> \</span><br /><span class="line">  --env=DRONE_SERVER_PROTO=<span class="hljs-string">"<span class="hljs-variable">$DRONE_SERVER_PROTO</span>"</span> \</span><br /><span class="line">  --publish=6080:80 \</span><br /><span class="line">  --publish=6043:443 \</span><br /><span class="line">  --restart=always \</span><br /><span class="line">  --detach=<span class="hljs-literal">true</span> \</span><br /><span class="line">  --name=drone \</span><br /><span class="line">  drone/drone:1</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>在启动成功后，使用命令：</p>
<figure id="code-1593273731172348" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">docker logs drone</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>确认是否部署成功，返回如下结果：</p>
<blockquote>
<p>{“level”:”info”,”msg”:”main: internal scheduler enabled”,”time”:”2020-05-15T11:04:01Z”}<br />{“acme”:false,”host”:”<code>100.100.100.100:6080</code>“,”level”:”info”,”msg”:”starting the http server”,”port”:”:80”,”proto”:”http”,”time”:”2020-05-15T11:04:01Z”,”url”:”<code>http://100.100.100.100:6080</code>“}<br />{“interval”:”30m0s”,”level”:”info”,”msg”:”starting the cron scheduler”,”time”:”2020-05-15T11:04:01Z”}</p>
</blockquote>
<p>则证明部署成功。</p>
<p>接下来，在<span> </span><strong>登录你的Gitea账号</strong><span> </span>的情况下，打开Drone CI的WebUI地址（根据实际情况而定）：</p>
<blockquote>
<p><a href="https://drone.example.com/" target="_blank" rel="noopener">https://drone.example.com/</a></p>
</blockquote>
<blockquote>
<p><a href="http://100.100.100.100:3000/" target="_blank" rel="noopener">http://100.100.100.100:3000/</a></p>
</blockquote>
<p>如果出现以下错误提示：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/7.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/7.png" alt="" /></a></p>
<p>则说明你填写的信息有误（比如Drone CI启动参数和Gitea中设定的OAuth2参数不一致），此时可以删除Drone CI的Docker实例并尝试重新部署：</p>
<figure id="code-1593273731172957" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span></pre>
</td>
<td class="code">
<pre><span class="line">docker <span class="hljs-built_in">kill</span> drone</span><br /><span class="line">docker rm drone</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>如果一切顺利，会出现以下提示：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/8.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/8.png" alt="" /></a></p>
<p>点击<span> </span><strong>应用授权</strong><span> </span>即可完成Drone CI到Gitea的注册。</p>
<p>在点击应用授权之后，如果能够顺利跳转到以下页面：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/9.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/9.png" alt="" /></a></p>
<p>则说明Drone CI服务器部署成功。</p>
<p>接下来，仅仅有一个Drone CI服务器是不够的，我们还需要部署对应的Runner才能实现自动化操作。</p>
<p>简单来讲，我们拥有了“指挥官”是没有用的，我们还需要有“士兵和装备”才能打仗。</p>
<p>还记得上面我们刚刚用到的那些变量参数么？</p>
<p>没错，我们要复用其中的部分参数：</p>
<ul>
<li>DRONE_RPC_PROTO: Drone CI访问使用的协议 (http/https)</li>
<li>DRONE_RPC_HOST: Drone CI的<strong>公网可达地址</strong>，<strong>不要带http/https前缀</strong></li>
<li>DRONE_RPC_SECRET: Drone CI Token (32位Token)</li>
<li>DRONE_RUNNER_CAPACITY: Drone Runner 单次可以并发运行的任务数量</li>
<li>DRONE_RUNNER_NAME: Drone Runner的名称 (随意设置)</li>
</ul>
<p>执行以下命令，部署Drone Runner：（请将对应的变量替换为实际值）</p>
<figure id="code-159327373117263" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span><br /><span class="line">3</span><br /><span class="line">4</span><br /><span class="line">5</span><br /><span class="line">6</span><br /><span class="line">7</span><br /><span class="line">8</span><br /><span class="line">9</span><br /><span class="line">10</span><br /><span class="line">11</span></pre>
</td>
<td class="code">
<pre><span class="line">docker run -d \</span><br /><span class="line">  -v /var/run/docker.sock:/var/run/docker.sock \</span><br /><span class="line">  -e DRONE_RPC_PROTO=<span class="hljs-string">"<span class="hljs-variable">$DRONE_RPC_PROTO</span>"</span> \</span><br /><span class="line">  -e DRONE_RPC_HOST=<span class="hljs-string">"<span class="hljs-variable">$DRONE_RPC_HOST</span>"</span> \</span><br /><span class="line">  -e DRONE_RPC_SECRET=<span class="hljs-string">"<span class="hljs-variable">$DRONE_RPC_SECRET</span>"</span> \</span><br /><span class="line">  -e DRONE_RUNNER_CAPACITY=<span class="hljs-string">"<span class="hljs-variable">$DRONE_RUNNER_CAPACITY</span>"</span> \</span><br /><span class="line">  -e DRONE_RUNNER_NAME=<span class="hljs-string">"<span class="hljs-variable">$DRONE_RUNNER_NAME</span>"</span> \</span><br /><span class="line">  -p 6030:3000 \</span><br /><span class="line">  --restart always \</span><br /><span class="line">  --name runner \</span><br /><span class="line">  drone/drone-runner-docker:1</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>在启动成功后，使用命令：</p>
<figure id="code-159327373117220" class="highlight plain hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">docker logs runner</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>如果得到如下返回结果：</p>
<blockquote>
<p>time=”2020-05-15T11:21:09Z” level=info msg=”starting the server” addr=”:3000”<br />time=”2020-05-15T11:21:09Z” level=info msg=”successfully pinged the remote server”<br />time=”2020-05-15T11:21:09Z” level=info msg=”polling the remote server” arch=amd64 capacity=2 endpoint=”<code>http://100.100.100.100:6080</code>“ kind=pipeline os=linux type=docker</p>
</blockquote>
<p>则说明Drone Runner启动成功。</p>
<p>至此，已经完成了Drone CI的配置，以及与Gitea的对接。</p>
<p>是不是有点迫不及待的准备开始Hexo的安装配置了？那么，Now Let’s GO!</p>
<h2 id="Chapter-06-Hexo-初始化博客">Chapter 06: Hexo - 初始化博客</h2>
<p>服务器端的工作暂时告一段落，我们先回到客户端（也就是博客撰写平台）上。</p>
<p>首先，我们前往Gitea页面，创建Hexo仓库。</p>
<p>点击右上角的<span> </span><strong>+</strong><span> </span>号，然后点击<span> </span><strong>创建仓库</strong><span> </span>：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/10.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/10.png" alt="" /></a></p>
<p>之后在创建仓库页面中，输入你的仓库名称；</p>
<p>由于仓库内会包括关于你的服务器的某些敏感数据（比如服务器地址、服务器密码等），建议勾选<span> </span><strong>将仓库设为私有</strong><span> </span>，将仓库转换为私有仓库。</p>
<p>仓库描述为可选项，可以写上，也可以不写。</p>
<p>完成后点击<span> </span><strong>创建仓库</strong><span> </span>，完成仓库的初始化配置。</p>
<p>之后我们会来到仓库页面中，由于新建的仓库为空仓库，所以我们需要将这个空仓库clone到本地，以备进行Hexo的安装操作：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/11.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/11.png" alt="" /></a></p>
<p>如果你在Chapter 02中安装好了<span> </span><code>hexo-cli</code>，请继续往下看；</p>
<p>如果你还没安装好<span> </span><code>hexo-cli</code>，仅需一个简单的命令即可：</p>
<figure id="code-1593273731173610" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">npm install -g hexo-cli</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>我们首先创建一个新文件夹（因为Hexo的初始化<strong>必须在一个空文件夹中</strong>）：</p>
<figure id="code-159327373117336" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">mkdir myhexoblog</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>之后进入该文件夹中，执行命令，初始化我们的hexo blog：</p>
<figure id="code-1593273731173890" class="highlight plain hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span></pre>
</td>
<td class="code">
<pre><span class="line">hexo init</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>会得到这样的结果：</p>
<blockquote>
<p>INFO Cloning hexo-starter<span> </span><code>https://github.com/hexojs/hexo-starter.git</code><br />Cloning into ‘C:\Users\iLemonrain\Desktop\myhexoblog’…<br />remote: Enumerating objects: 30, done.<br />remote: Counting objects: 100% (30/30), done.<br />remote: Compressing objects: 100% (24/24), done.<br />Receiving objects: 84% (136/161)sed 12 (delta 4), pack-reused 131 eceiving objects: 83% (134/161)<br />Receiving objects: 100% (161/161), 31.79 KiB | 161.00 KiB/s, done.<br />Resolving deltas: 100% (74/74), done.<br />Submodule ‘themes/landscape’ (<code>https://github.com/hexojs/hexo-theme-landscape.git</code>) registered for path ‘themes/landscape’<br />Cloning into ‘C:/Users/iLemonrain/Desktop/myhexoblog/themes/landscape’…<br />remote: Enumerating objects: 4, done.<br />remote: Counting objects: 100% (4/4), done.<br />remote: Compressing objects: 100% (4/4), done.<br />remote: Total 1067 (delta 0), reused 0 (delta 0), pack-reused 1063<br />Receiving objects: 100% (1067/1067), 3.22 MiB | 653.00 KiB/s, done.<br />Resolving deltas: 100% (585/585), done.<br />Submodule path ‘themes/landscape’: checked out ‘73a23c51f8487cfcd7c6deec96ccc7543960d350’<br />[32mINFO [39m Install dependencies</p>
<blockquote>
<p><a href="mailto:ejs@2.7.4">ejs@2.7.4</a><span> </span>postinstall C:\Users\iLemonrain\Desktop\myhexoblog\node_modules\ejs<br />node ./postinstall.js</p>
</blockquote>
<p>Thank you for installing EJS: built with the Jake JavaScript build tool (<code>https://jakejs.com/</code>)</p>
<p>npm notice created a lockfile as package-lock.json. You should commit this file.<br />npm WARN optional SKIPPING OPTIONAL DEPENDENCY:<span> </span><a href="mailto:fsevents@2.1.3">fsevents@2.1.3</a><span> </span>(node_modules\fsevents):<br />npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for<span> </span><a href="mailto:fsevents@2.1.3">fsevents@2.1.3</a>: wanted {“os”:”darwin”,”arch”:”any”} (current: {“os”:”win32”,”arch”:”x64”})</p>
<p>added 253 packages from 450 contributors in 6.318s</p>
<p>5 packages are looking for funding<br />run `npm fund` for details</p>
<p>INFO Start blogging with Hexo!</p>
</blockquote>
<p>则说明Hexo初始化完成。</p>
<p>我们可以先看下Hexo长什么样子，在此目录下执行命令：</p>
<figure id="code-1593273731173470" class="highlight plain hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span></pre>
</td>
<td class="code">
<pre><span class="line">hexo generate</span><br /><span class="line">hexo server</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>然后访问<span> </span><a href="http://localhost:4000/" target="_blank" rel="noopener">http://localhost:4000</a><span> </span>打开看看：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/12.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/12.png" alt="" /></a></p>
<p>没错！简单的几个命令，我们就成功的创建了属于自己的Blog！</p>
<p>不过 “革命尚未成功，同志仍需努力”，我们的目标是星辰大海的嘛（</p>
<p>在命令行下按下两次 Ctrl+C ，停止Hexo服务器的运行，我们接下来继续配置Git仓库和Drone CI：</p>
<p>打开Drone CI控制面板：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/9.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/9.png" alt="" /></a></p>
<p>有的人会疑惑，为什么Repo列表还是空白的？</p>
<p>不用紧张，点击右上角的<span> </span><strong>SYNC</strong><span> </span>就可以啦~</p>
<p>稍待一会，Gitea里面的Repo列表将会被同步过来；如果超过一分钟没有反应，请手动刷新：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/13.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/13.png" alt="" /></a></p>
<p>我们点击这个Repo，打开配置页面：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/14.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/14.png" alt="" /></a></p>
<p>由于我们没有为此仓库启用CI/CD能力，所以这时只需要点击<span> </span><strong>ACTIVATE REPOSITORY</strong><span> </span>就可以啦~</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/15.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/15.png" alt="" /></a></p>
<p>之后往下翻，会有个<span> </span><strong>Secrets</strong><span> </span>选项卡：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/16.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/16.png" alt="" /></a></p>
<p>这里，我们将会用来保存CI/CD过程中，不想被其他人知道的“秘密”，比如服务器的连接方式、一些不想被人看见的配置参数等。</p>
<p>我们来创建如下Secret：</p>
<ul>
<li>ssh_host: 100.100.100.100 (部署目标服务器的地址)</li>
<li>ssh_password: mypassword123 (部署目标服务器的登录密码)</li>
<li>ssh_key: —–BEGIN RSA PRIVATE KEY—– (部署目标服务器的私钥，如果你使用密钥登录)</li>
<li>ssh_passphrase: keypass456 (部署目标服务器私钥密码，如果你使用密钥登录)</li>
</ul>
<p>将这些信息填写进Secret中，每写一条，点击一次<span> </span><strong>ADD A SECRET</strong><span> </span>，直到全部添加完成：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/17.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/17.png" alt="" /></a></p>
<p>这样就完成了自动构建的配置，接下来，我们为此仓库写对应的CI/CD文件（.drone.yml）：</p>
<p>参考配置文件如下：</p>
<figure id="code-159327373117488" class="highlight yaml hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span><br /><span class="line">3</span><br /><span class="line">4</span><br /><span class="line">5</span><br /><span class="line">6</span><br /><span class="line">7</span><br /><span class="line">8</span><br /><span class="line">9</span><br /><span class="line">10</span><br /><span class="line">11</span><br /><span class="line">12</span><br /><span class="line">13</span><br /><span class="line">14</span><br /><span class="line">15</span><br /><span class="line">16</span><br /><span class="line">17</span><br /><span class="line">18</span><br /><span class="line">19</span><br /><span class="line">20</span><br /><span class="line">21</span><br /><span class="line">22</span><br /><span class="line">23</span><br /><span class="line">24</span><br /><span class="line">25</span><br /><span class="line">26</span><br /><span class="line">27</span><br /><span class="line">28</span><br /><span class="line">29</span><br /><span class="line">30</span><br /><span class="line">31</span><br /><span class="line">32</span><br /><span class="line">33</span><br /><span class="line">34</span><br /><span class="line">35</span><br /><span class="line">36</span><br /><span class="line">37</span><br /><span class="line">38</span><br /><span class="line">39</span><br /><span class="line">40</span><br /><span class="line">41</span><br /><span class="line">42</span><br /><span class="line">43</span><br /><span class="line">44</span><br /><span class="line">45</span><br /><span class="line">46</span><br /><span class="line">47</span><br /><span class="line">48</span><br /><span class="line">49</span><br /><span class="line">50</span><br /><span class="line">51</span><br /><span class="line">52</span><br /><span class="line">53</span><br /><span class="line">54</span><br /><span class="line">55</span><br /><span class="line">56</span><br /><span class="line">57</span><br /><span class="line">58</span></pre>
</td>
<td class="code">
<pre><span class="line"><span class="hljs-attr">kind:</span> <span class="hljs-string">pipeline</span></span><br /><span class="line"><span class="hljs-attr">type:</span> <span class="hljs-string">docker</span></span><br /><span class="line"><span class="hljs-attr">name:</span> <span class="hljs-string">default</span></span><br /><span class="line"></span><br /><span class="line"><span class="hljs-attr">steps:</span></span><br /><span class="line"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Hexo</span> <span class="hljs-string">Build</span></span><br /><span class="line">  <span class="hljs-attr">image:</span> <span class="hljs-string">node:12-alpine</span></span><br /><span class="line">  <span class="hljs-attr">commands:</span></span><br /><span class="line">  <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span></span><br /><span class="line">  <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">build</span></span><br /><span class="line"></span><br /><span class="line"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">SCP</span> <span class="hljs-string">File</span> <span class="hljs-string">Transfer</span></span><br /><span class="line">  <span class="hljs-attr">image:</span> <span class="hljs-string">appleboy/drone-scp</span></span><br /><span class="line">  <span class="hljs-attr">settings:</span></span><br /><span class="line">    <span class="hljs-attr">target:</span> <span class="hljs-string">/data/mywebroot/</span></span><br /><span class="line">    <span class="hljs-attr">source:</span> <span class="hljs-string">./public</span></span><br /><span class="line">    <span class="hljs-attr">host:</span> </span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_host</span></span><br /><span class="line">    <span class="hljs-attr">port:</span> </span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_port</span></span><br /><span class="line">    <span class="hljs-attr">username:</span> </span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_username</span></span><br /><span class="line">    <span class="hljs-attr">password:</span></span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_password</span></span><br /><span class="line">    <span class="hljs-attr">key:</span></span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_key</span></span><br /><span class="line">    <span class="hljs-attr">passphrase:</span></span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_keypass</span></span><br /><span class="line">    <span class="hljs-attr">rm:</span> <span class="hljs-literal">true</span></span><br /><span class="line">  <span class="hljs-attr">when:</span></span><br /><span class="line">    <span class="hljs-attr">branch:</span></span><br /><span class="line">    <span class="hljs-bullet">-</span> <span class="hljs-string">master</span></span><br /><span class="line">    <span class="hljs-attr">event:</span></span><br /><span class="line">      <span class="hljs-attr">exclude:</span></span><br /><span class="line">      <span class="hljs-bullet">-</span> <span class="hljs-string">pull_request</span></span><br /><span class="line">      </span><br /><span class="line"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Web</span> <span class="hljs-string">Deploy</span></span><br /><span class="line">  <span class="hljs-attr">image:</span> <span class="hljs-string">appleboy/drone-ssh</span></span><br /><span class="line">  <span class="hljs-attr">settings:</span></span><br /><span class="line">    <span class="hljs-attr">host:</span> </span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_host</span></span><br /><span class="line">    <span class="hljs-attr">port:</span> </span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_port</span></span><br /><span class="line">    <span class="hljs-attr">username:</span> </span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_username</span></span><br /><span class="line">    <span class="hljs-attr">password:</span></span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_password</span></span><br /><span class="line">    <span class="hljs-attr">key:</span></span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_key</span></span><br /><span class="line">    <span class="hljs-attr">passphrase:</span></span><br /><span class="line">      <span class="hljs-attr">from_secret:</span> <span class="hljs-string">ssh_keypass</span></span><br /><span class="line">    <span class="hljs-attr">script:</span></span><br /><span class="line">      <span class="hljs-bullet">-</span> <span class="hljs-string">mv</span> <span class="hljs-string">/data/mywebroot/public/*</span> <span class="hljs-string">/data/mywebroot/</span></span><br /><span class="line">      <span class="hljs-bullet">-</span> <span class="hljs-string">rm</span> <span class="hljs-string">-rf</span> <span class="hljs-string">/data/mywebroot/public/</span></span><br /><span class="line">      </span><br /><span class="line"><span class="hljs-attr">trigger:</span></span><br /><span class="line">  <span class="hljs-attr">event:</span></span><br /><span class="line">  <span class="hljs-bullet">-</span> <span class="hljs-string">push</span></span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p><strong>（小提示：如果你使用用户名+密码登录，参数选取host+port+username+password；如果你使用用户名+密钥登录，参数选取host+port+username+key；如果你使用用户名+密钥+密钥密码登录；参数选取host+port+username+key+passphrase。）</strong></p>
<p>将Drone配置文件放在Hexo同目录下，即可完成Hexo自动化构建配置。</p>
<p>接下来，我们将这个本地仓库与Gitea上的仓库进行初始化同步：</p>
<figure id="code-1593273731174752" class="highlight bash hljs">
<figcaption class="level is-mobile">
<div class="level-left"> </div>
<div class="level-right"> </div>
</figcaption>
<div class="highlight-body">
<table>
<tbody>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br /><span class="line">2</span><br /><span class="line">3</span><br /><span class="line">4</span><br /><span class="line">5</span></pre>
</td>
<td class="code">
<pre><span class="line">git init</span><br /><span class="line">git add .</span><br /><span class="line">git commit -m <span class="hljs-string">"first commit"</span></span><br /><span class="line">git remote add origin http://100.100.100.100:3000/ilemonrain/myhexoblog.git</span><br /><span class="line">git push -u origin master</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</figure>
<p>在弹出的登录提示中，输入你的 Gitea用户名和密码 ，即可完成初始化同步。</p>
<p>在完成配置，推送到仓库的瞬间，Gitea会自动触发Drone CI的构建请求，Drone CI会根据提交的最新分支，自动进行构建，就像这样：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/18.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/18.png" alt="" /></a></p>
<p>此时去打开你的Blog，发现是不是已经成功刷出来刚构建好的Blog啦：</p>
<p><a class="gallery-item" href="https://blog.ilemonrain.com/linux/hexo-with-cicd/19.png"><img src="https://blog.ilemonrain.com/linux/hexo-with-cicd/19.png" alt="" /></a></p>
<p>从现在开始，你只需要使用本地Markdown编辑器，编写好的文章直接使用Git推送到仓库，之后的事情，就拜托“高科技”啦~</p>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/hexo-on-ci-cd-%e6%9c%ac%e5%9c%b0%e9%83%a8%e7%bd%b2%e5%ae%9e%e6%88%98%e6%94%bb%e7%95%a5/</guid>
                    </item>
				                    <item>
                        <title> 如何在各个平台下挂载WebDAV</title>
                        <link>https://itprosec.com/community/programer/webdav-%e5%a6%82%e4%bd%95%e5%9c%a8%e5%90%84%e4%b8%aa%e5%b9%b3%e5%8f%b0%e4%b8%8b%e6%8c%82%e8%bd%bdwebdav/</link>
                        <pubDate>Sun, 03 May 2020 12:42:20 +0000</pubDate>
                        <description><![CDATA[WebDAV
 
这是什么？有什么用？
 
Linux
Centos &amp; Fedora &amp; RedHat
 复制
1
yum -y install davfs2
其他的比如Ubuntu之类的
 复制
1
apt-get -y install davfs2
安装完davfs2之后执行
 复制
123
sed -i &#039;s/# use_...]]></description>
                        <content:encoded><![CDATA[<h1>WebDAV</h1>
<div data-unique="这是什么？有什么用？"> </div>
<h2>这是什么？有什么用？</h2>
<p><a href="https://zh.wikipedia.org/wiki/WebDAV" target="_blank" rel="noopener">https://zh.wikipedia.org/wiki/WebDAV</a></p>
<div data-unique="Linux"> </div>
<h2>Linux</h2>
<p>Centos &amp; Fedora &amp; RedHat</p>
<pre><button class="btn-copy-code" title="" data-clipboard-target="#code-0" data-original-title=""><i class="fa fa-copy"></i> 复制</button></pre>
<div class="pre-row">1</div>
<div id="code-0" class="pre-div"><code class="language-bash hljs">yum -y install davfs2</code></div>
<p>其他的比如Ubuntu之类的</p>
<pre><button class="btn-copy-code" title="" data-clipboard-target="#code-1" data-original-title=""><i class="fa fa-copy"></i> 复制</button></pre>
<div class="pre-row">1</div>
<div id="code-1" class="pre-div"><code class="language-bash hljs">apt-get -y install davfs2</code></div>
<p>安装完davfs2之后执行</p>
<pre><button class="btn-copy-code" title="" data-clipboard-target="#code-2" data-original-title=""><i class="fa fa-copy"></i> 复制</button></pre>
<div class="pre-row">1<br />2<br />3</div>
<div id="code-2" class="pre-div"><code class="language-bash hljs">sed -i <span class="hljs-string">'s/# use_locks       1/use_locks       0/g'</span> /etc/davfs2/davfs2.conf
<span class="hljs-built_in">echo</span> <span class="hljs-string">"你的WebDAV地址 用户名 密码"</span> &gt;&gt; /etc/davfs2/secrets <span class="hljs-comment">#保存用户名密码，以后可以直接免密码挂载</span>
mount.davfs 你的WebDAV地址 你想要挂载到的目录</code></div>
<p>即可成功挂载</p>
<div class="yellow">注意1：挂载目录必须提前创建好！<br />注意2：如果你不执行第二句保存用户名密码，那么你以后挂载的时候都会要求输入用户名密码！</div>
<div data-unique="开机自动挂载"> </div>
<h3>开机自动挂载</h3>
<p>如果想要开机自动挂载，则再执行</p>
<pre><button class="btn-copy-code" title="" data-clipboard-target="#code-3" data-original-title=""><i class="fa fa-copy"></i> 复制</button></pre>
<div class="pre-row">1</div>
<div id="code-3" class="pre-div"><code class="language-bash hljs"><span class="hljs-built_in">echo</span> <span class="hljs-string">"mount.davfs 你的WebDAV地址 你想要挂载到的目录"</span> &gt;&gt; /etc/rc.local</code></div>
<p>执行完此句之后检查一下<code>/etc/rc.local</code>文件，看看是否有<code>exit 0</code>这句。如果有的话，要手动把上面命令添加进去的语句放到<code>exit 0</code>之前。</p>
<div data-unique="Windows"> </div>
<h2>Windows</h2>
<div class="yellow">Windows 资源管理器挂载只能挂载 HTTPS 的 WebDAV。如果想挂载 HTTP 的，貌似需要动点手脚，或者使用第三方软件（见下方）。</div>
<ol>
<li>直接打开“我的电脑”，右击-添加一个网络位置。</li>
<li>
<p>一路“下一步”，然后在这个框内填入你的WebDAV地址，这里以TeraCLOUD为例（<a title=" 免费20GB的WebDAV" href="https://moe.best/yoimono/teracloud.html" target="_blank" rel="noopener"> 免费20GB的WebDAV</a>）。<br /><a class="light-link" href="https://search.pstatic.net/common?type=origin&amp;src=https://moe.best/usr/uploads/2017/10/189786174.jpg" data-fancybox="gallery" data-type="image" data-caption="输入WebDAV地址"><img src="https://search.pstatic.net/common?type=origin&amp;src=https://moe.best/usr/uploads/2017/10/189786174.jpg" alt="输入WebDAV地址" /></a></p>
</li>
<li>
<p>继续下一步，然后等待，会弹出一个登录框让你输入用户名密码，即为你账户的用户名密码。<br /><a class="light-link" href="https://search.pstatic.net/common?type=origin&amp;src=https://moe.best/usr/uploads/2017/10/791205003.jpg" data-fancybox="gallery" data-type="image" data-caption="输入用户名密码"><img src="https://search.pstatic.net/common?type=origin&amp;src=https://moe.best/usr/uploads/2017/10/791205003.jpg" alt="输入用户名密码" /></a></p>
</li>
<li>输入网络位置名称，其实就是取个名字，请随意，然后一路“下一步”，完工，现在你应该可以在我的电脑里看到你挂载的WebDAV了。</li>
</ol>
<div data-unique="MacOS"> </div>
<h2>MacOS</h2>
<p>在 Finder 中连接到服务器，操作与Windows大同小异，由于我没有Mac所以就不讲了，此处直接给出苹果官方文档。<br /><a href="http://support.apple.com/kb/PH3857" target="_blank" rel="noopener">http://support.apple.com/kb/PH3857</a></p>
<div data-unique="第三方软件"> </div>
<h2>第三方软件</h2>
<p>实际上比较推荐使用第三方软件，特别是Windows，资源管理器总有一点科学无法解释的BUG，使用体验不是很好。</p>
<div class="table-responsive">
<table>
<thead>
<tr>
<th>程序名</th>
<th>适用平台</th>
<th>许可</th>
<th>注释</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.raidrive.com/" target="_blank" rel="noopener">RaiDrive</a></td>
<td>Windows</td>
<td>免费</td>
<td>还支持谷歌、OneDrive等网盘</td>
</tr>
<tr>
<td><a href="http://cyberduck.ch/" target="_blank" rel="noopener">Cyberduck</a></td>
<td>Windows/MacOS</td>
<td>免费</td>
<td> </td>
</tr>
<tr>
<td><a href="https://southrivertech.com/products/webdrive/download/" target="_blank" rel="noopener">WebDrive</a></td>
<td>Windows/MacOS</td>
<td class="col2">免费试用10天</td>
<td> </td>
</tr>
<tr>
<td><a href="http://www.netdrive.net/" target="_blank" rel="noopener">NetDrive</a></td>
<td class="col1">Windows</td>
<td class="col2">个人免费使用</td>
<td> </td>
</tr>
<tr>
<td><a href="https://www.webdavsystem.com/" target="_blank" rel="noopener">IT Hit "Map Drive"</a></td>
<td>Windows</td>
<td>商业使用</td>
<td> </td>
</tr>
<tr>
<td><a href="https://www.goodsync.com/" target="_blank" rel="noopener">GoodSync</a></td>
<td>Windows/MacOS/Android/iOS</td>
<td>免费/专业版</td>
<td>适用于双向文件夹同步</td>
</tr>
<tr>
<td><a href="https://itunes.apple.com/us/app/webdav-navigator/id382551345?mt=8" target="_blank" rel="noopener">WebDAV Navigator</a></td>
<td>iOS</td>
<td>免费</td>
<td> </td>
</tr>
<tr>
<td><a href="http://sourceforge.net/projects/webdav-sync/" target="_blank" rel="noopener">WebDAV-Sync</a></td>
<td>任意平台(Java)</td>
<td>开源</td>
<td>适用于双向文件夹同步的命令行工具</td>
</tr>
<tr>
<td><a href="http://www.pincette.biz/davbox/index.xhtml" target="_blank" rel="noopener">DAVbox</a></td>
<td>任意平台(Java)</td>
<td>商业使用</td>
<td>适用于双向文件夹同步</td>
</tr>
</tbody>
</table>
</div>
<blockquote class="content-copyright">
<p class="content-copyright">版权声明：本文为原创文章，版权归<span> </span><a href="https://moe.best/" target="_blank" rel="noopener">神代</a></p>
</blockquote>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/webdav-%e5%a6%82%e4%bd%95%e5%9c%a8%e5%90%84%e4%b8%aa%e5%b9%b3%e5%8f%b0%e4%b8%8b%e6%8c%82%e8%bd%bdwebdav/</guid>
                    </item>
				                    <item>
                        <title>Python简单的图片裁剪</title>
                        <link>https://itprosec.com/community/programer/python%e7%ae%80%e5%8d%95%e7%9a%84%e5%9b%be%e7%89%87%e8%a3%81%e5%89%aa/</link>
                        <pubDate>Wed, 29 Apr 2020 16:44:04 +0000</pubDate>
                        <description><![CDATA[这里我们将使用到python的pillow模块提供的crop方法该方法的调用需要提供4个参数(left, upper, right, lower)对应的是所需截图（距离图片左边界距离x， 距离图片上边界距离y，距离图片左边界距离+裁剪框宽度x+w，距离图片上边界距离+裁剪框高度y+h，根据下图我所需要的截图数据参数为(0,0,800,1151)

 这里贴上我的代码
複製...]]></description>
                        <content:encoded><![CDATA[<p><span>这里我们将使用到python的pillow模块提供的crop方法</span><br /><span>该方法的调用需要提供4个参数(left, upper, right, lower)对应的是所需截图（距离图片左边界距离x， 距离图片上边界距离y，距离图片左边界距离+裁剪框宽度x+w，距离图片上边界距离+裁剪框高度y+h，根据下图我所需要的截图数据参数为(0,0,800,1151)</span></p>
<div class="image-big"><img src="https://www.vxotu.com/u/20200429/15245862.png" data-link="https://www.vxotu.com/i/?i=u/20200429/15245862.png" /></div>
<p><span> </span><br /><span>这里贴上我的代码</span></p>
<h6 class="quote"><a>複製代碼</a></h6>
<blockquote id="code1">from PIL import Image #引用PIL模块<br />img = Image.open(\"01.jpg\") #选择图片 图片路径与py文件同一目录<br />cropped = img.crop((0, 0, 800, 1151))  # (left, upper, right, lower)<br />cropped.save(\"N01.jpg\") #保存裁剪好的照片</blockquote>
<p><br /><br /><span>这里附上裁剪后的效果</span></p>
<div class="image-big"><img src="https://www.vxotu.com/u/20200429/15363736.jpg" data-link="https://www.vxotu.com/i/?i=u/20200429/15363736.jpg" /></div>
<p><span> </span><br /><span>接下来问题又来了，不是每张图片的大小都是一样的，比如下面这张横向的，宽高不一样 但是下方的水印高度是一样的49，</span></p>
<div class="image-big"><img src="https://www.vxotu.com/u/20200429/15363791.png" data-link="https://www.vxotu.com/i/?i=u/20200429/15363791.png" /></div>
<p><span> </span><br /><span>这里就要稍微改一改代码，这里用到两个属性img.width和img.height对应图片的宽高。</span><br /><span>这里修改一下crop方法里面的参数(0,0,img.width,img.height-49).</span><br /><span>最后代码如下</span></p>
<h6 class="quote"><a>複製代碼</a></h6>
<blockquote id="code2">from PIL import Image #引用PIL模块<br />img = Image.open(\"02.jpg\") #选择图片 图片路径与py文件同一目录<br />cropped = img.crop((0, 0, img.width,img.height-49))  # (left, upper, right, lower)<br />cropped.save(\"N02.jpg\") #保存裁剪好的照片</blockquote>
<p><br /><span>搞定测试一下效果。</span></p>
<div class="image-big"><img src="https://www.vxotu.com/u/20200429/15363881.jpg" data-link="https://www.vxotu.com/i/?i=u/20200429/15363881.jpg" /></div>
<p><span> </span></p>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/python%e7%ae%80%e5%8d%95%e7%9a%84%e5%9b%be%e7%89%87%e8%a3%81%e5%89%aa/</guid>
                    </item>
				                    <item>
                        <title>简单的Python爬虫自动下载小说</title>
                        <link>https://itprosec.com/community/programer/%e7%ae%80%e5%8d%95%e7%9a%84python%e7%88%ac%e8%99%ab%e8%87%aa%e5%8a%a8%e4%b8%8b%e8%bd%bd%e5%b0%8f%e8%af%b4/</link>
                        <pubDate>Wed, 29 Apr 2020 16:42:19 +0000</pubDate>
                        <description><![CDATA[简单的爬虫自动下载小说
import requests                                #导入HTTP请求库from pyquery import PyQuery                        #PyQuery，原生css选择器&#039;&#039;&#039;获取单章节内容&#039;&#039;&#039;def get_one_chapter(chapter_url = None,...]]></description>
                        <content:encoded><![CDATA[<p><span>简单的爬虫自动下载小说</span></p>
<p><span>import requests                                #导入HTTP请求库</span><br /><span>from pyquery import PyQuery                        #PyQuery，原生css选择器</span><br /><br /><span>'''获取单章节内容'''</span><br /><span>def get_one_chapter(chapter_url = None, name = None):</span><br /><span>    response = requests.get(url = chapter_url)</span><br /><span>    doc = PyQuery(response.text)</span><br /><span>    title = doc("h1").text()                            #“h1”各网站标签不尽相同，请自行分析网站源码配置</span><br /><span>    content = doc("#content").text()                    #“#content”各网站小说内容关键词，请自行分析网站源码配置</span><br /><span>    print(title,content)</span><br /><span>    with open(file = name + ".txt", mode = "a+", encoding = "utf-8") as f:</span><br /><span>        f.write(title + "\n\n" + content)</span><br /><br /><span>'''解析一本书所有章节的url和书名''</span><br /><span>def get_index(book_url):</span><br /><span>    index_url = book_url</span><br /><span>    text = requests.get(url = index_url).text</span><br /><span>    doc = PyQuery(text)</span><br /><span>    links = doc('#list a')                                                      #links 获取所有链接标签</span><br /><span>    name = doc('h1').text()</span><br /><span>    for link in list(links.items()):                            #一般目录网页都会有限显示最新更新章节，更具实际情况跳过章节</span><br /><span>        chapter_url = 'http://www.XXXXXX' + link.attr.href            #防止有人说我打广告，网址自己配置</span><br /><span>        get_one_chapter(chapter_url = chapter_url, name = name)</span><br /><br /><span>'''解析全站书籍url'''</span><br /><span>def get_all_book_url():</span><br /><span>    all_book_url = "</span><a href="http://www.viidii.info/?http://www______XXXXXX%22&amp;z" target="_blank" rel="noopener">http://www.XXXXXX"</a><br /><span>    response = requests.get(url = all_book_url).text</span><br /><span>    doc = PyQuery(response)</span><br /><span>    links = doc('#main a')</span><br /><span>    for link in list(links.items()):</span><br /><span>        book_url = 'http://www.XXXXXX' + link.attr.href</span><br /><span>        get_index(book_url = book_url)</span><br /><br /><span>get_all_book_url()</span></p>
<p> </p>
<p> </p>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/%e7%ae%80%e5%8d%95%e7%9a%84python%e7%88%ac%e8%99%ab%e8%87%aa%e5%8a%a8%e4%b8%8b%e8%bd%bd%e5%b0%8f%e8%af%b4/</guid>
                    </item>
				                    <item>
                        <title>==01课==程序员必上的十大网站 - Python</title>
                        <link>https://itprosec.com/community/programer/%e7%bc%96%e7%a8%8b%e5%9f%ba%e7%a1%80%e5%9f%b9%e8%ae%ad01%e8%af%be%e7%a8%8b%e5%ba%8f%e5%91%98%e5%bf%85%e4%b8%8a%e7%9a%84%e5%8d%81%e5%a4%a7%e7%bd%91%e7%ab%99-python/</link>
                        <pubDate>Tue, 28 Apr 2020 13:13:31 +0000</pubDate>
                        <description><![CDATA[一、github.com开源代码（代码活跃社区

 二、code.google.com 谷歌开源站点

 三、stackoverflow.com 程序员的百度知道，问答社区，大牛无数 

   四、developer.android.com 安卓程序员必去网站 

   五、developer.apple.com IOS开发必去的苹果官方网站 

  六、c...]]></description>
                        <content:encoded><![CDATA[<h4><br /><span>一、github.com开源代码（代码活跃社区</span><br /><br /><span></span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21254015.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21254015.jpeg" /></div>
<h4><span> </span><span><br /></span><span><br /></span><span><br />二、code.google.com 谷歌开源站点</span><span><br /></span><span><br /></span><span><br /></span><span><br /></span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21265748.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21265748.jpeg" /></div>
<h4><span> </span><span><br /></span><span><br /></span><br /><span>三、stackoverflow.com 程序员的百度知道，问答社区，大牛无数</span><br /><span> </span><br /><br /></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21314523.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21314523.jpeg" /></div>
<h4><span> </span><br /><span> </span><br /><span> </span><br /><span>四、developer.android.com 安卓程序员必去网站</span><br /><span> </span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21315431.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21315431.jpeg" /></div>
<h4><span> </span><br /><span> </span><br /><span> </span><br /><span>五、developer.apple.com IOS开发必去的苹果官方网站</span><br /><span> </span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/2132004.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/2132004.jpeg" /></div>
<h4><span> </span><br /><span> </span><br /><span>六、codeproject.com 上千万名程序员聚集的问答社区</span><br /><span> </span><br /><br /></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21320523.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21320523.jpeg" /></div>
<h4><span> </span><br /><span> </span><br /><span>适合初学者的网站</span><br /><span> </span><br /><span>七、</span><a href="http://www.viidii.info/?http://www______oschina______net/%26%23160%3B&amp;z" target="_blank" rel="noopener">http://www.oschina.net/ </a><span>开源中国社区</span><br /><span> </span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21321031.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21321031.jpeg" /></div>
<h4><span> </span><br /><span> </span><br /><span>八、cocoachina.com（IOS） 学习IOS开发</span><br /><span> </span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21321369.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21321369.jpeg" /></div>
<h4><span> </span><br /><span> </span><br /><span>九、csdn.net 曾经很红火的IT社区</span><br /><span> </span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21321674.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21321674.jpeg" /></div>
<h4><span> </span><br /><span> </span><br /><span>十、segmentfault.com 年轻开发者社区</span><br /><span> </span></h4>
<div class="image-big"><img src="https://yuoimg.com/u/20200425/21321824.jpeg" data-link="https://yuoimg.com/i/?i=u/20200425/21321824.jpeg" /></div>
<h4><span> </span><br /><br /><span>产品交流群提到的网站</span><br /><br /></h4>
<hr />
<h4><br /><span>感谢整理者：青青</span><br /><span> </span><br /><span>w3school.com.cn(web开发|初级)</span><br /><span>csdn.net（综合|初中级）</span><br /><span>cnblogs.com（综合|中级）</span><br /><span>oschina.net（综合|中级）</span><br /><span>iteye.com（偏java|中级）</span><br /><span>51cto.com（偏服务端|中级）</span><br /><span>html-js.com（前端|初中级）</span><br /><span>html5cn.org（前端|初中级）</span><br /><span>infoq.com（综合|高级）</span><br /><span>php100.com（php）</span><br /><span>phpchina.com（php）</span><br /><span>cnodejs.org（nodejs）</span><br /><span>ruby-china.org（ruby）</span><br /><span>code4app.com（IOS）</span><br /><span>apkbus.com（android）</span><br /><span>segmentfault.com（编程问答）</span><br /><span>code.so（代码）</span><br /><br /></h4>
<hr />
<h4><br /><span>我个人开发方向在web+python。</span><br /><span>常去网站有</span><br /><span>Bootstrap中文网</span><br /><a href="http://www.viidii.info/?https://www______bootcss______com/&amp;z" target="_blank" rel="noopener">https://www.bootcss.com/</a><br /><span>python官方网站 - Welcome to Python.org</span><br /><a href="http://www.viidii.info/?http://www______python______org&amp;z" target="_blank" rel="noopener">http://www.python.org</a><br /><span>Django中文网</span><br /><a href="http://www.viidii.info/?http://django______cn&amp;z" target="_blank" rel="noopener">http://django.cn</a><br /><span>编程是一个日积月累的漫长修行，需要不断充电学习，任何妄图一日自学速成几乎是痴心妄想。端正心态再看看自己适合哪个方向，再决定不迟！</span></h4>]]></content:encoded>
						                            <category domain="https://itprosec.com/community/programer/">Programer/IT Automation</category>                        <dc:creator>tai chi</dc:creator>
                        <guid isPermaLink="true">https://itprosec.com/community/programer/%e7%bc%96%e7%a8%8b%e5%9f%ba%e7%a1%80%e5%9f%b9%e8%ae%ad01%e8%af%be%e7%a8%8b%e5%ba%8f%e5%91%98%e5%bf%85%e4%b8%8a%e7%9a%84%e5%8d%81%e5%a4%a7%e7%bd%91%e7%ab%99-python/</guid>
                    </item>
							        </channel>
        </rss>
		