Macam mana saya deploy fajarhac.com yang dijana dengan hugo secara automatik termasuk mengoptimumkan kualiti

November 03, 2016

Saya telah memindahkan blog dari wordpress ke hexo, kemudian menggabungkan blog dan web senarai projek ke fajarhac.com menggunakan Hugo. Perpindahan ke statik web daripada CMS sangat berbeza dan banyak masalah yang perlu diselesaikan sendiri.

Sebagai seorang programmer, cabaran ini sangat menyeronokkan. Alhamdulillah segala masalah berjaya saya selesaikan walaupun mengambil masa berbulan. Dalam artikel kali saya akan menulis langkah demi langkah untuk men- deploy -kan sebuah web yang dijana menggunakan Hugo dengan cara yang paling senang dan asset-asset seperti gambar (png, jpg), html, css dan javascript juga dioptimumkan supaya laman web kita jadi pantas. Akhir sekali, saya akan ajarkan macam mana nak meng- automatik -kan semua langkah ini.

Saya juga menyiapkan satu tema Hugo (Hugo theme) yang besar dan sesuai untuk semua jenis web dan dioptimumkan dengan langkah-langkah ini.

Perkakas-perkakas yang diguna

  1. Hugo - pemproses web statik

  2. Node.js - digunakan untuk menulis skrip untuk memproses aset-aset. Gulp sangat penting. Skrip boleh copy paste saja, tapi pastikan anda pasang (install) node.js, baru boleh jalankan skrip.

  3. Git - version control system.

  4. Nginx - sebab web ini ialah web statik iaitu sekadar fail-fail html, kita perlukan web server. Nginx adalah web server yang terbaik untuk sebuah web statik. Atau anda boleh gunakan Apache.

  5. Pelayan VPS (VPS Server) - saya beli servis VPS dari Digital Ocean, USD 10 (~ RM42) per bulan. Agak mahal tapi saya ada banyak web dan yang paling penting saya boleh guna untuk host automation script. Ada VPS server ini seumpama ada sebuah pc yang hidup 24 jam. Nak guna Digital Ocean? Klik referral link saya dan daftar untuk dapatkan diskaun USD 10.

Saya menulis artikel ini dengan harapan pembaca dah biasa guna semua perkakas di atas. Semua perkakas di atas hendaklah dipasang di pelayan VPS anda. Kalau ada perkara tak faham juga, boleh tanya dekat komen di bawah.

Langkah demi langkah

  1. Sediakan direktori web anda dan git commit semuanya. Untuk mengelakkan sebarang konflik dengan web yang akan diproses di pelayan VPS anda anda, pastikan anda ada fail .gitignore yang ditulis :

    public
    node_modules

themes ```

Contoh struktur direktori web :

```text
fajarhac_com
|-- archetypes/
|-- content/
|   |-- blog/
|   |	  |-- article-one.md
|   |	  |-- article-two.md
|   |
|   |-- projects/
|   		|-- project-one.md
|
|-- data/
|-- layouts/
|-- node_modules/
|-- themes/
|-- .gitignore
|-- config.toml
|-- gulpfile.js
|-- package.json
```
  1. Sediakan direktori-direktori yang membolehkan kita git push sahaja untuk kemas-kini web secara automatik. Berdasarkan artikel autodeploy dari digital ocean ini, saya tulis skrip bash untuk senangkan hidup semuanya siap dengan satu command saja.

    Di pelayan VPS kita, muat-turun dan jalankan skrip.

    # download skrip - guna gist dan git clone
    $ git clone https://gist.github.com/6aa1ed19b3e74fcd19aee6bf4b3d4775.git
    $ cd ~/
    $ sudo chmod +x /path/to/prepare-git-repo-and-deploy.sh
    $ path/to/prepare-git-repo-and-deploy.sh mywebsite

    Sekarang pastikan anda akan ada 2 direktori : satu untuk direktori untuk host web mywebsite dan satu lagi ialah repositori git mywebsite.git.

    Segala fail untuk web anda berada di mywebsite/public/. Jadi jangan lupa sediakan Nginx server block untuk serve web pada direktori ini.

    Contoh:

    server {
    	listen 80;
    	root /home/username/fajarhac_com/mywebsite/public/;
    	...
    }
  2. Sekarang kita kena tambah git repo yang dibina di pelayan VPS tadi ke development kita.

    Di local komputer :

    $ git remote add live [email protected]:~/fajarhac_com/mywebsite.git/

    Mulai sekarang, apabila kita git push live master, web akan dibina tanpa perlu kita log masuk ke pelayan VPS lagi.

  1. Tambah fail gulpfile.js (lihat struktur fail di 1) sebagai skrip untuk memproses gambar-gambar, html, css dan js. Penting untuk mengoptimumkan kelajuan web.

    Kandungan dalam fail gulpfile.js bergantung pada keinginan masing-masing. Lihat contoh gulpfile.js saya di gist github yang akan sentiasa dikemaskini.

    Sebab kita guna node.js, kita perlukan package.json yang mengandungi senarai dependencies yang akan digunakan dalam gulpfile.js.

    Jadi, jalan npm install <packages> --save. Berdasarkan gulpfile.js saya, saya perlukan :

    $ npm install gulp gulp-jimp gulp-htmlmin gulp-filelist
  2. Seterusnya kita nak segala arahan dalam gulpfile.js ini dijalankan di server selepas kita git push. Untuk itu, kita kena masukkan skrip yang nak dijalankan pada fail post-receive pada repositori git di pelayan VPS kita.

    Log masuk pelayan VPS, sunting fail post-receive dalam repositori git mengikut kehendak anda. Contoh post-receive saya :

    #!/bin/sh
    git --work-tree=/home/username/fajarhac_com --git-dir=/home/username/fajarhac_com.git checkout -f
    cd /home/username/fajarhac_com
    hugo
    npm install
    ./node_modules/.bin/gulp create-nginx-redirect-file
    ./node_modules/.bin/gulp build-html
    ./node_modules/.bin/gulp build-images
    
  3. Belum siap lagi! Perasan tak yang kita masukkan themes dalam fail .gitignore? Maksudnya, web statik kita belum ada tema. Jadi tambah tema untuk web di pelayan VPS.

    Untuk memastikan tema yang saya gunakan sentiasa boleh di kemas-kini dengan mudah saya gunakan git clone.

    git clone <theme-repo> themes/<theme-name>

    Sini ada sikit tidak puas hati, sebab saya perlu log masuk ke pelayan VPS setiap nak kemas-kini tema. Walau bagaimana pun, perkara ini mungkin hanya sebulan sekali.

  4. Sekarang, semua dah setel. Jom ke PC kita dan git push.

    $ git add .
    $ git commit -m "Initial commit"
    $ git push live master
    

    Lihat laman web anda, semuanya menjadi. Sekiranya ada cadangan, masalah dan perkara yang tak faham, sila komen di bawah.

Beberapa masalah yang dihadapi

  1. npm permission error

    Selesaikan dengan => sudo chown -R $USER:$GROUP ~/.npm

    $ git push live master
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 303 bytes | 0 bytes/s, done.
    Total 3 (delta 2), reused 0 (delta 0)
    remote: Started building site
    remote: ERROR: 2016/10/28 05:15:02 pygments.go:111: Error: no lexer for alias 'markdown' found
    remote: 0 of 4 drafts rendered
    remote: 0 future content
    remote: 104 pages created
    remote: 0 non-page files copied
    remote: 125 paginator pages created
    remote: 10 categories created
    remote: 72 tags created
    remote: in 2837 ms
    remote: npm WARN package.json [email protected] No description
    remote: npm WARN package.json [email protected] No repository field.
    remote: npm WARN package.json [email protected] No README data
    remote: npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
    remote: npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
    remote: npm WARN deprecated [email protected]: graceful-fs v3.0.0 and before will fail on node releases >= v7.0. Please update to graceful-fs@^4.0.0 as soon as possible. Use 'npm ls graceful-fs' to find it in the tree
    remote: npm ERR! Linux 3.13.0-43-generic
    remote: npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install"
    remote: npm ERR! node v4.6.1
    remote: npm ERR! npm  v2.15.9
    remote: npm ERR! path /home/fakhrul/.npm/micromatch/2.3.11
    remote: npm ERR! code EACCES
    remote: npm ERR! errno -13
    remote: npm ERR! syscall mkdir
    remote:
    remote: npm ERR! Error: EACCES: permission denied, mkdir '/home/fakhrul/.npm/micromatch/2.3.11'
    remote: npm ERR!     at Error (native)
    remote: npm ERR!  { [Error: EACCES: permission denied, mkdir '/home/fakhrul/.npm/micromatch/2.3.11']
    remote: npm ERR!   errno: -13,
    remote: npm ERR!   code: 'EACCES',
    remote: npm ERR!   syscall: 'mkdir',
    remote: npm ERR!   path: '/home/fakhrul/.npm/micromatch/2.3.11',
    remote: npm ERR!   parent: 'findup-sync' }
    remote: npm ERR!
    remote: npm ERR! Please try running this command again as root/Administrator.
    remote:
    remote: npm ERR! Please include the following file with any support request:
    remote: npm ERR!     /home/fakhrul/fajarhac_com/npm-debug.log
    remote: hooks/post-receive: 7: hooks/post-receive: gulp: not found
    remote: hooks/post-receive: 8: hooks/post-receive: gulp: not found
    remote: hooks/post-receive: 9: hooks/post-receive: gulp: not found
    remote: Overwrite old with new. Then reload nginx.
    remote: cat: /home/fakhrul/fajarhac_com/tmp/redirect-blog-slug-only: No such file or directory
    remote:  * Reloading nginx nginx
    remote:    ...done.
    To [email protected]:~/fajarhac_com.git
       4292b9e..7d41914  master -> master
    
  2. gulp not found

    guna local ./node_modules/.bin/gulp

    remote: npm WARN package.json [email protected] No README data
    remote: hooks/post-receive: 7: hooks/post-receive: gulp: not found
    remote: hooks/post-receive: 8: hooks/post-receive: gulp: not found
    remote: hooks/post-receive: 9: hooks/post-receive: gulp: not found
    remote: Overwrite old with new. Then reload nginx.
    

Penutup

Keseluruhannya, segala perubahan seperti tambah artikel baru dan gambar baru, semuanya dioptimumkan secara automatik. Saya cuma perlu git commit dan git push yang sememangnya rutin programmer.

2023, Built with Gatsby

Hire MeNota & idea