¡Volvemos a la carga! Esta vez con un post un poco más técnico que los últimos. Hace tiempo que llevo dandole vuelta a como mejorar la manera en la que desplegamos el software, sobre todo desde que vi la charla de «Deliveritis Aguda« de Carlos Buenosvinos.
Así que me he puesto manos a la obra analizando como desplegamos nosotros y como automatizar al máximo posible el deploy. Después de ver distintas opciones la que más sencilla me ha parecido para proyectos personales es Heroku.
Crear cuenta en Heroku
Lo primero es crear una cuenta en Heroku. Tiene una capa gratuita que es suficiente para hacer pruebas.
Una vez que tengamos la cuenta lista, tenemos que instalar en nuestro ordenador Heroku CLI, en mi caso he optado por la instalación de brew
brew tap heroku/brew && brew install heroku

Creando una aplicación en Go para desplegar
Si ya me conoces o as leído otros posts, a mi me gusta ir paso a paso. Por eso, vamos a construir una app muy simple. La idea del post es desplegar en Heroku, así que haremos todo lo posible por acercarnos a ese objetivo. Dicho esto, crearemos una aplicación muy simple en Go, que solo nos muestro por pantalla un mensaje.
Lo primero es crear en Go module (la manera de crear aplicaciones en cualquier ruta del sistema de ficheros, independiente de donde tengamos definido GOPATH). Más información aquí o en este otro enlace. Para ello en una directorio donde queramos construir el proyecto escribimos:
$ go mod init github.com/{your_username}/{repo_name}
En mi caso sería algo así:
$ go mod init github.com/jeslopcru/go-heroku
Esto nos creará un fichero go.mod que es donde está toda la información de los módulos.
Ahora solo tenemos que crear nuestro fichero main.go. En mi caso he decidido usar el framework gin para que sea aún más sencillo. Por ello solo tengo que escribir esto en el main:
package main import ( "github.com/gin-gonic/gin" "os" ) func main() { port := os.Getenv("PORT") app := gin.New() app.GET("/", func(context *gin.Context) { context.String(200, "Go App working!") }) _ = app.Run(":" + port) }
Lo más importante a tener en cuenta con Heroku, es que el puerto es aleatorio, por tanto a la hora de lanzar nuestra aplicación tenemos que leer la variable PORT y ejecutar el servidor en dicho puerto.
Desplegando en Heroku
Con solo un directorio con 2 ficheros (go.mod y main.go) ya tenemos una aplicación lista para desplegar. Ahora vamos a Heroku y creamos nuestra app (básicamente es darle un nombre), en mi caso go-heroku-server
Listo. Metemos nuestro directorio en git
$ git init
$ git add -A .
$ git commit -m "initial commit"
Y añadimos el remoto
$ heroku git:remote -a go-heroku-server
Con solo hacer un push a Heroku tenemos nuestra aplicación desplegada:
Ahora solo nos queda probarla https://go-heroku-server.herokuapp.com/ o en un terminal ejecutar
$ heroku open
Para ver los logs es tan sencillo como:
$ heroku logs --tail
1 ↵ 2020-02-08T07:34:30.078424+00:00 heroku[web.1]: Unidling 2020-02-08T07:34:30.392047+00:00 heroku[web.1]: State changed from down to starting 2020-02-08T07:34:31.220692+00:00 heroku[web.1]: Starting process with command `bin/go-heroku` 2020-02-08T07:34:33.596599+00:00 heroku[web.1]: State changed from starting to up 2020-02-08T07:34:33.550762+00:00 app[web.1]: [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. 2020-02-08T07:34:33.550778+00:00 app[web.1]: - using env: export GIN_MODE=release 2020-02-08T07:34:33.550779+00:00 app[web.1]: - using code: gin.SetMode(gin.ReleaseMode) 2020-02-08T07:34:33.550779+00:00 app[web.1]: 2020-02-08T07:34:33.550785+00:00 app[web.1]: [GIN-debug] GET / --> main.main.func1 (1 handlers) 2020-02-08T07:34:33.550786+00:00 app[web.1]: [GIN-debug] Listening and serving HTTP on :57068 2020-02-08T07:34:34.575426+00:00 heroku[router]: at=info method=GET path="/" host=go-heroku-server.herokuapp.com request_id=4896cba0-abf6-4134-94b1-76916dbfb9be fwd="95.121.236.30" dyno=web.1 connect=1ms service=5ms status=200 bytes=151 protocol=https
Probando en local
Lo primero que tenemos que hacer para poder ejecutar en local es definir un Procfile. Este fichero especifica los comandos que se deben ejecutar para iniciar la aplicación. El Procfile debe estar en la raíz de nuestro proyecto.
En nuestro caso el Procfile indica que tenemos una aplicación web y que para ejecutarla es necesario ejecutar el comando bin/go-heroku, por lo que nos queda un fichero tal que así:
web: bin/go-heroku
Ahora para ejecutar la app en local solo tenemos que ejecutar
$ heroku local 10:07:29 AM web.1 | [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. 10:07:29 AM web.1 | - using env: export GIN_MODE=release 10:07:29 AM web.1 | - using code: gin.SetMode(gin.ReleaseMode) 10:07:29 AM web.1 | [GIN-debug] GET / --> main.main.func1 (1 handlers) 10:07:29 AM web.1 | [GIN-debug] Listening and serving HTTP on :5000
Y ya tenemos nuestra aplicación funcionando en localhost:5000
Otra manera de desplegar sería utilizando Docker y un Dockerfile pero eso lo dejaremos para otro post tipo «haciendo debugging con delve».
Conclusiones
Tener una app funcionando y desplegada en un servidor usando Heroku es lo muy sencillo. Además Heroku nos ofrece muchas más posibilidades como desplegar contenedores o integraciones con Github para automatizar el despliegue.