<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://blog.17lai.site</id>
    <title>夜法之书 • Posts by &#34;gitlab&#34; category</title>
    <link href="https://blog.17lai.site" />
    <updated>2021-11-01T11:25:00.000Z</updated>
    <category term="github" />
    <category term="jekyll" />
    <category term="blog" />
    <category term="embeded" />
    <category term="hisilicon" />
    <category term="linux" />
    <category term="driver" />
    <category term="3798m" />
    <category term="mpp" />
    <category term="unf" />
    <category term="kernel" />
    <category term="gitlab" />
    <category term="git" />
    <category term="crack" />
    <category term="hardlink" />
    <category term="bt" />
    <category term="pt" />
    <category term="qnap" />
    <category term="硬盘" />
    <category term="nas" />
    <category term="markdown" />
    <category term="picgo" />
    <category term="wiz" />
    <category term="joplin" />
    <category term="typora" />
    <category term="3G" />
    <category term="4G" />
    <category term="3531a" />
    <category term="移植" />
    <category term="嵌入式" />
    <category term="宝塔" />
    <category term="vps" />
    <category term="建站" />
    <category term="nginx" />
    <category term="apache" />
    <category term="mysql" />
    <category term="docker" />
    <category term="lamp" />
    <category term="php" />
    <category term="tomcat" />
    <category term="registry" />
    <category term="教程" />
    <category term="email" />
    <category term="https" />
    <category term="ssl" />
    <category term="debian" />
    <category term="laptop" />
    <category term="ed2k" />
    <category term="ati" />
    <category term="qbittorrent" />
    <category term="ssd" />
    <category term="hdd" />
    <category term="transmission" />
    <category term="pdca" />
    <category term="5w2h" />
    <category term="smart" />
    <category term="swot" />
    <category term="grow" />
    <category term="okr" />
    <category term="wbs" />
    <category term="启动" />
    <category term="emby" />
    <category term="sonarr" />
    <category term="jeckett" />
    <category term="portainer" />
    <category term="tls" />
    <category term="隐私" />
    <category term="安全" />
    <category term="优化" />
    <category term="gitbook" />
    <category term="mariadb" />
    <category term="note" />
    <category term="mermaid" />
    <category term="webdav" />
    <category term="hexo" />
    <category term="matery" />
    <category term="npm" />
    <category term="web" />
    <category term="http" />
    <category term="css" />
    <category term="js" />
    <category term="ai" />
    <category term="face" />
    <category term="3a" />
    <category term="ae" />
    <category term="image" />
    <category term="ccs" />
    <category term="vim" />
    <category term="ide" />
    <category term="music" />
    <category term="韩红" />
    <category term="thinkpad" />
    <category term="sound" />
    <category term="speaker" />
    <category term="刮削" />
    <category term="musicbrainz" />
    <category term="mp3tag" />
    <category term="tmm" />
    <category term="字幕" />
    <category term="plex" />
    <category term="cmake" />
    <category term="develop" />
    <category term="ipv6" />
    <category term="traefik" />
    <category term="proxy" />
    <category term="swarm" />
    <category term="ubuntu" />
    <category term="vscode" />
    <category term="插件" />
    <category term="编码" />
    <category term="ci/cd" />
    <category term="plantuml" />
    <category term="mathjax" />
    <category term="earthly" />
    <category term="mstream" />
    <category term="selfhost" />
    <category term="中岛美嘉" />
    <category term="node" />
    <category term="jenkins" />
    <category term="shell" />
    <category term="tools" />
    <category term="winrar" />
    <category term="emoji" />
    <category term="isp" />
    <category term="awb" />
    <category term="mywork" />
    <category term="cdn" />
    <category term="seo" />
    <category term="fitness" />
    <category term="健身" />
    <category term="运动" />
    <category term="devops" />
    <category term="k8s" />
    <category term="harbor" />
    <category term="drowio" />
    <category term="框架" />
    <category term="图解" />
    <category term="man" />
    <category term="pmbok" />
    <category term="管理" />
    <category term="ipd" />
    <category term="绩效" />
    <category term="doxygen" />
    <category term="bash" />
    <category term="中医" />
    <category term="西医" />
    <category term="文化历史" />
    <category term="竞品分析" />
    <category term="rss" />
    <category term="rsshub" />
    <category term="社会观察" />
    <category term="知识" />
    <category term="智慧" />
    <category term="os" />
    <category term="自制" />
    <category term="驱动" />
    <category term="sensor" />
    <category term="编译器" />
    <category term="C" />
    <category term="compiler" />
    <category term="nodeppt" />
    <category term="故事" />
    <category term="写作" />
    <category term="vercel" />
    <category term="potplayer" />
    <category term="echarts" />
    <category term="action" />
    <category term="workflow" />
    <category term="概率" />
    <category term="普朗克" />
    <category term="yandex" />
    <category term="source" />
    <category term="hack" />
    <category term="download" />
    <category term="投资" />
    <category term="理财" />
    <category term="金融" />
    <category term="chatgpt" />
    <category term="openai" />
    <category term="calibre" />
    <category term="douban" />
    <category term="book" />
    <category term="不可能三角" />
    <category term="waline" />
    <category term="IPD" />
    <category term="MM方法论" />
    <category term="端到端" />
    <category term="信用卡" />
    <category term="search" />
    <category term="定制服务器" />
    <category term="开源" />
    <category term="读书评鉴" />
    <category term="穿越必备" />
    <category term="易学" />
    <category term="google" />
    <category term="高考" />
    <category term="专业" />
    <category term="人性" />
    <category term="人格分析" />
    <category term="profile" />
    <category term="tampermonkey" />
    <category term="zhihu" />
    <category term="csdn" />
    <category term="juejin" />
    <category term="webhook" />
    <category term="密码" />
    <category term="bitwarden" />
    <category term="office" />
    <category term="kms" />
    <category term="破解" />
    <category term="健康" />
    <category term="恢复" />
    <category term="养生" />
    <category term="刀郎" />
    <category term="umami" />
    <category term="windows" />
    <category term="垃圾清理" />
    <category term="速度优化" />
    <category term="阳历" />
    <category term="阴历" />
    <category term="阴阳和历" />
    <category term="天干" />
    <category term="地支" />
    <category term="热水器" />
    <category term="维护" />
    <category term="汽车" />
    <category term="study" />
    <category term="english" />
    <category term="雅思" />
    <category term="测速" />
    <category term="nat" />
    <category term="光猫" />
    <category term="ipfs" />
    <category term="zlibrary" />
    <category term="sql" />
    <category term="postgresql" />
    <category term="sqlite" />
    <category term="dns" />
    <category term="smartdns" />
    <category term="dnsmasq" />
    <category term="物理" />
    <category term="广义相对论" />
    <category term="科学" />
    <category term="侠义相对论" />
    <category term="高薪" />
    <category term="传媒" />
    <category term="llm" />
    <category term="api" />
    <category term="免费" />
    <category term="ollama" />
    <category term="codex" />
    <category term="electron" />
    <entry>
        <id>https://blog.17lai.site/posts/1879721e/</id>
        <title>CI/CD与Git Flow与GitLab</title>
        <link rel="alternate" href="https://blog.17lai.site/posts/1879721e/"/>
        <content type="html">&lt;blockquote&gt;
&lt;p&gt;CI/CD + Git Flow + GitLab 的整体工作流程记录。主要介绍一下 GitLab CI 相关功能，并通过 GitLab CI 实现自动化构建项目。项目中所用的示例项目已经上传到了 &lt;a href=&#34;https://github.com/mritd/GitLabCI-TestProject&#34;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;一、Git-Flow-简介&#34;&gt;一、Git Flow 简介&lt;/h3&gt;
&lt;p&gt;Git Flow 定义了一个围绕项目开发发布的严格 git 分支模型，用于管理多人协作的大型项目中实现高效的协作开发；Git Flow 分支模型最早起源于 &lt;a href=&#34;http://nvie.com/about/&#34;&gt;Vincent Driessen&lt;/a&gt; 的 &lt;a href=&#34;http://nvie.com/posts/a-successful-git-branching-model/&#34;&gt;A successful Git branching model&lt;/a&gt; 文章；随着时间发展，Git Flow 大致分为三种:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git Flow: 最原始的 Git Flow 分支模型&lt;/li&gt;
&lt;li&gt;Github Flow: Git Flow 的简化版，专门配合持续发布&lt;/li&gt;
&lt;li&gt;GitLab Flow: Git Flow 与 Github Flow 的结合版&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于三种 Git Flow 区别详情可参考 &lt;a href=&#34;https://www.ruanyifeng.com/blog/2015/12/git-workflow.html&#34;&gt;Git 工作流程&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;二、-Git-Flow-流程&#34;&gt;二、 Git Flow 流程&lt;/h3&gt;
&lt;p&gt;Github Flow 和 GitLab Flow 对于持续发布支持比较好，但是原始版本的 Git Flow 对于传统的按照版本发布更加友好一些，所以以下主要说明以下 Git Flow 的工作流程；Git Flow 主要分支模型如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220215.jpg&#34; alt=&#34;git flow&#34;&gt;&lt;/p&gt;
&lt;p&gt;在整个分支模型中 &lt;strong&gt;存在两个长期分支: develop 和 master&lt;/strong&gt;，其中 develop 分支为开发分支，master 为生产分支；&lt;strong&gt;master 代码始终保持随时可以部署到线上的状态；develop 分支用于合并最新提交的功能性代码&lt;/strong&gt;；具体的分支定义如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;master: 生产代码，始终保持可以直接部署生产的状态&lt;/li&gt;
&lt;li&gt;develop: 开发分支，每次合并最新功能代码到此分支&lt;/li&gt;
&lt;li&gt;feature: 新功能分支，所有新开发的功能将采用 &lt;code&gt;feature/xxxx&lt;/code&gt; 形式命名分支&lt;/li&gt;
&lt;li&gt;hotfixes: 紧急修复补丁分支，当新功能部署到了线上出现了严重 bug 需要紧急修复时，则创建 &lt;code&gt;hotfixes/xxxx&lt;/code&gt; 形式命名的分支&lt;/li&gt;
&lt;li&gt;release: 稳定版分支，当完成大版本变动后，应该创建 &lt;code&gt;release/xxxx&lt;/code&gt; 分支&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在整个分支模型中，develop 分支为最上游分支，会不断有新的 feature 合并入 develop 分支，当功能开发达到完成所有版本需求时，则从 develop 分支创建 release 分支，release 后如没有发现其他问题，最终 release 会被合并到 master 分支以完成线上部署&lt;/p&gt;
&lt;h3 id=&#34;三、Git-Flow-工具&#34;&gt;三、Git Flow 工具&lt;/h3&gt;
&lt;p&gt;针对于 Git Flow，其手动操作 git 命令可能过于繁琐，所以后来有了 git-flow 工具；git-flow 是一个 git 扩展集，按 Vincent Driessen 的分支模型提供高层次的库操作；使用 git-flow 工具可以以更加简单的命令完成对 Vincent Driessen 分支模型的实践；&lt;br&gt;
git-flow 安装以及使用具体请参考 &lt;a href=&#34;https://danielkummer.github.io/git-flow-cheatsheet/index.zh_CN.html&#34;&gt;git-flow 备忘清单&lt;/a&gt;，该文章详细描述了 git-flow 工具的使用方式&lt;/p&gt;
&lt;p&gt;还有另一个工具是 &lt;a href=&#34;https://github.com/tj/git-extras&#34;&gt;git-extras&lt;/a&gt;，该工具没有 git-flow 那么简单化，不过其提供更加强大的命令支持&lt;/p&gt;
&lt;h3 id=&#34;四、Git-Commit-Message&#34;&gt;四、Git Commit Message&lt;/h3&gt;
&lt;p&gt;在整个 Git Flow 中，commit message 也是必不可少的一部分；一个良好且统一的 commit message 有助于代码审计以及 review 等；目前使用最广泛的写法是 &lt;a href=&#34;https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#heading=h.greljkmo14y0&#34;&gt;Angular 社区规范&lt;/a&gt;，该规范大中 commit message 格式大致如下:&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-markup&#34; data-language=&#34;markup&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-markup&#34;&gt;&amp;lt;type&amp;gt;(&amp;lt;scope&amp;gt;): &amp;lt;subject&amp;gt;
&amp;lt;BLANK LINE&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;BLANK LINE&amp;gt;
&amp;lt;footer&amp;gt;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;总体格式大致分为 3 部分，首行主要 3 个组成部分:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;type: 本次提交类型&lt;/li&gt;
&lt;li&gt;scope: 本次提交影响范围，一般标明影响版本号或者具体的范围如 &lt;code&gt;$browser, $compile, $rootScope, ngHref, ngClick, ngView, etc...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;subject: 本次提交简短说明&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于 type 提交类型，有如下几种值:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;feat：新功能(feature)&lt;/li&gt;
&lt;li&gt;fix：修补 bug&lt;/li&gt;
&lt;li&gt;docs：文档(documentation)&lt;/li&gt;
&lt;li&gt;style： 格式(不影响代码运行的变动)&lt;/li&gt;
&lt;li&gt;refactor：重构(即不是新增功能，也不是修改 bug 的代码变动)&lt;/li&gt;
&lt;li&gt;test：增加测试&lt;/li&gt;
&lt;li&gt;chore：构建过程或辅助工具的变动&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;中间的 body 部分是对本次提交的详细描述信息，底部的 footer 部分一般分为两种情况:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不兼容变动: 如果出现不兼容变动，则以 &lt;code&gt;BREAKING CHANGE:&lt;/code&gt; 开头，后面跟上不兼容变动的具体描述和解决办法&lt;/li&gt;
&lt;li&gt;关闭 issue: 如果该 commit 针对某个 issue，并且可以将其关闭，则可以在其中指定关闭的 issue，如 &lt;code&gt;Close #9527,#9528&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不过 footer 部分也有特殊情况，如回滚某次提交，则以 &lt;code&gt;revert:&lt;/code&gt; 开头，后面紧跟 commit 信息和具体描述；还有时某些 commit 只是解决了 某个 issue 的一部分问题，这是可以使用 &lt;code&gt;refs ISSUE&lt;/code&gt; 的方式来引用该 issue&lt;/p&gt;
&lt;h3 id=&#34;五、Git-Commit-Message-工具&#34;&gt;五、Git Commit Message 工具&lt;/h3&gt;
&lt;p&gt;针对 Git 的 commit message 目前已经有了成熟的生成工具，比较有名的为 &lt;a href=&#34;https://github.com/commitizen/cz-cli&#34;&gt;commitizen-cli&lt;/a&gt; 工具，其采用 node.js 编写，执行 &lt;code&gt;git cz&lt;/code&gt; 命令能够自动生成符合 Angular 社区规范的 commit message；不过由于其使用 node.js 编写，所以安装前需要安装 node.js，因此可能不适合其他非 node.js 的项目使用；这里推荐一个基于 shell 编写的 &lt;a href=&#34;https://cimhealth.github.io/git-toolkit&#34;&gt;Git-toolkit&lt;/a&gt;，安装此工具后执行 &lt;code&gt;git ci&lt;/code&gt; 命令进行提交将会产生交互式生成 Angular git commit message 格式的提交说明，截图如下:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220233.jpg&#34; alt=&#34;git ci&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;六、GitLab-整合&#34;&gt;六、GitLab 整合&lt;/h3&gt;
&lt;p&gt;以上 Git Flow 所有操作介绍的都是在本地操作，而正常我们在工作中都是基于 GitLab 搭建私有 Git 仓库来进行协同开发的，以下简述以下 Git Flow 配合 GitLab 的流程&lt;/p&gt;
&lt;h4 id=&#34;6-1、开发-features&#34;&gt;6.1、开发 features&lt;/h4&gt;
&lt;p&gt;当开发一个新功能时流程如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地 &lt;code&gt;git flow feature start xxxx&lt;/code&gt; 开启一个 feature 新分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git flow feature publish xxxx&lt;/code&gt; 将此分支推送到远端以便他人获取&lt;/li&gt;
&lt;li&gt;完成开发后 GitLab 上向 &lt;code&gt;develop&lt;/code&gt; 分支发起合并请求&lt;/li&gt;
&lt;li&gt;CI sonar 等质量检测工具扫描，其他用户 review 代码&lt;/li&gt;
&lt;li&gt;确认无误后 &lt;code&gt;master&lt;/code&gt; 权限用户合并其到 &lt;code&gt;develop&lt;/code&gt; 分支&lt;/li&gt;
&lt;li&gt;部署到测试环境以便测试组测试&lt;/li&gt;
&lt;li&gt;如果测试不通过，则继续基于此分支开发，直到该功能开发完成&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;6-2、创建-release&#34;&gt;6.2、创建 release&lt;/h4&gt;
&lt;p&gt;当一定量的 feature 开发完成并合并到 develop 后，如所有 feature 都测试通过并满足版本需求，则可以创建 release 版本分支；release 分支流程如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地 &lt;code&gt;git flow release start xxxx&lt;/code&gt; 开启 release 分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git flow release publish xxxx&lt;/code&gt; 将其推送到远端以便他人获取&lt;/li&gt;
&lt;li&gt;继续进行完整性测试，出现问题继续修复，直到 release 完全稳定&lt;/li&gt;
&lt;li&gt;从 release 分支向 master、develop 分支分别发起合并请求&lt;/li&gt;
&lt;li&gt;master 合并后创建对应的 release 标签，并部署生产环境&lt;/li&gt;
&lt;li&gt;develop 合并 release 的后期修改&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;6-3、紧急修复&#34;&gt;6.3、紧急修复&lt;/h4&gt;
&lt;p&gt;当 master 某个 tag 部署到生产环境后，也可能出现不符合预期的问题出现；此时应该基于 master 创建 hotfix 分支进行修复，流程如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地 &lt;code&gt;git flow hotfix start xxxx&lt;/code&gt; 创建紧急修复分支&lt;/li&gt;
&lt;li&gt;修改代码后将其推送到远端，并像 master、develop 分支发起合并&lt;/li&gt;
&lt;li&gt;develop 合并紧急修复补丁，如果必要最好再做一下测试&lt;/li&gt;
&lt;li&gt;master 合并紧急修复补丁，创建紧急修复 tag，并部署生产环境&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;七、环境准备&#34;&gt;七、环境准备&lt;/h3&gt;
&lt;p&gt;首先需要有一台 GitLab 服务器，然后需要有个项目；这里示例项目以 Spring Boot 项目为例，然后最好有一台专门用来 Build 的机器，实际生产中如果 Build 任务不频繁可适当用一些业务机器进行 Build；本文示例所有组件将采用 Docker 启动， GitLab HA 等不在本文阐述范围内&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker Version : 1.13.1&lt;/li&gt;
&lt;li&gt;GitLab Version : 10.1.4-ce.0&lt;/li&gt;
&lt;li&gt;GitLab Runner Version : 10.1.0&lt;/li&gt;
&lt;li&gt;GitLab IP : 172.16.0.37&lt;/li&gt;
&lt;li&gt;GitLab Runner IP : 172.16.0.36&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;八、GitLab-CI-简介&#34;&gt;八、GitLab CI 简介&lt;/h3&gt;
&lt;p&gt;GitLab CI 是 GitLab 默认集成的 CI 功能，GitLab CI 通过在项目内 &lt;code&gt;.gitlab-ci.yaml&lt;/code&gt; 配置文件读取 CI 任务并进行相应处理；GitLab CI 通过其称为 GitLab Runner 的 Agent 端进行 build 操作；Runner 本身可以使用多种方式安装，比如使用 Docker 镜像启动等；Runner 在进行 build 操作时也可以选择多种 build 环境提供者；比如直接在 Runner 所在宿主机 build、通过新创建虚拟机(vmware、virtualbox)进行 build等；同时 Runner 支持 Docker 作为 build 提供者，即每次 build 新启动容器进行 build；GitLab CI 其大致架构如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220236.png&#34; alt=&#34;GitLab&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;九、搭建-GitLab-服务器&#34;&gt;九、搭建 GitLab 服务器&lt;/h3&gt;
&lt;h4 id=&#34;9-1、GitLab-搭建&#34;&gt;9.1、GitLab 搭建&lt;/h4&gt;
&lt;p&gt;GitLab 搭建这里直接使用 docker compose 启动，compose 配置如下&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-yaml&#34; data-language=&#34;yaml&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;version: &amp;#39;2&amp;#39;
services:
  gitlab:
    image: &amp;#39;gitlab&amp;#x2F;gitlab-ce:10.1.4-ce.0&amp;#39;
    restart: always
    container_name: gitlab
    hostname: &amp;#39;git.mritd.me&amp;#39;
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url &amp;#39;http:&amp;#x2F;&amp;#x2F;git.mritd.me&amp;#39;
        # Add any other gitlab.rb configuration here, each on its own line
    ports:
      - &amp;#39;80:80&amp;#39;
      - &amp;#39;443:443&amp;#39;
      - &amp;#39;8022:22&amp;#39;
    volumes:
      - &amp;#39;.&amp;#x2F;data&amp;#x2F;gitlab&amp;#x2F;config:&amp;#x2F;etc&amp;#x2F;gitlab&amp;#39;
      - &amp;#39;.&amp;#x2F;data&amp;#x2F;gitlab&amp;#x2F;logs:&amp;#x2F;var&amp;#x2F;log&amp;#x2F;gitlab&amp;#39;
      - &amp;#39;.&amp;#x2F;data&amp;#x2F;gitlab&amp;#x2F;data:&amp;#x2F;var&amp;#x2F;opt&amp;#x2F;gitlab&amp;#39;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;直接启动后，首次登陆需要设置初始密码如下，默认用户为 &lt;code&gt;root&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220240.png&#34; alt=&#34;gitkab init&#34;&gt;&lt;/p&gt;
&lt;p&gt;登陆成功后创建一个用户(该用户最好给予 Admin 权限，以后操作以该用户为例)，并且创建一个测试 Group 和 Project，如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220427.png&#34; alt=&#34;Create User&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220432.png&#34; alt=&#34;Test Project&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;9-2、增加示例项目&#34;&gt;9.2、增加示例项目&lt;/h4&gt;
&lt;p&gt;这里示例项目采用 Java 的 SpringBoot 项目，并采用 Gradle 构建，其他语言原理一样；&lt;strong&gt;如果不熟悉 Java 的没必要死磕此步配置，任意语言(最好 Java)整一个能用的 Web 项目就行，并不强求一定 Java 并且使用 Gradle 构建，以下只是一个样例项目&lt;/strong&gt;；SpringBoot 可以采用 &lt;a href=&#34;https://start.spring.io/&#34;&gt;Spring Initializr&lt;/a&gt; 直接生成(依赖要加入 WEB)，如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220246.png&#34; alt=&#34;Spring Initializr&#34;&gt;&lt;/p&gt;
&lt;p&gt;将项目导入 IDEA，然后创建一个 index 示例页面，主要修改如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;build.gradle&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-jade&#34; data-language=&#34;jade&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-jade&#34;&gt;buildscript &amp;#123;
    ext &amp;#123;
        springBootVersion &amp;#x3D; &amp;#39;1.5.8.RELEASE&amp;#39;
    &amp;#125;
    repositories &amp;#123;
        mavenCentral()
    &amp;#125;
    dependencies &amp;#123;
        classpath(&amp;quot;org.springframework.boot:spring-boot-gradle-plugin:$&amp;#123;springBootVersion&amp;#125;&amp;quot;)
    &amp;#125;
&amp;#125;

apply plugin: &amp;#39;java&amp;#39;
apply plugin: &amp;#39;eclipse&amp;#39;
apply plugin: &amp;#39;idea&amp;#39;
apply plugin: &amp;#39;org.springframework.boot&amp;#39;

group &amp;#x3D; &amp;#39;me.mritd&amp;#39;
version &amp;#x3D; &amp;#39;0.0.1-SNAPSHOT&amp;#39;
sourceCompatibility &amp;#x3D; 1.8

repositories &amp;#123;
    mavenCentral()
&amp;#125;


dependencies &amp;#123;
    compile(&amp;#39;org.springframework.boot:spring-boot-starter&amp;#39;)
    compile(&amp;#39;org.springframework.boot:spring-boot-starter-web&amp;#39;)
    compile(&amp;#39;org.springframework.boot:spring-boot-starter-thymeleaf&amp;#39;)
    testCompile(&amp;#39;org.springframework.boot:spring-boot-starter-test&amp;#39;)
&amp;#125;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;新建一个 HomeController&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-jade&#34; data-language=&#34;jade&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-jade&#34;&gt;package me.mritd.TestProject;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

&amp;#x2F;*******************************************************************************
 * Copyright (c) 2005-2017 Mritd, Inc.
 * TestProject
 * me.mritd.TestProject
 * Created by mritd on 2017&amp;#x2F;11&amp;#x2F;24 下午12:23.
 * Description: 
 *******************************************************************************&amp;#x2F;
@Controller
public class HomeController &amp;#123;

    @RequestMapping(&amp;quot;&amp;#x2F;&amp;quot;)
    public String home()&amp;#123;
        return &amp;quot;index&amp;quot;;
    &amp;#125;
&amp;#125;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;templates 下新建 index.html&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-markup&#34; data-language=&#34;markup&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-markup&#34;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang&amp;#x3D;&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset&amp;#x3D;&amp;quot;UTF-8&amp;quot;&amp;#x2F;&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;&amp;#x2F;title&amp;gt;
&amp;lt;&amp;#x2F;head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;Test...&amp;lt;&amp;#x2F;h1&amp;gt;
&amp;lt;&amp;#x2F;body&amp;gt;
&amp;lt;&amp;#x2F;html&amp;gt;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;最后项目整体结构如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220249.png&#34; alt=&#34;TestProject&#34;&gt;&lt;/p&gt;
&lt;p&gt;执行 &lt;code&gt;assemble&lt;/code&gt; Task 打包出可执行 jar 包，并运行 &lt;code&gt;java -jar TestProject-0.0.1-SNAPSHOT.jar&lt;/code&gt; 测试下能启动访问页面即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220251.png&#34; alt=&#34;TestProject assemble&#34;&gt;&lt;/p&gt;
&lt;p&gt;最后将项目提交到 GitLab 后如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220304.png&#34; alt=&#34;init Project&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;十、GitLab-CI-配置&#34;&gt;十、GitLab CI 配置&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;针对这一章节创建基础镜像以及项目镜像，这里仅以 Java 项目为例；其他语言原理相通，按照其他语言对应的运行环境修改即可&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;10-1、增加-Runner&#34;&gt;10.1、增加 Runner&lt;/h4&gt;
&lt;p&gt;GitLab CI 在进行构建时会将任务下发给 Runner，让 Runner 去执行；所以先要添加一个 Runner，Runner 这里采用 Docker Compose 启动，build 方式也使用 Docker 方式 Build；compose 文件如下&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-yaml&#34; data-language=&#34;yaml&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;version: &amp;#39;2&amp;#39;
services:
  gitlab-runner:
    container_name: gitlab-runner
    image: gitlab&amp;#x2F;gitlab-runner:alpine-v10.1.0
    restart: always
    network_mode: &amp;quot;host&amp;quot;
    volumes:
      - &amp;#x2F;var&amp;#x2F;run&amp;#x2F;docker.sock:&amp;#x2F;var&amp;#x2F;run&amp;#x2F;docker.sock
      - .&amp;#x2F;config.toml:&amp;#x2F;etc&amp;#x2F;gitlab-runner&amp;#x2F;config.toml
    extra_hosts:
      - &amp;quot;git.mritd.me:172.16.0.37&amp;quot;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;在启动前，我们需要先 touch 一下这个 config.toml 配置文件&lt;/strong&gt;；该文件是 Runner 的运行配置，此后 Runner 所有配置都会写入这个文件(不 touch 出来 docker-compose 发现不存在会挂载一个目录进去，导致 Runner 启动失败)；启动 docker-compose 后，&lt;strong&gt;需要进入容器执行注册，让 Runner 主动去连接 GitLab 服务器&lt;/strong&gt;&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;# 生成 Runner 配置文件
touch config.toml
# 启动 Runner
docker-compose up -d
# 激活 Runner
docker exec -it gitlab-runner gitlab-runner registerCopy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;在执行上一条激活命令后，会按照提示让你输入一些信息；&lt;strong&gt;首先输入 GitLab 地址，然后是 Runner Token，Runner Token 可以从 GitLab 设置中查看&lt;/strong&gt;，如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220624.png&#34; alt=&#34;Runner Token&#34;&gt;&lt;/p&gt;
&lt;p&gt;整体注册流程如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220312.png&#34; alt=&#34;Runner registry&#34;&gt;&lt;/p&gt;
&lt;p&gt;注册完成后，在 GitLab Runner 设置中就可以看到刚刚注册的 Runner，如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220628.png&#34; alt=&#34;Runner List&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Runner 注册成功后会将配置写入到 config.toml 配置文件；由于两个测试宿主机都没有配置内网 DNS，所以为了保证 runner 在使用 docker build 时能正确的找到 GitLab 仓库地址，还需要增加一个 docker 的 host 映射( &lt;code&gt;extra_hosts&lt;/code&gt; )；同时为了能调用 宿主机 Docker 和持久化 build 的一些缓存还挂载了一些文件和目录；完整的 配置如下(配置文件可以做一些更高级的配置，具体参考 &lt;a href=&#34;https://docs.gitlab.com/runner/configuration/advanced-configuration.html&#34;&gt;官方文档&lt;/a&gt; )&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;config.toml&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-toml&#34; data-language=&#34;toml&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-toml&#34;&gt;concurrent &amp;#x3D; 1
check_interval &amp;#x3D; 0

[[runners]]
  name &amp;#x3D; &amp;quot;Test Runner&amp;quot;
  url &amp;#x3D; &amp;quot;http:&amp;#x2F;&amp;#x2F;git.mritd.me&amp;quot;
  token &amp;#x3D; &amp;quot;c279ec1ac08aec98c7141c7cf2d474&amp;quot;
  executor &amp;#x3D; &amp;quot;docker&amp;quot;
  builds_dir &amp;#x3D; &amp;quot;&amp;#x2F;gitlab&amp;#x2F;runner-builds&amp;quot;
  cache_dir &amp;#x3D; &amp;quot;&amp;#x2F;gitlab&amp;#x2F;runner-cache&amp;quot;
  [runners.docker]
    tls_verify &amp;#x3D; false
    image &amp;#x3D; &amp;quot;debian&amp;quot;
    privileged &amp;#x3D; false
    disable_cache &amp;#x3D; false
    shm_size &amp;#x3D; 0
    volumes &amp;#x3D; [&amp;quot;&amp;#x2F;data&amp;#x2F;gitlab-runner:&amp;#x2F;gitlab&amp;quot;,&amp;quot;&amp;#x2F;var&amp;#x2F;run&amp;#x2F;docker.sock:&amp;#x2F;var&amp;#x2F;run&amp;#x2F;docker.sock&amp;quot;,&amp;quot;&amp;#x2F;data&amp;#x2F;maven_repo:&amp;#x2F;data&amp;#x2F;repo&amp;quot;,&amp;quot;&amp;#x2F;data&amp;#x2F;maven_repo:&amp;#x2F;data&amp;#x2F;maven&amp;quot;,&amp;quot;&amp;#x2F;data&amp;#x2F;gradle:&amp;#x2F;data&amp;#x2F;gradle&amp;quot;,&amp;quot;&amp;#x2F;data&amp;#x2F;sonar_cache:&amp;#x2F;root&amp;#x2F;.sonar&amp;quot;,&amp;quot;&amp;#x2F;data&amp;#x2F;androidsdk:&amp;#x2F;usr&amp;#x2F;local&amp;#x2F;android&amp;quot;,&amp;quot;&amp;#x2F;data&amp;#x2F;node_modules:&amp;#x2F;data&amp;#x2F;node_modules&amp;quot;]
    extra_hosts &amp;#x3D; [&amp;quot;git.mritd.me:172.16.0.37&amp;quot;]
  [runners.cache]Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;注意，这里声明的 Volumes 会在每个运行的容器中都生效；也就是说 build 时新开启的每个容器都会被挂载这些目录&lt;/strong&gt;；修改完成后重启 runner 容器即可，由于 runner 中没啥可保存的东西，所以可以直接 &lt;code&gt;docker-compose down &amp;amp;&amp;amp; docker-compose up -d&lt;/code&gt; 重启&lt;/p&gt;
&lt;h4 id=&#34;10-2、创建基础镜像&#34;&gt;10.2、创建基础镜像&lt;/h4&gt;
&lt;p&gt;由于示例项目是一个 Java 项目，而且是采用 Spring Boot 的，所以该项目想要运行起来只需要一个 java 环境即可，中间件已经被打包到了 jar 包中；以下是一个作为基础运行环境的 openjdk 镜像的 Dockerfile&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-docker&#34; data-language=&#34;docker&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-docker&#34;&gt;FROM alpine:edge 

LABEL maintainer&amp;#x3D;&amp;quot;mritd &amp;lt;mritd1234@gmail.com&amp;gt;&amp;quot;

ENV JAVA_HOME &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;jvm&amp;#x2F;java-1.8-openjdk
ENV PATH $PATH:&amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;jvm&amp;#x2F;java-1.8-openjdk&amp;#x2F;jre&amp;#x2F;bin:&amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;jvm&amp;#x2F;java-1.8-openjdk&amp;#x2F;bin

RUN apk add --update bash curl tar wget ca-certificates unzip \
        openjdk8 font-adobe-100dpi ttf-dejavu fontconfig \
    &amp;amp;&amp;amp; rm -rf &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;apk&amp;#x2F;* \

CMD [&amp;quot;bash&amp;quot;]Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;这个 openjdk Dockerfile 升级到了 8.151 版本，并且集成了一些字体相关的软件，以解决在 Java 中某些验证码库无法运行问题，详见 &lt;a href=&#34;https://mritd.me/2017/09/27/alpine-3.6-openjdk-8-bug/&#34;&gt;Alpine 3.6 OpenJDK 8 Bug&lt;/a&gt;&lt;/strong&gt;；使用这个 Dockerfile，在当前目录执行 &lt;code&gt;docker build -t mritd/openjdk:8 .&lt;/code&gt; build 一个 openjdk8 的基础镜像，然后将其推送到私服，或者 Docker Hub 即可&lt;/p&gt;
&lt;h4 id=&#34;10-3、创建项目镜像&#34;&gt;10.3、创建项目镜像&lt;/h4&gt;
&lt;p&gt;有了基本的 openjdk 的 docker 镜像后，针对于项目每次 build 都应该生成一个包含发布物的 docker 镜像，所以对于项目来说还需要一个项目本身的 Dockerfile；&lt;strong&gt;项目的 Dockerfile 有两种使用方式；一种是动态生成 Dockerfile，然后每次使用新生成的 Dockerfile 去 build；还有一种是写一个通用的 Dockerfile，build 时利用 ARG 参数传入变量&lt;/strong&gt;；这里采用第二种方式，以下为一个可以反复使用的 Dockerfile&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-docker&#34; data-language=&#34;docker&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-docker&#34;&gt;FROM mritd&amp;#x2F;openjdk:8-144-01

MAINTAINER mritd &amp;lt;mritd1234@gmail.com&amp;gt;

ARG PROJECT_BUILD_FINALNAME

ENV TZ &amp;#39;Asia&amp;#x2F;Shanghai&amp;#39;
ENV PROJECT_BUILD_FINALNAME $&amp;#123;PROJECT_BUILD_FINALNAME&amp;#125;


COPY build&amp;#x2F;libs&amp;#x2F;$&amp;#123;PROJECT_BUILD_FINALNAME&amp;#125;.jar &amp;#x2F;$&amp;#123;PROJECT_BUILD_FINALNAME&amp;#125;.jar

CMD [&amp;quot;bash&amp;quot;,&amp;quot;-c&amp;quot;,&amp;quot;java -jar &amp;#x2F;$&amp;#123;PROJECT_BUILD_FINALNAME&amp;#125;.jar&amp;quot;]Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;该 Dockerfile 通过声明一个 &lt;code&gt;PROJECT_BUILD_FINALNAME&lt;/code&gt; 变量来表示项目的发布物名称；然后将其复制到根目录下，最终利用 java 执行这个 jar 包；所以每次 build 之前只要能拿到项目发布物的名称即可&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;10-4、Gradle-修改&#34;&gt;10.4、Gradle 修改&lt;/h4&gt;
&lt;p&gt;上面已经创建了一个标准的通用型 Dockerfile，每次 build 镜像只要传入 &lt;code&gt;PROJECT_BUILD_FINALNAME&lt;/code&gt; 这个最终发布物名称即可；对于发布物名称来说，最好不要固定死；当然不论是 Java 还是其他语言的项目我们都能将最终发布物变成一个固定名字，最不济可以写脚本重命名一下；但是不建议那么干，最好保留版本号信息，以便于异常情况下进入容器能够分辨；对于当前 Java 项目来说，想要拿到 &lt;code&gt;PROJECT_BUILD_FINALNAME&lt;/code&gt; 很简单，我们只需要略微修改一下 Gradle 的 build 脚本，让其每次打包 jar 包时将项目的名称及版本号导出到文件中即可；同时这里也加入了镜像版本号的处理，Gradle 脚本修改如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;build.gradle 最后面增加如下&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-jade&#34; data-language=&#34;jade&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-jade&#34;&gt;bootRepackage &amp;#123;

    mainClass &amp;#x3D; &amp;#39;me.mritd.TestProject.TestProjectApplication&amp;#39;
    executable &amp;#x3D; true

    doLast &amp;#123;
        File envFile &amp;#x3D; new File(&amp;quot;build&amp;#x2F;tmp&amp;#x2F;PROJECT_ENV&amp;quot;)

        println(&amp;quot;Create $&amp;#123;archivesBaseName&amp;#125; ENV File &amp;#x3D;&amp;#x3D;&amp;#x3D;&amp;gt; &amp;quot; + envFile.createNewFile())
        println(&amp;quot;Export $&amp;#123;archivesBaseName&amp;#125; Build Version &amp;#x3D;&amp;#x3D;&amp;#x3D;&amp;gt; $&amp;#123;version&amp;#125;&amp;quot;)
        envFile.write(&amp;quot;export PROJECT_BUILD_FINALNAME&amp;#x3D;$&amp;#123;archivesBaseName&amp;#125;-$&amp;#123;version&amp;#125;\n&amp;quot;)

        println(&amp;quot;Generate Docker image tag...&amp;quot;)
        envFile.append(&amp;quot;export BUILD_DATE&amp;#x3D;&amp;#96;date +%Y%m%d%H%M%S&amp;#96;\n&amp;quot;)
        envFile.append(&amp;quot;export IMAGE_NAME&amp;#x3D;mritd&amp;#x2F;test:&amp;#96;echo \$&amp;#123;CI_BUILD_REF_NAME&amp;#125; | tr &amp;#39;&amp;#x2F;&amp;#39; &amp;#39;-&amp;#39;&amp;#96;-&amp;#96;echo \$&amp;#123;CI_COMMIT_SHA&amp;#125; | cut -c1-8&amp;#96;-\$&amp;#123;BUILD_DATE&amp;#125;\n&amp;quot;)
        envFile.append(&amp;quot;export LATEST_IMAGE_NAME&amp;#x3D;mritd&amp;#x2F;test:latest\n&amp;quot;)
    &amp;#125;
&amp;#125;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;这一步操作实际上是修改了 &lt;code&gt;bootRepackage&lt;/code&gt; 这个 Task(不了解 Gradle 或者不是 Java 项目的请忽略)，在其结束后创建了一个叫 &lt;code&gt;PROJECT_ENV&lt;/code&gt; 的文件，里面实际上就是写入了一些 bash 环境变量声明，以方便后面 source 一下这个文件拿到一些变量，然后用户 build 镜像使用&lt;/strong&gt;，&lt;code&gt;PROJECT_ENV&lt;/code&gt; 最终生成如下&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;export PROJECT_BUILD_FINALNAME&amp;#x3D;TestProject-0.0.1-SNAPSHOT
export BUILD_DATE&amp;#x3D;&amp;#96;date +%Y%m%d%H%M%S&amp;#96;
export IMAGE_NAME&amp;#x3D;mritd&amp;#x2F;test:&amp;#96;echo $&amp;#123;CI_BUILD_REF_NAME&amp;#125; | tr &amp;#39;&amp;#x2F;&amp;#39; &amp;#39;-&amp;#39;&amp;#96;-&amp;#96;echo $&amp;#123;CI_COMMIT_SHA&amp;#125; | cut -c1-8&amp;#96;-$&amp;#123;BUILD_DATE&amp;#125;
export LATEST_IMAGE_NAME&amp;#x3D;mritd&amp;#x2F;test:latestCopy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220738.png&#34; alt=&#34;PROJECT_ENV&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;10-5、创建-CI-配置文件&#34;&gt;10.5、创建 CI 配置文件&lt;/h4&gt;
&lt;p&gt;一切准备就绪以后，就可以编写 CI 脚本了；GitLab 依靠读取项目根目录下的 &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; 文件来执行相应的 CI 操作；以下为测试项目的 &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; 配置&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-yaml&#34; data-language=&#34;yaml&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;# 调试开启
#before_script:
#  - pwd
#  - env

cache:
  key: $CI_PROJECT_NAME&amp;#x2F;$CI_COMMIT_REF_NAME-$CI_COMMIT_SHA
  paths:
    - build

stages:
  - build
  - deploy

auto-build:
  image: mritd&amp;#x2F;build:2.1.1
  stage: build
  script:
    - gradle --no-daemon clean assemble
  tags:
    - test

deploy:
  image: mritd&amp;#x2F;docker-kubectl:v1.7.4
  stage: deploy
  script:
    - source build&amp;#x2F;tmp&amp;#x2F;PROJECT_ENV
    - echo &amp;quot;Build Docker Image &amp;#x3D;&amp;#x3D;&amp;gt; $&amp;#123;IMAGE_NAME&amp;#125;&amp;quot;
    - docker build -t $&amp;#123;IMAGE_NAME&amp;#125; --build-arg PROJECT_BUILD_FINALNAME&amp;#x3D;$&amp;#123;PROJECT_BUILD_FINALNAME&amp;#125; .
#    - docker push $&amp;#123;IMAGE_NAME&amp;#125;
    - docker tag $&amp;#123;IMAGE_NAME&amp;#125; $&amp;#123;LATEST_IMAGE_NAME&amp;#125;
#    - docker push $&amp;#123;LATEST_IMAGE_NAME&amp;#125;
#    - docker rmi $&amp;#123;IMAGE_NAME&amp;#125; $&amp;#123;LATEST_IMAGE_NAME&amp;#125;
#    - kubectl --kubeconfig $&amp;#123;KUBE_CONFIG&amp;#125; set image deployment&amp;#x2F;test test&amp;#x3D;$IMAGE_NAME
  tags:
    - test
  only:
    - master
    - develop
    - &amp;#x2F;^chore.*$&amp;#x2F;Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;关于 CI 配置的一些简要说明如下&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;stages&#34;&gt;stages&lt;/h5&gt;
&lt;p&gt;stages 字段定义了整个 CI 一共有哪些阶段流程，以上的 CI 配置中，定义了该项目的 CI 总共分为 &lt;code&gt;build&lt;/code&gt;、&lt;code&gt;deploy&lt;/code&gt; 两个阶段；GitLab CI 会根据其顺序执行对应阶段下的所有任务；&lt;strong&gt;在正常生产环境流程可以定义很多个，比如可以有 &lt;code&gt;test&lt;/code&gt;、&lt;code&gt;publish&lt;/code&gt;，甚至可能有代码扫描的 &lt;code&gt;sonar&lt;/code&gt; 阶段等；这些阶段没有任何限制，完全是自定义的&lt;/strong&gt;，上面的阶段定义好后在 CI 中表现如下图&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220327.png&#34; alt=&#34;stages&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;task&#34;&gt;task&lt;/h5&gt;
&lt;p&gt;task 隶属于 stages 之下；也就是说一个阶段可以有多个任务，任务执行顺序默认不指定会并发执行；对于上面的 CI 配置来说 &lt;code&gt;auto-build&lt;/code&gt; 和 &lt;code&gt;deploy&lt;/code&gt; 都是 task，他们通过 &lt;code&gt;stage: xxxx&lt;/code&gt; 这个标签来指定他们隶属于哪个 stage；当 Runner 使用 Docker 作为 build 提供者时，我们可以在 task 的 &lt;code&gt;image&lt;/code&gt; 标签下声明该 task 要使用哪个镜像运行，不指定则默认为 Runner 注册时的镜像(这里是 debian)；&lt;strong&gt;同时 task 还有一个 &lt;code&gt;tags&lt;/code&gt; 的标签，该标签指明了这个任务将可以在哪些 Runner 上运行；这个标签可以从 Runner 页面看到，实际上就是 Runner 注册时输入的哪个 tag；对于某些特殊的项目，比如 IOS 项目，则必须在特定机器上执行，所以此时指定 tags 标签很有用&lt;/strong&gt;，当 task 运行后如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101221014.png&#34; alt=&#34;Task&#34;&gt;&lt;/p&gt;
&lt;p&gt;除此之外 task 还能指定 &lt;code&gt;only&lt;/code&gt; 标签用于限定那些分支才能触发这个 task，如果分支名字不满足则不会触发；&lt;strong&gt;默认情况下，这些 task 都是自动执行的，如果感觉某些任务太过危险，则可以通过增加 &lt;code&gt;when: manual&lt;/code&gt; 改为手动执行；注意: 手动执行被 GitLab 认为是高权限的写操作，所以只有项目管理员才能手动运行一个 task，直白的说就是管理员才能点击&lt;/strong&gt;；手动执行如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220759.png&#34; alt=&#34;manual task&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;cache&#34;&gt;cache&lt;/h5&gt;
&lt;p&gt;cache 这个参数用于定义全局那些文件将被 cache；&lt;strong&gt;在 GitLab CI 中，跨 stage 是不能保存东西的；也就是说在第一步 build 的操作生成的 jar 包，到第二部打包 docker image 时就会被删除；GitLab 会保证每个 stage 中任务在执行时都将工作目录(Docker 容器 中)还原到跟 GitLab 代码仓库中一模一样，多余文件及变更都会被删除&lt;/strong&gt;；正常情况下，第一步 build 生成 jar 包应当立即推送到 nexus 私服；但是这里测试没有搭建，所以只能放到本地；但是放到本地下一个 task 就会删除它，所以利用 &lt;code&gt;cache&lt;/code&gt; 这个参数将 &lt;code&gt;build&lt;/code&gt; 目录 cache 住，保证其跨 stage 也能存在&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关于 &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; 具体配置更完整的请参考 &lt;a href=&#34;https://docs.gitlab.com/ee/ci/yaml/&#34;&gt;官方文档&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;十一、其他相关&#34;&gt;十一、其他相关&lt;/h3&gt;
&lt;h4 id=&#34;11-1、GitLab-内置环境变量&#34;&gt;11.1、GitLab 内置环境变量&lt;/h4&gt;
&lt;p&gt;上面已经基本搞定了一个项目的 CI，但是有些变量可能并未说清楚；比如在创建的 &lt;code&gt;PROJECT_ENV&lt;/code&gt; 文件中引用了 &lt;code&gt;$&amp;#123;CI_COMMIT_SHA&amp;#125;&lt;/code&gt; 变量；这种变量其实是 GitLab CI 的内置隐藏变量，这些变量在每次 CI 调用 Runner 运行某个任务时都会传递到对应的 Runner 的执行环境中；&lt;strong&gt;也就是说这些变量在每次的任务容器 SHELL 环境中都会存在，可以直接引用&lt;/strong&gt;，具体的完整环境变量列表可以从 &lt;a href=&#34;https://docs.gitlab.com/ee/ci/variables/&#34;&gt;官方文档&lt;/a&gt; 中获取；如果想知道环境变量具体的值，实际上可以通过在任务执行前用 &lt;code&gt;env&lt;/code&gt; 指令打印出来，如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220338.png&#34; alt=&#34;env&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220800.png&#34; alt=&#34;env task&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;11-2、GitLab-自定义环境变量&#34;&gt;11.2、GitLab 自定义环境变量&lt;/h4&gt;
&lt;p&gt;在某些情况下，我们希望 CI 能自动的发布或者修改一些东西；比如将 jar 包上传到 nexus、将 docker 镜像 push 到私服；这些动作往往需要一个高权限或者说有可写入对应仓库权限的账户来支持，但是这些账户又不想写到项目的 CI 配置里；因为这样很不安全，谁都能看到；此时我们可以将这些敏感变量写入到 GitLab 自定义环境变量中，GitLab 会像对待内置变量一样将其传送到 Runner 端，以供我们使用；GitLab 中自定义的环境变量可以有两种，一种是项目级别的，只能够在当前项目使用，如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220803.png&#34; alt=&#34;project env&#34;&gt;&lt;/p&gt;
&lt;p&gt;另一种是组级别的，可以在整个组内的所有项目中使用，如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220805.png&#34; alt=&#34;group env&#34;&gt;&lt;/p&gt;
&lt;p&gt;这两种变量添加后都可以在 CI 的脚本中直接引用&lt;/p&gt;
&lt;h4 id=&#34;11-3、Kubernetes-集成&#34;&gt;11.3、Kubernetes 集成&lt;/h4&gt;
&lt;p&gt;对于 Kubernetes 集成实际上有两种方案，一种是对接 Kubernetes 的 api，纯代码实现；另一种取巧的方案是调用 kubectl 工具，用 kubectl 工具来实现滚动升级；这里采用后一种取巧的方式，将 kubectl 二进制文件封装到镜像中，然后在 deploy 阶段使用这个镜像直接部署就可以&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cimg1.17lai.site/data/2021/11/0120211101220345.png&#34; alt=&#34;kubectl&#34;&gt;&lt;/p&gt;
&lt;p&gt;其中 &lt;code&gt;mritd/docker-kubectl:v1.7.4&lt;/code&gt; 这个镜像的 Dockerfile 如下&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-docker&#34; data-language=&#34;docker&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-docker&#34;&gt;FROM docker:dind 

LABEL maintainer&amp;#x3D;&amp;quot;mritd &amp;lt;mritd1234@gmail.com&amp;gt;&amp;quot;

ARG TZ&amp;#x3D;&amp;quot;Asia&amp;#x2F;Shanghai&amp;quot;

ENV TZ $&amp;#123;TZ&amp;#125;

ENV KUBE_VERSION v1.8.0

RUN apk upgrade --update \
    &amp;amp;&amp;amp; apk add bash tzdata wget ca-certificates \
    &amp;amp;&amp;amp; wget https:&amp;#x2F;&amp;#x2F;storage.googleapis.com&amp;#x2F;kubernetes-release&amp;#x2F;release&amp;#x2F;$&amp;#123;KUBE_VERSION&amp;#125;&amp;#x2F;bin&amp;#x2F;linux&amp;#x2F;amd64&amp;#x2F;kubectl -O &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;bin&amp;#x2F;kubectl \
    &amp;amp;&amp;amp; chmod +x &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;bin&amp;#x2F;kubectl \
    &amp;amp;&amp;amp; ln -sf &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;zoneinfo&amp;#x2F;$&amp;#123;TZ&amp;#125; &amp;#x2F;etc&amp;#x2F;localtime \
    &amp;amp;&amp;amp; echo $&amp;#123;TZ&amp;#125; &amp;gt; &amp;#x2F;etc&amp;#x2F;timezone \
    &amp;amp;&amp;amp; rm -rf &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;apk&amp;#x2F;*

CMD [&amp;quot;&amp;#x2F;bin&amp;#x2F;bash&amp;quot;]Copy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;这里面的 &lt;code&gt;$&amp;#123;KUBE_CONFIG&amp;#125;&lt;/code&gt; 是一个自定义的环境变量，对于测试环境我将配置文件直接挂载入了容器中，然后 &lt;code&gt;$&amp;#123;KUBE_CONFIG&amp;#125;&lt;/code&gt; 只是指定了一个配置文件位置，实际生产环境中可以选择将配置文件变成自定义环境变量使用&lt;/p&gt;
&lt;h4 id=&#34;11-4、GitLab-CI-总结&#34;&gt;11.4、GitLab CI 总结&lt;/h4&gt;
&lt;p&gt;关于 GitLab CI 上面已经讲了很多，但是并不全面，也不算太细致；因为这东西说起来实际太多了，现在目测已经 1W 多字了；以下总结一下 GitLab CI 的总体思想，当思路清晰了以后，我想后面的只是查查文档自己试一试就行了&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CS 架构&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GitLab 作为 Server 端，控制 Runner 端执行一系列的 CI 任务；代码 clone 等无需关心，GitLab 会自动处理好一切；Runner 每次都会启动新的容器执行 CI 任务&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;容器即环境&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 Runner 使用 Docker build 的前提下；&lt;strong&gt;所有依赖切换、环境切换应当由切换不同镜像实现，即 build 那就使用 build 的镜像，deploy 就用带有 deploy 功能的镜像；通过不同镜像容器实现完整的环境隔离&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CI即脚本&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不同的 CI 任务实际上就是在使用不同镜像的容器中执行 SHELL 命令，自动化 CI 就是执行预先写好的一些小脚本&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;敏感信息走环境变量&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一切重要的敏感信息，如账户密码等，不要写到 CI 配置中，直接放到 GitLab 的环境变量中；GitLab 会保证将其推送到远端 Runner 的 SHELL 变量中&lt;/p&gt;
&lt;p&gt;转载整理From：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://mritd.com/2017/09/05/git-flow-note/&#34;&gt;git-flow-note&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mritd.com/2017/11/28/ci-cd-gitlab-ci/&#34;&gt;ci-cd-gitlab-ci&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;系列教程&#34;&gt;&lt;strong&gt;系列教程&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;全部文章RSS订阅&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&#34;Gitlab-使用系列&#34;&gt;&lt;strong&gt;Gitlab 使用系列&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/categories/gitlab/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;&lt;strong&gt;Gitlab RSS 分类订阅&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/posts/acc13b70/&#34;&gt;&lt;strong&gt;Gitlab的安装及使用教程完全版&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/29a820b3/&#34;&gt;破解Gitlab EE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d08eb7b/&#34;&gt;Gitlab的安装及使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/1879721e/&#34;&gt;CI/CD与Git Flow与GitLab&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;Devops系列&#34;&gt;&lt;strong&gt;Devops系列&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/categories/devops/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;&lt;strong&gt;Devops 分类 RSS 订阅&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ab63eb8f/&#34;&gt;自建全套开源Devops开发系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d32a07a7/&#34;&gt;Git介绍以及分支模型图解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/39563241/&#34;&gt;三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/3437994a/&#34;&gt;DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/f4c3ad41/&#34;&gt;项目开发管理工具推荐&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/acc13b70/&#34;&gt;Gitlab的安装及使用教程完全版&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d08eb7b/&#34;&gt;Gitlab的安装及使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/78c3371/&#34;&gt;那些有用的Github工具介绍！Action、app、workflow等&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;项目管理系列&#34;&gt;&lt;strong&gt;项目管理系列&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/categories/ai/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;&lt;strong&gt;AI 分类 RSS 订阅&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d8b1e381/&#34;&gt;如何做一个完整的硬件项目的项目管理之简明教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ca630feb/&#34;&gt;几种常用管理模型和方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ac0df556/&#34;&gt;PMBOK指南（第6版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/99be6dfb/&#34;&gt;如何做好竞品分析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/a6477052/&#34;&gt;一大堆寓意深刻的管理故事锦集&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ec34b111/&#34;&gt;人格类型分类总结归纳&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;https://fastly.jsdelivr.net/npm/markmap-toolbar@0.18.10/dist/style.css&#34;&gt;&lt;script src=&#34;https://fastly.jsdelivr.net/npm/d3@7&#34;&gt;&lt;/script&gt;&lt;script src=&#34;https://fastly.jsdelivr.net/npm/markmap-view@0.18.10&#34;&gt;&lt;/script&gt;&lt;script src=&#34;https://fastly.jsdelivr.net/npm/markmap-toolbar@0.18.10&#34;&gt;&lt;/script&gt;
&lt;link rel=&#34;stylesheet&#34; href=&#34;/css/markmap.css&#34;&gt;

&lt;script src=&#34;/js/markmap.js&#34;&gt;&lt;/script&gt;
</content>
        <category term="gitlab" />
        <category term="git" />
        <category term="ci/cd" />
        <updated>2021-11-01T11:25:00.000Z</updated>
    </entry>
    <entry>
        <id>https://blog.17lai.site/posts/29a820b3/</id>
        <title>破解Gitlab EE</title>
        <link rel="alternate" href="https://blog.17lai.site/posts/29a820b3/"/>
        <content type="html">&lt;blockquote&gt;
&lt;p&gt;由于需要一些镜像等 gitlab 高级功能，所有破解gitlab ee版本。你能信么？ 这些破解方法来自官方自己的文档！个人研究使用，企业请付费购买正版授权。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;已经在最新 gitlab ee 18.5 上验证可行&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;使用-ruby-生成许可证&#34;&gt;使用 ruby 生成许可证&lt;/h2&gt;
&lt;h3 id=&#34;安装ruby&#34;&gt;安装ruby&lt;/h3&gt;
&lt;p&gt;安装完gitlab ee之后&lt;/p&gt;
&lt;p&gt;安装ruby：yum install ruby&lt;/p&gt;
&lt;p&gt;ruby版本需要2.3或以上。&lt;/p&gt;
&lt;h3 id=&#34;生成许可证&#34;&gt;&lt;strong&gt;生成许可证&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;gem install gitlab-license&lt;/p&gt;
&lt;h3 id=&#34;创建一个rb文件&#34;&gt;创建一个rb文件&lt;/h3&gt;
&lt;p&gt;license.rb&lt;/p&gt;
&lt;hr&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-ruby&#34; data-language=&#34;ruby&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-ruby&#34;&gt;require &amp;quot;openssl&amp;quot;
require &amp;quot;gitlab&amp;#x2F;license&amp;quot;
 
key_pair &amp;#x3D; OpenSSL::PKey::RSA.generate(2048)
File.open(&amp;quot;license_key&amp;quot;, &amp;quot;w&amp;quot;) &amp;#123; |f| f.write(key_pair.to_pem) &amp;#125;
 
public_key &amp;#x3D; key_pair.public_key
File.open(&amp;quot;license_key.pub&amp;quot;, &amp;quot;w&amp;quot;) &amp;#123; |f| f.write(public_key.to_pem) &amp;#125;
 
private_key &amp;#x3D; OpenSSL::PKey::RSA.new File.read(&amp;quot;license_key&amp;quot;)
Gitlab::License.encryption_key &amp;#x3D; private_key
 
license &amp;#x3D; Gitlab::License.new
license.licensee &amp;#x3D; &amp;#123;
  &amp;quot;Name&amp;quot; &amp;#x3D;&amp;gt; &amp;quot;none&amp;quot;,
  &amp;quot;Company&amp;quot; &amp;#x3D;&amp;gt; &amp;quot;none&amp;quot;,
  &amp;quot;Email&amp;quot; &amp;#x3D;&amp;gt; &amp;quot;example@test.com&amp;quot;,
&amp;#125;
license.starts_at &amp;#x3D; Date.new(2020, 1, 1) # 开始时间
license.expires_at &amp;#x3D; Date.new(2050, 1, 1) # 结束时间
license.notify_admins_at &amp;#x3D; Date.new(2049, 12, 1)
license.notify_users_at &amp;#x3D; Date.new(2049, 12, 1)
license.block_changes_at &amp;#x3D; Date.new(2050, 1, 1)
license.restrictions &amp;#x3D; &amp;#123;
  active_user_count: 10000,
&amp;#125;
 
puts &amp;quot;License:&amp;quot;
puts license
 
data &amp;#x3D; license.export
puts &amp;quot;Exported license:&amp;quot;
puts data
File.open(&amp;quot;GitLabBV.gitlab-license&amp;quot;, &amp;quot;w&amp;quot;) &amp;#123; |f| f.write(data) &amp;#125;
 
public_key &amp;#x3D; OpenSSL::PKey::RSA.new File.read(&amp;quot;license_key.pub&amp;quot;)
Gitlab::License.encryption_key &amp;#x3D; public_key
 
data &amp;#x3D; File.read(&amp;quot;GitLabBV.gitlab-license&amp;quot;)
$license &amp;#x3D; Gitlab::License.import(data)
 
puts &amp;quot;Imported license:&amp;quot;
puts $license
 
unless $license
  raise &amp;quot;The license is invalid.&amp;quot;
end
 
if $license.restricted?(:active_user_count)
  active_user_count &amp;#x3D; 10000
  if active_user_count &amp;gt; $license.restrictions[:active_user_count]
    raise &amp;quot;The active user count exceeds the allowed amount!&amp;quot;
  end
end
 
if $license.notify_admins?
  puts &amp;quot;The license is due to expire on #&amp;#123;$license.expires_at&amp;#125;.&amp;quot;
end
 
if $license.notify_users?
  puts &amp;quot;The license is due to expire on #&amp;#123;$license.expires_at&amp;#125;.&amp;quot;
end
 
module Gitlab
  class GitAccess
    def check(cmd, changes &amp;#x3D; nil)
      if $license.block_changes?
        return build_status_object(false, &amp;quot;License expired&amp;quot;)
      end
    end
  end
end
 
puts &amp;quot;This instance of GitLab Enterprise Edition is licensed to:&amp;quot;
$license.licensee.each do |key, value|
  puts &amp;quot;#&amp;#123;key&amp;#125;: #&amp;#123;value&amp;#125;&amp;quot;
end
 
if $license.expired?
  puts &amp;quot;The license expired on #&amp;#123;$license.expires_at&amp;#125;&amp;quot;
elsif $license.will_expire?
  puts &amp;quot;The license will expire on #&amp;#123;$license.expires_at&amp;#125;&amp;quot;
else
  puts &amp;quot;The license will never expire.&amp;quot;
end
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;hr&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;ruby license.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;生成 &lt;code&gt;GitLabBV.gitlab-license&lt;/code&gt; &lt;code&gt;license_key&lt;/code&gt; &lt;code&gt;license_key.pub&lt;/code&gt; 这三个文件。&lt;/p&gt;
&lt;h3 id=&#34;使用许可证&#34;&gt;&lt;strong&gt;使用许可证&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;用 &lt;code&gt;license_key.pub&lt;/code&gt; 文件替换 &lt;code&gt;/opt/gitlab/embedded/service/gitlab-rails/.license_encryption_key.pub&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GitLabBV.gitlab-license&lt;/code&gt; 即是许可证，填入 &lt;code&gt;$&amp;#123;address&amp;#125;/admin/license&lt;/code&gt; 地址并重启 &lt;code&gt;gitlab-ctl restart&lt;/code&gt; 。&lt;/p&gt;
&lt;h3 id=&#34;修改等级&#34;&gt;&lt;strong&gt;修改等级&lt;/strong&gt;&lt;/h3&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-diff-ruby&#34; data-language=&#34;diff-ruby&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-diff-ruby&#34;&gt;--- &amp;#x2F;opt&amp;#x2F;gitlab&amp;#x2F;embedded&amp;#x2F;service&amp;#x2F;gitlab-rails&amp;#x2F;ee&amp;#x2F;app&amp;#x2F;models&amp;#x2F;license.rb
+++ &amp;#x2F;opt&amp;#x2F;gitlab&amp;#x2F;embedded&amp;#x2F;service&amp;#x2F;gitlab-rails&amp;#x2F;ee&amp;#x2F;app&amp;#x2F;models&amp;#x2F;license.rb
@@ -458,7 +458,7 @@
  end
 
  def plan
-    restricted_attr(:plan).presence || STARTER_PLAN
+    restricted_attr(:plan).presence || ULTIMATE_PLAN
  end
 
  def edition
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;h2 id=&#34;使用-GitLab-License-Generator-生成许可证&#34;&gt;使用 GitLab-License-Generator 生成许可证&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/Lakr233/GitLab-License-Generator.git&#34;&gt;https://github.com/Lakr233/GitLab-License-Generator.git&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用 GitLab-License-Generator 生成许可证&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;Docker-运行&#34;&gt;Docker  运行&lt;/h2&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;docker run --rm -it \
  -v &amp;quot;.&amp;#x2F;license:&amp;#x2F;license-generator&amp;#x2F;build&amp;quot; \
  -e LICENSE_NAME&amp;#x3D;&amp;quot;Tim Cook&amp;quot; \
  -e LICENSE_COMPANY&amp;#x3D;&amp;quot;Apple Computer, Inc.&amp;quot; \
  -e LICENSE_EMAIL&amp;#x3D;&amp;quot;tcook@apple.com&amp;quot; \
  -e LICENSE_PLAN&amp;#x3D;&amp;quot;ultimate&amp;quot; \
  -e LICENSE_USER_COUNT&amp;#x3D;&amp;quot;2147483647&amp;quot; \
  -e LICENSE_EXPIRE_YEAR&amp;#x3D;&amp;quot;2500&amp;quot; \
  ghcr.io&amp;#x2F;lakr233&amp;#x2F;gitlab-license-generator:main&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;或者自己编译镜像，需要选择前几个没有被 DMCA 的提交&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;git clone https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;Lakr233&amp;#x2F;GitLab-License-Generator.git
docker build GitLab-License-Generator -t gitlab-license-generator:main
docker run --rm -it \
  -v &amp;quot;.&amp;#x2F;license:&amp;#x2F;license-generator&amp;#x2F;build&amp;quot; \
  -e LICENSE_NAME&amp;#x3D;&amp;quot;Tim Cook&amp;quot; \
  -e LICENSE_COMPANY&amp;#x3D;&amp;quot;Apple Computer, Inc.&amp;quot; \
  -e LICENSE_EMAIL&amp;#x3D;&amp;quot;tcook@apple.com&amp;quot; \
  -e LICENSE_PLAN&amp;#x3D;&amp;quot;ultimate&amp;quot; \
  -e LICENSE_USER_COUNT&amp;#x3D;&amp;quot;2147483647&amp;quot; \
  -e LICENSE_EXPIRE_YEAR&amp;#x3D;&amp;quot;2500&amp;quot; \
  gitlab-license-generator:main&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;h2 id=&#34;人工运行破解&#34;&gt;人工运行破解&lt;/h2&gt;
&lt;p&gt;由于 GitLab-License-Generator 被 DMCA takedown 了，所以我们需要手动运行它：&lt;/p&gt;
&lt;h3 id=&#34;复制-仓库&#34;&gt;复制 仓库&lt;/h3&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;# 可以直接在 gitlab docker 中运行，或者使用你喜欢的环境
docker exec -it gitlabee bash
apt update
apt install ruby-full
gem install bundler
gem install gitlab-license
git clone https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;Lakr233&amp;#x2F;GitLab-License-Generator.git
cd GitLab-License-Generator&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;h3 id=&#34;修改生成脚本&#34;&gt;修改生成脚本&lt;/h3&gt;
&lt;p&gt;然后编辑 &lt;code&gt;src/scan.features.rb&lt;/code&gt; 粘贴以下内容：&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-ruby&#34; data-language=&#34;ruby&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-ruby&#34;&gt;#!&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;env ruby
# encoding: utf-8

require &amp;#39;json&amp;#39;
require &amp;#39;optparse&amp;#39;

OptionParser.new do |opts|
    opts.banner &amp;#x3D; &amp;quot;Usage: scan.features.rb [options]&amp;quot;

    opts.on(&amp;quot;-s&amp;quot;, &amp;quot;--src-dir PATH&amp;quot;, &amp;quot;Specify gitlab source dir (required if --features-file is ommited)&amp;quot;) do |v|
        GITLAB_FEATURES_FILE&amp;#x3D;&amp;quot;#&amp;#123;File.expand_path(v)&amp;#125;&amp;#x2F;ee&amp;#x2F;app&amp;#x2F;models&amp;#x2F;gitlab_subscriptions&amp;#x2F;features.rb&amp;quot;
    end

    opts.on(&amp;quot;-f&amp;quot;, &amp;quot;--features-file PATH&amp;quot;, &amp;quot;Specify gitlab features path (required if --src-dir is ommited)&amp;quot;) do |v|
        GITLAB_FEATURES_FILE &amp;#x3D; File.expand_path(v)
    end

    opts.on(&amp;quot;-o&amp;quot;, &amp;quot;--output PATH&amp;quot;, &amp;quot;Output to json file (required)&amp;quot;) do |v|
        EXPORT_JSON_FILE &amp;#x3D; File.expand_path(v)
    end

    opts.on(&amp;quot;-h&amp;quot;, &amp;quot;--help&amp;quot;, &amp;quot;Prints this help&amp;quot;) do
        puts opts
        exit
    end
end
.parse!
if GITLAB_FEATURES_FILE.nil? || EXPORT_JSON_FILE.nil?
    puts &amp;quot;[!] missing required options&amp;quot;
    puts &amp;quot;[!] use -h for help&amp;quot;
    exit 1
end
puts &amp;quot;Reading features from #&amp;#123;GITLAB_FEATURES_FILE&amp;#125;&amp;quot;

def ignore_exception
    begin
      yield
    rescue Exception
    end
end

puts &amp;quot;[*] loading features.rb...&amp;quot;
ignore_exception do
    require_relative &amp;quot;#&amp;#123;GITLAB_FEATURES_FILE&amp;#125;&amp;quot;
end

ALL_FEATURES &amp;#x3D; []
GitlabSubscriptions::Features.constants.each do |const_name|
    puts &amp;quot;[*] gathering features from #&amp;#123;const_name&amp;#125;&amp;quot;
    if const_name.to_s.include? &amp;#39;FEATURE&amp;#39;
        ALL_FEATURES.concat(GitlabSubscriptions::Features.const_get(const_name))
    else
        puts &amp;quot;[?] unrecognized constant #&amp;#123;const_name&amp;#125;&amp;quot;
    end
end

ALL_FEATURES.uniq!
ALL_FEATURES.sort_by! &amp;#123; |feature| feature &amp;#125;

puts &amp;quot;[*] total features: #&amp;#123;ALL_FEATURES.size&amp;#125;&amp;quot;

puts &amp;quot;[*] writing to #&amp;#123;EXPORT_JSON_FILE&amp;#125;&amp;quot;
File.write(EXPORT_JSON_FILE, JSON.pretty_generate(ALL_FEATURES))

puts &amp;quot;[*] done&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;生成许可证（按需求修改&lt;code&gt;LICENSE&lt;/code&gt;变量）：&lt;/p&gt;
&lt;h3 id=&#34;运行-make-sh-脚本&#34;&gt;运行  &lt;code&gt;make.sh&lt;/code&gt; 脚本&lt;/h3&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;chmod +x src&amp;#x2F;scan.features.rb
LICENSE_NAME&amp;#x3D;&amp;quot;Tim Cook&amp;quot;
LICENSE_COMPANY&amp;#x3D;&amp;quot;Apple Computer, Inc.&amp;quot;
LICENSE_EMAIL&amp;#x3D;&amp;quot;tcook@apple.com&amp;quot;
LICENSE_PLAN&amp;#x3D;&amp;quot;ultimate&amp;quot;
LICENSE_USER_COUNT&amp;#x3D;&amp;quot;2147483647&amp;quot;
LICENSE_EXPIRE_YEAR&amp;#x3D;&amp;quot;2500&amp;quot;
.&amp;#x2F;make.sh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;生成的许可证在 &lt;code&gt;build&lt;/code&gt; 文件夹下。&lt;/p&gt;
&lt;p&gt;要使用的文件有 &lt;code&gt;public.key&lt;/code&gt; 和 &lt;code&gt;result.gitlab-license&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;替换-Gitlab-public-key&#34;&gt;替换 Gitlab  public key&lt;/h3&gt;
&lt;p&gt;我们要使用生成的 &lt;code&gt;public.key&lt;/code&gt; 替换 GitLab 的 &lt;code&gt;.license_encryption_key.pub&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地安装&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;sudo cp .&amp;#x2F;build&amp;#x2F;public.key &amp;#x2F;opt&amp;#x2F;gitlab&amp;#x2F;embedded&amp;#x2F;service&amp;#x2F;gitlab-rails&amp;#x2F;.license_encryption_key.pub
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;docker compose 安装&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-yaml&#34; data-language=&#34;yaml&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;volumes:
  - &amp;quot;.&amp;#x2F;build&amp;#x2F;public.key:&amp;#x2F;opt&amp;#x2F;gitlab&amp;#x2F;embedded&amp;#x2F;service&amp;#x2F;gitlab-rails&amp;#x2F;.license_encryption_key.pub&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;然后重启 container&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;docker-compose down
docker-compose up -d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;将 &lt;code&gt;result.gitlab-license&lt;/code&gt; 的内容粘贴至&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;YourGitLabURL&amp;gt;/admin/license/new&lt;/code&gt; 点击 Add License 选择 Enter license key 粘贴你 &lt;code&gt;result.gitlab-license&lt;/code&gt; 里的内容。&lt;/p&gt;
&lt;p&gt;选择接受 TOS 点击 Add license。&lt;/p&gt;
&lt;p&gt;这时候 GitLab 就成功激活了！&lt;/p&gt;
&lt;h2 id=&#34;安装-Gitlab-许可证&#34;&gt;安装 Gitlab 许可证&lt;/h2&gt;
&lt;h3 id=&#34;14-x-Gitlab之前添加许可证位置&#34;&gt;14.x Gitlab之前添加许可证位置&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;菜单-&amp;gt;管理员-&amp;gt;订阅-&amp;gt;许可证上传&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;新版Gitlab添加许可证的位置在&#34;&gt;新版Gitlab添加许可证的位置在&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;菜单-&amp;gt;管理员-&amp;gt;设置-&amp;gt;通用-&amp;gt;添加许可证处点击展开-&amp;gt;点击上传（build/result.gitlab-license）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;修改完成后使用 &lt;code&gt;gitlab-ctl restart&lt;/code&gt; 重新加载配置。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;菜单-&amp;gt;管理员-&amp;gt;订阅&lt;/p&gt;
&lt;p&gt;在这里可以看到激活状态，上面操作没问题的话，这里可以看到激活成功！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;关闭-gitlab-Service-Ping-可选&#34;&gt;关闭 gitlab Service Ping (可选)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Open the configuration file:&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;sudo nano &amp;#x2F;etc&amp;#x2F;gitlab&amp;#x2F;gitlab.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following line:&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gitlab_rails[&amp;#39;usage_ping_enabled&amp;#39;] &amp;#x3D; false&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reconfigure and restart GitLab:&lt;/p&gt;
&lt;figure&gt;&lt;div class=&#34;code-area&#34;&gt;&lt;pre class=&#34;line-numbers language-bash&#34; data-language=&#34;bash&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;参考&#34;&gt;&lt;strong&gt;参考&lt;/strong&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.rubydoc.info/gems/gitlab-license/1.0.0/file/README.md&#34;&gt;https://www.rubydoc.info/gems/gitlab-license/1.0.0/file/README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Lakr233/GitLab-License-Generator&#34;&gt;https://github.com/Lakr233/GitLab-License-Generator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;现在你已经破解好了Gitlab ee， 可以使用其中的高级功能。&lt;/p&gt;
&lt;p&gt;更多的Gitlab ee详细教程，请参考下面的gitlab系列教程！ 👇︎&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;系列教程&#34;&gt;&lt;strong&gt;系列教程&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;全部文章RSS订阅&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&#34;Gitlab-使用系列&#34;&gt;&lt;strong&gt;Gitlab 使用系列&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/categories/gitlab/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;&lt;strong&gt;Gitlab RSS 分类订阅&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/posts/acc13b70/&#34;&gt;&lt;strong&gt;Gitlab的安装及使用教程完全版&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/29a820b3/&#34;&gt;破解Gitlab EE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d08eb7b/&#34;&gt;Gitlab的安装及使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/1879721e/&#34;&gt;CI/CD与Git Flow与GitLab&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;Devops系列&#34;&gt;&lt;strong&gt;Devops系列&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/categories/devops/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;&lt;strong&gt;Devops 分类 RSS 订阅&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ab63eb8f/&#34;&gt;自建全套开源Devops开发系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d32a07a7/&#34;&gt;Git介绍以及分支模型图解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/39563241/&#34;&gt;三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/3437994a/&#34;&gt;DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/f4c3ad41/&#34;&gt;项目开发管理工具推荐&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/acc13b70/&#34;&gt;Gitlab的安装及使用教程完全版&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d08eb7b/&#34;&gt;Gitlab的安装及使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/78c3371/&#34;&gt;那些有用的Github工具介绍！Action、app、workflow等&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;项目管理系列&#34;&gt;&lt;strong&gt;项目管理系列&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/categories/ai/atom.xml&#34;&gt;&lt;i class=&#34;fas fa-rss&#34;&gt;&lt;/i&gt;&lt;strong&gt;AI 分类 RSS 订阅&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/posts/d8b1e381/&#34;&gt;如何做一个完整的硬件项目的项目管理之简明教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ca630feb/&#34;&gt;几种常用管理模型和方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ac0df556/&#34;&gt;PMBOK指南（第6版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/99be6dfb/&#34;&gt;如何做好竞品分析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/a6477052/&#34;&gt;一大堆寓意深刻的管理故事锦集&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/posts/ec34b111/&#34;&gt;人格类型分类总结归纳&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;https://fastly.jsdelivr.net/npm/markmap-toolbar@0.18.10/dist/style.css&#34;&gt;&lt;script src=&#34;https://fastly.jsdelivr.net/npm/d3@7&#34;&gt;&lt;/script&gt;&lt;script src=&#34;https://fastly.jsdelivr.net/npm/markmap-view@0.18.10&#34;&gt;&lt;/script&gt;&lt;script src=&#34;https://fastly.jsdelivr.net/npm/markmap-toolbar@0.18.10&#34;&gt;&lt;/script&gt;
&lt;link rel=&#34;stylesheet&#34; href=&#34;/css/markmap.css&#34;&gt;

&lt;script src=&#34;/js/markmap.js&#34;&gt;&lt;/script&gt;
</content>
        <category term="gitlab" />
        <category term="git" />
        <category term="crack" />
        <updated>2021-07-09T07:25:00.000Z</updated>
    </entry>
</feed>
