{"id":4616,"date":"2018-02-20T07:00:23","date_gmt":"2018-02-20T15:00:23","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4616"},"modified":"2025-06-13T18:45:42","modified_gmt":"2025-06-14T01:45:42","slug":"create-continuous-deployment-pipeline-golang-jenkins","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/create-continuous-deployment-pipeline-golang-jenkins\/","title":{"rendered":"Crear tuber\u00edas de despliegue continuo con Golang y Jenkins"},"content":{"rendered":"<p>Hace unas semanas hab\u00eda escrito sobre el despliegue continuo de una aplicaci\u00f3n escrita con el lenguaje de programaci\u00f3n Go utilizando un popular servicio llamado Travis CI. Este ejemplo demostraba la creaci\u00f3n de una aplicaci\u00f3n que utilizaba un <a href=\"https:\/\/www.couchbase.com\/blog\/es\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a> NoSQL, creando pruebas unitarias, ejecutando esas pruebas en el canal de integraci\u00f3n continua de Golang y, finalmente, desplegando la aplicaci\u00f3n en alg\u00fan servidor remoto cuando todo haya ido bien.<\/p>\n<p>Travis CI no es el \u00fanico servicio que ofrece estas caracter\u00edsticas. De hecho, puedes alojar tu propio servicio CI \/ CD usando Jenkins.<\/p>\n<p>Vamos a ver c\u00f3mo utilizar Jenkins para un pipeline de una aplicaci\u00f3n Golang, permitiendo la integraci\u00f3n continua y el despliegue continuo.<\/p>\n<p><!--more--><\/p>\n<p>Si a\u00fan no ha le\u00eddo mi <a href=\"https:\/\/www.couchbase.com\/blog\/es\/continuously-deploying-golang-application-using-travis-ci\/\" target=\"_blank\" rel=\"noopener noreferrer\">tutorial anterior Golang con Travis CI<\/a>le recomiendo que lo haga, ya que ofrece muchas explicaciones \u00fatiles. Mucho del mismo material aparecer\u00e1 aqu\u00ed, pero se explicar\u00e1 de manera diferente, por lo que dos explicaciones podr\u00edan ser \u00fatiles.<\/p>\n<p>Si quieres experimentar de verdad este tutorial de Jenkins con Golang, vas a necesitar <a href=\"https:\/\/www.couchbase.com\/blog\/es\/products\/server\/\" target=\"_blank\" rel=\"noopener noreferrer\">Servidor Couchbase<\/a> instalada en alg\u00fan lugar. El objetivo es que la aplicaci\u00f3n se ejecute y utilice esa instancia de base de datos una vez desplegada.<\/p>\n<h2>Desarrollo de una aplicaci\u00f3n Go con Couchbase<\/h2>\n<p>Para tener \u00e9xito con este tutorial, vamos a necesitar una aplicaci\u00f3n Go para probar y desplegar. Si quieres adelantarte, he subido un proyecto funcional a <a href=\"https:\/\/github.com\/couchbaselabs\/golang-ci-example\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>. En realidad es el mismo proyecto del ejemplo de Travis CI.<\/p>\n<p>Si prefieres recorrer el proyecto, dediquemos algo de tiempo a hacerlo.<\/p>\n<p>En alg\u00fan lugar de tu\u00a0<strong>$GOPATH<\/strong> crear un archivo llamado\u00a0<strong>main.go<\/strong> e incluir el siguiente c\u00f3digo Go. Vamos a desglosarlo despu\u00e9s.<\/p>\n<pre class=\"lang:default decode:true\">package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"os\"\r\n\r\n\tgocb \"gopkg.in\/couchbase\/gocb.v1\"\r\n)\r\n\r\ntype BucketInterface interface {\r\n\tGet(key string, value interface{}) (gocb.Cas, error)\r\n\tInsert(key string, value interface{}, expiry uint32) (gocb.Cas, error)\r\n}\r\n\r\ntype Database struct {\r\n\tbucket BucketInterface\r\n}\r\n\r\ntype Person struct {\r\n\tType      string `json:\"type\"`\r\n\tFirstname string `json:\"firstname\"`\r\n\tLastname  string `json:\"lastname\"`\r\n}\r\n\r\nfunc (d Database) GetPersonDocument(key string) (interface{}, error) {\r\n\tvar data interface{}\r\n\t_, err := d.bucket.Get(key, &amp;data)\r\n\tif err != nil {\r\n\t\treturn nil, err\r\n\t}\r\n\treturn data, nil\r\n}\r\n\r\nfunc (d Database) CreatePersonDocument(key string, data interface{}) (interface{}, error) {\r\n\t_, err := d.bucket.Insert(key, data, 0)\r\n\tif err != nil {\r\n\t\treturn nil, err\r\n\t}\r\n\treturn data, nil\r\n}\r\n\r\nfunc main() {\r\n\tfmt.Println(\"Starting the application...\")\r\n\tvar database Database\r\n\tcluster, _ := gocb.Connect(\"couchbase:\/\/\" + os.Getenv(\"DB_HOST\"))\r\n\tcluster.Authenticate(gocb.PasswordAuthenticator{Username: os.Getenv(\"DB_USER\"), Password: os.Getenv(\"DB_PASS\")})\r\n\tdatabase.bucket, _ = cluster.OpenBucket(os.Getenv(\"DB_BUCKET\"), \"\")\r\n\tfmt.Println(database.GetPersonDocument(\"8eaf1065-5bc7-49b5-8f04-c6a33472d9d5\"))\r\n\tdatabase.CreatePersonDocument(\"blawson\", Person{Type: \"person\", Firstname: \"Brett\", Lastname: \"Lawson\"})\r\n}<\/pre>\n<p>La aplicaci\u00f3n no hace gran cosa, pero hay mucho que hacer.<\/p>\n<p>En las importaciones, notar\u00e1s nuestro uso del SDK de Couchbase para Go. Para poder compilar este proyecto, necesitar\u00e1s descargar el SDK. Se puede hacer con el siguiente comando:<\/p>\n<pre class=\"lang:default decode:true\">go get gopkg.in\/couchbase\/gocb.v1<\/pre>\n<p>Antes de empezar a recorrer el c\u00f3digo, tenemos que dar un paso atr\u00e1s y averiguar c\u00f3mo deber\u00eda funcionar esta aplicaci\u00f3n.<\/p>\n<p>El objetivo aqu\u00ed es conectarse a la base de datos NoSQL, Couchbase, recuperar algunos datos, y crear algunos datos. Naturalmente, esto ser\u00eda bastante f\u00e1cil a trav\u00e9s del SDK, sin embargo, queremos crear pruebas unitarias para nuestra aplicaci\u00f3n. Es una buena pr\u00e1ctica nunca probar contra una base de datos en una prueba unitaria. Guarda eso para tus pruebas de integraci\u00f3n. Si no estamos probando contra la base de datos, tenemos que crear escenarios simulados.<\/p>\n<p>En lugar de crear un mont\u00f3n de locuras, la mejor manera de dividir entre escenarios reales y simulados es crear una interfaz para ambos con Go. La aplicaci\u00f3n principal utilizar\u00e1 las clases reales como parte de la interfaz, mientras que las pruebas utilizar\u00e1n las simuladas.<\/p>\n<p>Por esta raz\u00f3n, necesitamos crear una interfaz para el SDK de Couchbase Go <code>Cubo<\/code> componente.<\/p>\n<pre class=\"lang:default decode:true\">type BucketInterface interface {\r\n\tGet(key string, value interface{}) (gocb.Cas, error)\r\n\tInsert(key string, value interface{}, expiry uint32) (gocb.Cas, error)\r\n}<\/pre>\n<p>Un Couchbase Bucket tiene muchas m\u00e1s funciones que <code>Visite<\/code> y <code>Inserte<\/code>pero esas ser\u00e1n las \u00fanicas funciones que utilizaremos en este ejemplo. Para simplificar m\u00e1s adelante en la aplicaci\u00f3n, vamos a crear un <code>struct<\/code> con la nueva interfaz.<\/p>\n<pre class=\"lang:default decode:true\">type Database struct {\r\n\tbucket BucketInterface\r\n}<\/pre>\n<p>S\u00f3lo habr\u00e1 un modelo de datos para este ejemplo. Vamos a utilizar un modelo de datos basado en el m\u00e9todo <code>Persona<\/code> estructura de datos. Puede cambiar libremente sin afectar a nuestra aplicaci\u00f3n.<\/p>\n<p>Echa un vistazo a una de nuestras funciones para la que eventualmente tendremos pruebas unitarias:<\/p>\n<pre class=\"lang:default decode:true\">func (d Database) GetPersonDocument(key string) (interface{}, error) {\r\n\tvar data interface{}\r\n\t_, err := d.bucket.Get(key, &amp;data)\r\n\tif err != nil {\r\n\t\treturn nil, err\r\n\t}\r\n\treturn data, nil\r\n}<\/pre>\n<p>En el <code>GetPersonDocument<\/code> utilizamos una funci\u00f3n <code>BucketInterface<\/code> y obtener un documento concreto mediante la clave de documento.<\/p>\n<p>Del mismo modo, si quisi\u00e9ramos crear datos, tendr\u00edamos lo siguiente:<\/p>\n<pre class=\"lang:default decode:true\">func (d Database) CreatePersonDocument(key string, data interface{}) (interface{}, error) {\r\n\t_, err := d.bucket.Insert(key, data, 0)\r\n\tif err != nil {\r\n\t\treturn nil, err\r\n\t}\r\n\treturn data, nil\r\n}<\/pre>\n<p>Siento que necesito reiterar esto, pero estas funciones fueron dise\u00f1adas para ser m\u00e1s complejas de lo que necesitan ser. Estamos haciendo esto porque queremos demostrar algunas pruebas. Si te hace sentir mejor, a\u00f1adir un poco m\u00e1s de complejidad a ellos en lugar de s\u00f3lo simple <code>Visite<\/code> y <code>Inserte<\/code> funcionalidad.<\/p>\n<p>Por \u00faltimo, tenemos lo siguiente que se ejecuta en tiempo de ejecuci\u00f3n:<\/p>\n<pre class=\"lang:default decode:true\">func main() {\r\n\tfmt.Println(\"Starting the application...\")\r\n\tvar database Database\r\n\tcluster, _ := gocb.Connect(\"couchbase:\/\/\" + os.Getenv(\"DB_HOST\"))\r\n\tcluster.Authenticate(gocb.PasswordAuthenticator{Username: os.Getenv(\"DB_USER\"), Password: os.Getenv(\"DB_PASS\")})\r\n\tdatabase.bucket, _ = cluster.OpenBucket(os.Getenv(\"DB_BUCKET\"), \"\")\r\n\tfmt.Println(database.GetPersonDocument(\"8eaf1065-5bc7-49b5-8f04-c6a33472d9d5\"))\r\n\tdatabase.CreatePersonDocument(\"blawson\", Person{Type: \"person\", Firstname: \"Brett\", Lastname: \"Lawson\"})\r\n}<\/pre>\n<p>Cuando se ejecuta la aplicaci\u00f3n, establecemos una conexi\u00f3n con Couchbase utilizando variables de entorno. El Bucket abierto se establece en nuestro <code>BucketInterface<\/code>y, a continuaci\u00f3n, se ejecutan las dos funciones.<\/p>\n<p>\u00bfC\u00f3mo lo comprobamos?<\/p>\n<p>Crea un archivo en tu proyecto llamado\u00a0<strong>main_test.go<\/strong> con el siguiente c\u00f3digo:<\/p>\n<pre class=\"lang:default decode:true\">package main\r\n\r\nimport (\r\n\t\"encoding\/json\"\r\n\t\"os\"\r\n\t\"testing\"\r\n\r\n\t\"github.com\/mitchellh\/mapstructure\"\r\n\tgocb \"gopkg.in\/couchbase\/gocb.v1\"\r\n)\r\n\r\ntype MockBucket struct{}\r\n\r\nvar testdatabase Database\r\n\r\nfunc convert(start interface{}, end interface{}) error {\r\n\tbytes, err := json.Marshal(start)\r\n\tif err != nil {\r\n\t\treturn err\r\n\t}\r\n\terr = json.Unmarshal(bytes, end)\r\n\tif err != nil {\r\n\t\treturn err\r\n\t}\r\n\treturn nil\r\n}\r\n\r\nfunc (b MockBucket) Get(key string, value interface{}) (gocb.Cas, error) {\r\n\tswitch key {\r\n\tcase \"nraboy\":\r\n\t\terr := convert(Person{Type: \"person\", Firstname: \"Nic\", Lastname: \"Raboy\"}, value)\r\n\t\tif err != nil {\r\n\t\t\treturn 0, err\r\n\t\t}\r\n\tdefault:\r\n\t\treturn 0, gocb.ErrKeyNotFound\r\n\t}\r\n\treturn 1, nil\r\n}\r\n\r\nfunc (b MockBucket) Insert(key string, value interface{}, expiry uint32) (gocb.Cas, error) {\r\n\tswitch key {\r\n\tcase \"nraboy\":\r\n\t\treturn 0, gocb.ErrKeyExists\r\n\t}\r\n\treturn 1, nil\r\n}\r\n\r\nfunc TestMain(m *testing.M) {\r\n\ttestdatabase.bucket = &amp;MockBucket{}\r\n\tos.Exit(m.Run())\r\n}\r\n\r\nfunc TestGetPersonDocument(t *testing.T) {\r\n\tdata, err := testdatabase.GetPersonDocument(\"nraboy\")\r\n\tif err != nil {\r\n\t\tt.Fatalf(\"Expected `err` to be `%s`, but got `%s`\", \"nil\", err)\r\n\t}\r\n\tvar person Person\r\n\tmapstructure.Decode(data, &amp;person)\r\n\tif person.Type != \"person\" {\r\n\t\tt.Fatalf(\"Expected `type` to be %s, but got %s\", \"person\", person.Type)\r\n\t}\r\n}\r\n\r\nfunc TestCreatePersonDocument(t *testing.T) {\r\n\t_, err := testdatabase.CreatePersonDocument(\"blawson\", Person{Type: \"person\", Firstname: \"Brett\", Lastname: \"Lawson\"})\r\n\tif err != nil {\r\n\t\tt.Fatalf(\"Expected `err` to be `%s`, but got `%s`\", \"nil\", err)\r\n\t}\r\n}<\/pre>\n<p>Notar\u00e1s que este archivo es bastante largo y que tambi\u00e9n incluimos otro paquete personalizado. Antes de analizar el c\u00f3digo, descarguemos ese paquete. Desde la l\u00ednea de comandos, ejecuta lo siguiente:<\/p>\n<pre class=\"lang:default decode:true\">go get github.com\/mitchellh\/mapstructure<\/pre>\n<p>El paquete mapstructure nos permitir\u00e1 tomar mapas y convertirlos en estructuras de datos reales, como el paquete <code>Persona<\/code> estructura de datos que hab\u00edamos creado previamente. Esencialmente nos da un poco de flexibilidad en lo que podemos hacer.<\/p>\n<p>Si quieres saber m\u00e1s sobre el paquete mapstructure, consulta un art\u00edculo anterior que escrib\u00ed titulado,\u00a0<a href=\"https:\/\/www.thepolyglotdeveloper.com\/2017\/04\/decode-map-values-native-golang-structures\/\" target=\"_blank\" rel=\"noopener noreferrer\">Decodificaci\u00f3n de valores de mapas en estructuras Golang nativas<\/a>.<\/p>\n<p>Con las dependencias instaladas, ahora podemos ver el c\u00f3digo. \u00bfRecuerdas que usamos el Bucket del Go SDK en nuestro c\u00f3digo principal? En el c\u00f3digo de prueba, no vamos a hacer eso.<\/p>\n<pre class=\"lang:default decode:true\">type MockBucket struct{}\r\n\r\nvar testdatabase Database<\/pre>\n<p>En nuestro c\u00f3digo de prueba, estamos creando un <code>struct<\/code>pero lo fijamos en el <code>BucketInterface<\/code> en el <code>Base de datos<\/code> que se cre\u00f3 en nuestro c\u00f3digo principal.<\/p>\n<p>La configuraci\u00f3n real de la estructura de datos se realiza en la funci\u00f3n <code>TestMain<\/code> que se ejecuta antes de todas las dem\u00e1s pruebas:<\/p>\n<pre class=\"lang:default decode:true\">func TestMain(m *testing.M) {\r\n\ttestdatabase.bucket = &amp;MockBucket{}\r\n\tos.Exit(m.Run())\r\n}<\/pre>\n<p>Ahora bien, puesto que estamos utilizando un <code>MockBucket<\/code>no tiene todas las funciones que el <code>gocb.Bucket<\/code> podr\u00eda haber tenido. En su lugar, tenemos que confiar en la <code>BucketInterface<\/code> definici\u00f3n.<\/p>\n<p>Necesitamos crear un <code>Visite<\/code> y un <code>Inserte<\/code> como se define en la interfaz.<\/p>\n<p>Empezando por el <code>Visite<\/code> tenemos lo siguiente:<\/p>\n<pre class=\"lang:default decode:true\">func convert(start interface{}, end interface{}) error {\r\n\tbytes, err := json.Marshal(start)\r\n\tif err != nil {\r\n\t\treturn err\r\n\t}\r\n\terr = json.Unmarshal(bytes, end)\r\n\tif err != nil {\r\n\t\treturn err\r\n\t}\r\n\treturn nil\r\n}\r\n\r\nfunc (b MockBucket) Get(key string, value interface{}) (gocb.Cas, error) {\r\n\tswitch key {\r\n\tcase \"nraboy\":\r\n\t\terr := convert(Person{Type: \"person\", Firstname: \"Nic\", Lastname: \"Raboy\"}, value)\r\n\t\tif err != nil {\r\n\t\t\treturn 0, err\r\n\t\t}\r\n\tdefault:\r\n\t\treturn 0, gocb.ErrKeyNotFound\r\n\t}\r\n\treturn 1, nil\r\n}<\/pre>\n<p>Si utilizamos un <code>MockBucket<\/code> e intentamos <code>Visite<\/code>esperamos que s\u00f3lo una clave sea v\u00e1lida. Recuerda, esto es una prueba, as\u00ed que nosotros ponemos las reglas. Si <code>nraboy<\/code> se utiliza como clave, devolvemos algunos datos simulados, de lo contrario, devolvemos un <em>clave no encontrada<\/em> error. Dado que estamos trabajando con varios tipos de datos potenciales, necesitamos convertir nuestros datos utilizando la funci\u00f3n <code>convertir<\/code> funci\u00f3n. Esencialmente estamos marshaling una interfaz en JSON, a continuaci\u00f3n, marshaling de nuevo.<\/p>\n<p>Ahora echemos un vistazo a ese simulacro <code>Inserte<\/code> funci\u00f3n.<\/p>\n<pre class=\"lang:default decode:true\">func (b MockBucket) Insert(key string, value interface{}, expiry uint32) (gocb.Cas, error) {\r\n\tswitch key {\r\n\tcase \"nraboy\":\r\n\t\treturn 0, gocb.ErrKeyExists\r\n\t}\r\n\treturn 1, nil\r\n}<\/pre>\n<p>Si intentamos insertar datos utilizando nuestro mock Bucket, estamos esperando que la clave no sea igual a <code>nraboy<\/code>de lo contrario, arrojar\u00e1 un error.<\/p>\n<p>Con las funciones de interfaz creadas, podemos centrarnos en las pruebas reales que prueban las funciones en el c\u00f3digo Go principal.<\/p>\n<pre class=\"lang:default decode:true\">func TestGetPersonDocument(t *testing.T) {\r\n\tdata, err := testdatabase.GetPersonDocument(\"nraboy\")\r\n\tif err != nil {\r\n\t\tt.Fatalf(\"Expected `err` to be `%s`, but got `%s`\", \"nil\", err)\r\n\t}\r\n\tvar person Person\r\n\tmapstructure.Decode(data, &amp;person)\r\n\tif person.Type != \"person\" {\r\n\t\tt.Fatalf(\"Expected `type` to be %s, but got %s\", \"person\", person.Type)\r\n\t}\r\n}<\/pre>\n<p>En <code>TestGetPersonDocument<\/code> utilizar\u00e1 nuestro cubo simulado en el actual <code>GetPersonDocument<\/code> funci\u00f3n. Recuerda, estamos usando interfaces, as\u00ed que Go averiguar\u00e1 qu\u00e9 funci\u00f3n de la interfaz usar, si la funci\u00f3n real del SDK de Couchbase Go o la funci\u00f3n mock que hemos usado. Dependiendo de los resultados es lo que ocurre en el test.<\/p>\n<pre class=\"lang:default decode:true\">func TestCreatePersonDocument(t *testing.T) {\r\n\t_, err := testdatabase.CreatePersonDocument(\"blawson\", Person{Type: \"person\", Firstname: \"Brett\", Lastname: \"Lawson\"})\r\n\tif err != nil {\r\n\t\tt.Fatalf(\"Expected `err` to be `%s`, but got `%s`\", \"nil\", err)\r\n\t}\r\n}<\/pre>\n<p>En <code>TestCreatePersonDocument<\/code> no es diferente de la anterior. Estamos llamando a la actual <code>CrearDocumentoPersona<\/code>pero estamos utilizando nuestro cubo simulado con el mock <code>Inserte<\/code> funci\u00f3n.<\/p>\n<p>En este momento, tenemos una aplicaci\u00f3n Go funcional con pruebas y estamos listos para la integraci\u00f3n continua y el despliegue continuo.<\/p>\n<h2>Instalaci\u00f3n y configuraci\u00f3n de Jenkins para despliegues SSH y Golang<\/h2>\n<p>Este siguiente paso asume que tienes un servidor remoto que est\u00e1 listo para recibir despliegues. Yo no lo ten\u00eda, as\u00ed que cre\u00e9 un contenedor Docker con Ubuntu. De hecho, tanto mi instalaci\u00f3n de Jenkins como mi servidor remoto est\u00e1n usando Docker.<\/p>\n<p>Si quieres seguir lo que yo hice, echa un vistazo a esto. Desde la l\u00ednea de comandos, ejecuta lo siguiente para iniciar un contenedor Ubuntu:<\/p>\n<pre class=\"lang:default decode:true\">docker run -it --name ubuntu ubuntu \/bin\/bash<\/pre>\n<p>El comando anterior desplegar\u00e1 un contenedor Ubuntu y lo nombrar\u00e1 <code>ubuntu<\/code>. Una vez desplegado, se conectar\u00e1 a trav\u00e9s del terminal interactivo. No abr\u00ed ning\u00fan puerto porque la comunicaci\u00f3n de contenedor a contenedor no necesitar\u00e1 un puerto mapeado.<\/p>\n<p>El contenedor Ubuntu no tendr\u00e1 un servidor SSH disponible, por lo que necesitamos instalarlo. Dentro del shell de Ubuntu, ejecuta lo siguiente:<\/p>\n<pre class=\"lang:default decode:true\">apt-get update\r\napt-get install openssh-server\r\nservice ssh restart<\/pre>\n<p>Los comandos anteriores instalar\u00e1n <code>openssh-servidor<\/code> e iniciarlo. Mientras estamos en ello, probablemente deber\u00edamos crear una combinaci\u00f3n de clave p\u00fablica y privada para que Jenkins la utilice.<\/p>\n<p>Dentro del shell de Ubuntu, ejecute lo siguiente:<\/p>\n<pre class=\"lang:default decode:true\">ssh-keygen -t rsa<\/pre>\n<p>Cuando haya terminado, copie el archivo\u00a0<strong>~\/.ssh\/id_rsa.pub<\/strong> contenido en\u00a0<strong>~\/.ssh\/authorized_keys<\/strong> ya que usaremos la clave privada en el servidor Jenkins.<\/p>\n<p>Recuerda, estoy usando Jenkins como un contenedor Docker tambi\u00e9n. No tienes que usar ning\u00fan contenedor si no quieres. Todo deber\u00eda traducirse bien.<\/p>\n<p>Si utiliza Docker, cree un contenedor Jenkins ejecutando lo siguiente:<\/p>\n<pre class=\"lang:default decode:true\">docker run -d -p 8080:8080 -p 50000:50000 --name jenkins jenkins<\/pre>\n<p>El comando anterior desplegar\u00e1 Jenkins en modo separado y mapear\u00e1 algunos puertos para nosotros.<\/p>\n<p>Cuando visite\u00a0<strong>https:\/\/localhost:8080<\/strong> en su navegador web, siga los pasos del asistente y aseg\u00farese de elegir instalar los plugins recomendados.<\/p>\n<p>Una vez que llegue al panel principal de Jenkins, seleccione\u00a0<strong>Administrar Jenkins -&gt; Administrar Plugins<\/strong> ya que necesitamos descargar algunas cosas.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4617 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/golang-jenkins-plugins.png\" alt=\"Golang Jenkins Plugins\" width=\"2082\" height=\"452\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins.png 2082w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins-300x65.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins-1024x222.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins-768x167.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins-1536x333.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins-2048x445.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins-20x4.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins-1320x287.png 1320w\" sizes=\"auto, (max-width: 2082px) 100vw, 2082px\" \/><\/p>\n<p>Vamos a necesitar una forma de compilar nuestro c\u00f3digo Go, por lo que vamos a necesitar el comando <a href=\"https:\/\/wiki.jenkins.io\/display\/JENKINS\/Go+Plugin\" target=\"_blank\" rel=\"noopener noreferrer\">Vaya a<\/a> plugin. Vamos a necesitar ejecutar nuestros propios scripts personalizados para la construcci\u00f3n, por lo que necesitamos el plugin <a href=\"https:\/\/wiki.jenkins.io\/display\/JENKINS\/PostBuildScript+Plugin\" target=\"_blank\" rel=\"noopener noreferrer\">PostBuildScript<\/a> plugin. Por \u00faltimo, queremos poder publicar en un servidor remoto y ejecutar comandos, por lo que necesitaremos el plugin <a href=\"https:\/\/wiki.jenkins.io\/display\/JENKINS\/Publish+Over+SSH+Plugin\" target=\"_blank\" rel=\"noopener noreferrer\">Publicar a trav\u00e9s de SSH<\/a> que viene con otros plugins incluidos.<\/p>\n<p>Despu\u00e9s de que los plugins terminen de descargarse, tenemos que configurarlos globalmente.<\/p>\n<p>En el panel principal de Jenkins, seleccione\u00a0<strong>Gestionar Jenkins -&gt; Configuraci\u00f3n Global de Herramientas<\/strong>\u00a0y busca la secci\u00f3n Go.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4618 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/golang-jenkins-config.png\" alt=\"Golang Jenkins Configuration\" width=\"2048\" height=\"866\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-config.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-config-300x127.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-config-1024x433.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-config-768x325.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-config-1536x650.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-config-20x8.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-config-1320x558.png 1320w\" sizes=\"auto, (max-width: 2048px) 100vw, 2048px\" \/><\/p>\n<p>Querr\u00e1s definir qu\u00e9 versiones de Go est\u00e1n disponibles. Para este proyecto, s\u00f3lo necesitamos la versi\u00f3n 1.8, pero el resto depende de ti.<\/p>\n<p>El siguiente paso es configurar nuestras claves SSH para el despliegue. Recuerda, a\u00fan no estamos creando nuestro flujo de trabajo, solo configurando Jenkins como un todo.<\/p>\n<p>En el panel principal de Jenkins, seleccione\u00a0<strong>Gestionar Jenkins -&gt; Configurar sistema<\/strong> y encuentra la secci\u00f3n SSH.<\/p>\n<p>Usted va a querer proporcionar su clave privada y la informaci\u00f3n de conexi\u00f3n del servidor. Si tanto Jenkins como el servidor remoto son contenedores Docker en la misma red que el m\u00edo, no olvides usar las direcciones IP o nombres de host de los contenedores, no localhost.<\/p>\n<p>Con todo configurado, seleccione\u00a0<strong>Art\u00edculo nuevo<\/strong> desde el panel principal de Jenkins.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4619 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/jenkins-golang-project.png\" alt=\"New Jenkins Golang Project\" width=\"2866\" height=\"922\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-project.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-project-300x97.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-project-1024x330.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-project-768x247.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-project-1536x494.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-project-20x6.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-project-1320x425.png 1320w\" sizes=\"auto, (max-width: 2866px) 100vw, 2866px\" \/><\/p>\n<p>Vas a querer darle un nombre y seleccionar\u00a0<strong>Proyecto Freestyle<\/strong> para que podamos a\u00f1adir nuestro propio flujo de trabajo. Tome nota del nombre, porque el nombre ser\u00e1 el binario del proyecto que se construye.<\/p>\n<p>Ahora podemos definir nuestro flujo de trabajo.<\/p>\n<p>Empezaremos con el\u00a0<strong>Gesti\u00f3n del c\u00f3digo fuente<\/strong> secci\u00f3n. Recuerda, tengo este proyecto en <a href=\"https:\/\/github.com\/couchbaselabs\/golang-ci-example\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>as\u00ed que deber\u00edas aprovecharlo.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4620 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/jenkins-golang-source-management.png\" alt=\"Jenkins Source Code Management Golang\" width=\"2880\" height=\"1056\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-source-management.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-source-management-300x110.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-source-management-1024x376.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-source-management-768x282.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-source-management-1536x563.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-source-management-20x7.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-source-management-1320x484.png 1320w\" sizes=\"auto, (max-width: 2880px) 100vw, 2880px\" \/><\/p>\n<p>Dado que Jenkins en este ejemplo se est\u00e1 ejecutando en localhost y no en un dominio, no podemos hacer nada con los disparadores de construcci\u00f3n. Para este ejemplo, vamos a desencadenar las cosas manualmente.<\/p>\n<p>Antes de intentar ejecutar cualquier script, necesitamos configurar el entorno de compilaci\u00f3n a la versi\u00f3n de Go especificada previamente.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4621 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/jenkins-golang-build-environment.png\" alt=\"Jenkins Golang Build Environment\" width=\"2880\" height=\"818\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-build-environment.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-build-environment-300x85.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-build-environment-1024x291.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-build-environment-768x218.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-build-environment-1536x437.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-build-environment-20x6.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-build-environment-1320x375.png 1320w\" sizes=\"auto, (max-width: 2880px) 100vw, 2880px\" \/><\/p>\n<p>Cuando se inicie el flujo de trabajo, descargar\u00e1 e instalar\u00e1 esa versi\u00f3n de Go antes de ejecutar pruebas o compilaciones.<\/p>\n<p>Para la fase de construcci\u00f3n, vamos a realizar tres pasos diferentes, separados para mantener el flujo de las cosas muy limpio.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4622 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/jenkins-golang-prep-test-build.png\" alt=\"Jenkins Golang Build\" width=\"2880\" height=\"1250\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-prep-test-build.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-prep-test-build-300x130.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-prep-test-build-1024x445.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-prep-test-build-768x333.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-prep-test-build-1536x667.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-prep-test-build-20x9.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-golang-prep-test-build-1320x573.png 1320w\" sizes=\"auto, (max-width: 2880px) 100vw, 2880px\" \/><\/p>\n<p>El primer paso es descargar nuestros paquetes Go. Despu\u00e9s de tener nuestros paquetes, podemos ejecutar nuestras pruebas. Despu\u00e9s de ejecutar nuestras pruebas podemos hacer un <code>ir a construir<\/code> para crear nuestro binario. Si alguno de estos pasos falla, toda la compilaci\u00f3n falla, que es como debe ser.<\/p>\n<p>El \u00faltimo paso es el despliegue. En el\u00a0<strong>Acciones posteriores a la construcci\u00f3n,<\/strong> queremos enviar nuestro binario por SSH y ejecutarlo.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4623 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/jenkins-deploy-golang.png\" alt=\"Jenkins Deploy with SSH\" width=\"2880\" height=\"1326\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-deploy-golang.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-deploy-golang-300x138.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-deploy-golang-1024x472.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-deploy-golang-768x354.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-deploy-golang-1536x707.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-deploy-golang-20x9.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/jenkins-deploy-golang-1320x608.png 1320w\" sizes=\"auto, (max-width: 2880px) 100vw, 2880px\" \/><\/p>\n<p>En realidad, habr\u00e1 dos conjuntos de transferencia implicados en este proceso.<\/p>\n<p>La primera fase consiste en tomar nuestro fichero fuente, que es el binario, y enviarlo utilizando el perfil SSH que hab\u00edamos creado previamente. Una vez transferido el archivo cambiaremos los permisos para que pueda ser ejecutado.<\/p>\n<p>Una vez cargado el archivo, queremos ejecutarlo utilizando otro comando\u00a0<strong>Conjunto de transferencia<\/strong>. En lugar de tener un archivo fuente en el segundo conjunto, s\u00f3lo tendremos un comando:<\/p>\n<pre class=\"lang:default decode:true\">DB_HOST=ec2-34-226-41-140.compute-1.amazonaws.com DB_USER=demo DB_PASS=123456 DB_BUCKET=example .\/Golang_CI<\/pre>\n<p>F\u00edjate que estoy pasando variables para ser usadas como variables de entorno en la aplicaci\u00f3n. C\u00e1mbialas por lo que est\u00e9s usando, o piensa en otro enfoque como tener estas variables configuradas en tu servidor por seguridad.<\/p>\n<p>En teor\u00eda, estar\u00edas desplegando una aplicaci\u00f3n web y este comando final se utiliza para iniciar el servidor con la informaci\u00f3n de conexi\u00f3n.<\/p>\n<h2>Conclusi\u00f3n<\/h2>\n<p>Acaba de ver c\u00f3mo configurar <span style=\"font-weight: 400\">Jenkins y Golang en un pipeline para <\/span>despliegue continuo. Por si fuera poco, utilizamos <a href=\"https:\/\/www.couchbase.com\/blog\/es\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a> y Docker en este ejemplo para manejar nuestro servidor remoto as\u00ed como nuestro servidor Jenkins. Su configuraci\u00f3n puede diferir, pero los pasos son m\u00e1s o menos los mismos.<\/p>\n<p>Si desea obtener m\u00e1s informaci\u00f3n sobre el uso de Jenkins y Go con Couchbase, consulte el documento <a href=\"https:\/\/www.couchbase.com\/blog\/es\/developers\/\" target=\"_blank\" rel=\"noopener noreferrer\">Portal para desarrolladores de Couchbase<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>A few weeks ago I had written about continuously deploying an application written with the Go programming language using a popular service called Travis CI. This example demonstrated creating an application that used a Couchbase NoSQL database, creating unit tests, [&hellip;]<\/p>","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1816,1820],"tags":[1919,2031,1567,2150,1565,1725,1921],"ppma_author":[9032],"class_list":["post-4616","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-server","category-golang","tag-cd","tag-ci","tag-continuous-deployment","tag-continuous-integration","tag-jenkins","tag-nosql-database","tag-pipeline"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Continuous Deployment Pipelines with Golang + Jenkins<\/title>\n<meta name=\"description\" content=\"In this Couchbase post find out how to use Jenkins for a pipeline for a Golang application, enabling continuous integration and continuous deployment.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/create-continuous-deployment-pipeline-golang-jenkins\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create Continuous Deployment Pipelines with Golang &amp; Jenkins\" \/>\n<meta property=\"og:description\" content=\"In this Couchbase post find out how to use Jenkins for a pipeline for a Golang application, enabling continuous integration and continuous deployment.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/create-continuous-deployment-pipeline-golang-jenkins\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2018-02-20T15:00:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T01:45:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2082\" \/>\n\t<meta property=\"og:image:height\" content=\"452\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Create Continuous Deployment Pipelines with Golang &amp; Jenkins\",\"datePublished\":\"2018-02-20T15:00:23+00:00\",\"dateModified\":\"2025-06-14T01:45:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/\"},\"wordCount\":2131,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"cd\",\"ci\",\"Continuous Deployment\",\"continuous integration\",\"Jenkins\",\"NoSQL Database\",\"pipeline\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Server\",\"GoLang\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/\",\"name\":\"Continuous Deployment Pipelines with Golang + Jenkins\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2018-02-20T15:00:23+00:00\",\"dateModified\":\"2025-06-14T01:45:42+00:00\",\"description\":\"In this Couchbase post find out how to use Jenkins for a pipeline for a Golang application, enabling continuous integration and continuous deployment.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create Continuous Deployment Pipelines with Golang &amp; Jenkins\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Continuous Deployment Pipelines with Golang + Jenkins","description":"In this Couchbase post find out how to use Jenkins for a pipeline for a Golang application, enabling continuous integration and continuous deployment.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/create-continuous-deployment-pipeline-golang-jenkins\/","og_locale":"es_MX","og_type":"article","og_title":"Create Continuous Deployment Pipelines with Golang &amp; Jenkins","og_description":"In this Couchbase post find out how to use Jenkins for a pipeline for a Golang application, enabling continuous integration and continuous deployment.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/create-continuous-deployment-pipeline-golang-jenkins\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2018-02-20T15:00:23+00:00","article_modified_time":"2025-06-14T01:45:42+00:00","og_image":[{"width":2082,"height":452,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/golang-jenkins-plugins.png","type":"image\/png"}],"author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"11 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Create Continuous Deployment Pipelines with Golang &amp; Jenkins","datePublished":"2018-02-20T15:00:23+00:00","dateModified":"2025-06-14T01:45:42+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/"},"wordCount":2131,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["cd","ci","Continuous Deployment","continuous integration","Jenkins","NoSQL Database","pipeline"],"articleSection":["Best Practices and Tutorials","Couchbase Server","GoLang"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/","url":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/","name":"Continuous Deployment Pipelines with Golang + Jenkins","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2018-02-20T15:00:23+00:00","dateModified":"2025-06-14T01:45:42+00:00","description":"In this Couchbase post find out how to use Jenkins for a pipeline for a Golang application, enabling continuous integration and continuous deployment.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create Continuous Deployment Pipelines with Golang &amp; Jenkins"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, Defensor del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","first_name":"Nic","last_name":"Raboy","user_url":"https:\/\/www.thepolyglotdeveloper.com","author_category":"","description":"Nic Raboy es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4616","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=4616"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4616\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=4616"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=4616"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=4616"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=4616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}