Є кілька недорогих способів розміщення статичного веб-сайту, створеного за допомогою генератора статичних сайтів, наприклад Jekyll, Hugo або Pelican: Весь цей блог статично створено за допомогою Jekyll. Однак я не можу скористатися жодним із наведених вище варіантів, оскільки за час існування цього блогу я змінив доменні імена, змінив схеми URL-адрес і перейменував дописи, і я хочу зберегти всі старі URL-адреси Я розміщував цей блог за допомогою Apache і, нещодавно, nginx на одній віртуальній машині, і функції переспрямування будь-якої частини програмного забезпечення працюють чудово, але я був готовий розмістити його в іншому та новому місці. У попередній публікації описано, як я перенаправляю URL-адреси зі старого домену на новий за допомогою Google App Engine і Python, але тепер мені потрібен був спосіб обслуговування статичного вмісту **і** переспрямовують URL-адреси з одного домену. Ця сама вимога щодо переспрямування домену є причиною того, чому я не можу просто використовувати функцію лише статичного вмісту Google App Engine (посилання на яку наведено у списку вище). Однак я можу використовувати Google App Engine у ​​поєднанні з простою програмою Golang, щоб обслуговувати як статичний вміст **і** переспрямування того самого домену ## Чому Google App Engine? Перш ніж заглибитися в решту публікації, можливо, ви запитаєте, навіщо розміщувати блог на Google App Engine? Ось мої причини: - Якщо ваш трафік вписується в безкоштовний рівень App Engine із 28 годинами екземплярів і 1 Гб вихідного трафіку на день, розміщення блогу практично безкоштовне. - Надсилання оновлень виконується за допомогою однієї команди - Ведення журналів і моніторинг інтегровані за допомогою Stackdriver - Автоматичне збільшення та зменшення масштабу на основі моделей трафіку - Кількома клацаннями миші веб-журнали можна легко перемістити в щось на кшталт BigQuery для тривалого зберігання та спеціального аналізу - Керовані SSL-сертифікати за допомогою LetâÃÂýs Encrypt ## Передумови Ця посада передбачає наступне: - Ви знайомі з Google Cloud Platform (GCP) і вже створили проект GCP - Ви встановили Google Cloud SDK - Ви підтвердили автентичність gcloudcommand проти вашого облікового запису Google Створіть проект GCP Якщо ви ще не створили a **Проект GCP виконайте такі дії: - Відкрийте веб-браузер і створіть обліковий запис Google або увійдіть до нього - Перейдіть до консолі GCP – якщо це ваш перший проект GCP, вам буде запропоновано створити проект GCP. Кожен обліковий запис Google отримує кредит у розмірі 300 доларів США, який можна використовувати протягом 12 місяців для GCP. Вам потрібно ввести кредитну картку, щоб створити проект GCP, але плата не буде стягнена, доки не буде використано кредит у розмірі 300 доларів США або не закінчиться 12 місяців - Якщо це новий проект GCP, вам потрібно буде ввімкнути API Compute Engine, перейшовши до розділу Compute Engine консолі GCP і дочекавшись завершення ініціалізації Установіть Google Cloud SDK Якщо ви ще не встановили **Google Cloud SDK дотримуйтесь інструкцій тут Автентифікуйте gcloud Після того як ви створили проект GCP і встановили Google Cloud SDK, останнім кроком є ​​автентифікація gcloud у свій обліковий запис Google. Відкрийте термінальну програму та виконайте таку команду: авторизація gcloud У веб-браузері відкриється веб-сторінка. Виберіть свій обліковий запис Google і надайте йому доступ до GCP. Після завершення ви будете автентифіковані та готові рухатися далі ## Створіть каталог Далі створіть каталог десь на своїй робочій станції для зберігання програми Google App Engine: mkdir ~/Sites/example.com/app_engine Перейдіть у цей каталог: cd ~/Sites/example.com/app_engine Решта цієї публікації передбачає, що ви працюєте всередині цього каталогу Крім того, створіть каталог усередині Каталог **app_engine** називається **static mkdir ~/Sites/example.com/app_engine/static Ви переглянете цей каталог пізніше ## Створіть app.yaml Для Google App Engine зазвичай потрібні два файли: **app.yaml** і **файл програми**, написаний на Python, Golang, Java або PHP - у цьому випадку це буде Golang. **app.yaml** забезпечує необхідну конфігурацію для запуску програми. У **app.yaml може існувати багато різних параметрів. Ці параметри можуть відрізнятися залежно від мови програмування, яка використовується. Для цієї публікації буде використано Golang, і ви можете знайти всі доступні параметри Golang тут Створити файл **app.yaml** із таким вмістом: час виконання: go api_version: go1 handlers: - url:script: _go_app secure: завжди redirect_http_response_code: 301 Зверніть увагу на це **безпечно: завжди** встановлено. Це означає, що програма Golang завжди обслуговуватиметься через HTTPS. Якщо кінцевий користувач переходить до веб-програми через HTTP, він за умовчанням буде 302 перенаправлений на версію HTTPS. Ось чому також встановлено **redirect_http_response_code: 301**. Я завжди хочу, щоб веб-додаток обслуговувався через HTTPS, і я не хочу, щоб пошукові системи інтерпретували перенаправлення з HTTP на HTTPS як тимчасове перенаправлення; це постійне перенаправлення Якщо у вас є статичні ресурси, і, ймовірно, є, найкраще повідомити про це App Engine і дозволити йому обслуговувати ці ресурси зі сховища об’єктів, а не з вашої програми. Зробити це легко і також через файл **app.yaml** Наприклад, якщо у вас є файл favicon, каталог CSS, каталог Javascript і каталог зображень, використовуйте наступне Файл **app.yaml**: час виконання: go api_version: 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: завжди перенаправляти_http_response_code: 301 ## Створіть main.go Далі вам потрібен файл програми Golang Щоб наступний код відповідав вашим потребам, створіть файл **main.go скопіюйте та вставте наведений нижче код і внесіть такі зміни: - В змінна домену, змініть значення, щоб ім’я домену відповідало правильному протоколу HTTP - В urlsmap, замініть усі пари ключ-значення, щоб вони відповідали перенаправленням, які вам потрібні. Замініть кожен ключ лише частиною шляху ( /example-post-1.htmlзамість httpsexample.com/example-post-1.html) старої URL-адреси поточного домену, яку ви хочете отримати підтримувати. Потім замініть кожне значення частиною шляху до нової URL-адреси поточного домену, на яку ви хочете переспрямувати Усі перенаправлення будуть 301 перенаправленнями. Це можна змінити шляхом зміни **301** у наведеному нижче коді на інший код статусу перенаправлення HTTP, наприклад **302** основний імпорт пакета ( "net/http""os""strings") func init() { http.HandleFunc handler) } func handler(w http.ResponseWriter, r *http.Request) { // True (OK) якщо запит шлях у карті URL-адрес, якщо значення, добре := urls[r.URL.Path]; ok { value = domain + value http.Redirect(w, r, value, 301) } else { path := "static/"+ r.URL.Path // Повернення 403, якщо HTTP-запит спрямовано до каталогу, який існує та працює не містить файл index.html, якщо 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 Заборонено

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