<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>GitLab｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/gitlab/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>GitLab｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/gitlab/</link><width>144</width><height>144</height></image>
    <description>林鼎淵（Dean Lin）的部落格：生成式 AI 企業內訓講師、外商資安公司軟體專家、7 本書作者。400 多篇文章用白話分享生成式 AI 實戰、Claude Code 與 Vibe Coding 教學、團隊合作與職場成長。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <copyright>© 2020–2026 林鼎淵 Dean Lin</copyright>
    <lastBuildDate>Mon, 02 Dec 2024 18:17:56 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/gitlab/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>GitLab CI 實戰（踩坑）筆記</title>
      <link>https://deanlin.net/blog/202412/gitlab-ci-notes/</link>
      <pubDate>Mon, 02 Dec 2024 18:17:56 +0800</pubDate>
      <guid>https://deanlin.net/blog/202412/gitlab-ci-notes/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>技術教學</category>
      <description>GitLab CI 是 GitLab 的內建工具，每次 Push 都會觸發一次腳本執行，內容通常涵蓋測試、編譯、部署等一系列自定義內容。 這篇文章會分享設計上要注意的細節，以及實戰過程踩過的坑。</description>
      <media:content url="https://deanlin.net/blog/202412/gitlab-ci-notes/images/gitlab-ci-notes-og_hu_93c7e0cda81c9d07.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>GitLab CI 是 GitLab 的內建工具，每次 Push 都會觸發一次腳本執行，內容通常涵蓋測試、編譯、部署等一系列自定義內容。</p>
<p>這篇文章會分享設計上要注意的細節，以及實戰過程踩過的坑，不會特別說明基礎資訊，想更深入理解的朋友可以參考<a href="https://docs.gitlab.com/ee/ci/">官網文件</a>；如果讀者有更好的方案，或對名詞有更精準的定義，歡迎留言分享。</p>
<p><img src="https://deanlin.net/blog/202412/gitlab-ci-notes/images/gitlab-ci-notes-01.webp" width="1400" height="775" alt="GitLab CI 實戰（踩坑）筆記（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>文章大綱

▋ GitLab CI 資料夾結構設計
▋ 在 .gitlab/.default.gitlab-ci.yml 定義要執行 pipeline 的 Branchs
▋ 根據專案需求定義對應的 Stages
▋ 想在不同 stage 傳遞資料時，artifacts 跟 cache 的使用時機
▋ 讓 stage 下的 job 並行執行 or 順序執行
▋ notify 階段建議要有的資訊
▋ Dockerfile 多階段構建
▋ 其他的坑（套件安裝、相容性、單元測試）
</code></pre><h2 id="-gitlab-ci-資料夾結構設計">GitLab CI 資料夾結構設計<a class="h-anchor" href="#-gitlab-ci-%e8%b3%87%e6%96%99%e5%a4%be%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88" aria-label="這個段落的連結"></a></h2>
<pre tabindex="0"><code>Project
├── .gitlab-ci.yml
└── .gitlab
    ├── stages
    │   ├── 1.xxx.yml
    │   └── 2.xxx.yml
    ├── .default.gitlab-ci.yml
    └── docker-bake.hcl
</code></pre><p>下面說明一下資料夾結構下各檔案要負責的任務：</p>
<ul>
<li><strong>.gitlab-ci.yml</strong>: 定義有要執行的 stages，以及參考的 yml 檔案（ex: <code>.gitlab/.default.gitlab-ci.yml</code>）。</li>
<li><strong>.gitlab</strong>: 存放 GitLab 設定檔的資料夾。</li>
<li><strong>.gitlab/stages</strong>: 存放各 stage 的資料夾，讓邏輯更容易維護。</li>
<li><strong>.gitlab/stages/xxx.yml</strong>: 定義 stage 下各 jobs 要執行的任務。</li>
<li><strong>.gitlab/.default.gitlab-ci.yml</strong>: 用來定義默認的設定，避免重複性的工作（ex: 設定通用的 <code>variables</code>、定義要執行 pipeline 的 branchs）。</li>
<li><strong>.gitlab/docker-bake.hcl</strong>: 定義 Build Docker Image 的資訊（ex: 支援多平台、傳遞參數）。</li>
</ul>
<hr>
<h2 id="-在-gitlabdefaultgitlab-ciyml-定義要執行-pipeline-的-branchs">在 .gitlab/.default.gitlab-ci.yml 定義要執行 pipeline 的 Branchs<a class="h-anchor" href="#-%e5%9c%a8-gitlabdefaultgitlab-ciyml-%e5%ae%9a%e7%be%a9%e8%a6%81%e5%9f%b7%e8%a1%8c-pipeline-%e7%9a%84-branchs" aria-label="這個段落的連結"></a></h2>
<p>僅管我們期待每次 Push 一版都會觸發 pipeline，但有時也會有一些例外狀況（ex: 需要高頻率 Push 測試一些特殊功能）。</p>
<p>以下面的設計來說，就是僅允許「merge_request_event」以及「release/<em>、hotfix/</em>、feature/*」，還有 Default Branch（ex: master、develop）會觸發 pipeline。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#7ee787">workflow</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">rules</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#7ee787">if</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;$CI_PIPELINE_SOURCE == &#34;merge_request_event&#34;&#39;</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#7ee787">if</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;$CI_COMMIT_BRANCH =~ /^release\/.*$/&#39;</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#7ee787">if</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;$CI_COMMIT_BRANCH =~ /^hotfix\/.*$/&#39;</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#7ee787">if</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;$CI_COMMIT_BRANCH =~ /^feature\/.*$/&#39;</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#7ee787">if</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH&#39;</span><span style="color:#6e7681">
</span></span></span></code></pre></div><hr>
<h2 id="-根據專案需求定義對應的-stages">根據專案需求定義對應的 Stages<a class="h-anchor" href="#-%e6%a0%b9%e6%93%9a%e5%b0%88%e6%a1%88%e9%9c%80%e6%b1%82%e5%ae%9a%e7%be%a9%e5%b0%8d%e6%87%89%e7%9a%84-stages" aria-label="這個段落的連結"></a></h2>
<p>筆者習慣設計下面 5 個 Stages:</p>
<ul>
<li><strong>init</strong>: 在這個階段做套件安裝的任務（ex: npm install）。</li>
<li><strong>analysis</strong>: 如果 init 順利才會進入這個階段，會在這裡進行單元測試(test)、Coding Style 檢查(lint)，並將對應的 report 保存到 artifacts 當中。</li>
<li><strong>build_image</strong>: 如果前面都通過才會 Build Docker Image，並將 $TARGET_IMAGE:$TAG 保存到 artifacts/tags.txt 當中（要在 notify 階段使用）。</li>
<li><strong>notify</strong>: 我將它設定為 always 執行，用來傳送 pipeline 成功/失敗的訊息到對應的 Chanel（ex: Zoom、Teams、Line）。</li>
<li><strong>deploy</strong>: 根據實際需求設計部署流程。</li>
</ul>
<hr>
<h2 id="-想在不同-stage-傳遞資料時artifacts-跟-cache-的使用時機">想在不同 stage 傳遞資料時，artifacts 跟 cache 的使用時機<a class="h-anchor" href="#-%e6%83%b3%e5%9c%a8%e4%b8%8d%e5%90%8c-stage-%e5%82%b3%e9%81%9e%e8%b3%87%e6%96%99%e6%99%82artifacts-%e8%b7%9f-cache-%e7%9a%84%e4%bd%bf%e7%94%a8%e6%99%82%e6%a9%9f" aria-label="這個段落的連結"></a></h2>
<p>上個 stage 做完的事情，在下個 stage 是不會知道細節的。</p>
<p>想要傳遞資訊就需要透過 artifacts 或 cache，而這兩者的用途不太一樣：</p>
<ul>
<li><strong>artifacts</strong>: 記錄這次 pipeline 獨有的資訊，像是 test report、image_id 這類的，建議要設定對應的 expire_in 時間，否則資料會永久保存消耗硬碟空間。</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#7ee787">analysis</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">artifacts</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span><span style="color:#7ee787">paths</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">      </span>- <span style="color:#a5d6ff">reports</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span><span style="color:#7ee787">expire_in</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">1</span><span style="color:#6e7681"> </span><span style="color:#a5d6ff">day</span><span style="color:#6e7681">
</span></span></span></code></pre></div><ul>
<li><strong>cache</strong>: 這個專案經常使用的資料，比如 node_modules 這類保存套件的資料夾。</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#7ee787">analysis</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">cache</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span><span style="color:#7ee787">key</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#34;${CI_PROJECT_PATH_SLUG}&#34;</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span><span style="color:#7ee787">paths</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">      </span>- <span style="color:#a5d6ff">node_modules</span><span style="color:#6e7681">
</span></span></span></code></pre></div><hr>
<h2 id="-讓-stage-下的-job-並行執行-or-順序執行">讓 stage 下的 job 並行執行 or 順序執行<a class="h-anchor" href="#-%e8%ae%93-stage-%e4%b8%8b%e7%9a%84-job-%e4%b8%a6%e8%a1%8c%e5%9f%b7%e8%a1%8c-or-%e9%a0%86%e5%ba%8f%e5%9f%b7%e8%a1%8c" aria-label="這個段落的連結"></a></h2>
<p>如果沒有特別設計，stage 下的 job 默認都是並行執行的（比如 unit test &amp; lint 可以同時進行）；如果想要順序執行，可以透過 needs 來設定，範例如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#7ee787">job1</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">stage</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">build</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">script</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#a5d6ff">echo &#34;Executing job1&#34;</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#7ee787">job2</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">stage</span>:<span style="color:#6e7681"> </span><span style="color:#a5d6ff">build</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">script</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#a5d6ff">echo &#34;Executing job2&#34;</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span><span style="color:#7ee787">needs</span>:<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">    </span>- <span style="color:#a5d6ff">job1 </span><span style="color:#6e7681"> </span><span style="color:#8b949e;font-style:italic"># 等待 job1 完成後執行</span><span style="color:#6e7681">
</span></span></span></code></pre></div><hr>
<h2 id="-notify-階段建議要有的資訊">notify 階段建議要有的資訊<a class="h-anchor" href="#-notify-%e9%9a%8e%e6%ae%b5%e5%bb%ba%e8%ad%b0%e8%a6%81%e6%9c%89%e7%9a%84%e8%b3%87%e8%a8%8a" aria-label="這個段落的連結"></a></h2>
<p>GitLab CI 通常要跑幾分鐘的時間（通常跟 unit test 多寡有關），所以要設計 notify 的機制來傳遞資訊，建議包含的內容如下：</p>
<ul>
<li><strong>project</strong>: $PROJECT_NAME，方便了解執行的專案。</li>
<li><strong>branch</strong>: $CI_COMMIT_REF_NAME，了解哪個 branch 更新了。</li>
<li><strong>result</strong>: 會包含成功與失敗的詳細資訊。</li>
<li><strong>pipeline_link</strong>: $PIPELINE_LINK，出問題時點擊連結可以看到最直接的資訊。</li>
<li><strong>image_id</strong>: 從 artifacts 裡面讀取。</li>
</ul>
<hr>
<h2 id="-dockerfile-多階段構建">Dockerfile 多階段構建<a class="h-anchor" href="#-dockerfile-%e5%a4%9a%e9%9a%8e%e6%ae%b5%e6%a7%8b%e5%bb%ba" aria-label="這個段落的連結"></a></h2>
<p>下面用一個範例來說明如何用多階段構建（multi-stage build）來減少 Docker Image 大小並提高效率（<code>COPY &ndash;from=builder</code> 的作用是從第一階段複製文件到第二階段）。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"># 第一階段：使用 Node.js 安裝套件，並進行打包</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">FROM node:23.3-alpine as builder</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">WORKDIR /app</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">COPY package.json package-lock.json ./</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">RUN npm install</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">COPY . .</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">RUN npm run build</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"># 第二階段：使用 Nginx 部署靜態文件</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">FROM nginx:alpine3.20</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">COPY --from=builder /app/dist /usr/share/nginx/html</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">WORKDIR /usr/share/nginx/html</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#a5d6ff">COPY ./build/nginx/default.conf /etc/nginx/conf.d/default.conf</span><span style="color:#6e7681">
</span></span></span></code></pre></div><p>透過這個方案，最終的 Image 只有靜態文件跟 Nginx，不包含 Node.js 開發工具；不但減少 Image 大小，還減少了潛在攻擊面向。</p>
<hr>
<h2 id="-其他的坑套件安裝相容性單元測試">其他的坑（套件安裝、相容性、單元測試）<a class="h-anchor" href="#-%e5%85%b6%e4%bb%96%e7%9a%84%e5%9d%91%e5%a5%97%e4%bb%b6%e5%ae%89%e8%a3%9d%e7%9b%b8%e5%ae%b9%e6%80%a7%e5%96%ae%e5%85%83%e6%b8%ac%e8%a9%a6" aria-label="這個段落的連結"></a></h2>
<ul>
<li><strong>套件無法順利安裝</strong>: 如果套件是經由私有庫來安裝的，就需要設定對應的網路環境；如果在 Dockerfile 裡面安裝，請記得將 <code>.npmrc</code> 這類設定 COPY 到對應的位置。</li>
<li><strong>qemu-user-static 相容性錯誤</strong>: 有些專案需要指定對應的 platform 才能順利 build 出來（Dockerfile from 的 image 可能僅支持 arm 或 amd）。</li>
<li><strong>單元測試錯誤突然暴增</strong>: 如果在 local 環境測試起來正常，但在 GitLab CI 時出現錯誤，那通常是「非同步」的問題，可以先用 <code>await</code> 拉長等待時間，並搭配 log 來釐清狀況。</li>
</ul>
<p>有段時間沒發純技術的文章了，希望能幫助到有相關需求的朋友們，也歡迎大家分享自己在 GitLab CI 的使用經驗。</p>
]]></content:encoded>
    </item>
    <item>
      <title>[Gitlab] 建立 Merge Request Templates，讓團隊合作更加順利！</title>
      <link>https://deanlin.net/blog/202405/gitlab-merge-request-templates/</link>
      <pubDate>Sat, 11 May 2024 10:32:39 +0800</pubDate>
      <guid>https://deanlin.net/blog/202405/gitlab-merge-request-templates/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>在多人協作的開發過程中，我們通常會需要透過 Merge Request 來進行 Code Review。 但這時會遇到一個問題：「每個人對專案的認知有差異，且文字表達能力不同。」 這會導致 Code Review 的人需要花更多的時間來理解程式，甚至浪費寶貴的時間在溝通上。</description>
      <media:content url="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-og_hu_d992785d9459a49.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>在多人協作的開發過程中，我們通常會需要透過 Merge Request 來進行 Code Review。</p>
<p>但這時會遇到一個問題：「每個人對專案的認知有差異，且文字表達能力不同。」</p>
<p>這會導致 Code Review 的人需要花更多的時間來理解程式，甚至浪費寶貴的時間在溝通上；有些交代不清楚的 Merge Request 如果被合併了，也容易在未來發現 Bug 時難以釐清問題。</p>
<p>而解決上面問題的方式也很簡單：「建立 Template（模板）」</p>
<p>如果大家都按照模板撰寫，就能保證每個 MR 都有一定的品質。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-01.webp" width="1147" height="645" alt="\[Gitlab\] 建立 Merge Request Templates，讓團隊合作更加順利！（圖 1）" fetchpriority="high" decoding="async"></p>
<h2 id="merge-request-要有哪些資訊">Merge Request 要有哪些資訊？<a class="h-anchor" href="#merge-request-%e8%a6%81%e6%9c%89%e5%93%aa%e4%ba%9b%e8%b3%87%e8%a8%8a" aria-label="這個段落的連結"></a></h2>
<p>筆者個人建議一個好的 Merge Request 要包含以下元素：</p>
<ol>
<li><strong>概要 &amp; 背景</strong>：簡短描述這次 Merge Request 的目的，讓 Code Review 的人可以快速理解前因後果。</li>
<li><strong>相關資訊</strong>：放上專案需求規格連結、關聯的 Project/branch、會議紀錄等資訊。</li>
<li><strong>變更內容</strong>：說明新增/修改/移除了什麼內容，如果邏輯複雜可以簡述演算法。</li>
<li><strong>測試步驟</strong>：描述如何驗證這次的變更，包括需要運行的測試和預期結果。</li>
</ol>
<p>大家可以參考我的 Merge Request Template 格式（Markdown 語法）：</p>
<pre tabindex="0"><code># 概要 &amp; 背景

# 相關資訊

- 需求規格: 
- 關聯的 Project/branch: 
- 任務 Ticket/會議紀錄: 

# 變更內容

- [新增] xxx
- [修改] yyy
- [移除] zzz

# 測試步驟

### 測試項目 1

- STEP 1: 
- STEP 2: 
- STEP 3: 

預期結果:
</code></pre><p>英文版：</p>
<pre tabindex="0"><code># Summary &amp; Background

# Relevant Information

- Requirement Specifications: 
- Associated Project/Branch: 
- Task Ticket/Meeting Notes: 

# Changes

- [Added] xxx
- [Modified] yyy
- [Removed] zzz

# Testing Steps

### Test Case 1

- STEP 1: 
- STEP 2: 
- STEP 3: 

Expected Result:
</code></pre><hr>
<h2 id="在-gitlab-建立-merge-request-templates-的步驟">在 Gitlab 建立 Merge Request Templates 的步驟<a class="h-anchor" href="#%e5%9c%a8-gitlab-%e5%bb%ba%e7%ab%8b-merge-request-templates-%e7%9a%84%e6%ad%a5%e9%a9%9f" aria-label="這個段落的連結"></a></h2>
<h3 id="step-1-選擇-project-default-branch建立存放-templates-的資料夾">STEP 1: 選擇 Project default branch，建立存放 Templates 的資料夾<a class="h-anchor" href="#step-1-%e9%81%b8%e6%93%87-project-default-branch%e5%bb%ba%e7%ab%8b%e5%ad%98%e6%94%be-templates-%e7%9a%84%e8%b3%87%e6%96%99%e5%a4%be" aria-label="這個段落的連結"></a></h3>
<p>我們要先在根目錄下建立 <code>.gitlab/merge_request_templates/</code> 的資料夾。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-02.webp" width="1400" height="407" alt="STEP 1: 選擇 Project default branch，建立存放 Templates 的資料夾（圖 2）" loading="lazy" decoding="async"></p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-03.webp" width="1400" height="137" alt="STEP 1: 選擇 Project default branch，建立存放 Templates 的資料夾（圖 3）" loading="lazy" decoding="async"></p>
<blockquote>
<p><strong>小提醒</strong>：一定要在「default branch（ex: main、develop）」下建立，否則是沒有效的。</p>
</blockquote>
<h3 id="step-2-在資料夾下建立md的-templates">STEP 2: 在資料夾下建立「.md」的 Templates<a class="h-anchor" href="#step-2-%e5%9c%a8%e8%b3%87%e6%96%99%e5%a4%be%e4%b8%8b%e5%bb%ba%e7%ab%8bmd%e7%9a%84-templates" aria-label="這個段落的連結"></a></h3>
<p>你可以直接複製筆者在前面提供的 Markdown Template，這邊我將檔案命名為「merge.md」。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-04.webp" width="1400" height="915" alt="STEP 2: 在資料夾下建立「.md」的 Templates（圖 4）" loading="lazy" decoding="async"></p>
<p>這邊我開一個測試的 branch 來做 Merge request，大家可以看到在 Description 旁邊有一個下拉選單，裡面的 merge 就是我們剛剛新增的模板。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-05.webp" width="1400" height="669" alt="STEP 2: 在資料夾下建立「.md」的 Templates（圖 5）" loading="lazy" decoding="async"></p>
<p>選擇後就能看到剛剛建立的 Merge request Template：</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-06.webp" width="1400" height="747" alt="STEP 2: 在資料夾下建立「.md」的 Templates（圖 6）" loading="lazy" decoding="async"></p>
<p>相信一個好的 Merge request Template 能提高專案的品質，並加速團隊的協作流程，減少不必要的溝通成本。</p>
<a class="linkcard" href="https://dean-lin.medium.com/list/7f3c9b6e2442" target="_blank" rel="noopener">
  <span class="lc-body">
    <span class="lc-title">軟體工程</span>
    <span class="lc-desc">Edit description</span>
    <span class="lc-site"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M7 17 17 7M8.5 7H17v8.5"/></svg>dean-lin.medium.com</span>
  </span>
  <span class="lc-thumb">
    <img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-card-01_hu_8de84ea4754d7f76.webp" width="320" height="320" alt="" loading="lazy" decoding="async">
  </span>
</a>

]]></content:encoded>
    </item>
    <item>
      <title>Gitlab 安裝以及我曾經遇到的坑</title>
      <link>https://deanlin.net/blog/202006/gitlab-installation-pitfalls/</link>
      <pubDate>Tue, 09 Jun 2020 09:59:21 +0800</pubDate>
      <guid>https://deanlin.net/blog/202006/gitlab-installation-pitfalls/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>技術教學</category>
      <description>Gitlab被各大企業廣泛地用於專案管理上，他可以追蹤每個project的進度設定milestone開sprint、分配不同team相互的權限，甚至在同一個project裡面也能有不同角色的權限區分，CI/CD等功能也能很方便地去實現。</description>
      <media:content url="https://deanlin.net/blog/202006/gitlab-installation-pitfalls/images/gitlab-installation-pitfalls-og_hu_ffea41822b416bcb.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>Gitlab被各大企業廣泛地用於專案管理上，他可以追蹤每個project的進度設定milestone開sprint、分配不同team相互的權限，甚至在同一個project裡面也能有不同角色的權限區分，CI/CD等功能也能很方便地去實現。</p>
<p>因為過去在使用的路上遇到各式各樣的問題，我把相關經驗整合在這裡，希望看到文章的朋友可以順利跨過這些難關，如果我的文章幫你解決問題歡迎多按幾次拍手。</p>
<p>此Gitlab安裝時的ubuntu版本為16.4，指令如有不同，請自行google，如果你願意，也非常歡迎回覆在下方分享您的經驗。</p>
<blockquote>
<p>建議硬體需求</p>
</blockquote>
<p>RAM至少4GB，以百人公司規模來說建議8GB以上大家使用上會順暢很多(如果你用官方建議2GB可能會連安裝都卡住，這部分有親自體驗過)</p>
<h2 id="安裝前置作業">安裝前置作業<a class="h-anchor" href="#%e5%ae%89%e8%a3%9d%e5%89%8d%e7%bd%ae%e4%bd%9c%e6%a5%ad" aria-label="這個段落的連結"></a></h2>
<ol>
<li>因為git在連線時需要使用ssh連線進行安全性驗證 所以需要openssh-server ca-certificates</li>
<li>gitlab支援寄信通知或是驗證功能所以需要信箱伺服器支援需要postfix</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl openssh-server ca-certificates postfix
</span></span><span style="display:flex;"><span>sudo apt-get install curl openssh-server ca-certificates postfix
</span></span></code></pre></div><h2 id="安裝gitlab">安裝gitlab<a class="h-anchor" href="#%e5%ae%89%e8%a3%9dgitlab" aria-label="這個段落的連結"></a></h2>
<ol>
<li>gitlab下載目前運行版本指令</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
</span></span><span style="display:flex;"><span>sudo apt-get install gitlab-ce<span style="color:#ff7b72;font-weight:bold">=</span>11.1.4-ce.0
</span></span></code></pre></div><p>2. 單純下載封包</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>wget — content-disposition https://packages.gitlab.com/gitlab/gitlab-ce/packages/ubuntu/trusty/gitlab-ce_11.1.4-ce.0_amd64.deb/download.deb
</span></span></code></pre></div><blockquote>
<p>建議要備份下載的deb檔案到自己的硬碟，如果日後災難復原時會用上，像我是備份到公司的NAS Server上面</p>
</blockquote>
<h2 id="gitlab環境配置">gitlab環境配置<a class="h-anchor" href="#gitlab%e7%92%b0%e5%a2%83%e9%85%8d%e7%bd%ae" aria-label="這個段落的連結"></a></h2>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo gitlab-ctl reconfigure
</span></span></code></pre></div><p>如果環境沒問題，上面這個指令會順順的過去；<strong><em>但如果做了版本升級或是降級，所有的環境都可能會產生或大或小的bug</em></strong>，官方並沒有提供一個很健全的解決方案，建議未來的使用者除非很有把握不然建議不要隨意升級。</p>
<blockquote>
<p>筆者在之後新版的gitlab有更新成功，但是舊版直接升級會遇到許多問題整理部份如下</p>
</blockquote>
<p>Gitlab 500 Error: PG::ConnectionBad:</p>
<p><a href="https://gitlab.com/gitlab-org/omnibus-gitlab/issues/1637">https://gitlab.com/gitlab-org/omnibus-gitlab/issues/1637</a></p>
<p>/opt/gitlab/embedded/bin/bundle:23:in `&lt;main&gt;’</p>
<p><a href="https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3185">https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3185</a></p>
<blockquote>
<p>輸入以下指令可獲得版本資訊:</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo gitlab-rake gitlab:env:info
</span></span></code></pre></div><p><img src="https://deanlin.net/blog/202006/gitlab-installation-pitfalls/images/gitlab-installation-pitfalls-01.webp" width="661" height="562" alt="gitlab環境配置（圖 1）" fetchpriority="high" decoding="async"></p>
<h2 id="設定對外網址">設定對外網址<a class="h-anchor" href="#%e8%a8%ad%e5%ae%9a%e5%b0%8d%e5%a4%96%e7%b6%b2%e5%9d%80" aria-label="這個段落的連結"></a></h2>
<p>輸入下面指令後尋找external_url，將其修改成自己的url與開放的port</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo vi /etc/gitlab/gitlab.rb
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>external_url <span style="color:#a5d6ff">&#39;https://domain.com&#39;</span><span style="color:#ff7b72;font-weight:bold">.</span>  <span style="color:#79c0ff">//</span><span style="color:#f85149">你自己的</span>url
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>registry_nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;redirect_http_to_https&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>   <span style="color:#79c0ff">//</span><span style="color:#f85149">是否自動轉址為</span>https
</span></span><span style="display:flex;"><span>mattermost_nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;redirect_http_to_https&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;enable&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;redirect_http_to_https&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;redirect_http_to_https_port&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">80</span>
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;ssl_certificate&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;/etc/your_path/ssl/gitlab.xxxxx.com.crt&#34;</span>   <span style="color:#79c0ff">//</span><span style="color:#f85149">如果你的</span>gitlab為https請設定ssl的路徑
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;ssl_certificate_key&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;/etc/your_path/ssl/gitlab.xxxxx.com.key&#34;</span>
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/8cfb4e440691d49a32f37be832d27329" rel="noopener">gitlab.rb</a>（GitHub Gist）</p>
<blockquote>
<p>每次修改過這個檔記得要重新配置才會生效</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo gitlab-ctl reconfigure
</span></span></code></pre></div><p>(到這一部已經可以使用gitlab了，但是如果要寄信相關還要做如下設定)</p>
<h2 id="寄信相關設定">寄信相關設定<a class="h-anchor" href="#%e5%af%84%e4%bf%a1%e7%9b%b8%e9%97%9c%e8%a8%ad%e5%ae%9a" aria-label="這個段落的連結"></a></h2>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo vi /etc/gitlab/gitlab.rb
</span></span></code></pre></div><p>把下面這些貼到最下面後sudo gitlab-ctl reconfigure就生效了</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#79c0ff">//</span><span style="color:#f85149">下面的是</span>email信箱設定(<span style="color:#f85149">此為</span>gmail範例)
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_enable&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_address&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;smtp.gmail.com&#34;</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_port&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">587</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_user_name&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;your@gmail.com&#34;</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_password&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;your_password&#34;</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_domain&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;smtp.gmail.com&#34;</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_authentication&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;login&#34;</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_enable_starttls_auto&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_tls&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">false</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_openssl_verify_mode&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#39;peer&#39;</span> <span style="color:#8b949e;font-style:italic"># Can be: &#39;none&#39;, &#39;peer&#39;, &#39;client_once&#39;, &#39;fail_if_no_peer_cert&#39;, see http://api.rubyonrails.org/classes/ActionMailer/Base.html</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_ca_path&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;/etc/ssl/certs&#34;</span>
</span></span><span style="display:flex;"><span>gitlab_rails<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;smtp_ca_file&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;/etc/ssl/certs/ca-certificates.crt&#34;</span>
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/16b5ea24384f6fe888cd99722b832ba3" rel="noopener">gitlab_gmail.rb</a>（GitHub Gist）</p>
<p>可下指令測試是否設定成功</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo gitlab-rails console
</span></span><span style="display:flex;"><span>Notify.test_email<span style="color:#ff7b72;font-weight:bold">(</span>‘email@example.com’, ‘test’, ‘test’<span style="color:#ff7b72;font-weight:bold">)</span>.deliver_now
</span></span></code></pre></div><p>但是當gitlab的server有設定雙網卡（同時有內網以及外網）的時候就有可能出現email無法寄送的狀況，這個時候你要確定你外網的優先權必須要高於內網。</p>
<p>看mail錯誤log</p>
<pre tabindex="0"><code>vi /var/log/mail.log
</code></pre><p>改mail postfix設定</p>
<pre tabindex="0"><code>vi /etc/postfix/main.cf
postfix reload
</code></pre><h2 id="ssh對外設定">ssh對外設定<a class="h-anchor" href="#ssh%e5%b0%8d%e5%a4%96%e8%a8%ad%e5%ae%9a" aria-label="這個段落的連結"></a></h2>
<p>如果你對外網址的22 port已經被其他專案佔用了（ex:我公司），所以要將預設ssh的22 port改為轉址的223 port(或是其他你希望的)，一樣是在sudo vi /etc/gitlab/gitlab.rb設定，這樣在gitlab才能用ssh下載</p>
<pre tabindex="0"><code>gitlab_rails[‘gitlab_shell_ssh_port’] = 223
</code></pre><h2 id="nginx設定">nginx設定<a class="h-anchor" href="#nginx%e8%a8%ad%e5%ae%9a" aria-label="這個段落的連結"></a></h2>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;enable&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;redirect_http_to_https&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#79c0ff">true</span>
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;redirect_http_to_https_port&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">80</span>
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;ssl_certificate&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;/etc/your_path/ssl/gitlab.xxxxx.com.crt&#34;</span>   <span style="color:#79c0ff">//</span><span style="color:#f85149">如果你的</span>gitlab為https請設定ssl的路徑
</span></span><span style="display:flex;"><span>nginx<span style="color:#ff7b72;font-weight:bold">[</span><span style="color:#a5d6ff">&#39;ssl_certificate_key&#39;</span><span style="color:#ff7b72;font-weight:bold">]</span> <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;/etc/your_path/ssl/gitlab.xxxxx.com.key&#34;</span>
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/d2485274a4609b5f8ceef16b2db507cc" rel="noopener">gitlab_nginx.rb</a>（GitHub Gist）</p>
<h2 id="讓gitlab可通內網外網">讓Gitlab可通內網外網<a class="h-anchor" href="#%e8%ae%93gitlab%e5%8f%af%e9%80%9a%e5%85%a7%e7%b6%b2%e5%a4%96%e7%b6%b2" aria-label="這個段落的連結"></a></h2>
<p>在gitlab分配兩張網卡後需要完成以下步驟</p>
<blockquote>
<p>先看新增的網卡名稱</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cd /proc/sys/net/ipv4/conf
</span></span></code></pre></div><p>確認完網卡後將他們編輯加入</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo vi /etc/network/interfaces
</span></span><span style="display:flex;"><span>auto ethXXX
</span></span><span style="display:flex;"><span>iface ethXXX inet dhcp
</span></span></code></pre></div><p>改完後</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo /etc/init.d/networking restart
</span></span></code></pre></div><p>用ifconfig查看是不是抓到</p>
<blockquote>
<p>設定路由可以透過閘道連通</p>
</blockquote>
<p>sudo /sbin/route add 10.1.1.1(目標內網ip) gw 10.1.1.254(內網閘道) dev ens192(網卡)</p>
<blockquote>
<p>設定NAS上此共享資料夾必須符合NFS設定可參閱這篇文章</p>
</blockquote>
<p><a href="https://web.archive.org/web/20180906074211/http://blog.xuite.net:80/tolarku/blog/495291815-Qnap&#43;%E8%A8%AD%E5%AE%9A&#43;NFS&#43;%E5%88%86%E4%BA%AB%E8%A8%AD%E5%AE%9A&#43;-&#43;nfs&#43;export" title="原網頁已失效，連到網際網路檔案館的存檔">http://blog.xuite.net/tolarku/blog/495291815-Qnap+%E8%A8%AD%E5%AE%9A+NFS+%E5%88%86%E4%BA%AB%E8%A8%AD%E5%AE%9A+-+nfs+export</a></p>
<blockquote>
<p>確認是否可連通，並觀看有哪些資料夾</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt install nfs-common
</span></span><span style="display:flex;"><span>showmount -e 10.1.1.1<span style="color:#ff7b72;font-weight:bold">(</span>目標內網ip<span style="color:#ff7b72;font-weight:bold">)</span>
</span></span></code></pre></div><blockquote>
<p>將NAS上的共享資料夾掛載到ubuntu上面</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo mount -t nfs 10.1.1.1<span style="color:#ff7b72;font-weight:bold">(</span>目標內網ip<span style="color:#ff7b72;font-weight:bold">)</span>:ServerGit /home/your_path/gitlab_backup
</span></span></code></pre></div><blockquote>
<p>確認是否掛載</p>
</blockquote>
<pre tabindex="0"><code>df -h
</code></pre><h2 id="gitlab定時自動備份到nas的設定">gitlab定時自動備份到NAS的設定<a class="h-anchor" href="#gitlab%e5%ae%9a%e6%99%82%e8%87%aa%e5%8b%95%e5%82%99%e4%bb%bd%e5%88%b0nas%e7%9a%84%e8%a8%ad%e5%ae%9a" aria-label="這個段落的連結"></a></h2>
<p>在/etc/gitlab/gitlab.rb設定gitlab的備份路徑</p>
<pre tabindex="0"><code>gitlab_rails[‘backup_path’]=”/home/your_path/gitlab_backup/”
</code></pre><p>每個月1日創建本月的資料夾的script</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#79c0ff">now_month</span><span style="color:#ff7b72;font-weight:bold">=</span>”<span style="color:#ff7b72">$(</span>date +’%Y%m’<span style="color:#ff7b72">)</span>”
</span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic">#echo “$now_month”</span>
</span></span><span style="display:flex;"><span>cd /home/your_path/gitlab_backup
</span></span><span style="display:flex;"><span>mkdir <span style="color:#79c0ff">$now_month</span>
</span></span></code></pre></div><p>將產生的backup檔案轉移到月份資料夾底下的script,並刪除比較久的資料</p>
<pre tabindex="0"><code>mv /home/your_path/gitlab_backup/*.tar /home/your_path/gitlab_backup/$(date +’%Y%m’)
find /home/your_path/gitlab_backup/$(date +’%Y%m’) -name “*gitlab_backup.tar” -mtime +3 -exec rm -rf {} \;
find /home/your_path/gitlab_backup/$(date “+%Y%m” -d ‘1 month ago’) -name “*gitlab_backup.tar” -mtime +3 -exec rm -rf {} \;
</code></pre><p>排程設定</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo crontab -e
</span></span><span style="display:flex;"><span><span style="color:#a5d6ff">1</span> <span style="color:#a5d6ff">0</span> <span style="color:#a5d6ff">1</span> * * sh /home/your_path/script/mkdir.sh
</span></span><span style="display:flex;"><span><span style="color:#a5d6ff">1</span> <span style="color:#a5d6ff">1</span> * * * /opt/gitlab/bin/gitlab-rake gitlab:backup:create
</span></span><span style="display:flex;"><span><span style="color:#a5d6ff">1</span> <span style="color:#a5d6ff">2</span> * * * sh /home/your_path/script/mv_to_month.sh
</span></span></code></pre></div><blockquote class="pullquote"><p>Gitlab 的學問博大精深，希望這篇文章讓初學者上手時更加輕鬆。</p>
</blockquote>
]]></content:encoded>
    </item>
  </channel>
</rss>
