Unable to build a docker image in a Bitbucket pipeline - docker

When I try to build an image for my application, an image that relies upon buildkit, I receive an error: failed to dial gRPC: unable to upgrade to h2c, received 403
I can build standard docker images, but if it relies on Buildkit, I get errors
Specifically, the command that fails is:
docker build --ssh default --no-cache -t worker $BITBUCKET_CLONE_DIR/worker
My bitbucket-pipelines.yml is as follows, the first two docker build commands work, and the images are generated, however the third, that relies on buildkit does not.
image: docker:stable
pipelines:
default:
- step:
name: build
size: 2x
script:
- docker build -t alpine-base $BITBUCKET_CLONE_DIR/supporting/alpine-base
- docker build -t composer-xv:latest $BITBUCKET_CLONE_DIR/supporting/composer-xv
- apk add openssh-client
- eval `ssh-agent`
- export DOCKER_BUILDKIT=1
- docker build --ssh default --no-cache -t worker $BITBUCKET_CLONE_DIR/worker
- docker images
services:
- docker
caches:
- docker
My Dockerfile is as follows:
# syntax=docker/dockerfile:1.0.0-experimental
FROM composer:1.7 as phpdep
COPY application/database/ database/
COPY application/composer.json composer.json
COPY application/composer.lock composer.lock
# Install PHP dependencies in 'vendor'
RUN --mount=type=ssh composer install \
--ignore-platform-reqs \
--no-dev \
--no-interaction \
--no-plugins \
--no-scripts \
--prefer-dist
#
# Final image build stage
#
FROM alpine-base:latest as final
ADD application /app/application
COPY --from=phpdep /app/vendor/ /app/application/vendor/
ADD entrypoint.sh /entrypoint.sh
RUN \
apk update && \
apk upgrade && \
apk add \
php7 php7-mysqli php7-mcrypt php7-gd \
php7-curl php7-xml php7-bcmath php7-mbstring \
php7-zip php7-bz2 ca-certificates php7-openssl php7-zlib \
php7-bcmath php7-dom php7-json php7-phar php7-pdo_mysql php7-ctype \
php7-session php7-fileinfo php7-xmlwriter php7-tokenizer php7-soap \
php7-simplexml && \
cd /app/application && \
cp .env.example .env && \
chown nobody:nobody /app/application/.env && \
sed -i 's/;openssl.capath=/openssl.capath=\/etc\/ssl\/certs/' /etc/php7/php.ini && \
sed -i 's/memory_limit = 128M/memory_limit = 1024M/' /etc/php7/php.ini && \
apk del --purge curl wget && \
mkdir -p /var/log/workers && \
mkdir -p /run/php && \
echo "export PS1='WORKER \h:\w\$ '" >> /etc/profile
COPY files/logrotate.d/ /etc/logrotate.d/
CMD ["/entrypoint.sh"]

Bitbucket pipelines don't support DOCKER_BUILDKIT, it seems, see: https://jira.atlassian.com/browse/BCLOUD-17590?focusedCommentId=3019597&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-3019597 . They say they are waiting for this; https://github.com/moby/buildkit/pull/2723 to be fixed...

You could try again as, since July 2022, you have:
Announcing support for Docker BuildKit in Bitbucket Pipelines
(Jayant Gawali, Atlassian Team)
We are happy to announce that one of the top voted features for Bitbucket Pipelines, Docker BuildKit is now available. You can now build Docker images with the BuildKit utility.
With BuildKit you can take advantage of the various features it provides like:
Performance: BuildKit uses parallelism and caching internally to build images faster.
Secrets: Mount secrets and build images safely.
Cache: Mount caches to save re-downloading all external dependencies every time.
SSH: Mount SSH Keys to build images.
Configuring your bitbucket-pipelines.yaml
BuildKit is now available with the Docker Daemon service.
It is not enabled by default and can be enabled by setting the environment variable DOCKER_BUILDKIT=1 in the pipelines configuration.
pipelines:
default:
- step:
script:
- export DOCKER_BUILDKIT=1
- docker build --secret id=mysecret,src=mysecret.txt .
services:
- docker
To learn more about how to set it up please refer to the support documentation and for information on Docker Buildkit, visit: Docker Docs ? Build images with BuildKit.
Please note:
Use multi-stage builds to utilise parallelism.
Caching is not shared across different builds and it’s limited to the build running on the same docker node where the build runs.
With BuildKit, secrets can be mounted securely as shown above.
For restrictions and limitations please refer to the restrictions section of our support documentation.

Related

Receiving error on building an Alpine image on my M1 Macbook

When I build my Dockerfile image on my Macbook M1, I begin to receive errors in regards to syslinux specifically, and if I were to comment this out I continue to receive errors such as this:
fetch http://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
ERROR: http://dl-cdn.alpinelinux.org/alpine/v3.13/main: UNTRUSTED signature
WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.13/main: No such file or directory
fetch http://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
ERROR: http://dl-cdn.alpinelinux.org/alpine/v3.13/community: UNTRUSTED signature
WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.13/community: No such file or directory
So I know the issue revolves around my repositories that I use so this is where I have the ENTRYPOINT say this in my Dockerfile:
ENTRYPOINT /src/aports/scripts/mkimage.sh \
--tag v3.13 \
--outdir /build \
--arch x86_64 \
--repository http://dl-cdn.alpinelinux.org/alpine/v3.13/main \
--extra-repository http://dl-cdn.alpinelinux.org/alpine/v3.13/community \
--profile iot
I would believe this would work on my M1 but it doesn't! I used other another Macbook and that builds it but why not the M1? I would greatly appreciate any help in this.
EDIT 2: Adding full Dockerfile:
# This image contains the build environment for edge appliance install ISOs
FROM alpine:3.13
# Define metadata
LABEL maintainer="this_dude#dude.net"
# Configure user
RUN addgroup root this_build
# Initialize update and upgrade on Alpine AMI
RUN apk -U upgrade
# Install dependencies
RUN apk add --no-cache \
alpine-conf \
alpine-sdk \
apk-tools \
dosfstools \
grub-efi \
mtools \
squashfs-tools \
syslinux \
xorriso
WORKDIR /src
# Clone alpine ports repository containing the iso builder
RUN git clone --depth=1 --branch v3.13.2 git://git.alpinelinux.org/aports
RUN chmod +x aports/scripts/mkimage.sh
# Include edge appliance image profile
RUN ln -sf /build/mkimg.run.sh /src/aports/scripts/mkimg.run.sh
WORKDIR /build
# Run ISO build
ENTRYPOINT /src/aports/scripts/mkimage.sh \
--tag v3.13 \
--outdir /build \
--arch x86_64 \
--repository http://dl-cdn.alpinelinux.org/alpine/v3.13/main \
--extra-repository http://dl-cdn.alpinelinux.org/alpine/v3.13/community \
--profile iot
As you can see here https://pkgs.alpinelinux.org/packages?name=syslinux the syslinux bootloader package has not support for aarch64 (M1 processors). I would suggest to use another bootloader with AMD and ARM support - for example https://pkgs.alpinelinux.org/packages?name=u-boot&branch=edge.
And don't forget to change that --arch x86_64 argument in your entrypoint to --arch aarch64 if you want to run it without errors on your M1 processor. Or just remove it to use default_arch from the sh script.

Building of a Docker image with Qt5 compiled with MinGW works in a container run from "docker:latest" image, but fails in GitLab CI

I want to prepare a docker image with Qt5 with MinGW. Part of the process is building Qt 5.14.0 with MinGW and that is the part where it fails.
Building on my machine.
There weren't any problems when I pulled the docker:latest image on my PC, ran container from it and built my image in this container. It worked fine.
Building in GitLab CI pipeline.
When I pushed the Dockerfile in Gitlab, where it is built in container from the same docker:latest image, it fails to build Qt with the following error message:
Could not find qmake spec ''.
Error processing project file: /root/src/qt-everywhere-src-5.14.0
Screenshot of the failure
CI script:
stages:
- deploy
variables:
CONTAINER_NAME: "qt5-mingw"
PORT: "5000"
image: docker:latest
build-snapshot:
stage: deploy
tags:
- docker
- colo
environment:
name: snapshot
url: https://somedomain.com/artifactory/#/artifacts/qt5-mingw
before_script:
- docker login -u ${ARTIFACT_USER} -p ${ARTIFACT_PASS} somedomain.com:${PORT}
script:
- docker build -f Dockerfile -t ${CONTAINER_NAME} .
- export target_version=$(docker inspect --format='{{index .Config.Labels "com.domain.version" }}' ${CONTAINER_NAME})
- docker tag ${CONTAINER_NAME} dsl.domain.com:${PORT}/${CONTAINER_NAME}:${target_version}
- docker tag dsl.domain.com:${PORT}/${CONTAINER_NAME}:${target_version} dsl.domain.com:${PORT}/${CONTAINER_NAME}:latest
- docker push dsl.domain.com:${PORT}/${CONTAINER_NAME}:${target_version}
- docker push dsl.domain.com:${PORT}/${CONTAINER_NAME}:latest
after_script:
- docker logout dsl.domain.com:${PORT}
- docker rmi ${CONTAINER_NAME}
except:
- master
- tags
The Dockerfile:
FROM debian:buster-slim
########################
# Install what we need
########################
# Custom Directory
ENV CUSTOM_DIRECTORY YES
ENV WDEVBUILD /temp/build
ENV WDEVSOURCE /temp/src
ENV WDEVPREFIX /opt/windev
# Custom Version
ENV CUSTOM_VERSION NO
ENV QT_SERIES 5.14
ENV QT_BUILD 0
ENV LIBJPEGTURBO_VERSION 2.0.3
ENV LIBRESSL_VERSION 3.0.2
ENV OPENSSL_VERSION 1.1.1c
ENV UPX_VERSION 3.95
# SSL Choice
ENV USE_OPENSSL YES
# Exclude Static Qt
ENV BUILD_QT32_STATIC NO
ENV BUILD_QT64_STATIC NO
# Copy directory with qt_build script
COPY rootfs /
# install tools
RUN apt-get update \
&& apt-get install -y bash \
cmake \
coreutils \
g++ \
git \
gzip \
libucl1 \
libucl-dev \
make \
nasm \
ninja-build \
perl \
python \
qtchooser \
tar \
wget \
xz-utils \
zlib1g \
zlib1g-dev \
&& apt-get install -y binutils-mingw-w64-x86-64 \
mingw-w64-x86-64-dev \
g++-mingw-w64-x86-64 \
gcc-mingw-w64-x86-64 \
binutils-mingw-w64-i686 \
mingw-w64-i686-dev \
g++-mingw-w64-i686 \
gcc-mingw-w64-i686 \
&& rm -rf /temp \
&& rm -rf /var/lib/apt/lists/*
# Build Qt with mingw and the step where it fails.
RUN /opt/windev/bin/qt_build \
LABEL com.domain.version="1.0.0"
LABEL vendor="Someone"
LABEL com.domain.release-date="2020-01-21"
Debugging process so far:
The version of the docker:latest is the same in both cases.
The version of MinGW is the same in both cases.
I tried also with Qt 5.12.6 and the result is the same.
I have found it. I think the answer is here.
The package libseccomp2 is 2.3.1 on the CI Runner machine and 2.4.1 on my PC. But Qt versions after 5.10 are using system call that has been added in 2.3.3, so that's why it can be build on my PC and can't be built on the runner.
Reamrak: It doesn't matter that it is build in container run from docker:latest image, because the Docker Daemon is mounted when the container is started, so apparently it continue to use some features of the host and the docker work is not completely containerized.

Edit / hide Nginx Server header under Alpine Linux

When I use curl --head to test my website, it returns the server information.
I followed this tutorial to hide the nginx server header.
But when I run the command yum install nginx-module-security-headers
, it returns yum: not found.
I also tried apk add nginx-module-security-headers, and it shows that the package is missing.
I have used nginx:1.17.6-alpine as my base docker image. Does anyone know how to hide the server from header under this Alpine?
I think I have an easier solution here: https://gist.github.com/hermanbanken/96f0ff298c162a522ddbba44cad31081. Big thanks to hermanbanken on Github for sharing this gist.
The idea is to create a multi stage build with the nginx alpine image to be a base for compiling the module. This turns into the following Dockerfile:
ARG VERSION=alpine
FROM nginx:${VERSION} as builder
ENV MORE_HEADERS_VERSION=0.33
ENV MORE_HEADERS_GITREPO=openresty/headers-more-nginx-module
# Download sources
RUN wget "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" -O nginx.tar.gz && \
wget "https://github.com/${MORE_HEADERS_GITREPO}/archive/v${MORE_HEADERS_VERSION}.tar.gz" -O extra_module.tar.gz
# For latest build deps, see https://github.com/nginxinc/docker-nginx/blob/master/mainline/alpine/Dockerfile
RUN apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
make \
openssl-dev \
pcre-dev \
zlib-dev \
linux-headers \
libxslt-dev \
gd-dev \
geoip-dev \
perl-dev \
libedit-dev \
mercurial \
bash \
alpine-sdk \
findutils
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
RUN rm -rf /usr/src/nginx /usr/src/extra_module && mkdir -p /usr/src/nginx /usr/src/extra_module && \
tar -zxC /usr/src/nginx -f nginx.tar.gz && \
tar -xzC /usr/src/extra_module -f extra_module.tar.gz
WORKDIR /usr/src/nginx/nginx-${NGINX_VERSION}
# Reuse same cli arguments as the nginx:alpine image used to build
RUN CONFARGS=$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p') && \
sh -c "./configure --with-compat $CONFARGS --add-dynamic-module=/usr/src/extra_module/*" && make modules
# Production container starts here
FROM nginx:${VERSION}
COPY --from=builder /usr/src/nginx/nginx-${NGINX_VERSION}/objs/*_module.so /etc/nginx/modules/
.... skipped inserting config files and stuff ...
# Validate the config
RUN nginx -t
Alpine repo probably doesn't have the ngx_security_headers module but, the mentioned tutorial also provides an option of using Headers More module. You should be able to install this module in your alpine distro using the command:
apk add nginx-mod-http-headers-more
Hope it helps.
Source
I found the alternate solution. The reason that it shows binary not compatible is because I have one nginx pre-installed under the target route, and it is not compatible with the header-more module I am using. That means I cannot simply install the third party library from Alpine package.
So I prepare a clean Alpine OS, and follow the GitHub repository to build Nginx from the source with additional feature. The path of build result is the prefix path you specified.

How to combine Dockerfiles in gitlab ci?

I have this gitlab-ci.yml to build my SpringBoot app:
image: maven:latest
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
- target/
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS clean compile
only:
- /^release.*/
test:
stage: test
script:
- mvn $MAVEN_CLI_OPTS test
- "cat target/site/coverage/jacoco-ut/index.html"
only:
- /^release.*/
Now, i need to run another JOB on the Test Stage: Integration Tests. My app runs the integration tests on Headless Chrome with an in memory database, all i need to do on windows is: mvn integration-test
I've found a Dockerfile that has the Headless Chrome ready, so i need to combine the maven:latest image with this new image https://hub.docker.com/r/justinribeiro/chrome-headless/
How can i do that?
You can write a new docker file by choosing maven:latest as the base image. (That means all the maven latest image dependencies are there). You can refer this link to how to write a docker file.
Since the base image of the maven:latest is a debian image and docker file that contains Dockerfile that has the Headless Chrome is also a debian image so all the OS commands are same. So you can write a docker file like following where the base image is maven:latest and rest is same as here.
FROM maven:latest
LABEL name="chrome-headless" \
maintainer="Justin Ribeiro <justin#justinribeiro.com>" \
version="2.0" \
description="Google Chrome Headless in a container"
# Install deps + add Chrome Stable + purge all the things
RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
--no-install-recommends \
&& curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
&& apt-get update && apt-get install -y \
google-chrome-beta \
fontconfig \
fonts-ipafont-gothic \
fonts-wqy-zenhei \
fonts-thai-tlwg \
fonts-kacst \
fonts-symbola \
fonts-noto \
ttf-freefont \
--no-install-recommends \
&& apt-get purge --auto-remove -y curl gnupg \
&& rm -rf /var/lib/apt/lists/*
# Add Chrome as a user
RUN groupadd -r chrome && useradd -r -g chrome -G audio,video chrome \
&& mkdir -p /home/chrome && chown -R chrome:chrome /home/chrome \
&& mkdir -p /opt/google/chrome-beta && chown -R chrome:chrome /opt/google/chrome-beta
# Run Chrome non-privileged
USER chrome
# Expose port 9222
EXPOSE 9222
# Autorun chrome headless with no GPU
ENTRYPOINT [ "google-chrome" ]
CMD [ "--headless", "--disable-gpu", "--remote-debugging-address=0.0.0.0", "--remote-debugging-port=9222" ]
I have checked this and it's working fine. Once you have write the Dockerfile you can build it using dokcer build . from the same repository as Dockerfile. Then you can either push this to docker hub or your own registry where your gitlab runner can access the docker image. Make sure you tag the docker image of your preference as example let's think the tag is and you are pushing to your local repository {your-docker-repo}/maven-with-chrome-headless:1.0.0
Then use that previous tag in your gitlab-ci.yml file as image: {your-docker-repo}/maven-with-chrome-headless:1.0.0
You do not "combine" docker containers. You put different services into different containers and run them all together. Look at kubernetes (it has now generic support in gitlab) or choose simpler solution like docker-compose or docker-swarm.
For integration tests we use docker-compose.
Anyway, if using docker-compose, you will probably fall into the situation that you need so-called docker-in-docker. It depends on the type of worker, you use to run your gitlab jobs. If you use shell executor, everything will be fine. If you are using docker executor, you will have to setup it properly, because you cant call docker from docker without additional manual setup.
If using several containers is not your choice and you definitely want to put all in one container, the recommended way is to use supervisor to launch processes inside container. One of the options is supervisord: http://supervisord.org/

Unable to download docker golang image: No command specified

Newbie in docker here.
I want to build a project using go language and my docker-compose.yml file has the following:
go:
image: golang:1.7-alpine
volumes:
- ./:/server/http
ports:
- "80:8080"
links:
- postgres
- mongodb
- redis
environment:
DEBUG: 'true'
PORT: '8080'
When I run docker-compose up -d in terminal, it returns the following error:
`ERROR: for go Cannot create container for service go: No command specified`
How should I fix it?
Golang:1.7-alpine is just a basis for building a Go container, and does not have a CMD or an ENTRYPOINT, so ends immediately.
Use an image doing really something, like printing hello world every 45 seconds
I solved it by using golang:1.7 instead of golang:1.7-alpine.
You should run your container with an argument which will be passed to the default ENTRYPOINT, to be executed as a command
But the best practice these days is to use multistage, in order to generate a smaller image with just your application.
Or you can define your ENTRYPOINT being your build Go application.
See 'Using Docker Multi-Stage Builds with Go ', using the new AS build-stage keyword.
Your Dockerfile would be:
# build stage
ARG GO_VERSION=1.8.1
FROM golang:${GO_VERSION}-alpine AS build-stage
MAINTAINER fbgrecojr#me.com
WORKDIR /go/src/github.com/frankgreco/gobuild/
COPY ./ /go/src/github.com/frankgreco/gobuild/
RUN apk add --update --no-cache \
wget \
curl \
git \
&& wget "https://github.com/Masterminds/glide/releases/download/v0.12.3/glide-v0.12.3-`go env GOHOSTOS`-`go env GOHOSTARCH`.tar.gz" -O /tmp/glide.tar.gz \
&& mkdir /tmp/glide \
&& tar --directory=/tmp/glide -xvf /tmp/glide.tar.gz \
&& rm -rf /tmp/glide.tar.gz \
&& export PATH=$PATH:/tmp/glide/`go env GOHOSTOS`-`go env GOHOSTARCH` \
&& glide update -v \
&& glide install \
&& CGO_ENABLED=0 GOOS=`go env GOHOSTOS` GOARCH=`go env GOHOSTARCH` go build -o foo \
&& go test $(go list ./... | grep -v /vendor/) \
&& apk del wget curl git
# production stage
FROM alpine:3.5
MAINTAINER fbgrecojr#me.com
COPY --from=build-stage /go/src/github.com/frankgreco/go-docker-build/foo .
ENTRYPOINT ["/foo"]

Resources