# Como criar um Self-Hosted Runner do Bitbucket

## Introdução

Em um cenário de desenvolvimento ágil e integração contínua, a flexibilidade é importante. É nesse contexto que os Self-Hosted Runners do Bitbucket emergem como uma solução poderosa, oferecendo controle total sobre seu ambiente de build e deploy.

Neste artigo, exploraremos passo a passo como criar seu próprio Bitbucket Runner Auto Hospedado. Essa abordagem não apenas amplia a capacidade de personalização do seu pipeline, mas também proporciona maior eficiência ao permitir a execução de builds em um ambiente familiar e sob seu controle direto.

---

## Tipos de Runners do Bitbucket

O Bitbucket oferece flexibilidade na execução de pipelines de CI/CD através de dois tipos de Runners:

* `Shared`
    
* `Self-Hosted`
    

### **Shared Runner:**

* **Gerenciado pela Nuvem:** Você não precisa hospedar ou gerenciar nenhum servidor. O runner compartilhado é gerenciado e hospedado pelo Bitbucket na nuvem.
    
* **Pronto para Uso:** É uma opção pronta para uso, eliminando a necessidade de configurações adicionais.
    
* **Ideal para Projetos Menores:** Adequado para projetos menores e equipes que buscam uma solução rápida e eficiente sem a necessidade de manutenção direta.
    
* **Cobrança:** Oferece um limite de minutos de execução no plano gratuito com possibilidade de realizar upgrades.
    

### **Self-Hosted Runner:**

* **Controle Total:** Você precisa hospedar ou gerenciar o servidor. O runner self-hosted oferece controle total ao permitir que você configure e mantenha seus próprios agentes de build.
    
* **Adaptabilidade ao Ambiente:** Permite a execução de builds em um ambiente que você controla, com a flexibilidade de adaptar recursos conforme necessário.
    
* **Adequado para Projetos Complexos:** Ideal para projetos maiores, equipes que requerem ambientes específicos ou aqueles que precisam integrar com recursos internos.
    
* **Cobrança:** Você tem a cobrança do seu servidor, mas seus minutos são ilimitados e você não será cobrado pelo limite e preço do Bitbucket.
    

---

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Neste artigo, nos concentraremos no Self-Hosted Runner, ainda há vários tipos de instalação como por exemplo em Windows, Linux e Docker, nos concentraremos também na instalação em Docker para proporcionar maior isolamento e portabilidade.</div>
</div>

---

### Nível do Workspace

Se você for um administrador do espaço de trabalho, poderá configurar e gerenciar vários runners para toda a sua conta para que possam ser usados ​​em pipelines em qualquer repositório no espaço de trabalho. Isso torna mais fácil e economiza tempo na criação e gerenciamento de seus runners quando você tem muitos repositórios em seu espaço de trabalho.

![](https://bitbucket.wpengine.com/wp-content/uploads/2021/08/workspace-runners-1024x244.png align="left")

---

### Nível do Repositório

Você opcionalmente pode configurar e gerenciar runners para determinados repositórios, limitando seu uso em toda a organização, porém isso pode demandar mais tempo de administração sua.

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Prefiro configurar em nível do <code>workspace</code>, isso torna o runner disponível para todos os repositórios e ajuda na administração, manutenção e gerenciamento. Para nosso tutorial prático, configuraremos um runner a nível de <code>workspace</code>.</div>
</div>

---

## Benefícios do Self-Hosted Runner

* **Configurações de build personalizadas:** os runners permitem que você configure seu hardware para diferentes tipos de build. Por exemplo, se seu build tiver que consumir muitos recursos, usar hardware com mais memória pode melhorar o tempo de execução.
    
* **Acesse aplicativos ou bancos de dados internos:** ao executar pipelines na infraestrutura do Bitbucket com shared runners, dificulta o trabalho para poder acessar sistemas internos como banco de dados por exemplo. Se você precisa executar testes de integração em seus bancos de dados ou aplicativos internos, você poderá fazer isso com runners auto hospedados na mesma rede fornecendo acesso necessário aos serviços internos.
    
* **Fluxos de trabalho híbridos**: você pode otimizar seus recursos usando runners auto hospedados com configurações personalizadas para builds que exigem isso e usar a infraestrutura do Bitbucket com shared runners para outros trabalhos.
    

---

Todo esse contexto é interessante, mas talvez seu principal motivo seja resolver esse aviso em sua conta Bitbucket:

<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Your account has run out of build minutes. View plan details.</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708101492950/b6ab7f81-1b50-4190-a824-6a5569719576.png align="center")

Se você atingir o limite mensal do plano gratuito, receberá esse aviso e ficará incapaz de continuar usando os shared runners até o próximo mês, você pode resolver isso realizando um upgrade de conta ou usando seu próprio runner, e sim, se você usar seu próprio runner você também terá os custos relacionados a isso, mas considerando que você pode cria-lo no seu mesmo ambiente e que pode obter minutos ilimitados (pois ele é seu), talvez faça sentido considerar esse custo ao invés do custo de upgrade de conta no Bitbucket, você deve colocar na balança o melhor custo-benefício e decidir pela melhor escolha no seu cenário.

---

## Tutorial Prático - Pré-Requisitos

Para a instalação de um Runner auto hospedado do Bitbucket, como o nome sugere você precisará de uma máquina, isso pode ser desde seu próprio computador até qualquer VPS de sua preferência.

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Para o tutorial deste artigo, usaremos uma instância do AWS Lightsail, pois seu pacote de instância + tráfego de rede é ofertado a um preço mais acessível. Mas novamente você pode escolher de acordo com sua preferência como <code>AWS EC2</code>, <code>Google Compute Engine</code>, <code>Digital Ocean</code>, <code>Vultr</code>, <code>Linode</code>, etc.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Se você já é mais experiente, ou se não deseja usar o Lightsail, você pode ignorar as etapas abaixo de criação de instância, criação de IP fixo e conexão SSH, não importa qual VPS você criou. Você pode pular diretamente para etapa de configuração dentro da instância e encurtar seu caminho deste artigo, mas se você é mais iniciante ou se está um pouco confuso nesse momento, recomendo seguir todos os passos.</div>
</div>

---

### Criando uma instância Lightsail

1- Acesse o console **AWS → Lightsail → Create Instance**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708102124604/20d8b633-3829-489c-bd43-3905a0c2ba6d.png align="center")

2- Escolha a **região**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Em nosso exemplo escolhi a região <code>Norte da Virgínia</code> e a <code>Zona de Disponibilidade A</code></div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708102197827/088a9e8f-9e80-4950-9189-e8e39ebf7bb9.png align="center")

3- Escolha o **sistema operacional**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Nem todos os sistemas operacionais são suportados, então escolhi a opção <code>Ubuntu 22.04</code> que é a mais recente no momento da criação deste artigo</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708102303030/f881fb52-174c-46e5-b6fe-e4614fb8fa4b.png align="center")

4- Não adicione um `script de inicialização`, não altere sua `chave key-pair` e não habilite `snapshots automáticos`, as opções padrões parecem boas aqui.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708102404328/8c155344-8870-4bf8-93cc-7d9a36ade383.png align="center")

5- Escolha `Dual Stack`, pois ainda há limitações para uso do `IPv6` e precisamos que nossa **instância tenha IPv4 também**.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708102502783/ceb3b2da-e727-43a4-9fa2-837bf2485ed7.png align="center")

6- Selecione o **tamanho da instância**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembre-se que essa decisão é muito importante, quanto menor a instância você escolher, mais lentidão e problemas seu pipeline pode ter por conta de falta de memória ou cpu. Para nosso artigo escolhi a opção <code>small de USD 10 com 2GB de memória, 2 vCPU e 3TB de transferência de dados</code>.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Em minhas experiências, as instâncias abaixo de <code>1GB de memória não chegam a funcionar corretamente</code>, e tenho usado <code>instâncias acima de 4GB de memória em ambientes de produção</code> . Mas para efeitos de tutorial essa parece ser uma escolha boa.</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708102665985/a88dfcb6-207d-4edc-a16b-69430e9cf42d.png align="center")

7- Defina um **nome**, opcionalmente você pode inserir **tags** e clique em **criar instância**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103177871/cffd6b78-0131-425c-ae25-7f2713969992.png align="center")

8- Aguarde até o status `Pending` mudar para `Running`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103348081/b8268815-50df-4147-bb5f-50170f4fb0f9.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103389628/faaac9bd-22a1-4292-82a6-ba3399e6eae0.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Pronto! Nesse momento, você já tem uma instância criada com sucesso.</div>
</div>

---

### Criando um IP Fixo

Se olharmos bem, a instância Lightsail recebeu um `IPv4` e `IPv6` público dinâmicos, isso aconteceu porque selecionamos a opção `Dual Stack` quando criamos a instância. O dinâmico significa que quando desligarmos essa instância e ligarmos novamente, esses endereços IPs irão mudar, isso pode ser um pouco chato e frustrante de se lembrar, principalmente quando você está tentando se conectar a ela.

Então vamos resolver isso criando um IP Fixo.

1- No console **AWS Lightsail → Networking**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103655669/875fda53-8cb4-4868-acce-58f3e46e2be2.png align="center")

2- Clique em **Create Static IP**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103734361/c813a5b9-1aff-4353-b094-3f51890f1b31.png align="center")

3- Mantenha a **mesma região e zona de disponibilidade da sua instância → escolha a instância recém criada**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Em nosso exemplo <code>Norte da Virgínia</code> e <code>Zona de Disponibilidade A</code></div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103847183/e0e6838e-40e0-4748-bfc4-9bb975602808.png align="center")

4- Defina um **nome → Create**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103893965/c98f0e88-1c27-4821-a847-88a382f4323b.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708103931738/0bab2997-8a2a-4104-bd28-b66d531cc42f.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Pronto! Agora já temos um IP Fixo anexado a nossa instância Lightsail</div>
</div>

---

### Conectando via SSH na instância Lightsail

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Você pode fazer isso de muitas formas, com qualquer cliente SSH de sua preferência.</div>
</div>

Se você não quiser usar um cliente SSH, pode fazer isso diretamente no console da AWS clicando nesse botão:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708104200747/efc2d456-2ec2-42b8-815f-e1e991151ab4.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">E isso irá abrir uma nova janela com seu acesso com sucesso:</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708104232283/1ba179cd-0961-4b71-91e2-c5b064bece70.png align="center")

Se você estiver usando uma distribuição `linux`, como por exemplo `ubuntu`, poderia acessar também através do seu terminal com o comando:

```bash
ssh -i <LightsailDefaultKey.pem> <user>@<public-ip>
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembre-se que <code>LightsailDefaultKey.pem</code> é sua chave de acesso baixada do console da AWS, então especifique certinho o caminho da pasta para onde você fez download em sua máquina, também lembre-se que usamos o ubuntu, então mude <code>user</code> para <code>ubuntu</code> e <code>&lt;public-ip&gt;</code> para seu ip fixo criado.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Para nosso exemplo isso seria:</div>
</div>

```bash
# Example
ssh -i LightsailDefaultKey.pem ubuntu@44.198.68.63
```

Porém como estou usando em meu computador o sistema operacional Windows, eu poderia fazer isso através do `WSL2` com `Prompt de Comando` , `Powershell` ou `Terminal do Windows`, o `Putty` e muitas outras opções de clientes SSH disponíveis.

Mas prefiro usar o cliente gratuito chamado `Termius`, você pode obtê-lo em sua página de download e talvez seja necessário criar uma conta gratuita, há planos pagos disponíveis, mas o gratuito aqui é suficiente.

<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Importante ressaltar que a escolha do seu cliente SSH é totalmente opcional.</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708104728047/fd5b37ec-1cf1-46ec-b512-b28332f4efc5.png align="center")

Também há opções disponíveis para Mac e Linux no final da página;

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708104779160/b47df59a-d66d-42cc-b834-6707bf38da4b.png align="center")

Não importa qual ferramenta SSH você usará, vimos agora que há muitas opções, tudo que você precisa ter em mente aqui é que você precisa se conectar na instância de alguma forma para seguirmos o tutorial.

---

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Como acabamos de ver, vou utilizar o cliente SSH Termius, então nossos prints irão se basear nisso, mas uma vez que você estiver conectado, os comandos serão todos iguais independente de qual ferramenta usou.</div>
</div>

1- Acesse o console **AWS Lightsail → Account → SSH Keys**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708105477034/74dae1d0-e863-4dcd-a92f-c3a60f4f800a.png align="center")

2- Procure por **Default Keys → download**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembre-se que estou usando <code>Norte da Virgínia</code>, por isso faço download da chave padrão dessa região.</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708105623262/9eaa27e5-2734-43de-8801-bba602c86908.png align="center")

3- Abra o cliente **SSH (em nosso exemplo Termius) → clique no ícone de engrenagem**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708105306882/64124329-09e1-46dd-8992-08233a36715f.png align="center")

4- Defina um **nome de sua preferência → mova o arquivo da sua chave keypair que baixou do console AWS**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708105876870/8b909b8a-cb48-44a4-b6da-955173932330.png align="center")

5- Clique em **New Host**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708106087597/2c8d677c-e421-48c5-825f-9169b0928a02.png align="center")

6- Preencha os campos com:

* `Address`: o IP da instância
    
* `Label`: nome de sua preferência
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708107910901/7ca25286-8404-4c96-b5be-bef779a9e07e.png align="center")

* `User`: ubuntu
    
* Selecione `Key`
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708108034554/720336fb-5c99-4bba-ae23-98697d426e96.png align="center")

Clique em `Connect`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708108020163/f56241d8-e94a-4fc9-b9a3-aec063003d40.png align="center")

Clique em `Continue`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708108114171/ccbca068-93ab-4664-9a92-bd641c19b652.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708108139668/990d635c-730d-4ad9-9437-8a7e39fa4b8c.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Pronto! Você está conectado.</div>
</div>

---

### Instalando o Docker e Docker Compose

Uma vez conectado na instância, você precisará instalar o `Docker` e o `Docker Compose`, por favor copie o código de instalação que criamos em outro artigo disponível aqui:

* 👉 [Como Instalar ou Atualizar o Docker e o Docker Compose](https://simplescloud.io/como-instalar-ou-atualizar-o-docker-e-o-docker-compose#heading-instalacao-ou-atualizacao)
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1720619026889/759f3b95-6dee-4437-8fb0-a3c6633afbc0.png align="center")

Cole em seu terminal e pressione `Enter`.

Aguarde a instalação e ao final você deverá ver algo parecido com:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708109718243/eb7d08a7-ce3b-4412-be9d-454a7392ee1f.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Agora feche e abra seu terminal novamente para que os comandos <code>docker</code> sejam atualizados.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text"><strong>Essa instalação é muito importante</strong>, pois precisaremos dela mais a frente para a instalação do self-hosted, além disso muito provavelmente seu runner precisará do docker para baixar e construir imagens em seu pipeline através do <code>docker in doker (dind)</code>. <strong>Então certifique-se de concluir essa instalação antes de seguir aos próximos passos.</strong></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Pronto! Você está com todos os pré-requisitos deste tutorial concluídos.</div>
</div>

---

## Adicionando um Self-Hosted Runner do Bitbucket

1- Acesse sua conta **Bitbucket → ícone de engrenagem → Workspace Settings**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembre-se que comentamos que criaremos o runner a nível do workspace para disponibilizar para todos os repositórios. Mas se você preferir criar somente para o repositório você precisa entrar nas configurações do repositório e em runner, após isso todos os passos são exatamente iguais.</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708109248634/cfc1c91e-c662-47e5-ac40-58d11f23c237.png align="center")

2- Clique em **Workspace runners → Add runner**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708109347276/4d821728-bb5c-4518-879d-94cf84256cb5.png align="center")

3- Escolha **Linux Docker (x86\_64)**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Há várias opções disponíveis, mas vamos nos concentrar em Linux Docker, isso nos dará mais liberdade e flexibilidade para executar qualquer coisa nele.</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708110027440/d0d6da67-b9ee-4af0-9d5a-f2642fda5276.png align="center")

4- Defina um **nome de sua preferência → crie um label**

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">O <code>label</code> que você criar, é o que será usado de fato no arquivo <code>bitbucket-pipelines.yml</code> . Observe que para nosso tutorial prático o <code>label</code> foi definido como <code>lightsail1</code></div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708110199143/0c538378-42d7-480e-b972-a57b5e740bc3.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Você pode definir quantos <code>labels</code> quiser de sua preferência</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708110281789/29190438-ed25-46a5-a8c6-6413ea3065b3.png align="center")

5- Clique em **Next** → e ele fornecerá uma saída de comando como a seguinte

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Algumas informações foram omitidas por questões de segurança</div>
</div>

```bash
docker container run -it \
-v /tmp:/tmp -v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/containers:/var/lib/docker/containers:ro \
-e ACCOUNT_UUID={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} \
-e REPOSITORY_UUID={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} \
-e RUNNER_UUID={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} \
-e RUNTIME_PREREQUISITES_ENABLED=true \
-e OAUTH_CLIENT_ID=xxxxxxxxxxxxxxxx \
-e OAUTH_CLIENT_SECRET=xxxxxxxxxxxxxxxxxx \
-e WORKING_DIRECTORY=/tmp --name runner-xxxxxxxxxxxxxxxxxx docker-public.packages.atlassian.com/sox/atlassian/bitbucket-pipelines-runner:1
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text"><strong>Copie o código gerado</strong></div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708110414935/8cfd338a-a3f9-4168-846f-f17c4d84cea5.png align="center")

6- Cole em seu **terminal SSH → Enter**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708110505689/c9d374f1-5bf6-4748-adc2-6fbcebfe2b9a.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Ao final você verá algo parecido com:</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708116173901/a13b5dbb-30ce-4721-b0b7-517b381ebf0a.png align="center")

7- Feche seu **terminal SSH → retorne para sua conta Bitbucket**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708110694628/2cee350c-6241-4c8f-ba9b-dcb52e6048aa.png align="center")

8- Abra novamente seu **terminal → obtenha o ID do container do seu runner** com o comando:

```bash
docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Status}}'
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708210676885/2f44480e-02c5-459d-be70-78dec0101616.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Por padrão, se desligarmos a instância por qualquer motivo, o container do runner não será iniciado automaticamente, então vamos garantir que o runner sempre esteja <code>up</code> mesmo que você reinicie sua instância.</div>
</div>

9- Digite o comando abaixo para atualizar o `restart policy` deste container:

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembre-se de alterar <code>&lt;your-container-id&gt;</code> para o ID de seu container obtido no passo acima</div>
</div>

```bash
docker update --restart always <your-container-id>
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708210973170/be282244-fe34-4302-beeb-faf00417ce20.png align="center")

10- Verifique a inspeção de container com o novo `restart policy` definido:

```bash
docker inspect -f '{{ json .HostConfig.RestartPolicy }}' <your-container-id>
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708211308788/9813c6eb-4e59-4c58-8c9c-5e7b58eaecd9.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Pronto! Seu runner auto hospedado já está online e pronto para uso.</div>
</div>

---

## Use o Self-Hosted Runner do Bitbucket

Para usar seu Self-Hosted Runner criado, você deve definir o seguinte trecho em seu arquivo `bitbucket-pipelines.yml`:

```yaml
runs-on:
  - "lightsail1"
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembrando que <code>"lightsail1"</code> foi o nosso <code>label</code> que definimos em nosso tutorial, ajuste isso para seu valor real que está usando.</div>
</div>

---

**Vamos para um exemplo:**

1- Crie um arquivo `bitbucket-pipelines.yml` na raíz do seu repositório, por exemplo:

```yaml
definitions:

  hello_my_self_hosted_runner: &hello_my_self_hosted_runner
    name: Hi
    image: atlassian/default-image:4
    services:
      - docker
    runs-on:
      - "lightsail1"
    script:
      - echo "Hello, I'm running on Bitbucket's Self-Hosted Runner"

pipelines:

  branches:

    main:
      - stage:
          name: Production
          deployment: production
          steps:
            - step: *hello_my_self_hosted_runner
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Observe o trecho <code>runs-on</code></div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708112113087/ab7fe1c5-755a-4f9b-b4a0-8812615b76b6.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">É aqui que estamos definindo para rodar somente no nosso <code>runner</code> criado com este <code>label</code>.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">E então podemos verificar sua saída com sucesso</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708112519995/28bdaa4e-0a95-439d-966c-65011eb9381b.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Pronto! Você agora tem um runner próprio executando seu pipeline.</div>
</div>

---

## Bônus - Segurança

Se você utilizar uma conexão entre Bitbucket e AWS com OpenID Connect, descrevemos o passo a passo de como fazer isso aqui:

* 👉 [Como configurar a Autenticação entre Bitbucket e AWS com OpenID Connect (OIDC)](https://simplescloud.io/como-configurar-a-autenticacao-entre-bitbucket-e-aws-com-openid-connect-oidc)
    

Você pode aumentar ainda mais a sua segurança limitando o acesso apenas a este Self-Hosted Runner com o trecho `SourceIp` da seguinte forma:

```json
{
  "Effect": "Allow",
  "Principal": {
    "Federated": "arn:aws:iam::{AWS_ACCOUNT_NUMBER}:oidc-provider/api.bitbucket.org/2.0/workspaces/{WORKSPACE}/pipelines-config/identity/oidc"
  },
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringLike": {
      "api.bitbucket.org/2.0/workspaces/{WORKSPACE}/pipelines-config/identity/oidc:sub": "{REPO_UUID}:*"
    },
    "IpAddress": {
      "aws:SourceIp": [
        "<your-runner-ip>"
      ]
    }
  }
}
```

![Highlights editing your role trust relationship to limit tokens with IP ranges sub claim ](https://images.ctfassets.net/zsv3d0ugroxu/6gHQuuBiKmK1ukfOTJB5x0/8901fef78d97a5010cd29eb2bce9dd91/edit_role_trust_relationship align="left")

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Desta forma, somente seu runner é capaz de acessar, aumentando ainda mais sua segurança.</div>
</div>

---

## Limites de Uso

O Self-Hosted Runner tem os seguintes limites de uso:

* `Máximo de memória disponível`: você pode configurar até 32 GB (8x) de memória
    
* `Número total de runners`: você pode configurar até 100 runners por workspace e 100 runners por repositório
    
* `Tempo de fila dos steps`: os steps podem ficar na fila por no máximo 2,5 horas
    

---

## Conclusão

Em resumo, a escolha entre um Shared Runner e um Self-Hosted Runner no Bitbucket Pipelines depende das necessidades específicas do seu projeto. O Shared Runner oferece praticidade para projetos menores, enquanto o Self-Hosted Runner proporciona controle total, personalização e eficiência em ambientes mais complexos.

Vimos em um tutorial prático o passo a passo de como criar um Self-Hosted Runner hospedado na AWS. Também vimos que é possível limitar a segurança para um IP específico para que você tenha certeza de estar usando somente seu runner.

Se você observar bem, todo o processo ainda é manual e você pode repeti-lo quantas vezes precisar. Você ainda pode pensar em uma solução automática para lançar seus runners e escalar eles, mas para a grande maioria esse procedimento manual será suficiente.

Ao entender os benefícios do Self-Hosted Runner, como controle total do ambiente, personalização flexível e integração com recursos internos, você pode tomar decisões mais informadas para otimizar seus processos de CI/CD. Escolha o tipo de Runner que se alinha melhor com os requisitos únicos do seu projeto, garantindo uma implementação eficaz e adaptada ao seu ambiente de desenvolvimento.

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembre-se de excluir todos os recursos ao final para não obter cobranças indesejadas e manter sua conta AWS limpa e organizada.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Espero que as informações tenham sido úteis para você!</div>
</div>
