{"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\/pt\/create-continuous-deployment-pipeline-golang-jenkins\/","title":{"rendered":"Criar pipelines de implanta\u00e7\u00e3o cont\u00ednua com Golang e Jenkins"},"content":{"rendered":"<p>H\u00e1 algumas semanas, escrevi sobre a implanta\u00e7\u00e3o cont\u00ednua de um aplicativo escrito com a linguagem de programa\u00e7\u00e3o Go usando um servi\u00e7o popular chamado Travis CI. Esse exemplo demonstrou a cria\u00e7\u00e3o de um aplicativo que usava um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a> banco de dados NoSQL, criando testes de unidade, executando esses testes no pipeline de integra\u00e7\u00e3o cont\u00ednua do Golang e, por fim, implantando o aplicativo em algum servidor remoto quando tudo for bem-sucedido.<\/p>\n<p>O Travis CI n\u00e3o \u00e9 o \u00fanico servi\u00e7o que oferece esses recursos. Na verdade, voc\u00ea pode hospedar seu pr\u00f3prio servi\u00e7o de CI\/CD usando o Jenkins.<\/p>\n<p>Veremos como usar o Jenkins para um pipeline de um aplicativo Golang, permitindo a integra\u00e7\u00e3o e a implanta\u00e7\u00e3o cont\u00ednuas.<\/p>\n<p><!--more--><\/p>\n<p>Se voc\u00ea ainda n\u00e3o leu meu <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/continuously-deploying-golang-application-using-travis-ci\/\" target=\"_blank\" rel=\"noopener noreferrer\">tutorial anterior Golang com Travis CI<\/a>Recomendo que voc\u00ea o fa\u00e7a, pois ele fornece muitas explica\u00e7\u00f5es \u00fateis. Muito do mesmo material aparecer\u00e1 aqui, mas ser\u00e1 explicado de forma diferente, portanto, duas explica\u00e7\u00f5es podem ser \u00fateis.<\/p>\n<p>Se quiser experimentar de verdade este tutorial Jenkins with Golang, voc\u00ea precisar\u00e1 de <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/products\/server\/\" target=\"_blank\" rel=\"noopener noreferrer\">Servidor Couchbase<\/a> instalado em algum lugar. O objetivo \u00e9 fazer com que o aplicativo seja executado e use essa inst\u00e2ncia do banco de dados ap\u00f3s a implanta\u00e7\u00e3o.<\/p>\n<h2>Desenvolvimento de um aplicativo Go com Couchbase<\/h2>\n<p>Para ter sucesso com este tutorial, precisaremos de um aplicativo Go para testar e implantar. Se voc\u00ea quiser se adiantar, fiz o upload de um projeto funcional no <a href=\"https:\/\/github.com\/couchbaselabs\/golang-ci-example\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>. Na verdade, \u00e9 o mesmo projeto do exemplo do Travis CI.<\/p>\n<p>Se voc\u00ea preferir conhecer o projeto, vamos dedicar algum tempo para isso.<\/p>\n<p>Em algum lugar em seu\u00a0<strong>$GOPATH<\/strong> criar um arquivo chamado\u00a0<strong>main.go<\/strong> e inclua o seguinte c\u00f3digo Go. Vamos detalh\u00e1-lo depois.<\/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>O aplicativo n\u00e3o faz muita coisa, mas h\u00e1 muita coisa acontecendo.<\/p>\n<p>Nas importa\u00e7\u00f5es, voc\u00ea notar\u00e1 que usamos o SDK do Couchbase para Go. Para poder compilar esse projeto, voc\u00ea precisar\u00e1 fazer o download do SDK. Isso pode ser feito com o seguinte comando:<\/p>\n<pre class=\"lang:default decode:true\">go get gopkg.in\/couchbase\/gocb.v1<\/pre>\n<p>Antes de come\u00e7armos a analisar o c\u00f3digo, precisamos dar um passo atr\u00e1s e descobrir como esse aplicativo deve funcionar.<\/p>\n<p>O objetivo aqui \u00e9 conectar-se ao banco de dados NoSQL, Couchbase, recuperar alguns dados e criar alguns dados. Naturalmente, isso seria muito f\u00e1cil por meio do SDK, mas queremos criar testes de unidade para o nosso aplicativo. \u00c9 uma pr\u00e1tica recomendada nunca testar um banco de dados em um teste de unidade. Guarde isso para seus testes de integra\u00e7\u00e3o. Se n\u00e3o estivermos testando o banco de dados, precisaremos criar cen\u00e1rios de simula\u00e7\u00e3o.<\/p>\n<p>Em vez de criar um monte de maluquices, a melhor maneira de dividir entre cen\u00e1rios reais e simulados \u00e9 criar uma interface para ambos com Go. O aplicativo principal usar\u00e1 as classes reais como parte da interface, enquanto os testes usar\u00e3o a simula\u00e7\u00e3o.<\/p>\n<p>Por esse motivo, precisamos criar uma interface para o Couchbase Go SDK <code>Balde<\/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>Um Couchbase Bucket tem muito mais fun\u00e7\u00f5es do que <code>Obter<\/code> e <code>Inserir<\/code>mas essas ser\u00e3o as \u00fanicas fun\u00e7\u00f5es que usaremos neste exemplo. Para simplificar, mais adiante no aplicativo, criaremos uma fun\u00e7\u00e3o <code>estrutura<\/code> com a nova interface.<\/p>\n<pre class=\"lang:default decode:true\">type Database struct {\r\n\tbucket BucketInterface\r\n}<\/pre>\n<p>Haver\u00e1 apenas um modelo de dados para este exemplo. Usaremos um modelo de dados baseado no modelo <code>Pessoa<\/code> estrutura de dados. Ela pode ser alterada livremente sem afetar nosso aplicativo.<\/p>\n<p>D\u00ea uma olhada em uma de nossas fun\u00e7\u00f5es para a qual eventualmente teremos testes unit\u00e1rios:<\/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>No <code>GetPersonDocument<\/code> estamos usando uma fun\u00e7\u00e3o <code>BucketInterface<\/code> e obter um documento espec\u00edfico pela chave do documento.<\/p>\n<p>Da mesma forma, se quisermos criar dados, teremos o seguinte:<\/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>Sinto que preciso reiterar isso, mas essas fun\u00e7\u00f5es foram projetadas para serem mais complexas do que o necess\u00e1rio. Estamos fazendo isso porque queremos demonstrar alguns testes. Se voc\u00ea se sentir melhor, adicione um pouco mais de complexidade a elas em vez de apenas <code>Obter<\/code> e <code>Inserir<\/code> funcionalidade.<\/p>\n<p>Por fim, temos o seguinte, que \u00e9 executado em tempo de execu\u00e7\u00e3o:<\/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>Quando o aplicativo \u00e9 executado, estabelecemos uma conex\u00e3o com o Couchbase usando vari\u00e1veis de ambiente. O Bucket aberto \u00e9 definido como nosso <code>BucketInterface<\/code>e, em seguida, as duas fun\u00e7\u00f5es s\u00e3o executadas.<\/p>\n<p>Ent\u00e3o, como podemos testar isso?<\/p>\n<p>Crie um arquivo em seu projeto chamado\u00a0<strong>main_test.go<\/strong> com o seguinte 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>Voc\u00ea perceber\u00e1 que esse arquivo \u00e9 bastante longo e que tamb\u00e9m estamos incluindo outro pacote personalizado. Antes de analisarmos o c\u00f3digo, vamos fazer o download desse pacote. Na linha de comando, execute o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">go get github.com\/mitchellh\/mapstructure<\/pre>\n<p>O pacote mapstructure nos permitir\u00e1 pegar mapas e convert\u00ea-los em estruturas de dados reais, como o <code>Pessoa<\/code> estrutura de dados que hav\u00edamos criado anteriormente. Basicamente, isso nos d\u00e1 um pouco de flexibilidade no que podemos fazer.<\/p>\n<p>Se voc\u00ea quiser saber mais sobre o pacote mapstructure, confira um artigo anterior que escrevi intitulado,\u00a0<a href=\"https:\/\/www.thepolyglotdeveloper.com\/2017\/04\/decode-map-values-native-golang-structures\/\" target=\"_blank\" rel=\"noopener noreferrer\">Decodificar valores de mapas em estruturas nativas da Golang<\/a>.<\/p>\n<p>Com as depend\u00eancias instaladas, agora podemos dar uma olhada no c\u00f3digo. Lembra-se de como usamos o Bucket do Go SDK em nosso c\u00f3digo principal? No c\u00f3digo de teste, n\u00e3o faremos isso.<\/p>\n<pre class=\"lang:default decode:true\">type MockBucket struct{}\r\n\r\nvar testdatabase Database<\/pre>\n<p>Em nosso c\u00f3digo de teste, estamos criando um arquivo <code>estrutura<\/code>mas estamos definindo-o como <code>BucketInterface<\/code> no <code>Banco de dados<\/code> que foi criada em nosso c\u00f3digo principal.<\/p>\n<p>A configura\u00e7\u00e3o real da estrutura de dados ocorre no <code>TestMain<\/code> que \u00e9 executada antes de todos os outros testes:<\/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>Agora, como estamos usando um <code>MockBucket<\/code>Ele n\u00e3o tem todas as fun\u00e7\u00f5es que o <code>gocb.Bucket<\/code> poderia ter tido. Em vez disso, precisamos confiar na <code>BucketInterface<\/code> defini\u00e7\u00e3o.<\/p>\n<p>Precisamos criar um <code>Obter<\/code> e um <code>Inserir<\/code> conforme definido na interface.<\/p>\n<p>Come\u00e7ando com o <code>Obter<\/code> temos o seguinte:<\/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>Se estivermos usando um <code>MockBucket<\/code> e tentamos <code>Obter<\/code>Esperamos que apenas uma chave seja v\u00e1lida. Lembre-se de que este \u00e9 um teste, portanto, somos n\u00f3s que estabelecemos as regras. Se <code>garoto<\/code> \u00e9 usado como uma chave, retornamos alguns dados simulados; caso contr\u00e1rio, retornamos um <em>chave n\u00e3o encontrada<\/em> erro. Como estamos trabalhando com v\u00e1rios tipos de dados em potencial, precisamos converter nossos dados usando a fun\u00e7\u00e3o <code>converter<\/code> fun\u00e7\u00e3o. Essencialmente, estamos transformando uma interface em JSON e, em seguida, transformando-a de volta.<\/p>\n<p>Agora vamos dar uma olhada nessa simula\u00e7\u00e3o <code>Inserir<\/code> fun\u00e7\u00e3o.<\/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>Se tentarmos inserir dados usando nosso Bucket de simula\u00e7\u00e3o, esperamos que a chave n\u00e3o seja igual a <code>garoto<\/code>caso contr\u00e1rio, gera um erro.<\/p>\n<p>Com as fun\u00e7\u00f5es de interface criadas, podemos nos concentrar nos testes reais que testam as fun\u00e7\u00f5es no c\u00f3digo principal em Go.<\/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>O <code>TestGetPersonDocument<\/code> usar\u00e1 nosso Bucket de simula\u00e7\u00e3o no <code>GetPersonDocument<\/code> function. Lembre-se de que estamos usando interfaces, portanto, o Go descobrir\u00e1 qual fun\u00e7\u00e3o de interface usar, seja a fun\u00e7\u00e3o real do Couchbase Go SDK ou a fun\u00e7\u00e3o de simula\u00e7\u00e3o que usamos. Dependendo dos resultados, \u00e9 isso que acontece no teste.<\/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>O <code>TestCreatePersonDocument<\/code> n\u00e3o \u00e9 diferente do anterior. Estamos chamando o <code>CreatePersonDocument<\/code>mas estamos usando nosso Bucket de simula\u00e7\u00e3o com a fun\u00e7\u00e3o de simula\u00e7\u00e3o <code>Inserir<\/code> fun\u00e7\u00e3o.<\/p>\n<p>Neste momento, temos um aplicativo Go funcional com testes e estamos prontos para a integra\u00e7\u00e3o cont\u00ednua e a implanta\u00e7\u00e3o cont\u00ednua.<\/p>\n<h2>Instala\u00e7\u00e3o e configura\u00e7\u00e3o do Jenkins para implementa\u00e7\u00f5es de SSH e Golang<\/h2>\n<p>A pr\u00f3xima etapa pressup\u00f5e que voc\u00ea tenha um servidor remoto pronto para receber implementa\u00e7\u00f5es. Como eu n\u00e3o tinha, criei um cont\u00eainer do Docker com o Ubuntu. Na verdade, tanto a minha instala\u00e7\u00e3o do Jenkins quanto o servidor remoto est\u00e3o usando o Docker.<\/p>\n<p>Se voc\u00ea quiser seguir o que eu fiz, d\u00ea uma olhada nisto. Na linha de comando, execute o seguinte para iniciar um cont\u00eainer do Ubuntu:<\/p>\n<pre class=\"lang:default decode:true\">docker run -it --name ubuntu ubuntu \/bin\/bash<\/pre>\n<p>O comando acima implantar\u00e1 um cont\u00eainer do Ubuntu e o nomear\u00e1 <code>ubuntu<\/code>. Depois de implantado, voc\u00ea estar\u00e1 conectado por meio do terminal interativo. N\u00e3o abri nenhuma porta porque a comunica\u00e7\u00e3o entre cont\u00eaineres n\u00e3o precisar\u00e1 de uma porta mapeada.<\/p>\n<p>O cont\u00eainer do Ubuntu n\u00e3o ter\u00e1 um servidor SSH dispon\u00edvel, portanto, precisamos instal\u00e1-lo. No shell do Ubuntu, execute o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">apt-get update\r\napt-get install openssh-server\r\nservice ssh restart<\/pre>\n<p>Os comandos acima instalar\u00e3o <code>servidor openssh<\/code> e inici\u00e1-lo. Enquanto isso, provavelmente dever\u00edamos criar uma combina\u00e7\u00e3o de chave p\u00fablica e privada para o Jenkins usar.<\/p>\n<p>No shell do Ubuntu, execute o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">ssh-keygen -t rsa<\/pre>\n<p>Quando terminar, copie o\u00a0<strong>~\/.ssh\/id_rsa.pub<\/strong> conte\u00fado em\u00a0<strong>~\/.ssh\/authorized_keys<\/strong> pois usaremos a chave privada no servidor Jenkins.<\/p>\n<p>Lembre-se de que tamb\u00e9m estou usando o Jenkins como um cont\u00eainer do Docker. Voc\u00ea n\u00e3o precisa usar nenhum cont\u00eainer se n\u00e3o quiser. Tudo deve se traduzir bem.<\/p>\n<p>Se estiver usando o Docker, crie um cont\u00eainer do Jenkins executando o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">docker run -d -p 8080:8080 -p 50000:50000 --name jenkins jenkins<\/pre>\n<p>O comando acima implantar\u00e1 o Jenkins no modo desanexado e mapear\u00e1 algumas portas para n\u00f3s.<\/p>\n<p>Quando voc\u00ea visita\u00a0<strong>https:\/\/localhost:8080<\/strong> em seu navegador da Web, siga as etapas do assistente e certifique-se de optar por instalar os plug-ins recomendados.<\/p>\n<p>Quando voc\u00ea chegar ao painel principal do Jenkins, selecione\u00a0<strong>Gerenciar Jenkins -&gt; Gerenciar plug-ins<\/strong> pois precisamos fazer o download de algumas coisas.<\/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>Precisaremos de uma maneira de compilar nosso c\u00f3digo Go, portanto, precisaremos do <a href=\"https:\/\/wiki.jenkins.io\/display\/JENKINS\/Go+Plugin\" target=\"_blank\" rel=\"noopener noreferrer\">Ir<\/a> plugin. Vamos precisar executar nossos pr\u00f3prios scripts personalizados para a constru\u00e7\u00e3o, portanto, precisamos do <a href=\"https:\/\/wiki.jenkins.io\/display\/JENKINS\/PostBuildScript+Plugin\" target=\"_blank\" rel=\"noopener noreferrer\">PostBuildScript<\/a> plugin. Por fim, queremos poder publicar em um servidor remoto e executar comandos, portanto, precisaremos do plug-in <a href=\"https:\/\/wiki.jenkins.io\/display\/JENKINS\/Publish+Over+SSH+Plugin\" target=\"_blank\" rel=\"noopener noreferrer\">Publicar por SSH<\/a> que vem com outros plug-ins inclu\u00eddos.<\/p>\n<p>Depois que o download dos plug-ins for conclu\u00eddo, precisaremos configur\u00e1-los globalmente.<\/p>\n<p>No painel principal do Jenkins, selecione\u00a0<strong>Gerenciar Jenkins -&gt; Configura\u00e7\u00e3o global de ferramentas<\/strong>\u00a0e procure a se\u00e7\u00e3o 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>Voc\u00ea dever\u00e1 definir quais vers\u00f5es do Go est\u00e3o dispon\u00edveis. Para este projeto, precisamos apenas da vers\u00e3o 1.8, mas o restante fica a seu crit\u00e9rio.<\/p>\n<p>A pr\u00f3xima etapa \u00e9 configurar nossas chaves SSH para implanta\u00e7\u00e3o. Lembre-se de que ainda n\u00e3o estamos criando nosso fluxo de trabalho, apenas configurando o Jenkins como um todo.<\/p>\n<p>No painel principal do Jenkins, selecione\u00a0<strong>Gerenciar Jenkins -&gt; Configurar sistema<\/strong> e localize a se\u00e7\u00e3o SSH.<\/p>\n<p>Voc\u00ea vai querer fornecer sua chave privada e as informa\u00e7\u00f5es de conex\u00e3o do servidor. Se tanto o Jenkins quanto o servidor remoto forem cont\u00eaineres do Docker na mesma rede que a minha, n\u00e3o se esque\u00e7a de usar os endere\u00e7os IP ou nomes de host do cont\u00eainer, e n\u00e3o o host local.<\/p>\n<p>Com tudo configurado, selecione\u00a0<strong>Novo item<\/strong> no painel principal do 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>Voc\u00ea vai querer dar um nome a ele e selecionar\u00a0<strong>Projeto Freestyle<\/strong> para que possamos adicionar nosso pr\u00f3prio fluxo de trabalho. Observe o nome, pois ele ser\u00e1 o bin\u00e1rio do projeto que ser\u00e1 criado.<\/p>\n<p>Agora podemos definir nosso fluxo de trabalho.<\/p>\n<p>Come\u00e7aremos com o\u00a0<strong>Gerenciamento de c\u00f3digo-fonte<\/strong> se\u00e7\u00e3o. Lembre-se, tenho esse projeto em <a href=\"https:\/\/github.com\/couchbaselabs\/golang-ci-example\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>portanto, voc\u00ea definitivamente deve tirar proveito disso.<\/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>Como o Jenkins, neste exemplo, est\u00e1 sendo executado no localhost e n\u00e3o em um dom\u00ednio, n\u00e3o podemos realmente fazer nada com os acionadores de compila\u00e7\u00e3o. Para este exemplo, vamos acionar as coisas manualmente.<\/p>\n<p>Antes de tentarmos executar qualquer script, precisamos definir o ambiente de compila\u00e7\u00e3o para a vers\u00e3o do Go especificada anteriormente.<\/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>Quando o fluxo de trabalho for iniciado, ele baixar\u00e1 e instalar\u00e1 essa vers\u00e3o do Go antes de executar testes ou compila\u00e7\u00f5es.<\/p>\n<p>Para a fase de constru\u00e7\u00e3o, vamos realizar tr\u00eas etapas diferentes, separadas para manter o fluxo das coisas bem limpo.<\/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>A primeira etapa de compila\u00e7\u00e3o \u00e9 fazer o download dos pacotes Go. Depois que tivermos nossos pacotes, poderemos executar nossos testes. Depois de executar os testes, podemos fazer um <code>ir construir<\/code> para criar nosso bin\u00e1rio. Se alguma dessas etapas falhar, toda a compila\u00e7\u00e3o falhar\u00e1, e \u00e9 assim que deve ser.<\/p>\n<p>A etapa final \u00e9 a implanta\u00e7\u00e3o. Na se\u00e7\u00e3o\u00a0<strong>A\u00e7\u00f5es p\u00f3s-constru\u00e7\u00e3o,<\/strong> queremos enviar nosso bin\u00e1rio por SSH e execut\u00e1-lo.<\/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>Na verdade, haver\u00e1 dois conjuntos de transfer\u00eancias envolvidos nesse processo.<\/p>\n<p>A primeira fase \u00e9 pegar nosso arquivo de origem, que \u00e9 o bin\u00e1rio, e envi\u00e1-lo usando o perfil SSH que criamos anteriormente. Depois que o arquivo for transferido, alteraremos as permiss\u00f5es para que ele possa ser executado.<\/p>\n<p>Depois que o arquivo for carregado, queremos execut\u00e1-lo de fato usando outro\u00a0<strong>Conjunto de transfer\u00eancia<\/strong>. Em vez de ter um arquivo de c\u00f3digo-fonte no segundo conjunto, teremos apenas um 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>Observe que estou passando vari\u00e1veis para serem usadas como vari\u00e1veis de ambiente no aplicativo. Troque-as pelo que voc\u00ea estiver usando ou pense em outra abordagem, como definir essas vari\u00e1veis no servidor para fins de seguran\u00e7a.<\/p>\n<p>Em teoria, voc\u00ea estaria implantando um aplicativo da Web e esse comando final \u00e9 usado para iniciar o servidor com informa\u00e7\u00f5es de conex\u00e3o.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como configurar <span style=\"font-weight: 400\">Jenkins e Golang em um pipeline para <\/span>implanta\u00e7\u00e3o cont\u00ednua. Para completar, usamos de fato o <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a> e Docker neste exemplo para lidar com o nosso servidor remoto, bem como com o nosso servidor Jenkins. Sua configura\u00e7\u00e3o pode ser diferente, mas as etapas s\u00e3o mais ou menos as mesmas.<\/p>\n<p>Se voc\u00ea quiser saber mais sobre como usar o Jenkins e o Go com o Couchbase, confira o artigo <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/developers\/\" target=\"_blank\" rel=\"noopener noreferrer\">Portal do desenvolvedor do 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\/pt\/create-continuous-deployment-pipeline-golang-jenkins\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\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\/pt\/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\":\"pt-BR\",\"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\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\",\"@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\/pt\/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\/pt\/create-continuous-deployment-pipeline-golang-jenkins\/","og_locale":"pt_BR","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\/pt\/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":"pt-BR","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":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/create-continuous-deployment-pipeline-golang-jenkins\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@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":"Blog do Couchbase","description":"Couchbase, o banco de dados 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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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 dos desenvolvedores, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@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 \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/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 \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4616","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=4616"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4616\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=4616"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=4616"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=4616"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=4616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}