Есть несколько недорогих способов размещения статического веб-сайта, созданного с помощью генератора статических сайтов, такого как 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 Если вы еще не создали **GCP Project выполните следующие действия: - Откройте веб-браузер и создайте учетную запись 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 ~/Сайты/example.com/app_engine Перейдите в этот каталог: компакт-диск ~/Сайты/example.com/app_engine В оставшейся части этого поста предполагается, что вы работаете внутри этого каталога. Кроме того, создайте каталог внутри Каталог **app_engine** называется **static mkdir ~/Сайты/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 обработчики: - 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 загрузка: 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: всегда redirect_http_response_code: 301 ## Создать main.go Далее вам понадобится файл приложения Golang Чтобы следующий код соответствовал вашим потребностям, создайте файл **main.go скопируйте и вставьте приведенный ниже код и внесите следующие изменения: - В domainvariable, измените значение, чтобы оно соответствовало вашему доменному имени с правильным протоколом HTTP. - В urlsmap, замените все пары ключ-значение, чтобы они соответствовали перенаправлениям, которые вам нужны. Замените каждый ключ только частью пути (/example-post-1.htmlвместо httpsexample.com/example-post-1.html) старого URL-адреса текущего домена, который вы хотите держать в живых. Затем замените каждое значение частью пути нового URL-адреса текущего домена, на который вы хотите перенаправить Все редиректы будут 301 редиректами. Это можно изменить, изменив **301** в приведенном ниже коде на другой код состояния перенаправления HTTP, например **302** package main import ( "net/http""os""strings") func init() { http.HandleFunc handler) } func handler(w http.ResponseWriter, r *http.Request) { // True (ok), если запрос путь находится на карте URL-адресов, если значение, ok := 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 Forbidden

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