Merge pull request #4 from Loup-Garou911XD/docker_improvements

Docker improvements
This commit is contained in:
Loup 2024-06-13 17:53:07 +05:30 committed by GitHub
commit d2bbdcee49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 352 additions and 106 deletions

View File

@ -5,7 +5,7 @@ on:
- cron: '30 5 * * *'
jobs:
make_docker_image:
make_docker_gui_debug_image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -16,13 +16,35 @@ jobs:
- name: Setup project environment
run: make env
- name: Make the build
run: make docker-save
run: |
make docker-gui-debug
make docker-save
- name: Upload the build
uses: actions/upload-artifact@v4
with:
name: docker_server(release)
path: build/docker/bombsquad_server_docker.tar
name: docker_gui(debug)
path: build/docker/bombsquad_gui_debug_docker.tar
make_docker_server_debug_image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Setup project environment
run: make env
- name: Make the build
run: |
make docker-server-debug
make docker-save
- name: Upload the build
uses: actions/upload-artifact@v4
with:
name: docker_server(debug)
path: build/docker/bombsquad_server_debug_docker.tar
make_sphinx_docs:
runs-on: ubuntu-latest
steps:

View File

@ -208,7 +208,7 @@ jobs:
allowUpdates: true
artifacts: windows_x86_server_debug.tar
release_docker_image:
release_docker_gui_image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -219,12 +219,38 @@ jobs:
- name: Setup project environment
run: make env
- name: Make the build
run: make docker-save
run: |
make docker-gui-release
make docker-save
- name: Rename the build
run: mv build/docker/bombsquad_gui_release_docker.tar build/docker/bombsquad_docker_gui.tar
- name: Upload the build
uses: ncipollo/release-action@v1
with:
allowUpdates: true
artifacts: build/docker/bombsquad_server_docker.tar
artifacts: build/docker/bombsquad_docker_gui.tar
release_docker_server_image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Setup project environment
run: make env
- name: Make the build
run: |
make docker-server-release
make docker-save
- name: Rename the build
run: mv build/docker/bombsquad_server_release_docker.tar build/docker/bombsquad_docker_server.tar
- name: Upload the build
uses: ncipollo/release-action@v1
with:
allowUpdates: true
artifacts: build/docker/bombsquad_docker_server.tar
release_sphinx_docs:
runs-on: ubuntu-latest

View File

@ -1183,23 +1183,35 @@ clion-staging: assets-cmake resources meta
# #
################################################################################
# Build the docker image named bombsquad_server
docker-build: assets-cmake
$(PCOMMAND) build_docker
# Build the docker image
docker-gui-release: assets-cmake
$(PCOMMAND) build_docker_gui_release
# Run the bombsquad_server image
docker-run:
docker run -it bombsquad_server
# Build the docker image
docker-gui-debug: assets-cmake
$(PCOMMAND) build_docker_gui_debug
# Build the docker image
docker-server-release: assets-cmake
$(PCOMMAND) build_docker_server_release,
# Build the docker image
docker-server-debug: assets-cmake
$(PCOMMAND) build_docker_server_debug
# Build the docker image for arm64
docker-arm64-gui-release: assets-cmake
$(PCOMMAND) build_docker_arm64
# Save the bombsquad_server docker image to build/docker/bombsquad_server_docker.tar
docker-save: docker-build
docker-save:
mkdir -p build/docker/
docker save bombsquad_server -o build/docker/bombsquad_server_docker.tar
$(PCOMMAND) save_docker_images
# Cleanup docker files
docker-clean:
rm build/docker/bombsquad_server_docker.tar
docker rmi bombsquad_server --force
rm -rf build/docker/
$(PCOMMAND) remove_docker_images
docker system prune

View File

@ -1,21 +1,24 @@
# if provided it will make debug build
ARG cmake_build_type=Release
# system to start with the build with
# currently will break for non ubuntu system
ARG base_image=ubuntu:24.04
# whether to make GUI or headless build (defaults to headless)
ARG headless_build=1
# system to start with the build with
# currently will break for other images
ARG base_image=ubuntu:latest
#-------------------------------BUILDER--------------------------------
# Start with the base image
FROM ${base_image} AS builder
# Renew the arg
ARG headless_build
ARG cmake_build_type
ENV LANG en_US.utf8
ENV LANGUAGE=en_US
ENV DEBIAN_FRONTEND=noninteractive
ENV CMAKE_BUILD_TYPE=${cmake_build_type}
ENV HEADLESS_BUILD=${headless_build}
# Install build dependencies
RUN apt-get update -y && \
@ -24,25 +27,31 @@ RUN apt-get update -y && \
python3.12-venv \
python3-pip \
libsdl2-dev \
libvorbisfile3 \
freeglut3-dev \
libglut-dev \
libopenal-dev \
libvorbis-dev \
make \
curl \
rsync \
clang-format \
cmake \
libvorbis-dev
cmake
# Copy source code
COPY ./ /home/ubuntu/ballistica
COPY ./ /ballistica
WORKDIR /home/ubuntu/ballistica
WORKDIR /ballistica
# Compile the application
RUN make cmake-server-build \
&& mkdir ./../ballistica_cmake_server \
&& mv build/cmake/* ./../ballistica_cmake_server
RUN mkdir /ballistica_cmake && \
if [ "$HEADLESS_BUILD" != "0" ]; then \
make cmake-server-build && \
mv build/cmake/*/ballisticakit_headless build/cmake/*/staged/dist; \
else \
make cmake-build && \
mv build/cmake/*/ballisticakit build/cmake/*/staged/; \
fi && \
mv build/cmake/*/staged/* /ballistica_cmake
#-------------------------------RUNNER--------------------------------
# Create a new stage for the runtime environment
@ -53,33 +62,36 @@ ENV LANGUAGE=en_US
ENV DEBIAN_FRONTEND=noninteractive
# Renew the arg
ARG headless_build
ENV HEADLESS_BUILD=${headless_build}
ARG cmake_build_type
LABEL BUILD_TYPE=${cmake_build_type}
ARG bombsquad_build=N/A
LABEL BOMBSQUAD_BUILD=${bombsquad_build}
ARG bombsquad_version=N/A
LABEL BOMBSQUAD_VERSION=${bombsquad_version}
LABEL BOMBSQUAD_BUILD_TYPE=${cmake_build_type}
# Install runtime dependencies
RUN apt-get update -y && \
apt-get install -y \
python3.12-dev \
&& rm -rf /var/lib/apt/lists/* \
&& python3.12 -c "import uuid;print(uuid.uuid4())">/etc/machine-id
python3.12-dev && \
if [ "$HEADLESS_BUILD" = "0" ]; then \
apt-get install -y \
libsdl2-dev \
libvorbis-dev \
libglut-dev \
libopenal-dev; \
fi && \
rm -rf /var/lib/apt/lists/* && \
dbus-uuidgen > /etc/machine-id
# Copy the compiled application from the builder stage
COPY --from=builder /home/ubuntu/ballistica_cmake_server/*/staged \
COPY --from=builder /ballistica_cmake \
/home/ubuntu/ballistica
# ballisticakit_headless in staged is a symlink
COPY --from=builder /home/ubuntu/ballistica_cmake_server/*/ballisticakit_headless \
/home/ubuntu/ballistica/dist
WORKDIR /home/ubuntu/ballistica
RUN ln -s ballisticakit* run
# Expose the necessary port
EXPOSE 43210/udp
EXPOSE 43210/udp
# Set the default command to run the application
CMD [ "./ballisticakit_server" ]
CMD [ "./run" ]

View File

@ -644,59 +644,3 @@ def cmake_prep_dir(dirname: str, verbose: bool = False) -> None:
else:
if verbose:
print(f'{Clr.BLD}{title}:{Clr.RST} Keeping existing build dir.')
def _docker_build(
image_name: str,
dockerfile_dir: str,
bombsquad_version: str | None = None,
bombsquad_build: str | int | None = None,
cmake_build_type: str | None = None,
) -> None:
build_cmd = [
'docker',
'image',
'build',
'-t',
image_name,
'-f',
dockerfile_dir,
'.',
]
if bombsquad_version is not None:
build_cmd = build_cmd + [
'--build-arg',
f'bombsquad_version={bombsquad_version}',
]
if bombsquad_build is not None:
build_cmd = build_cmd + [
'--build-arg',
f'bombsquad_build={str(bombsquad_build)}',
]
if cmake_build_type is not None:
build_cmd = build_cmd + [
'--build-arg',
f'cmake_build_type={cmake_build_type}',
]
subprocess.run(build_cmd, check=True)
def docker_build() -> None:
"""Build docker image."""
# todo: add option to toggle between prefab and cmake
from batools import version
version_num, build_num = version.get_current_version()
image_name = 'bombsquad_server'
print(
f'Building docker image {image_name}'
+ 'version {version_num}:{build_num}'
)
_docker_build(
image_name,
'config/docker/Dockerfile',
version_num,
build_num,
)

173
tools/batools/docker.py Normal file
View File

@ -0,0 +1,173 @@
# Released under the MIT License. See LICENSE for details.
#
"""General functionality related to docker builds."""
import subprocess
def _docker_build(
image_name: str,
dockerfile_dir: str,
cmake_build_type: str | None = None,
labels: dict[str, str] | None = None,
platform: str | None = None,
headless_build: bool | str | None = None,
) -> None:
build_cmd = [
'docker',
'buildx',
'build',
'--tag',
image_name,
'--file',
dockerfile_dir,
'--load',
'.',
]
if cmake_build_type is not None:
build_cmd = build_cmd + [
'--build-arg',
f'cmake_build_type={cmake_build_type}',
]
if headless_build is not None:
if headless_build:
headless_build = '1'
else:
headless_build = '0'
build_cmd = build_cmd + [
'--build-arg',
f'headless_build={headless_build}',
]
if platform is not None:
build_cmd = build_cmd + [
'--platform',
platform,
]
if labels is not None:
build_cmd = build_cmd + [
f'--label={i}={labels[i]}' for i in labels.keys()
]
subprocess.run(build_cmd, check=True)
def docker_build(
platform: str | None = 'linux/amd64',
headless_build: bool | str | None = None,
build_type: str | None = None,
) -> None:
"""Build docker image.
platform == 'linux/arm64' or platform == 'linux/amd64'"""
from batools import version
version_num, build_num = version.get_current_version()
if headless_build is None:
headless_build = True
if build_type is None:
build_type = 'Release'
image_name = get_docker_image_name(
headless_build=headless_build, build_type=build_type
)
if platform is not None and 'arm64' in platform:
config_file = 'config/docker/Dockerfile_arm64'
else:
config_file = 'config/docker/Dockerfile'
print(
f'Building docker image {image_name} '
+ f'version {version_num}:{build_num}'
)
_docker_build(
image_name,
config_file,
labels={
'bombsquad_version': version_num,
'bombsquad_build': str(build_num),
},
platform=platform,
headless_build=headless_build,
cmake_build_type=build_type,
)
def get_docker_image_name(headless_build: bool | str, build_type: str) -> str:
"""Get name of docker images in predefined format."""
name = 'bombsquad'
if headless_build:
name += '_server'
else:
name += '_gui'
if 'release' in build_type.lower():
name += '_release'
else:
name += '_debug'
return name
def docker_save_images() -> None:
"""Saves bombsquad images loaded into docker."""
output = subprocess.run(
['docker', 'images'], capture_output=True, text=True, check=True
)
save_cmd = ['docker', 'save', '-o']
# we expect this directory is already present from Makefile
build_save_dir = 'build/docker/'
img_name = get_docker_image_name(headless_build=True, build_type='Release')
if img_name in output.stdout:
subprocess.run(
save_cmd + [build_save_dir + img_name + '_docker.tar', img_name],
check=True,
)
img_name = get_docker_image_name(headless_build=True, build_type='Debug')
if img_name in output.stdout:
subprocess.run(
save_cmd + [build_save_dir + img_name + '_docker.tar', img_name],
check=True,
)
img_name = get_docker_image_name(headless_build=False, build_type='Release')
if img_name in output.stdout:
subprocess.run(
save_cmd + [build_save_dir + img_name + '_docker.tar', img_name],
check=True,
)
img_name = get_docker_image_name(headless_build=False, build_type='Debug')
if img_name in output.stdout:
subprocess.run(
save_cmd + [build_save_dir + img_name + '_docker.tar', img_name],
check=True,
)
def docker_remove_images() -> None:
"""Remove the bombsquad images loaded in docker."""
output = subprocess.run(
['docker', 'images'], capture_output=True, text=True, check=True
)
remove_cmd = [
'docker',
'rmi',
]
img_name = get_docker_image_name(headless_build=True, build_type='Release')
if img_name in output.stdout:
subprocess.run(remove_cmd + [img_name], check=True)
img_name = get_docker_image_name(headless_build=True, build_type='Debug')
if img_name in output.stdout:
subprocess.run(remove_cmd + [img_name], check=True)
img_name = get_docker_image_name(headless_build=False, build_type='Release')
if img_name in output.stdout:
subprocess.run(remove_cmd + [img_name], check=True)
img_name = get_docker_image_name(headless_build=False, build_type='Debug')
if img_name in output.stdout:
subprocess.run(remove_cmd + [img_name], check=True)

View File

@ -104,7 +104,14 @@ from batools.pcommands import (
ensure_prefab_platform,
prefab_run_var,
prefab_binary_path,
build_docker,
build_docker_gui_release,
build_docker_gui_debug,
build_docker_server_release,
build_docker_server_debug,
build_docker_arm64_gui_release,
build_docker_arm64_server_release,
save_docker_images,
remove_docker_images,
make_prefab,
lazybuild,
efro_gradle,

View File

@ -9,6 +9,7 @@ import sys
from efrotools import pcommand
# pylint: disable=too-many-lines
def prune_includes() -> None:
"""Check for unnecessary includes in C++ files.
@ -667,11 +668,60 @@ def prefab_binary_path() -> None:
)
def build_docker() -> None:
"""Build the docker image with bombsquad cmake server."""
import batools.build
def build_docker_gui_release() -> None:
"""Build the docker image with bombsquad cmake gui."""
import batools.docker
batools.build.docker_build()
batools.docker.docker_build(headless_build=False)
def build_docker_gui_debug() -> None:
"""Build the docker image with bombsquad debug cmake gui."""
import batools.docker
batools.docker.docker_build(headless_build=False, build_type='Debug')
def build_docker_server_release() -> None:
"""Build the docker image with bombsquad cmake server."""
import batools.docker
batools.docker.docker_build()
def build_docker_server_debug() -> None:
"""Build the docker image with bombsquad debug cmake server."""
import batools.docker
batools.docker.docker_build(build_type='Debug')
def build_docker_arm64_gui_release() -> None:
"""Build the docker image with bombsquad cmake for arm64."""
import batools.docker
batools.docker.docker_build(headless_build=False, platform='linux/arm64')
def build_docker_arm64_server_release() -> None:
"""Build the docker image with bombsquad cmake server for arm64."""
import batools.docker
batools.docker.docker_build(platform='linux/arm64')
def save_docker_images() -> None:
"""Saves bombsquad images loaded into docker."""
import batools.docker
batools.docker.docker_save_images()
def remove_docker_images() -> None:
"""Remove the bombsquad images loaded in docker."""
import batools.docker
batools.docker.docker_remove_images()
def make_prefab() -> None: