Terdapat beberapa cara murah untuk mengehoskan tapak web statik yang dijana dengan penjana tapak statik seperti Jekyll, Hugo atau Pelican: Keseluruhan blog ini dijana secara statik menggunakan Jekyll. Walau bagaimanapun, saya tidak dapat menggunakan mana-mana pilihan di atas, kerana, sepanjang hayat blog ini, saya telah menukar nama domain, menukar skema URL dan menamakan semula siaran, dan saya ingin kekalkan hidup semua URL lama Saya telah mengehos blog ini menggunakan Apache dan, lebih baru-baru ini, nginx pada mesin maya tunggal, dan ciri pengalihan kedua-dua perisian berfungsi dengan baik, tetapi saya bersedia untuk mengehoskannya di tempat yang baharu dan berbeza Catatan sebelumnya menerangkan cara saya mengubah hala URL dari domain lama ke domain baharu menggunakan Google App Engine dan Python, tetapi kini saya memerlukan cara untuk menyampaikan kandungan statik **dan** ubah hala URL daripada domain yang sama. Keperluan ubah hala domain yang sama itulah sebabnya saya tidak boleh menggunakan ciri kandungan statik sahaja Google App Engine (dipautkan dalam senarai di atas). Walau bagaimanapun, saya boleh menggunakan Enjin Apl Google dalam kombinasi dengan aplikasi Golang mudah untuk menyampaikan kandungan statik **dan** ubah hala domain yang sama ## Mengapa Google App Engine? Sebelum anda menyelami siaran yang lain, mungkin anda tertanya-tanya, mengapa menjadi tuan rumah blog di Google App Engine? Inilah sebab saya mengapa: - Jika trafik anda sesuai dalam peringkat percuma Enjin Apl selama 28 jam kejadian dan 1 GB trafik keluar setiap hari, pengehosan blog boleh dikatakan percuma - Menolak kemas kini dilakukan dengan satu arahan - Pembalakan dan pemantauan disepadukan menggunakan Stackdriver - Penskalaan naik dan turun automatik berdasarkan corak trafik - Dengan beberapa klik, log web dengan mudah boleh ditolak ke sesuatu seperti BigQuery untuk storan jangka panjang dan analisis ad hoc - Sijil SSL terurus menggunakan LetâÃÂÃÂs Encrypt ## Prasyarat Jawatan ini menganggap perkara berikut: - Anda sudah biasa dengan Google Cloud Platform (GCP) dan telah pun membuat Projek GCP - Anda telah memasang SDK Awan Google - Anda telah mengesahkan gcloudcommand terhadap Akaun Google anda Buat Projek GCP Jika anda masih belum mencipta a **Projek GCP ikut langkah berikut: - Buka penyemak imbas web dan buat atau log masuk ke Akaun Google - Navigasi ke GCP Console - Jika ini adalah Projek GCP pertama anda, anda akan digesa untuk membuat Projek GCP. Setiap Akaun Google mendapat kredit $300 untuk digunakan dalam masa 12 bulan ke arah GCP. Anda dikehendaki memasukkan kad kredit untuk membuat Projek GCP, tetapi ia tidak akan dicaj sehingga kredit $300 digunakan atau 12 bulan tamat tempoh - Jika ini ialah Projek GCP baharu, anda perlu mendayakan Compute Engine API dengan menavigasi ke bahagian Compute Engine pada GCP Console dan tunggu sehingga permulaan selesai Pasang SDK Awan Google Jika anda masih belum memasang ** SDK Awan Google ikut arahan di sini Sahkan gcloud Sebaik sahaja anda telah membuat Projek GCP dan memasang SDK Awan Google, langkah terakhir ialah untuk mengesahkan perintah gcloud ke Akaun Google anda. Buka aplikasi terminal anda dan jalankan arahan berikut: log masuk auth gcloud Halaman web akan dibuka dalam pelayar web anda. Pilih Akaun Google anda dan berikannya kebenaran untuk mengakses GCP. Setelah selesai, anda akan disahkan dan bersedia untuk bergerak ke hadapan ## Buat Direktori Seterusnya, buat direktori di suatu tempat di stesen kerja anda untuk menyimpan aplikasi Google App Engine anda: mkdir ~/Sites/example.com/app_engine Tukar ke direktori itu: cd ~/Sites/example.com/app_engine Baki siaran ini akan menganggap anda sedang bekerja di dalam direktori ini Selain itu, buat direktori di dalam Direktori **app_engine** dipanggil **statik mkdir ~/Sites/example.com/app_engine/static Anda akan melawat semula direktori ini kemudian ## Buat app.yaml Enjin Apl Google biasanya memerlukan dua fail: **app.yaml** dan **fail aplikasi** yang ditulis dalam Python, Golang, Java atau PHP - dalam kes ini, ia akan menjadi Golang. **app.yaml** menyediakan konfigurasi yang diperlukan untuk menjalankan aplikasi anda. Terdapat banyak parameter berbeza yang boleh wujud dalam **app.yaml Parameter tersebut mungkin berbeza berdasarkan bahasa pengaturcaraan yang digunakan. Untuk siaran ini, Golang akan digunakan dan anda boleh menemui semua parameter Golang yang tersedia di sini Buat fail **app.yaml** dengan kandungan berikut: runtime: go api_version: pengendali go1: - url:script: _go_app secure: sentiasa redirect_http_response_code: 301 Perhatikan itu **secure: sentiasa** telah ditetapkan. Ini bermakna aplikasi Golang akan sentiasa disiarkan melalui HTTPS. Jika pengguna akhir menavigasi ke aplikasi web melalui HTTP, mereka secara lalai akan 302 diubah hala ke versi HTTPS. Inilah sebab mengapa **redirect_http_response_code: 301** juga telah ditetapkan. Saya sentiasa mahu aplikasi web disampaikan melalui HTTPS, dan saya tidak mahu enjin carian mentafsirkan pengalihan daripada HTTP ke HTTPS sebagai ubah hala sementara; ia adalah ubah hala kekal Jika anda mempunyai aset statik, dan anda mungkin ada, amalan terbaik adalah untuk memaklumkan App Engine tentang perkara ini dan biarkan ia menyampaikan aset tersebut daripada storan objek dan bukannya dari aplikasi anda. Melakukan ini adalah mudah dan juga dilakukan melalui **app.yaml** fail Contohnya, jika anda mempunyai fail favicon, direktori CSS, direktori Javascript dan direktori imej, gunakan yang berikut **app.yaml** fail: runtime: go api_version: pengendali go1: - 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: sentiasa redirect_http_response_code: 301 ## Cipta main.go Seterusnya, anda memerlukan fail aplikasi Golang Untuk kod berikut untuk memenuhi keperluan anda, buat fail **main.go salin dan tampal kod di bawah, dan buat pengubahsuaian berikut: - Di dalam domainvariable, tukar nilai agar sepadan dengan nama domain anda dengan protokol HTTP yang betul - Di dalam urlsmap, gantikan semua pasangan nilai utama untuk memadankan ubah hala yang anda perlukan. Gantikan setiap kekunci dengan hanya bahagian laluan ( /example-post-1.htmlbukannya httpsexample.com/example-post-1.html) URL lama domain semasa yang anda mahu terus hidup. Kemudian gantikan setiap nilai dengan bahagian laluan URL baharu domain semasa yang anda mahu ubah hala Semua ubah hala akan menjadi 301 ubah hala. Ini boleh diubah suai dengan menukar **301** dalam kod di bawah kepada kod status ubah hala HTTP yang berbeza seperti **302** import utama pakej ( "net/http""os""strings") func init() { http.HandleFunc handler) } func handler(w http.ResponseWriter, r *http.Request) { // True (ok) if request laluan berada dalam peta url jika nilai, ok := urls[r.URL.Path]; ok { value = domain + value http.Redirect(w, r, value, 301) } else { path := "static/"+ r.URL.Path // Kembalikan 403 jika permintaan HTTP adalah ke direktori yang wujud dan tidak tidak mengandungi fail index.html jika 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 Dilarang

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