Os builds do Bazel que têm sucesso localmente podem falhar quando executados remotamente devido a restrições e requisitos que não afetam os builds locais. As causas mais comuns dessas falhas são descritas em Como adaptar as regras do Bazel para a execução remota.
Nesta página, descrevemos como identificar e resolver os problemas mais comuns que surgem com a execução remota usando o recurso sandbox do Docker, que impõe restrições na versão igual às da execução remota. Isso permite que você solucione problemas de compilação sem a necessidade de um serviço de execução remota.
O recurso sandbox do Docker imita as restrições da execução remota da seguinte maneira:
As ações de compilação são executadas em contêineres de conjunto de ferramentas. É possível usar os mesmos contêineres de conjunto de ferramentas para executar sua versão localmente e remotamente usando um serviço compatível com a execução remota em contêiner.
Não há dados irrelevantes que ultrapassem os limites do contêiner. Somente entradas e saídas declaradas explicitamente entram e saem do contêiner, e somente após a conclusão da ação de versão associada.
Cada ação é executada em um novo contêiner. Um novo contêiner exclusivo é criado para cada ação de compilação gerada.
Para resolver esses problemas, use um dos seguintes métodos:
Solução de problemas nativa. Com esse método, o Bazel e suas ações de versão são executados nativamente em sua máquina local. O recurso de sandbox do Docker impõe restrições à versão igual às da execução remota. No entanto, esse método não detecta ferramentas, estados e vazamentos de dados locais na sua versão, o que causa problemas na execução remota.
Solução de problemas em um contêiner do Docker. Com esse método, o Bazel e suas ações de versão são executados em um contêiner do Docker, o que permite detectar ferramentas, estados e vazamentos de dados da máquina local na versão, além de impor restrições iguais às da execução remota. Esse método oferece insights sobre o build, mesmo que algumas partes dele apresentem falhas. Esse método é experimental e não é oficialmente compatível.
Pré-requisitos
Antes de começar a solução de problemas, faça o seguinte:
- Instale o Docker e configure as permissões necessárias para executá-lo.
- Instale o Bazel 0.14.1 ou posterior. As versões anteriores não oferecem suporte ao recurso sandbox do Docker.
- Adicione o repositório bazel-toolchains, fixado à versão de lançamento mais recente, ao arquivo
WORKSPACE
do build, conforme descrito aqui. - Adicione sinalizações ao arquivo
.bazelrc
para ativar o recurso. Crie o arquivo no diretório raiz do projeto do Bazel, se ele não existir. As sinalizações abaixo são um exemplo de referência. Consulte o arquivo.bazelrc
mais recente no repositório bazel-toolchains e copie os valores das sinalizações definidas para a configuraçãodocker-sandbox
.
# Docker Sandbox Mode
build:docker-sandbox --host_javabase=<...>
build:docker-sandbox --javabase=<...>
build:docker-sandbox --crosstool_top=<...>
build:docker-sandbox --experimental_docker_image=<...>
build:docker-sandbox --spawn_strategy=docker --strategy=Javac=docker --genrule_strategy=docker
build:docker-sandbox --define=EXECUTOR=remote
build:docker-sandbox --experimental_docker_verbose
build:docker-sandbox --experimental_enable_docker_sandbox
Se as regras exigirem outras ferramentas, faça o seguinte:
Crie um contêiner personalizado do Docker instalando ferramentas usando um Dockerfile e criando a imagem localmente.
Substitua o valor da sinalização
--experimental_docker_image
acima pelo nome da imagem de contêiner personalizada.
Solução de problemas nativa
Esse método executa o Bazel e todas as ações de versão dele diretamente na máquina local e é uma maneira confiável de confirmar se a versão será bem-sucedida quando executada remotamente.
No entanto, com esse método, ferramentas, binários e dados instalados localmente podem vazar para o build, especialmente se ele usar regras de trabalho do estilo de configuração. Esses vazamentos causam problemas na execução remota. Para detectá-los, solucione problemas em um contêiner do Docker, além de resolver problemas de maneira nativa.
Etapa 1: executar o build
Adicione a sinalização
--config=docker-sandbox
ao comando do Bazel que executa sua versão. Exemplo:bazel --bazelrc=.bazelrc build --config=docker-sandbox target
Execute o build e aguarde a conclusão. A versão será executada quatro vezes mais devagar do que o normal devido ao recurso sandbox do Docker.
Você pode encontrar o seguinte erro:
ERROR: 'docker' is an invalid value for docker spawn strategy.
Se você fizer isso, execute o build novamente com a sinalização --experimental_docker_verbose
.
Essa sinalização ativa mensagens de erro detalhadas. Esse erro normalmente é causado por uma
instalação incorreta do Docker ou pela falta de permissões para executá-lo na
conta de usuário atual. Consulte a documentação do Docker para mais informações. Se os problemas persistirem, avance para a seção Solução de problemas em um contêiner do Docker.
Etapa 2: resolver problemas detectados
Veja a seguir os problemas encontrados com mais frequência e as soluções alternativas.
Um arquivo, ferramenta, binário ou recurso referenciado pela árvore de arquivos de execução do Bazel está ausente.. Confirme se todas as dependências dos destinos afetados foram declaradas explicitamente. Consulte Como gerenciar dependências implícitas para mais informações.
Um arquivo, ferramenta, binário ou recurso referenciado por um caminho absoluto ou a variável
PATH
está ausente. Confirme se todas as ferramentas necessárias estão instaladas no contêiner de conjunto de ferramentas e use as regras para declarar corretamente as dependências que apontam para o recurso ausente. Consulte Como invocar ferramentas de compilação usando regras do conjunto de ferramentas para ver mais informações.Uma execução binária falha. Uma das regras de compilação está referenciando um binário incompatível com o ambiente de execução (o contêiner do Docker). Consulte Como gerenciar binários dependentes da plataforma para mais informações. Se você não conseguir resolver o problema, entre em contato com bazel-discuss@google.com para receber ajuda.
Um arquivo de
@local-jdk
está ausente ou causando erros. Os binários do Java na sua máquina local estão vazando para a versão enquanto são incompatíveis com ele. Usejava_toolchain
nas suas regras e destinos em vez de@local_jdk
. Entre em contato com bazel-discuss@google.com se precisar de mais ajuda.Outros erros. Entre em contato com bazel-discuss@google.com para receber ajuda.
Solução de problemas em um contêiner do Docker
Com esse método, o Bazel é executado dentro de um contêiner do Docker host e as ações de versão dele são executadas em contêineres de conjuntos de ferramentas individuais gerados pelo recurso sandbox do Docker. O sandbox gera um novo contêiner de conjunto de ferramentas para cada ação de versão, e apenas uma ação é executada em cada contêiner de conjunto de ferramentas.
Esse método oferece um controle mais granular das ferramentas instaladas no ambiente host. Ao separar a execução do build da execução das ações de build e manter as ferramentas instaladas mínimas, é possível verificar se o build tem dependências no ambiente de execução local.
Etapa 1: criar o contêiner
Crie um
Dockerfile
que crie o contêiner do Docker e instale o Bazel com um conjunto mínimo de ferramentas de build:FROM debian:stretch RUN apt-get update && apt-get install -y apt-transport-https curl software-properties-common git gcc gnupg2 g++ openjdk-8-jdk-headless python-dev zip wget vim RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" RUN apt-get update && apt-get install -y docker-ce RUN wget https://releases.bazel.build/<latest Bazel version>/release/bazel-<latest Bazel version>-installer-linux-x86_64.sh -O ./bazel-installer.sh && chmod 755 ./bazel-installer.sh RUN ./bazel-installer.sh
Crie o contêiner como
bazel_container
:docker build -t bazel_container - < Dockerfile
Etapa 2: iniciar o contêiner
Inicie o contêiner do Docker usando o comando mostrado abaixo. No comando, substitua o caminho para o código-fonte no host que você quer criar.
docker run -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /tmp:/tmp \
-v your source code directory:/src \
-w /src \
bazel_container \
/bin/bash
Esse comando executa o contêiner como raiz, mapeando o soquete do Docker e ativando o diretório /tmp
. Isso permite que o Bazel crie outros contêineres do Docker e use diretórios em /tmp
para compartilhar arquivos com esses contêineres. Seu código-fonte
está disponível em /src
dentro do contêiner.
O comando começa intencionalmente a partir de um contêiner de base debian:stretch
que inclui binários incompatíveis com o contêiner rbe-ubuntu16-04
usado como contêiner de conjunto de ferramentas. Se os binários do ambiente local estiverem vazando para o contêiner do conjunto de ferramentas, eles causarão erros de compilação.
Etapa 3: testar o contêiner
Execute os seguintes comandos no contêiner do Docker para testá-lo:
docker ps
bazel version
Etapa 4: executar o build
Execute o build conforme mostrado abaixo. O usuário de saída é raiz, então ele corresponde a um diretório acessível com o mesmo caminho dentro do contêiner do host em que o Bazel é executado, dos contêineres do conjunto de ferramentas gerados pelo recurso do sandbox do Docker em que as ações de versão do Bazel são executadas e da máquina local em que os contêineres do host e da ação são executados.
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
Etapa 5: resolver problemas detectados
Você pode resolver falhas de build da seguinte maneira:
Se o build falhar com um erro "fora do espaço em disco", será possível aumentar esse limite iniciando o contêiner do host com a sinalização
--memory=XX
, em queXX
é o espaço em disco alocado em gigabytes. Isso é experimental e pode resultar em um comportamento imprevisível.Se a versão falhar durante as fases de análise ou carregamento, uma ou mais das suas regras de compilação declaradas no arquivo WORKSPACE não serão compatíveis com a execução remota. Consulte Como adaptar as regras do Bazel para a execução remota para saber as possíveis causas e soluções alternativas.
Se o build falhar por qualquer outro motivo, consulte as etapas de solução de problemas na Etapa 2: resolver problemas detectados.