Hay varias formas económicas de alojar un sitio web estático generado con un generador de sitios estáticos como Jekyll, Hugo o Pelican: Todo este blog se genera estáticamente usando Jekyll. Sin embargo, no puedo usar ninguna de las opciones anteriores porque, durante la vida útil de este blog, cambié los nombres de dominio, cambié los esquemas de URL y renombré las publicaciones, y quiero mantener vivas todas las URL antiguas He estado alojando este blog usando Apache y, más recientemente, nginx en una sola máquina virtual, y las funciones de redirección de cualquier pieza de software funcionan bien, pero estaba listo para alojarlo en un lugar nuevo y diferente. Una publicación anterior describe cómo redirijo las URL de un dominio antiguo a un dominio nuevo usando Google App Engine y Python, pero ahora necesitaba una forma de publicar contenido estático. **y** redirigir las URL del mismo dominio. Ese mismo requisito de redirección de dominio es la razón por la que no puedo simplemente usar la función de contenido estático de Google App Engine (vinculada en la lista anterior). Sin embargo, puedo usar Google App Engine en combinación con una aplicación simple de Golang para servir tanto contenido estático ** como ** redireccionamientos del mismo dominio ## ¿Por qué Google App Engine? Antes de sumergirse en el resto de la publicación, tal vez se esté preguntando, ¿por qué alojar un blog en Google App Engine? Aquí están mis razones por las cuales: - Si su tráfico se ajusta al nivel gratuito de App Engine de 28 horas de instancia y 1 GB de tráfico de salida por día, alojar el blog es prácticamente gratuito. - Empujar actualizaciones se hace con un comando - El registro y la supervisión están integrados mediante Stackdriver - Escalado ascendente y descendente automático basado en patrones de tráfico - Con unos pocos clics, los registros web se pueden enviar fácilmente a algo como BigQuery para el almacenamiento a largo plazo y el análisis ad hoc. - Gestión de certificados SSL utilizando LetâÃÂÃÂs Encrypt ## Requisitos previos Esta publicación asume lo siguiente: - Está familiarizado con Google Cloud Platform (GCP) y ya ha creado un proyecto GCP - Ha instalado el SDK de Google Cloud - Ha autenticado el gcloudcommand contra su cuenta de Google Crear un proyecto de GCP Si aún no ha creado un **Proyecto GCP sigue estos pasos: - Abra un navegador web y cree o inicie sesión en una cuenta de Google - Navegar a la consola de GCP : si este es su primer proyecto de GCP, se le pedirá que cree un proyecto de GCP. Cada cuenta de Google obtiene $300 en crédito para usar dentro de los 12 meses en GCP. Debe ingresar una tarjeta de crédito para crear un proyecto de GCP, pero no se le cobrará hasta que se consuma el crédito de $ 300 o venzan los 12 meses. - Si se trata de un nuevo proyecto de GCP, deberá habilitar la API de Compute Engine navegando a la sección Compute Engine de GCP Console y esperar a que se complete la inicialización. Instalar el SDK de Google Cloud Si aún no ha instalado el **Google Cloud SDK sigue las instrucciones aquí Autenticar gcloud Una vez que haya creado un proyecto de GCP e instalado el SDK de Google Cloud, el último paso es autenticar el comando gcloud a su cuenta de Google. Abra su aplicación de terminal y ejecute el siguiente comando: inicio de sesión de autenticación de gcloud Se abrirá una página web en su navegador web. Selecciona tu cuenta de Google y dale permiso para acceder a GCP. Una vez completado, estará autenticado y listo para seguir adelante. ## Crear un directorio A continuación, cree un directorio en algún lugar de su estación de trabajo para almacenar su aplicación Google App Engine: mkdir ~/Sitios/ejemplo.com/app_engine Cambie a ese directorio: cd ~/Sitios/ejemplo.com/app_engine El resto de esta publicación asumirá que está trabajando dentro de este directorio Además, cree un directorio dentro del directorio **app_engine** llamado **estático mkdir ~/Sitios/ejemplo.com/app_engine/static Volverás a visitar este directorio más tarde. ## Crear aplicación.yaml Google App Engine normalmente requiere dos archivos: **app.yaml** y un **archivo de aplicación** escrito en Python, Golang, Java o PHP; en este caso, será Golang. **app.yaml** proporciona la configuración necesaria para ejecutar tu aplicación. Hay muchos parámetros diferentes que pueden existir en **app.yaml Esos parámetros pueden diferir según el lenguaje de programación utilizado. Para esta publicación, se usará Golang, y puede encontrar todos los parámetros de Golang disponibles aquí Crea un archivo **app.yaml** con los siguientes contenidos: runtime: go api_version: go1 handlers: - url:script: _go_app seguro: siempre redirect_http_response_code: 301 Darse cuenta de Se ha configurado **seguro: siempre**. Esto significa que la aplicación Golang siempre se servirá a través de HTTPS. Si un usuario final navega a la aplicación web a través de HTTP, será redirigido 302 de manera predeterminada a la versión HTTPS. Es por eso que también se ha configurado **redirect_http_response_code: 301**. Siempre quiero que la aplicación web se sirva a través de HTTPS y no quiero que los motores de búsqueda interpreten la redirección de HTTP a HTTPS como una redirección temporal; es una redirección permanente Si tiene activos estáticos, y probablemente los tenga, es una buena práctica informar a App Engine de esto y dejar que sirva esos activos desde el almacenamiento de objetos en lugar de desde su aplicación. Hacer esto es fácil y también se hace a través del **archivo app.yaml** Por ejemplo, si tiene un archivo favicon, un directorio CSS, un directorio Javascript y un directorio de imágenes, use lo siguiente **archivo app.yaml**: tiempo de ejecución: vaya versión_api: controladores 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 seguro: siempre redirigir_http_response_code: 301 ## Crear principal.ir A continuación, necesita el archivo de la aplicación Golang Para que el siguiente código satisfaga sus necesidades, cree un archivo **main.go copia y pega el código de abajo, y haz las siguientes modificaciones: - En el variable de dominio, cambie el valor para que coincida con su nombre de dominio con el protocolo HTTP correcto - En el urlsmap, reemplace todos los pares de valores clave para que coincidan con los redireccionamientos que necesita en su lugar. Reemplace cada clave con solo la parte de la ruta ( /example-post-1.html en lugar de httpsexample.com/example-post-1.html) de la antigua URL del dominio actual que desea mantener viva. A continuación, reemplace cada valor con la parte de la ruta de la nueva URL del dominio actual a la que desea redirigir Todos los redireccionamientos serán redireccionamientos 301. Esto se puede modificar cambiando **301** en el siguiente código a un código de estado de redirección HTTP diferente, como **302** importación principal del paquete ( "net/http""os""strings") func init() { http.HandleFunc handler) } func handler(w http.ResponseWriter, r *http.Request) { // True (ok) if request la ruta está en el mapa de URL si el valor, ok := urls[r.URL.Path]; ok { valor = dominio + valor http.Redirect(w, r, valor, 301) } else { ruta := "static/"+ r.URL.Path // Devuelve 403 si la solicitud HTTP es a un directorio que existe y no no contiene un archivo index.html si f, err := os.Stat(ruta); err == nil&& f.IsDir() { index := strings.TrimSuffix(path,+ "/index.html"if _, err := os.Open(index); err != nil { w.WriteHeader (403) w.Writebytehtml> 403 Prohibido

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