Mayroong ilang mga murang paraan upang mag-host ng isang static na website na nabuo gamit ang isang static na generator ng site tulad ng Jekyll, Hugo, o Pelican: Ang buong blog na ito ay statically nabuo gamit ang Jekyll. Gayunpaman, hindi ko magagamit ang alinman sa mga opsyon sa itaas, dahil, sa buong buhay ng blog na ito, binago ko ang mga domain name, binago ang mga scheme ng URL, at pinalitan ang pangalan ng mga post, at gusto kong panatilihing buhay ang lahat ng lumang URL Ako ay nagho-host ng blog na ito gamit ang Apache at, kamakailan lamang, nginx sa isang virtual machine, at ang mga tampok sa pag-redirect ng alinmang piraso ng software ay gumagana nang maayos, ngunit handa akong i-host ito sa isang lugar na bago at naiiba. Ang isang nakaraang post ay naglalarawan kung paano ako nagre-redirect ng mga URL mula sa isang lumang domain patungo sa isang bagong domain gamit ang Google App Engine at Python, ngunit ngayon ay kailangan ko ng isang paraan upang maghatid ng static na nilalaman **at** pag-redirect ng mga URL mula sa parehong domain. Ang parehong kinakailangan sa pag-redirect ng domain ang dahilan kung bakit hindi ko basta-basta magagamit ang feature na static na content lang ng Google App Engine (naka-link sa listahan sa itaas). Gayunpaman, maaari kong gamitin ang Google App Engine kasama ng isang simpleng Golang application upang maghatid ng parehong static na nilalaman **at** parehong mga pag-redirect ng domain ## Bakit Google App Engine? Bago ka sumisid sa natitirang bahagi ng post, marahil ay nagtataka ka, bakit magho-host ng blog sa Google App Engine? Narito ang aking mga dahilan kung bakit: - Kung umaangkop ang iyong trapiko sa loob ng libreng tier ng App Engine na 28 instance hours at 1 GB ng egress traffic bawat araw, halos libre ang pagho-host sa blog. - Ang pagtulak ng mga update ay ginagawa gamit ang isang utos - Ang pag-log at pagsubaybay ay isinama gamit ang Stackdriver - Awtomatikong pataas at pababang pag-scale batay sa mga pattern ng trapiko - Sa ilang mga pag-click, ang mga web log ay madaling maitulak sa isang bagay tulad ng BigQuery para sa pangmatagalang storage at ad hoc analysis - Pinamahalaan ang mga SSL certificate gamit ang LetâÃÂÃÂs Encrypt ## Mga kinakailangan Ipinapalagay ng post na ito ang sumusunod: - Pamilyar ka sa Google Cloud Platform (GCP) at nakagawa na ng GCP Project - Na-install mo ang Google Cloud SDK - Na-authenticate mo ang gcloudcommand laban sa iyong Google Account Gumawa ng GCP Project Kung hindi ka pa nakakagawa ng a **GCP Project sundin ang mga hakbang na ito: - Magbukas ng web browser, at lumikha o mag-log in sa isang Google Account - Mag-navigate sa GCP Console - Kung ito ang iyong unang GCP Project, ipo-prompt kang gumawa ng GCP Project. Ang bawat Google Account ay nakakakuha ng $300 na credit na gagamitin sa loob ng 12 buwan patungo sa GCP. Kinakailangan mong maglagay ng credit card para gumawa ng GCP Project, ngunit hindi ito sisingilin hanggang sa maubos ang $300 na credit o mag-expire ang 12 buwan - Kung ito ay isang bagong GCP Project, kakailanganin mong paganahin ang Compute Engine API sa pamamagitan ng pag-navigate sa seksyong Compute Engine ng GCP Console at hintaying makumpleto ang pagsisimula I-install ang Google Cloud SDK Kung hindi mo pa na-install ang **Sundin ng Google Cloud SDK ang mga tagubilin dito I-authenticate ang gcloud Kapag nakagawa ka na ng GCP Project at na-install ang Google Cloud SDK, ang huling hakbang ay ang patotohanan ang gcloud command sa iyong Google Account. Buksan ang iyong terminal application at patakbuhin ang sumusunod na command: gcloud auth login Magbubukas ang isang web page sa iyong web browser. Piliin ang iyong Google Account at bigyan ito ng pahintulot na i-access ang GCP. Kapag nakumpleto na, maa-authenticate ka at handang sumulong ## Lumikha ng Direktoryo Susunod, lumikha ng isang direktoryo sa isang lugar sa iyong workstation upang iimbak ang iyong Google App Engine application: mkdir ~/Sites/example.com/app_engine Baguhin sa direktoryo na iyon: cd ~/Sites/example.com/app_engine Ipapalagay ng natitira sa post na ito na nagtatrabaho ka sa loob ng direktoryong ito Bilang karagdagan, lumikha ng isang direktoryo sa loob ng **app_engine** na direktoryo na tinatawag na **static mkdir ~/Sites/example.com/app_engine/static Muli mong bisitahin ang direktoryo na ito sa ibang pagkakataon ## Lumikha ng app.yaml Ang Google App Engine ay karaniwang nangangailangan ng dalawang file: **app.yaml** at isang **application file** na nakasulat sa Python, Golang, Java, o PHP - sa kasong ito ito ay magiging Golang. **app.yaml** ay nagbibigay ng kinakailangang configuration para patakbuhin ang iyong application. Mayroong maraming iba't ibang mga parameter na maaaring umiral sa **app.yaml Maaaring mag-iba ang mga parameter na iyon batay sa programming language na ginamit. Para sa post na ito, gagamitin ang Golang, at mahahanap mo ang lahat ng available na parameter ng Golang dito Lumikha ng file **app.yaml** na may mga sumusunod na nilalaman: runtime: go api_version: go1 handlers: - url:script: _go_app secure: palaging redirect_http_response_code: 301 Pansinin mo yan **secure: palaging** ay itinakda. Nangangahulugan ito na palaging ihahatid ang Golang application sa HTTPS. Kung ang isang end user ay magna-navigate sa web application sa pamamagitan ng HTTP, sila ay 302 bilang default na ire-redirect sa bersyon ng HTTPS. Ito ang dahilan kung bakit naitakda rin ang **redirect_http_response_code: 301**. Palagi kong nais na maihatid ang web application sa HTTPS, at hindi ko nais na binibigyang-kahulugan ng mga search engine ang pag-redirect mula sa HTTP patungo sa HTTPS bilang pansamantalang pag-redirect; ito ay isang permanenteng pag-redirect Kung mayroon kang mga static na asset, at malamang na mayroon ka, pinakamahusay na kasanayan na ipaalam ito sa App Engine at hayaan itong ihatid ang mga asset na iyon mula sa object storage sa halip na mula sa iyong application. Ang paggawa nito ay madali at ginagawa rin sa pamamagitan ng **app.yaml** file Halimbawa, kung mayroon kang favicon file, isang CSS directory, isang Javascript directory, at isang images directory, gamitin ang sumusunod **app.yaml** file: runtime: go api_version: go1 handlers: - url: /favicon.png$ static_files: static/favicon.png upload: static/favicon.png - url: /css static_dir: static/css - url: /js static_dir: static/js - url: /images static_dir: static/images - url:script: _go_app secure: palaging redirect_http_response_code: 301 ## Lumikha ng main.go Susunod, kailangan mo ang Golang application file Para matugunan ng sumusunod na code ang iyong mga pangangailangan, gumawa ng file **main.go kopyahin at i-paste ang code sa ibaba, at gawin ang mga sumusunod na pagbabago: - Nasa domainvariable, baguhin ang halaga upang tumugma sa iyong domain name sa tamang HTTP protocol - Nasa urlsmap, palitan ang lahat ng mga pares ng pangunahing halaga upang tumugma sa mga pag-redirect na kailangan mo sa lugar. Palitan ang bawat key gamit lang ang bahagi ng path ( /example-post-1.htmlsa halip na httpsexample.com/example-post-1.html) ng kasalukuyang domainâÃÂÃÂs na gusto mong panatilihing buhay. Pagkatapos ay palitan ang bawat value ng path na bahagi ng kasalukuyang domain ng bagong URL na gusto mong i-redirect sa Ang lahat ng mga pag-redirect ay magiging 301 mga pag-redirect. Ito ay maaaring baguhin sa pamamagitan ng pagbabago **301** sa code sa ibaba sa ibang HTTP redirect status code gaya ng **302** package main import ( "net/http""os""strings") func init() { http.HandleFunc handler) } func handler(w http.ResponseWriter, r *http.Request) { // True (ok) kung hihilingin ang path ay nasa urls map kung value, ok := urls[r.URL.Path]; ok { value = domain + value http.Redirect(w, r, value, 301) } else { path := "static/"+ r.URL.Path // Return 403 kung ang HTTP request ay sa isang directory na umiiral at ginagawa hindi naglalaman ng index.html file kung f, err := os.Stat(path); err == nil&& f.IsDir() { index := strings.TrimSuffix(path,+ "/index.html"if _, err := os.Open(index); err != nil { w.WriteHeader (403) w.Writebytehtml># 403 Ipinagbabawal

403 Forbidden

return } } // Return custom 404 page if HTTP request is to a non-existent file if _, err := os.Stat(path); os.IsNotExist(err) { w.WriteHeader(404) http.ServeFile(w, r, "static/404.html") return // Withoutreturn, a "404 page not found" string will be displayed at the bottom of your custom 404 page } http.ServeFile(w, r, path) return } } var domain string = "httpsexample.com" var urls = map[string]string{ "/example-post-1.html": "/post/example-post-1.html", "/example-post-2.html": "/post/example-post-2.html", "/example-post-3.html": "/post/example-post-3.html", } ## Generate the Static Content With **app.yaml** and **main.go** saved, the last piece is to generate your static content and store it in the **static** directory you created earlier How you do this entirely depends on what static site generator you are using If you are using Jekyll, you can configure the **destination** parameter in Jekyll’s _ **config.yml** file to save your static content in any directory on your workstation. So, you could set the **destination** parameter to Sites/example.com/app_engine/static and, every time you run jekyll build, the static content will be saved in that directory ## Deploy to App Engine With **app.yaml **main.go and your static content generated, you are ready to deploy your Google App Engine application Assuming gcloud is already pointed at the Google Cloud Project you want to deploy to, verify with gcloud config list project, run the following command: gcloud app deploy The command will output the appspot URL your application will be deployed to and ask if you want to continue. Typically, the appspot URL is **httpsyour-project-id.appspot.com This is also a useful self-check to make sure you are not deploying your application to the wrong Google Cloud Project. If everything looks okay, type **Y** and **Enter** to deploy your application. Depending on how large your static content is, your application should be deployed within about one minute ## Setup DNS At this point, your application is deployed under URL **httpsyour-project-id.appspot.com Unless your website uses that as its domain name, you will probably want to setup a custom domain that uses your actual current domain name The App Engine section of the Google Cloud Console can be used to do this. Go here and follow the instructions to configure your custom domain Once that is complete and DNS has had time to propagate, you should be able to navigate in your web browser to one of your current domain’s old URLs, for example **httpsexample.com/example-post-1.html and have it redirect to your current domain’s new URLs, for example **httpsexample.com/post/example-post-1.html** ## Pushing Updates To push updates, make the necessary changes in your static site’s source directory, regenerate the static content, and redeploy to Google App Engine by changing into the Sites/example.com/app_engine** directory and running gcloud app deploy ## References - A Surprising Feature of Golang that Colored Me Impressed - How to check if a map contains a key in go? - Disable directory listing with http.FileServer - 3 Ways to Disable http.FileServer Directory Listings - Handling HTTP Request Errors in GO - HTTP and Error management in Go - please add ability to set custom 404 notFoundHandler for http.FileServer