Trying to build a Spring Boot 3.1.5 container image using mvn spring-boot:build-image
within a BitBucket pipeline. It fails with the error:
authorization denied by plugin pipelines: -v only supports $BITBUCKET_CLONE_DIR and its subdirectories
Seems to be related to this old issue.
Is there a way to control the folders used by the buildpack during the build? I'd like to configure it to store everything under workspace
only.
Here's the docker logs:
time="2023-11-03T19:12:56.885434830Z" level=warning msg="could not change group /var/run/docker.sock to docker: group docker not found"
time="2023-11-03T19:12:56.885648523Z" level=warning msg="Binding to IP address without --tlsverify is insecure and gives root access on this machine to everyone who has access to your network." host="tcp://0.0.0.0:2375"
time="2023-11-03T19:12:56.885666219Z" level=warning msg="Binding to an IP address, even on localhost, can also give access to scripts run in a browser. Be safe out there!" host="tcp://0.0.0.0:2375"
time="2023-11-03T19:12:57.885961215Z" level=warning msg="Binding to an IP address without --tlsverify is deprecated. Startup is intentionally being slowed down to show this message" host="tcp://0.0.0.0:2375"
time="2023-11-03T19:12:57.885989373Z" level=warning msg="Please consider generating tls certificates with client validation to prevent exposing unauthenticated root access to your network" host="tcp://0.0.0.0:2375"
time="2023-11-03T19:12:57.886017149Z" level=warning msg="You can override this by explicitly specifying '--tls=false' or '--tlsverify=false'" host="tcp://0.0.0.0:2375"
time="2023-11-03T19:12:57.886028707Z" level=warning msg="Support for listening on TCP without authentication or explicit intent to run without authentication will be removed in the next release" host="tcp://0.0.0.0:2375"
time="2023-11-03T19:13:12Z" level=warning msg="containerd config version `1` has been deprecated and will be removed in containerd v2.0, please switch to version `2`, see https://github.com/containerd/containerd/blob/main/docs/PLUGINS.md#version-header"
time="2023-11-03T19:13:12.926730931Z" level=warning msg="failed to load plugin io.containerd.snapshotter.v1.devmapper" error="devmapper not configured"
time="2023-11-03T19:13:12.927374579Z" level=warning msg="could not use snapshotter devmapper in metadata plugin" error="devmapper not configured"
time="2023-11-03T19:13:12.929579015Z" level=warning msg="failed to load plugin io.containerd.internal.v1.opt" error="mkdir /opt/containerd: read-only file system"
time="2023-11-03T19:13:12.929903334Z" level=error msg="failed to initialize a tracing processor \"otlp\"" error="no OpenTelemetry endpoint: skip plugin"
time="2023-11-03T19:13:12.997037717Z" level=warning msg="Your kernel does not support CPU realtime scheduler"
time="2023-11-03T19:13:12.997063850Z" level=warning msg="Your kernel does not support cgroup blkio weight"
time="2023-11-03T19:13:12.997071625Z" level=warning msg="Your kernel does not support cgroup blkio weight_device"
time="2023-11-03T19:13:48Z" level=info msg="Pipelines plugin request authorization." allowed=true method=POST plugin=pipelines uri="/v1.24/images/create?fromImage=docker.io%2Fpaketobuildpacks%2Fbuilder-jammy-base%3Alatest"
time="2023-11-03T19:14:15Z" level=info msg="Pipelines plugin request authorization." allowed=true method=GET plugin=pipelines uri="/v1.24/images/docker.io/paketobuildpacks/builder-jammy-base:latest/json"
time="2023-11-03T19:14:15Z" level=info msg="Pipelines plugin request authorization." allowed=true method=POST plugin=pipelines uri="/v1.24/images/create?fromImage=docker.io%2Fpaketobuildpacks%2Frun-jammy-base%3Alatest"
time="2023-11-03T19:14:17Z" level=info msg="Pipelines plugin request authorization." allowed=true method=GET plugin=pipelines uri="/v1.24/images/docker.io/paketobuildpacks/run-jammy-base:latest/json"
time="2023-11-03T19:14:17Z" level=info msg="Pipelines plugin request authorization." allowed=true method=POST plugin=pipelines uri=/v1.24/images/load
time="2023-11-03T19:14:17Z" level=info msg="Container create request." ArgsEscaped=false AttachStderr=false AttachStdin=false AttachStdout=false ExposedPorts="map[]" Healthcheck="<nil>" Labels="map[author:spring-boot]" MacAddress= NetworkDisabled=false OnBuild="[]" OpenStdin=false StdinOnce=false StopSignal= StopTimeout="<nil>" Tty=false plugin=pipelines
time="2023-11-03T19:14:17Z" level=info msg="Container create request." AutoRemove=false BlkioDeviceReadBps="[]" BlkioDeviceReadIOps="[]" BlkioDeviceWriteBps="[]" BlkioDeviceWriteIOps="[]" BlkioWeight=0 BlkioWeightDevice="[]" CPUCount=0 CPUPercent=0 CPUPeriod=0 CPUQuota=0 CPURealtimePeriod=0 CPURealtimeRuntime=0 CPUShares=0 CapAdd="[]" CapDrop="[]" Cgroup= CgroupParent= ConsoleSize="[0 0]" ContainerIDFile= CpusetCpus= CpusetMems= DNS="[]" DNSOptions="[]" DNSSearch="[]" DeviceCgroupRules="[]" Devices="[]" ExtraHosts="[]" GroupAdd="[]" IOMaximumBandwidth=0 IOMaximumIOps=0 Init="<nil>" IpcMode= Isolations= KernelMemory=0 Links="[]" LogConfig="{ map[]}" MaskedPaths="[]" Memory=0 MemoryReservation=0 MemorySwap=0 MemorySwappiness="<nil>" Mounts="[]" NanoCPUs=0 NetworkMode=default OomKillDisable="<nil>" OomScoreAdj=0 PidMode= PidsLimit="<nil>" PortBindings="map[]" Privileged=false PublishAllPorts=false ReadOnlyPaths="[]" RestartPolicy="{ 0}" Runtime= SecurityOpt="[label=disable]" ShmSize=0 StorageOpt="map[]" Sysctls="map[]" Ulimits="[]" UsernsMode= VolumeDriver= VolumesFrom="[]" plugin=pipelines
time="2023-11-03T19:14:17Z" level=info msg="Pipelines plugin request authorization." allowed=false method=POST plugin=pipelines uri=/v1.24/containers/create
time="2023-11-03T19:14:17.669873437Z" level=error msg="AuthZRequest for POST /v1.24/containers/create returned error: authorization denied by plugin pipelines: -v only supports $BITBUCKET_CLONE_DIR and its subdirectories"
time="2023-11-03T19:14:17Z" level=info msg="Pipelines plugin request authorization." allowed=true method=DELETE plugin=pipelines uri="/v1.24/volumes/pack-layers-cnovyjjtrm?force=1"
time="2023-11-03T19:14:17Z" level=info msg="Pipelines plugin request authorization." allowed=true method=DELETE plugin=pipelines uri="/v1.24/volumes/pack-app-bedsbabobb?force=1"
time="2023-11-03T19:14:17Z" level=info msg="Pipelines plugin request authorization." allowed=true method=DELETE plugin=pipelines uri="/v1.24/images/pack.local/builder/tfgunegkrx:latest?force=1"
@Scott's answer works, but I've decided to share here my own answer where I removed one line from the plugin configuration as I found it's not required. I also added a bit of more colours to help others to understand what's going on here.
You need to use Spring Boot 3.2+ in order for this to work. Here is the Maven plugin configuration to use as of writing. The same configuration is available in Gradle as well.
Buildpack's builders need a location to store temporary files during image building. By default buildpacks use Docker volumes but this is only allowed by Bitbucket under either /opt/atlassian/bitbucketci/agent/build/
or /opt/atlassian/pipelines/agent/build/.*
as specified here. Therefore we need to configure the plugin to store everything under one of these folders through the new config options described here.
We also need to :
<securityOptions></securityOptions>
config empty (see here)DOCKER_HOST
environment variable in the pipeline step rather than in the plugin configuration (I tried both options)docker.bindHostToBuilder
option to true in order to instruct the builder container to use the docker configuration from the host (see here)Here's my whole plugin configuration:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
<docker>
<bindHostToBuilder>true</bindHostToBuilder>
</docker>
<image>
<env>
<BP_JVM_VERSION>${java.version}</BP_JVM_VERSION>
</env>
<securityOptions></securityOptions>
<buildWorkspace>
<bind>
<source>/opt/atlassian/bitbucketci/agent/build/cache-${project.artifactId}.work</source>
</bind>
</buildWorkspace>
<buildCache>
<bind>
<source>/opt/atlassian/bitbucketci/agent/build/cache-${project.artifactId}.build</source>
</bind>
</buildCache>
<launchCache>
<bind>
<source>/opt/atlassian/bitbucketci/agent/build/cache-${project.artifactId}.launch</source>
</bind>
</launchCache>
</image>
</configuration>
</plugin>
And here's my BitBucket step configuration:
- step: build-container-image
name: Build container image
caches:
- maven
- docker
script:
- export DOCKER_HOST=tcp://172.17.0.1:2375
- mvn spring-boot:build-image
services:
- docker
N.B. This solution has been built by the hard work of @Scott Frederick (from the Spring team) and the insights from @Andrej Urvantsev (see here).