feat: switch image builds to buildx
This commit is contained in:
parent
99538a3343
commit
32e17253e5
|
|
@ -4,16 +4,74 @@ stages:
|
|||
- deploy
|
||||
|
||||
variables:
|
||||
DOCKER_IMAGE_ENVS: "production test"
|
||||
# Disable the shared image build jobs from turniere-infra; this repo owns buildx builds below.
|
||||
DOCKER_IMAGE_ENVS: ""
|
||||
DOCKER_BUILDKIT: "1"
|
||||
BUILDX_PLATFORMS: "linux/amd64,linux/arm64"
|
||||
|
||||
include:
|
||||
- project: 'turniere/turniere-infra'
|
||||
file: '/ci/pipeline.yaml'
|
||||
|
||||
.buildx-image:
|
||||
stage: build
|
||||
tags:
|
||||
- shell
|
||||
before_script:
|
||||
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
|
||||
- export BUILDX_BUILDER_NAME="turniere-buildx-$CI_PIPELINE_ID-$CI_JOB_ID"
|
||||
- docker buildx create --name "$BUILDX_BUILDER_NAME" --driver docker-container --use
|
||||
- docker buildx inspect --builder "$BUILDX_BUILDER_NAME" --bootstrap
|
||||
after_script:
|
||||
- export BUILDX_BUILDER_NAME="turniere-buildx-$CI_PIPELINE_ID-$CI_JOB_ID"
|
||||
- docker buildx rm "$BUILDX_BUILDER_NAME" || true
|
||||
- docker logout "$CI_REGISTRY" || true
|
||||
|
||||
build production image:
|
||||
extends: .buildx-image
|
||||
script:
|
||||
- >-
|
||||
docker buildx build
|
||||
--builder "$BUILDX_BUILDER_NAME"
|
||||
--file Dockerfile
|
||||
--target production
|
||||
--platform "$BUILDX_PLATFORMS"
|
||||
--cache-from "type=registry,ref=$CI_REGISTRY_IMAGE/buildcache:production"
|
||||
--cache-to "type=registry,ref=$CI_REGISTRY_IMAGE/buildcache:production,mode=max"
|
||||
--tag "$CI_REGISTRY_IMAGE/production/commits:$CI_COMMIT_SHA"
|
||||
--push
|
||||
.
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE != "push"
|
||||
when: never
|
||||
- when: always
|
||||
|
||||
build test image:
|
||||
extends: .buildx-image
|
||||
script:
|
||||
- >-
|
||||
docker buildx build
|
||||
--builder "$BUILDX_BUILDER_NAME"
|
||||
--file Dockerfile
|
||||
--target test
|
||||
--platform "$BUILDX_PLATFORMS"
|
||||
--cache-from "type=registry,ref=$CI_REGISTRY_IMAGE/buildcache:production"
|
||||
--cache-from "type=registry,ref=$CI_REGISTRY_IMAGE/buildcache:test"
|
||||
--cache-to "type=registry,ref=$CI_REGISTRY_IMAGE/buildcache:test,mode=max"
|
||||
--tag "$CI_REGISTRY_IMAGE/test/commits:$CI_COMMIT_SHA"
|
||||
--push
|
||||
.
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE != "push"
|
||||
when: never
|
||||
- when: always
|
||||
|
||||
rails spec:
|
||||
stage: test
|
||||
tags:
|
||||
- docker
|
||||
needs:
|
||||
- build test image
|
||||
image: $CI_REGISTRY_IMAGE/test/commits:$CI_COMMIT_SHA
|
||||
parallel:
|
||||
matrix:
|
||||
|
|
@ -42,6 +100,9 @@ rails e2e spec:
|
|||
stage: test
|
||||
tags:
|
||||
- docker
|
||||
needs:
|
||||
- build production image
|
||||
- build test image
|
||||
image: $CI_REGISTRY_IMAGE/test/commits:$CI_COMMIT_SHA
|
||||
services:
|
||||
- name: postgres:16
|
||||
|
|
@ -93,6 +154,9 @@ rails follow sync e2e spec:
|
|||
stage: test
|
||||
tags:
|
||||
- docker
|
||||
needs:
|
||||
- build production image
|
||||
- build test image
|
||||
image: $CI_REGISTRY_IMAGE/test/commits:$CI_COMMIT_SHA
|
||||
services:
|
||||
- name: postgres:16
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
ARG RUBY_VERSION=3.1.2
|
||||
ARG BUNDLER_VERSION=2.3.13
|
||||
|
||||
FROM ruby:${RUBY_VERSION}-slim AS runtime-base
|
||||
|
||||
ARG BUNDLER_VERSION
|
||||
|
||||
ENV LANG=C.UTF-8 \
|
||||
BUNDLE_JOBS=4 \
|
||||
BUNDLE_RETRY=3 \
|
||||
BUNDLE_PATH=/usr/local/bundle
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libpq5 \
|
||||
nodejs \
|
||||
openssl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& gem install bundler -v ${BUNDLER_VERSION} \
|
||||
&& gem install tzinfo-data
|
||||
|
||||
FROM runtime-base AS build-base
|
||||
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
git \
|
||||
libpq-dev \
|
||||
libsqlite3-dev \
|
||||
pkg-config \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY Gemfile Gemfile.lock ./
|
||||
|
||||
FROM build-base AS bundle-production
|
||||
|
||||
RUN bundle config set deployment 'true' \
|
||||
&& bundle config set without 'development test' \
|
||||
&& bundle install \
|
||||
&& rm -rf /usr/local/bundle/cache/*.gem
|
||||
|
||||
FROM build-base AS bundle-test
|
||||
|
||||
RUN bundle config set with 'development test' \
|
||||
&& bundle install \
|
||||
&& rm -rf /usr/local/bundle/cache/*.gem
|
||||
|
||||
FROM runtime-base AS production
|
||||
|
||||
ENV RAILS_ENV=production
|
||||
|
||||
COPY --from=bundle-production /usr/local/bundle /usr/local/bundle
|
||||
COPY app /app/app
|
||||
COPY bin /app/bin
|
||||
COPY config /app/config
|
||||
COPY db /app/db
|
||||
COPY public /app/public
|
||||
COPY script /app/script
|
||||
COPY config.ru Rakefile /app/
|
||||
# Duplicate production environment to beta environment
|
||||
COPY config/environments/production.rb /app/config/environments/beta.rb
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["sh", "-lc", "bundle exec rails db:migrate && bundle exec rails s -p 3000 -b 0.0.0.0"]
|
||||
|
||||
FROM runtime-base AS test
|
||||
|
||||
ENV RAILS_ENV=test
|
||||
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libsqlite3-0 \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& python3 -m pip install --no-cache-dir invoke
|
||||
|
||||
COPY --from=bundle-test /usr/local/bundle /usr/local/bundle
|
||||
COPY app /app/app
|
||||
COPY bin /app/bin
|
||||
COPY config /app/config
|
||||
COPY db /app/db
|
||||
COPY public /app/public
|
||||
COPY script /app/script
|
||||
COPY config.ru Rakefile /app/
|
||||
COPY config/environments/production.rb /app/config/environments/beta.rb
|
||||
COPY tasks.py /app/tasks.py
|
||||
COPY e2e /app/e2e
|
||||
COPY lib /app/lib
|
||||
COPY spec /app/spec
|
||||
COPY .rspec /app/.rspec
|
||||
|
||||
CMD ["sh", "-lc", "bundle exec rails db:migrate && bundle exec rails spec"]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
ARG base_commit
|
||||
FROM ruby:3.1.2-slim
|
||||
ENV RAILS_ENV production
|
||||
# RUN apk add --no-cache build-base tzdata sqlite sqlite-dev postgresql-dev git && gem install tzinfo-data
|
||||
RUN apt-get update -qq && apt-get install -y openssl git build-essential libpq-dev nodejs && apt-get clean && gem install tzinfo-data
|
||||
WORKDIR /app
|
||||
COPY Gemfile* /app/
|
||||
RUN gem install bundler:2.3.13 && bundle config set deployment 'true' && bundle install
|
||||
COPY app /app/app
|
||||
COPY bin /app/bin
|
||||
COPY config /app/config
|
||||
COPY db /app/db
|
||||
COPY public /app/public
|
||||
COPY script /app/script
|
||||
COPY config.ru Rakefile /app/
|
||||
# Duplicate production environment to beta environment
|
||||
COPY config/environments/production.rb config/environments/beta.rb
|
||||
EXPOSE 3000
|
||||
CMD bundle exec rails db:migrate && bundle exec rails s -p 3000 -b 0.0.0.0
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
# Build production container locally first with following tag
|
||||
ARG base_commit
|
||||
FROM registry.gitlab.com/turniere/turniere-backend/production/commits:$base_commit
|
||||
WORKDIR /app
|
||||
RUN apt-get update -qq && apt-get install -y python3 python3-pip && apt-get clean && python3 -m pip install --no-cache-dir invoke
|
||||
RUN bundle config set with 'development test' && bundle install
|
||||
COPY tasks.py /app/tasks.py
|
||||
COPY e2e /app/e2e
|
||||
COPY lib /app/lib
|
||||
COPY spec /app/spec
|
||||
COPY .rspec /app/.rspec
|
||||
ENV RAILS_ENV test
|
||||
CMD bundle exec rails db:migrate && bundle exec rails spec
|
||||
36
tasks.py
36
tasks.py
|
|
@ -31,6 +31,9 @@ E2E_ALT_USERNAME = "e2e-alt-user"
|
|||
|
||||
PRODUCTION_TAG = "registry.gitlab.com/turniere/turniere-backend/production/commits:local"
|
||||
TEST_TAG = "registry.gitlab.com/turniere/turniere-backend/test/commits:local"
|
||||
DOCKERFILE_PATH = "Dockerfile"
|
||||
PRODUCTION_DOCKER_TARGET = "production"
|
||||
TEST_DOCKER_TARGET = "test"
|
||||
BLACKBOX_COMPOSE_FILE = "docker-compose.blackbox.yml"
|
||||
BLACKBOX_PROJECT = "turniere-blackbox"
|
||||
BLACKBOX_FOLLOW_COMPOSE_FILE = "docker-compose.blackbox-follow.yml"
|
||||
|
|
@ -228,6 +231,31 @@ def _format_command(command):
|
|||
return " ".join(shlex.quote(part) for part in command)
|
||||
|
||||
|
||||
def _docker_build_command(tag, target, platforms=None, push=False):
|
||||
if platforms and "," in str(platforms) and not push:
|
||||
raise ValueError("multi-platform buildx builds require push=True")
|
||||
|
||||
if platforms or push:
|
||||
command = [
|
||||
"docker",
|
||||
"buildx",
|
||||
"build",
|
||||
"--target",
|
||||
target,
|
||||
"-t",
|
||||
tag,
|
||||
"-f",
|
||||
DOCKERFILE_PATH,
|
||||
]
|
||||
if platforms:
|
||||
command.extend(["--platform", platforms])
|
||||
command.append("--push" if push else "--load")
|
||||
command.append(".")
|
||||
return _format_command(command)
|
||||
|
||||
return f"docker build --target {target} -t {tag} -f {DOCKERFILE_PATH} ."
|
||||
|
||||
|
||||
def _rspec_command(*paths):
|
||||
command = ["bundle", "exec", "rspec", *paths]
|
||||
if os.environ.get("CI"):
|
||||
|
|
@ -814,15 +842,15 @@ def scenario_render_profile(
|
|||
|
||||
|
||||
@task(name="docker-build-production")
|
||||
def docker_build_production(c, tag=PRODUCTION_TAG):
|
||||
def docker_build_production(c, tag=PRODUCTION_TAG, platforms=None, push=False):
|
||||
"""Build the production Docker image."""
|
||||
c.run(f"docker build -t {tag} -f docker/production/Dockerfile .", pty=True)
|
||||
c.run(_docker_build_command(tag, PRODUCTION_DOCKER_TARGET, platforms=platforms, push=push), pty=True)
|
||||
|
||||
|
||||
@task(name="docker-build-test")
|
||||
def docker_build_test(c, tag=TEST_TAG):
|
||||
def docker_build_test(c, tag=TEST_TAG, platforms=None, push=False):
|
||||
"""Build the test Docker image."""
|
||||
c.run(f"docker build --build-arg base_commit=local -t {tag} -f docker/test/Dockerfile .", pty=True)
|
||||
c.run(_docker_build_command(tag, TEST_DOCKER_TARGET, platforms=platforms, push=push), pty=True)
|
||||
|
||||
|
||||
@task(name="docker-build-all")
|
||||
|
|
|
|||
Loading…
Reference in New Issue