============
== vtranq ==
============

Upgrade Centos 7, cài đặt Go và Hugo

Centos Go Hugo

MỤC TIÊU CHÍNH: Thiết lập một blog dùng flat-file CMS có hỗ trợ Markdown

TAKE-AWAY:

  • Không dùng WordPress vì WordPress cồng kềnh, thiết lập rườm rà, nội dung lại lưu trên database nên không versioning được, và thủ tục để edit cũng rườm rà.
  • Đã thử Grav, Pico nhưng thấy cũng cùi, rườm rà
  • Sau đó bắt gặp được Hugo. Hugo là flat file CMS viết bằng Go, hiện là flat file CMS tốc độ nhanh nhất.
  • Hugo viết bởi Go lang lead ở Google
  • Hugo dựa trên ý tưởng của Jekyll nhưng tốc độ nhanh hơn nhiều
  • Để compile Hugo thì cần phải có Go
  • Lúc compile Go thì có một số lỗi. Nghi ngờ phiên bản Centos hiện tại cũ quá nên quyết định upgrade Centos lên phiên bản mới nhất
  • Gatsby không nhanh, không tiện dụng, không hiện đại bằng Hugo. Gatsby toàn quảng cáo sai sự thật, rườm rà khó sử dụng, lúc nào cũng muốn câu, lôi kéo khách hàng sử dụng dịch vụ cloud và hosting của họ –> tẩy chay Gatsby

Nâng cấp Centos 7

Các bước thực hiện:

  • Kiểm tra phiên bản hiện tại
  • Chuẩn bị repo
  • Xem available kernel
  • Install phiên bản mới nhất
  • Kiểm tra thông tin boot menu
  • Thiết lập kernel mặc định để boot
  • Cập nhật lại boot menu
  • Khởi động lại
  • Kiểm tra mount xem có bị trường hợp readonly (ro)
  • Mount lại readwrite
  • Cập nhật /etc/fstab để bỏ barrier=1
  • Khởi động lại
uname -msr
sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
sudo rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
yum list available --disablerepo='*' --enablerepo=elrepo-kernel
sudo yum --enablerepo=elrepo-kernel install kernel-lt
awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg
grep saved /boot/grub2/grubenv
(edit /etc/default/grub)
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
uname -msr
mount
mount -n -o remount,defaults /dev/sda1 /
(edit /etc/fstab)
reboot

Cài GCC 9.4.0 từ source (tested OK)

  • Khi cài Hugo extended từ binary release thì khi chạy Hugo nó yêu cầu phải có libstdc mới, do đó cần phải cài GCC phiên bản mới từ source
  • CentOS 7 distribution (as well as RHEL 7) ships with a somewhat outdated version of the GCC compiler (4.8.5 on CentOS 7.5), which may not be suitable to your compilation requirements.
  • Make sure you have enough space. You will need ~1 GB for gcc sources, ~6 GB for the build)
  • This will install gcc in /usr/local/bin/gcc (default prefix is /usr/local). Your distro gcc (/usr/bin/gcc) will not be overwritten, but if later on you need to invoke it, you will have to do so explicitly. Configure with option –prefix if you want to change this.
cd ~
rm -fr tmp
mkdir tmp
cd ~/tmp
GCC_VERSION=9.4.0
wget https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.gz
tar xzvf gcc-${GCC_VERSION}.tar.gz
mkdir obj.gcc-${GCC_VERSION}
cd gcc-${GCC_VERSION}
./contrib/download_prerequisites
cd ../obj.gcc-${GCC_VERSION}
../gcc-${GCC_VERSION}/configure --disable-multilib --enable-languages=c,c++
make -j $(nproc)
make install
gcc --version

ls -la /usr/local/lib64/
ls -la /lib64/libstdc++.so.6

whereis libstdc++.so.6
ldconfig -p | grep libstdc

unlink /usr/local/lib64/libstdc++.so.6
sudo ln -s /usr/local/lib64/libstdc++.so.6.0.28 /usr/local/lib64/libstdc++.so.6

unlink /usr/lib64/libstdc++.so.6
sudo ln -s /usr/local/lib64/libstdc++.so.6.0.28 /usr/lib64/libstdc++.so.6

cd ~
rm -fr ~/tmp

Sau đó thiết lập tiếp các biến môi trường như hướng dẫn tại đây: https://www.jwillikers.com/build-gcc-from-source-on-centos-7

echo "export CC=/usr/local/bin/gcc" >> ~/.bashrc
echo "export CXX=/usr/local/bin/g++" >> ~/.bashrc
echo "export PATH=/usr/local/bin:$PATH" >> ~/.bashrc
echo "export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIRBARY_PATH" >> ~/.bashrc
source ~/.bashrc

Kiểm tra libstdc

ls -la /usr/local/lib64/libstdc++.so.6
strings /usr/local/lib64/libstdc++.so.6 | grep GLIBCXX
strings /usr/local/lib64/libstdc++.so.6.0.28 | grep GLIBCXX
strings /usr/local/lib64/libstdc++.so.6.0.29 | grep GLIBCXX

Nếu nó không hiển thị đầy đủ các các phiên bản GLIBCXX thì kiểm tra tiếp với /usr/local/lib64/libstdc++.so.6.xxx.yyy cho đến tìm ra tập tin đúng đắn.

Khi tìm ra rồi thì thay thế tập tin này thành /usr/local/lib64/libstdc++.so.6, ví dụ:

mv /usr/local/lib64/libstdc++.so.6 /usr/local/lib64/libstdc++.so.6.ori
sudo ln -s /usr/local/lib64/libstdc++.so.6.0.28 /usr/local/lib64/libstdc++.so.6

Cài đặt Go 1.17

Có hai cách cài đặt Go

  • Cách 1: cài từ binary
  • Cách 2: cài từ source

Đối với cách cài từ source mới nhất thì yêu cầu hệ thống phải có sẵn Go ít nhất là version 1.4 có sẵn trên hệ thống. Do đó, nếu hệ thống chưa có Go thì phải cài Go từ binary trước.

Cài Go 1.17 từ binary

cd $HOME
wget https://golang.org/dl/go1.17.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version

Cài Go 1.17 từ source

Lưu ý: hệ thống phải có sẵn Go thì mới cài được phiên bản Go mới nhất từ source.

Cách cài từ source như sau:

cd $HOME
rm -fr goroot
git clone https://go.googlesource.com/go goroot
cd goroot
git checkout go1.17
cd src
./all.bash

Sau đó nano ~/.bashrc cập nhật để thêm:

export PATH=$PATH:/$HOME/goroot/bin

Rồi reload lại:

source ~/.bashrc
go env

Cài đặt Hugo

  • Đầu tiên phải dùng Go để compile Hugo từ source
  • Sau đó mới dùng Hugo để tạo website

Compile Hugo từ source

unlink /usr/local/bin/hugo
cd ~
rm -fr tmp
mkdir tmp
cd tmp
git clone https://github.com/gohugoio/hugo.git
cd hugo
go install -v -n -a --tags extended
hugo version

Cài Hugo thông qua yum trên Centos 7

unlink /usr/local/bin/hugo
yum-config-manager --add-repo=https://copr.fedorainfracloud.org/coprs/daftaupe/hugo/repo/epel-7/daftaupe-hugo-epel-7.repo
yum install hugo
mv /usr/bin/hugo /usr/local/bin/hugo
hugo version

Cài Hugo extended từ binary release

cd ~
rm -fr tmp
mkdir tmp
cd tmp
wget https://github.com/gohugoio/hugo/releases/download/v0.88.1/hugo_extended_0.88.1_Linux-64bit.tar.gz
tar -xzvf hugo_extended_0.88.1_Linux-64bit.tar.gz
chmod +x hugo
mv hugo /usr/local/bin/hugo
hugo version

Dùng Hugo để tạo website

cd <webroot>
git init
mkdir www
cd www
hugo version
hugo new site hugo
cd ..
git submodule add https://gitlab.com/ian-s-mcb/smigle-hugo-theme.git www/hugo/themes/smigle
git submodule foreach git pull origin main
cd www/hugo
echo theme = \"smigle\" >> config.toml
cp -R content/posts/ content/case-studies
cp -R themes/smigle/layouts/posts themes/smigle/layouts/case-studies
hugo new posts/my-first-post.md
hugo new case-studies/sample-case-study.md
hugo new about.md
hugo -D

Khi đó Hugo sẽ tạo ra nội dung website ở thư mục public. Chỉ cần trỏ Nginx vào thư mục này thì có thể truy cập vào website

Nếu muốn cấu hình lại thư mục output thì thêm publishdir = "<thư mục output>" vào config.toml

Cấu hình lại config.toml để thêm các menu như sau:

baseURL = 'http://your-site.com/'
languageCode = 'en-us'
title = 'your-site'
theme = "smigle"

# Parameters
[params]
subtitle = "A blog"
dateFmt = "02.01.2006 15:04"

# Header
[menu]
[[menu.main]]
identifier = "posts"
name = "Posts"
url = "/posts/"
weight = 1

[[menu.main]]
identifier = "categories"
name = "Categories"
url = "/categories/"
weight = 2

[[menu.main]]
identifier = "about"
name = "About"
url = "/about/"
weight = 3

# Footer
[[menu.footer]]
name = "your-site"
url = "https://your-site.com"
weight = 1

Sau đó rebuild lại nội dung với hugo -D và kiểm tra lại site trên browser

Để có thể rebuild thông qua SSH trên cloudpad9 thì thay đổi ownership như sau:

chown cloudpad9:cloudpad9 -R hugo/

Cách tạo / edit bài với Hugo

  • Bước 1: Vào cloudpad9 > tab Editor > rồi chọn repository vtranq.com
  • Bước 2: Để chỉnh sửa bài thì cứ search bài tương ứng trên editor, chỉnh sửa và save lại
  • Bước 3: Tạo bài mới bằng cách clone một bài có sẵn, đặt tên, và edit nội dung
  • Bước 4: Vào thư mục ../vtran.com/www/hugo và chạy lệnh hugo -D, khi đó static website sẽ được tạo lại, và các nội dung mới sẽ được phản ánh trên website

UPDATED: Hiện tại, để tạo bài mới thì phải dùng hugo new posts/xxx.md thì bài viết mới có thể show trên website. Còn nếu tạo bài viết thông qua việc clone thì Hugo không detect được bài này

Các lưu ý khác:

  • Hugo tự động tạo site map ở địa chỉ:
    • http://<webroot>/index.xml
    • http://<webroot>/sitemap.xml

Thêm Youtube video

Dùng shortcode như ví dụ sau:


Ví dụ về cách dùng checkbox trong nội dung Markdown

- [ ] a task list item
- [ ] list syntax required
- [ ] incomplete
- [x] completed

Clean cache

hugo mod clean --all
hugo -D

Creating a Hugo theme from scratch

REF: https://retrolog.io/blog/creating-a-hugo-theme-from-scratch/

Ví dụ về cách dùng menu riêng cho 1 section nào đó

Ví dụ chúng ta muốn các trang trong section /services dùng menu riêng cho services, và các trang trong section /careers thì dùng menu riêng cho careers. Khi đó, chúng ta làm như sau:

  • Định nghĩa các menu riêng cho các section này, ví dụ:
[[menu.main]]
identifier = "about"
name = "About"
url = "/about/"
weight = 3

[[menu.main]]
identifier = "case-studies"
name = "Case Studies"
url = "/case-studies/"
weight = 4

# Services
[[menu.services]]
identifier = "foo"
name = "Foo"
url = "/foo/"
weight = 1

[[menu.services]]
identifier = "bar"
name = "Bar"
url = "/bar/"
weight = 2

# Careers
[[menu.careers]]
identifier = "apply"
name = "Apply now"
url = "/apply/"
weight = 1

[[menu.careers]]
identifier = "fraud"
name = "Fraudulent alert"
url = "/fraud/"
weight = 2
  • Trong phần display menu thì dùng lấy ra biến menu tùy theo tên của section như sau:
{{ $menu := .Site.Menus.main }}

{{ if isset $.Site.Menus .Section }}
    {{ $menu = index $.Site.Menus .Section }}
{{ end }}

<div id="nav-border" class="container">
    <nav id="nav" class="nav justify-content-center">
        {{ range $menu }}
        <a class="nav-link" href="{{ .URL }}">
            {{ $text := print .Name | safeHTML }}
            {{ $text }}
        </a>
        {{ end }}
    </nav>
</div>

Syntax highlighting

  • Bước 1: thêm vào config.toml như sau
[markup]
  [markup.highlight]
    anchorLineNos = false
    codeFences = true
    guessSyntax = true
    hl_Lines = ''
    lineAnchors = ''
    lineNoStart = 1
    lineNos = true
    lineNumbersInTable = true
    noClasses = true
    style = 'monokailight'
    tabWidth = 4
    pygmentsUseClasses=false
  • Bước 2: Tạo ra file CSS, và move vào thư mục phù hợp
hugo gen chromastyles --style=monokailight > syntax.css
mv syntax.css themes/smol/static/css/

Xem chi tiết danh sách các style ở đây: https://xyproto.github.io/splash/docs/all.html

  • Bước 3: Thêm vào template lại để include file này, ví dụ:
<link rel="stylesheet" href="{{ "css/syntax.css" | relURL }}">
  • Bước 4: code block nào muốn highlight thì thêm mã language vào code block đó, ngay sau 3 dấu backtick

Cấu hình nginx

server {
    listen 80;
	server_name example.com;
    index index.html index.htm;

    location / {
        root /<path-to>/hugo/public/;
    }

    error_page 404 /404.html;
}

Trang 404 sẽ lấy template từ /layouts/_default/404.html

Misc