如何在 Ubuntu 架設 private Git server (Gitolite + GitWeb)

自己租的 VPS 經歷上次的更新 MySQL 5.7 版本之後就爛掉,資料庫變成只能讀不能儲存…..

一氣之下,就把上面的專案都把它放到其他的主機裡,這台就重新的 reset 掉。

這台目前打算就拿來架設:Git server 與 CI server 作為日後有private Git 專案使用,本來打算是是架設 GitLab 作為 Git server,可是現在目前的VPS規格不夠好。

據說 GitLab 要跑得順的話,需要將近 8G RAM 才有辦法…..於是目前就先放棄了….先打算架設版本控制跟可以做持續整合的服務的 server 為主。

在經歷了一番GitLab server 安裝不起來之後,現在是轉向這篇要講的東西了,這個方式的 private Git server 算是比較輕量型的方案,也是比較合理的。

所以以下就是安裝 Gitolite + GitWeb 的方法。

[參考的資料]

install_git_server.sh

how-to-create-own-git-server-with-gitolite-and-gitweb-in-ubuntu

 

  1. 首先,先 setup 一個乾淨 VPS 並裝好Ubuntu 14.04 或是 16.04 的 LTS 版本,沒有的話就自己去租一臺吧,DigitalOcean 都有很便宜的價格有可以加上 Github 的學生方案可以使用,可以拿到 50 美金作運用。不過,不用的話要記得關掉,不然可是會一直的扣錢喔!
  2. 接著跑下面的 bash script: initial_ubuntu.sh,使用方式是:
    # initial_ubuntu.sh
    #!/bin/bash
    #Firstly, we have to login the root user via ssh.
    # install some required package
    # set locales (zh_TW.UTF-8 or en_US.UTF-8)
    
    sudo locale-gen "en_US.UTF-8"
    
    sudo dpkg-reconfigure locales
    
    sudo echo 'LC_ALL="en_US.UTF-8"' > /etc/default/locale
    
    export USERNAME=$1
    
    if [ "$USERNAME" = "" ]
    then
    echo 'please add the user name!'
    exit 1;
    fi
    
    sudo apt-get update
    
    echo 'Upgrading the package...It will be let user type the yes | no'
    echo 'We have to notice that this upgrade package will be installed the Apache2 HTTP server...'
    # skip the kernel update (OpenVZ is not allowed updating the Kernel.)
    sudo apt-mark hold linux-image-generic linux-headers-generic
    sudo apt-get upgrade
    
    sudo apt-get install -y curl wget vim ufw
    
    sudo useradd -m $USERNAME
    sudo usermod -s /bin/bash $USERNAME
    sudo adduser $USERNAME sudo
    echo 'Please set password for the $USERNAME ...'
    sudo passwd $USERNAME
    
    sudo ufw enable
    sudo ufw default deny
    sudo ufw allow in ssh
    sed -i 's/PermitRootLogin yes/PermitRootLogin no/g' /etc/ssh/sshd_config
    sudo echo 'ClientAliveInterval 60' >> /etc/ssh/sshd_config
    sudo service ssh restart
    
    echo 'done.'
    
    exit 0;
    
    
    bash initial_ubuntu.sh your-usernmae
    

    可以安裝一些基本或是需要的套件在以及設定基本的軟體防火牆還有 SSH 的簡易安全防禦設定。
    這裡的 your-username 在範例中,我們先填  peter 做為這一次範例的使用者名稱。

  3. 接下來就是要安裝 Git server 了,首先先依照步驟慢慢來。
  4. 首先,先更新一下軟體來源庫的網址。
    sudo apt-get update
    

    接著,在安裝 Git 套件:git-core,接著新增一個使用者

    sudo apt-get install git-core -y
    
    #新增一個使用者
    sudo adduser \
     --system \
     --shell /bin/bash \
     --gecos 'git version control' \
     --group \
     --disabled-password \
     --home /home/git git
    
    #切換使用者:git
    sudo su -l git
    
  5. 切換到 git 使用者的家目錄下面並 clone Gitolite 的 repository.
    在家目錄下建立 bin 目錄。

    mkdir $HOME/bin
    cd /home/git/bin
    git clone git://github.com/sitaramc/gitolite
    
  6. 驗證使用者為 git 相關的設定 (user verification)
    # Verification 登入使用者 git
    # ------------------------------
    # git@ubuntu:~$ ls bin/gitolite/src/gitolite
    # git@ubuntu:~$
    # ------------------------------
    
    # ssh key generation and we have to type one and more enter key to check some interactive message.
    # In your Linux client and run your-name@your-ip-address-or-hostname:~$ ssh-keygen -t rsa -C "Git-Admin"
    # If you have already had the id_rsa.pub, we can skip previous step and run following command directly: (我們使用這一項)
    # scp ~/.ssh/id_rsa.pub username@git-server-FQDN-or-its-ip-address:~ then go back to the git-server
    
    
  7. 我們使用的是將本地端的 id_rsa.pub 上傳到 Git server 上
    要注意的是,我們在新建使用者 Git 的時候,我們並沒有為使用者: git 設定一組密碼,因此使用 scp 傳輸 public key 時,我們需要先傳給另一個使用者。
    並登入之後把檔案搬移到 git 使用者的家目錄下面。

    scp ~/.ssh/id_rsa.pub username@git-server-FQDN-or-its-ip-address:~
    
  8. 接著,執行下面的指令:
    sudo mv id_rsa.pub /home/git/Git-Admin.pub
    sudo chown git:git /home/git/Git-Admin.pub
    sudo su -l git
    bin/gitolite/src/gitolite setup -pk Git-Admin.pub
    # 離開使用者 git (logout)
    exit
    
  9. 安裝 GitWeb 與 Apache2 以及修改權限
    sudo apt-get install gitweb apache2
    sudo usermod -G git www-data
    sudo chmod -R 750 /home/git/repositories/
    
  10. 修改 gitolite.rc 設定檔並找到下面這一行改成:
    # sudo vim /home/git/.gitolite.rc
    UMASK value as 0027
    
  11. 修改 /etc/gitweb.conf 的檔案
    sudo vim /etc/gitweb.conf
    並修改下面這幾行:

    $projectroot = "/home/git/repositories/";
    $projects_list = $projectroot;
    
  12. 重新啟動 Apache HTTP server
    sudo service apache2 restart
    
  13. 有啟動防火牆設定的話,記得將 ufw 允許 http 可以有外部連線。
    sudo ufw allow http
    
  14. 複製 gitweb.conf 設定檔
    sudo cp /etc/apache2/conf.d/gitweb /etc/apache2/conf-available/gitweb.conf
    cd /etc/apache2/conf-enabled
    sudo ln -s ../conf-available/gitweb.conf
    
  15. 修改位在:/etc/apache2/conf-available/gitweb.conf 的設定檔
    <Directory /usr/share/gitweb>
    # 修改這一行
    Options +FollowSymLinks +ExecCGI
    AddHandler cgi-script .cgi
    # 如果有 HTTPS 連線的需要,則需要使用以下的設定
    # 從下面開始,是要啟動 rewrite module 之外
    # 設定強制使用 HTTPS 進行連線
    # 可以進行 HTTPS 連線有:Cloudflare and Let's encrypt
    AllowOverride All
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    </Directory>
    
    
    # 接著重啟 Apcahe2 服務與啟用 cgi module
    sudo a2enmod cgi
    sudo service apache2 restart
    
  16. 最後,輸入網址:http://you-ip-address-or-hostname/gitweb 就可以看到 GitWeb 的清單了。
  17. 下面是要新建一個 repository 的方法
    git clone git@your-ip-address:gitolite-admin.git
    
  18. 接著切換到:gitolite/conf/gitolite.conf 編輯:
    
    RW+ = Git-Admin
    
    repo testing
    
    RW+ = @all
    

    像這樣就是新增一個名字叫做 testing 的 repository。如果要新增其他的,就依照新增 testing 的格式,再增加一個 repository.
    接著輸入: git commit -m “your commit message” && git push origin master

    這樣就完成新增一個 repository 了。

    [延伸閱讀]

    1.  為 VPS 增加 SSL 憑證:以  Let’s encrypt 為例
    2. 如何使用 Cloudflare 作為 DNS 代管
    3. 為你的 GitWeb 增加 HTTP-basic-Authentication
    4. 利用 reverse proxy server 把 git server 藏在其後面,增加安全性,以 Nginx 為例

在虛擬共享主機上使用 Git 版本控制專案

一般在使用 Git 作為版本控制與部署專案時,都是使用指令居多,很少會使用像是檔案傳輸等方式部署,而且用檔案方式部署我們不太能知道哪些檔案已經傳過,或是還沒有傳上去等。

有鑑於這個問題,我們在使用只提供 FTP/FTPS 等檔案傳輸協定傳輸檔案的共享主機(shared hosting)時,可以使用 git-ftp 來幫我們完成 deployment 的任務。

本篇文章,就是要來介紹與使用 git-ftp 來幫助我們達成這項任務。

初始化一些 Git 指令的設定(環境設定)


git config --global user.email "your-mail-address"

git config --global user.name "your-user-name"

git config --global core.editor "vim"

git config --global color.ui true

git config --global alias.lg "log --color --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --"

先建立一個 hello-world 的專案


mkdir hello-world

cd hello-world

git init

echo "<?php echo 'hello world'; ?>" > index.php

git add .

git commit -m "initial commit"

下載 git-ftp 套件來安裝。

照著 官方 INSTALL.md 加入 ppa repository


sudo add-apt-repository ppa:resmo/git-ftp
sudo apt-get update

可以參考官方的安裝教學文件,本篇使用 Linux Ubuntu 與Windows 來進行安裝。這時候可能會在 sudo apt-get update 時,發現 Package 的 source ppa 發生 404 Not found 的現象。


W: 無法取得 http://ppa.launchpad.net/resmo/git-ftp/ubuntu/dists/wily/main/binary-amd64/Packages,404 Not Found

W: 無法取得 http://ppa.launchpad.net/resmo/git-ftp/ubuntu/dists/wily/main/binary-i386/Packages,404 Not Found

E: Some index files failed to download. They have been ignored, or old ones used instead.

[Ubuntu]

為了避免這種情形的發生,因此需要自己手動安裝 deb package。因此需要自己前往這個網站:https://launchpad.net/ubuntu/+source/git-ftp

目前的新版本為:1.2.0-1 可以使用這個版本,並下載:git-ftp_1.2.0-1_all.deb 檔案。下載回來之後,便雙擊安裝了。安裝好之後,就有 git-ftp 的指令可以使用了。如下:

%e5%bf%ab%e7%85%a71

 

[Windows]

一開始需要先安裝 Git for Windows (mysysgit)。安裝過程中,可以都用預設,唯一可以自己更改安裝的路徑,需要自己去注意一下。

安裝好之後,回到 Windows 桌面,並點滑鼠右鍵,這時會多一個:Git Bash here 的選項可以選擇。接著可以執行下面的步驟:

 

cd ~
git clone https://github.com/git-ftp/git-ftp git-ftp.git
cd git-ftp.git && chmod +x git-ftp
cp ~/git-ftp.git/git-ftp /bin/git-ftp

可以參考下面安裝示意圖:
%e5%bf%ab%e7%85%a72

[使用方法]

[init] 第一次把專案透過 git-ftp 放到 FTP/FTPS sever 上。

git-ftp init -u "your-account-name" -p "your-password" - ftpes://peter.nctu.me/web/peter.nctu.me/public_html/hello-world

[push] 已經 init 過,需要去更新 server 上面的檔案(使用 push 推上更新過後的 commit git-ftp 會自己自動比對版本做更新檔案的動作。)

git-ftp push -u "your-account-name" -p "your-password" - ftpes://peter.nctu.me/web/peter.nctu.me/public_html/hello-world

[.gitignore 問題] 若是有些 library 檔案,像使用 PHP Composer 則需要去控制 dependency package. 這些 package 並不會進到版本控制中。而且在用 git-ftp 時,
也會參考 .gitignore 的檔案。若要解決這個問題,需要在專案的目錄底下新增:.git-ftp-include 作為宣告,這一些檔案或目錄,需要一併 push 上去。

下面是 .git-ftp-include 的內容。(當然這個檔案也可以加到版本控制中,讓人方便部署,也知道該部署什麼額外的目錄上去。)

!vendor/
!token/
!bower_components/

這樣之後在 push 的時候,就不會因為 library 目錄 被 ignore 而去忽略沒有上傳到了。

2018/01/18 更新

更新關於使用git-ftp走sftp協定來部署的方式。

git-ftp如果要走sftp的協定做部署的話,需要預先安裝好libcurl-dev以供支援。

可以的話,也可以順便把curl套件安裝起來,因為這是一個蠻好用的指令在對網址請求的時候很好使用。下面預先假設是用Linux Ubuntu 16.04作為示範。

在執行安裝套件之前,都先需要更新鏡像的來源:


sudo apt-get update

安裝curl套件


sudo apt-get install curl

安裝libcurl-dev


sudo apt-get install lib-curl-dev

這個時候,會跳出這是一個虛擬套件的名稱等字樣,如下圖所示:

我們選圖中第一個作為我們要安裝的套件名稱。


sudo apt-get install libcurl4-openssl-dev

接下來按照下面的指令步驟去執行,到編輯rules檔案時為止。

在rules檔案編輯,我們依照下列圖片中的方式進行編輯:

注意

有一點需要注意的是,因為重新編譯curl時所需要用到的openssl為舊版的。

使用新版的時候,在rebuild-package的時候會不成功。因此需要將openssl版本降級。下列是相關的原因。

against OpenSSL 1.1.0. This won’t work. You need 1.0.2 or earlier. The OpenSSL guys changed the API on 1.1.0.

若沒有把openssl的套件版本降級的話,將會出現像下列那樣的錯誤:


dereferencing pointer to incomplete type ‘EVP_PKEY {aka struct evp_pkey_st}’
if (pk->type == EVP_PKEY_RSA &&

降級openssl 相關package的方法


# 在第24行時,先去確認openssl版本是否為1.0.2的版本,若不是,需要做下面降級的動作

apt-get update

apt-get install openssl=1.0.2g-1ubuntu4.10

apt-get install libssl-dev=1.0.2g-1ubuntu4.10

apt-get install libssl1.0.0=1.0.2g-1ubuntu4.10

# 接著在從build_sftp_curl.sh中的第25行繼續

最後檢查curl是否有支援sftp協定,如果有的話,會像下面的示意圖一樣,在protocols那裡多了一個叫做:『sftp』

測試是否可以正常運行

試著執行下面的命令


git-ftp init -u "user-name" -p "your-password" - sftp://45.77.107.31/home/root

萬一有錯誤的話,但是錯誤的資訊太少,則可以加入下列參數加以使用,並看到更多的訊息。


git-ftp init -u "user-name" -p "password" - sftp://45.77.107.31/home/root -vv

如果正常的話,就可以下面的截圖一樣,成功的把專案部署到指定的server上了。

 

Git 實用技巧

在這篇文章,記錄一些使用 Git 的技巧。

回復上一個 commit (不知道 commit-id 可以使用 git log 查詢)


git reset commit-id --hard

將遠端的 commit 強制更新到指定回復的 commit 時間點


git push repo-url branch-name --force

刪除一個標籤


git tag -d tag-name

刪除遠端上的標籤


git push repo-url :tag_name

加入一個標籤


git tag tag-name

將一個標籤推送到遠端


git push repo-url tag tag-name

查看所有標籤


git tag

解决 Github push 時發生的錯誤:The requested URL returned error: 403 Forbidden while accessing

這個錯誤是因為使用了較低的版本 Git 發生的版本:1.7.10 以下。

解決方式:Github 目前沒有提供解法,但是有敘述這個 issue 官方解法:升級 Git 指令工具的版本,升級到 1.7.10 以上。

但是對使用 shared hosting 上附的 Git 就很舊了再叫它去升級,恐怕有難度,所以這裡提供了一種不升級 Git 也可以照常繼續使用並不會有 403 的錯誤出現。

修改 /path/to/your-repo-name/.git/config 這個設定檔案。

將原本的


[remote "origin"]
url = https://github.com/your-account-name/sample_repo.git

改成


[remote "origin"]
url = https://your-account-name@github.com/wangz/example.git

Github 官方 issue 界少與目前處裡方式與說明記者會。

以上,想到再補充。