From 1dc0cabc2ba3c1826f623f0cdfbd454ecb754f01 Mon Sep 17 00:00:00 2001 From: Sergey Stepanov Date: Mon, 24 Apr 2023 21:04:37 +0300 Subject: [PATCH] Add special Dockerfile for tiny coordinator (<10Mib) and worker (<150Mib) containers --- .dockerignore | 27 +++---- .github/workflows/build.yml | 2 +- Dockerfile | 139 ++++++++++++++++++++++-------------- Makefile | 8 ++- README.md | 17 ++--- docker-compose.yml | 28 +++++--- pkg/config/config.yaml | 5 +- scripts/install.sh | 28 -------- scripts/mkdirs.sh | 14 ++++ 9 files changed, 146 insertions(+), 122 deletions(-) delete mode 100755 scripts/install.sh create mode 100755 scripts/mkdirs.sh diff --git a/.dockerignore b/.dockerignore index d85038cf..9c6459c7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,18 +1,9 @@ -.git/ -.github/ -.idea/ -.vscode/ -.gitignore - -.editorconfig -.env -docker-compose.yml -Dockerfile - -LICENSE -README.md -DESIGNv2.md -bin/ -release/ - -assets/games/ +/** +!cmd/ +!pkg/ +!scripts/ +!web/ +!go.mod +!go.sum +!LICENSE +!Makefile diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f20391e1..17ce3d47 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -113,4 +113,4 @@ jobs: if: github.event_name == 'pull_request' steps: - uses: actions/checkout@v3 - - run: docker build --build-arg VERSION=$(./scripts/version.sh) . + - run: DOCKER_BUILDKIT=1 docker build --build-arg VERSION=$(./scripts/version.sh) . diff --git a/Dockerfile b/Dockerfile index ea96d31d..a5691748 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,68 +1,103 @@ -# The base cloud-game image -ARG BUILD_PATH=/go/src/github.com/giongto35/cloud-game +ARG BUILD_PATH=/tmp/cloud-game +ARG VERSION=master +ARG GO=1.20.4 -# build image -FROM ubuntu:lunar AS build +# base build stage +FROM ubuntu:lunar AS build0 +ARG GO + +RUN apt-get -q update && apt-get -q install --no-install-recommends -y \ + ca-certificates \ + wget \ + make \ + upx + +ARG GO_DIST=go${GO}.linux-amd64.tar.gz +RUN wget -q https://golang.org/dl/$GO_DIST && \ + rm -rf /usr/local/go && \ + tar -C /usr/local -xzf $GO_DIST && \ + rm $GO_DIST +ENV PATH="${PATH}:/usr/local/go/bin" + +# next conditional build stage +FROM build0 AS build_coordinator ARG BUILD_PATH +ARG VERSION +ENV GIT_VERSION ${VERSION} + WORKDIR ${BUILD_PATH} -# system libs layer -RUN apt-get -qq update && apt-get -qq install --no-install-recommends -y \ +# install deps +RUN rm -rf /var/lib/apt/lists/* + +# by default we ignore all except some folders and files, see .dockerignore +COPY . ./ +RUN --mount=type=cache,target=/root/.cache/go-build make build.coordinator +RUN find ./bin/* | xargs upx --best --lzma + +WORKDIR /usr/local/share/cloud-game +RUN mv ${BUILD_PATH}/bin/* ./ && \ + mv ${BUILD_PATH}/web ./web && \ + mv ${BUILD_PATH}/LICENSE ./ +RUN ${BUILD_PATH}/scripts/version.sh ./web/index.html ${VERSION} && \ + ${BUILD_PATH}/scripts/mkdirs.sh + +# next worker build stage +FROM build0 AS build_worker +ARG BUILD_PATH +ARG VERSION +ENV GIT_VERSION ${VERSION} + +WORKDIR ${BUILD_PATH} + +# install deps +RUN apt-get -q install --no-install-recommends -y \ gcc \ - ca-certificates \ libopus-dev \ libsdl2-dev \ libvpx-dev \ libx264-dev \ - make \ pkg-config \ - wget \ - upx \ - && rm -rf /var/lib/apt/lists/* +&& rm -rf /var/lib/apt/lists/* -# go setup layer -ARG GO=go1.20.3.linux-amd64.tar.gz -RUN wget -q https://golang.org/dl/$GO \ - && rm -rf /usr/local/go \ - && tar -C /usr/local -xzf $GO \ - && rm $GO -ENV PATH="${PATH}:/usr/local/go/bin" +# by default we ignore all except some folders and files, see .dockerignore +COPY . ./ +RUN --mount=type=cache,target=/root/.cache/go-build make GO_TAGS=static,st build.worker +RUN find ./bin/* | xargs upx --best --lzma -# go deps layer -COPY go.mod go.sum ./ -RUN go mod download +WORKDIR /usr/local/share/cloud-game +RUN mv ${BUILD_PATH}/bin/* ./ && \ + mv ${BUILD_PATH}/LICENSE ./ +RUN ${BUILD_PATH}/scripts/mkdirs.sh worker -# app build layer -COPY pkg ./pkg -COPY cmd ./cmd -COPY Makefile . -COPY scripts/version.sh scripts/version.sh -ARG VERSION -RUN GIT_VERSION=${VERSION} make GO_TAGS=static,st build -# compress -RUN find ${BUILD_PATH}/bin/* | xargs strip --strip-unneeded -RUN find ${BUILD_PATH}/bin/* | xargs upx --best --lzma +RUN wget https://raw.githubusercontent.com/sergystepanov/mesa-llvmpipe/main/release/M23.1.0-LLVM16/libGL.so.1.5.0 + +FROM scratch AS coordinator + +COPY --from=build_coordinator /usr/local/share/cloud-game /cloud-game +# autocertbot (SSL) requires these on the first run +COPY --from=build_coordinator /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ + +FROM ubuntu:lunar AS worker + +RUN apt-get -q update && apt-get -q install --no-install-recommends -y \ + libx11-6 \ + libxext6 \ + && apt-get autoremove \ + && rm -rf /var/lib/apt/lists/* /var/log/* /usr/share/bug /usr/share/doc /usr/share/doc-base \ + /usr/share/X11/locale/* + +COPY --from=build_worker /usr/local/share/cloud-game /cloud-game +COPY --from=build_worker /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ + +RUN mv /cloud-game/libGL.so.1.5.0 /usr/lib/x86_64-linux-gnu/ && \ + cd /usr/lib/x86_64-linux-gnu && \ + ln -s libGL.so.1.5.0 libGL.so.1 && \ + ln -s libGL.so.1 libGL.so + +FROM worker AS cloud-game -# base image -FROM ubuntu:lunar -ARG BUILD_PATH WORKDIR /usr/local/share/cloud-game -COPY scripts/install.sh install.sh -RUN bash install.sh x11-only && \ - rm -rf /var/lib/apt/lists/* install.sh - -COPY --from=build ${BUILD_PATH}/bin/ ./ -RUN cp -s $(pwd)/* /usr/local/bin -RUN mkdir -p ./assets/cache && \ - mkdir -p ./assets/cores && \ - mkdir -p ./assets/games && \ - mkdir -p ./libretro && \ - mkdir -p /root/.cr -COPY web ./web -ARG VERSION -COPY scripts/version.sh version.sh -RUN bash ./version.sh ./web/index.html ${VERSION} && \ - rm -rf version.sh - -EXPOSE 8000 9000 +COPY --from=coordinator /cloud-game ./ +COPY --from=worker /cloud-game ./ diff --git a/Makefile b/Makefile index 8341821d..585d2eac 100644 --- a/Makefile +++ b/Makefile @@ -18,14 +18,20 @@ clean: @rm -rf build @go clean ./cmd/* -build: + +build.coordinator: mkdir -p bin/ go build -ldflags "-w -s -X 'main.Version=$(GIT_VERSION)'" -o bin/ ./cmd/coordinator + +build.worker: + mkdir -p bin/ CGO_CFLAGS=${CGO_CFLAGS} CGO_LDFLAGS=${CGO_LDFLAGS} \ go build -buildmode=exe $(if $(GO_TAGS),-tags $(GO_TAGS),) \ -ldflags "-w -s -X 'main.Version=$(GIT_VERSION)'" $(EXT_WFLAGS) \ -o bin/ ./cmd/worker +build: build.coordinator build.worker + verify-cores: go test -run TestAllEmulatorRooms ./pkg/worker -v -renderFrames $(GL_CTX) -outputPath "../../_rendered" diff --git a/README.md b/README.md index c6963e80..66944fdc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # CloudRetro + [![Build](https://github.com/giongto35/cloud-game/workflows/build/badge.svg)](https://github.com/giongto35/cloud-game/actions?query=workflow:build) [![Latest release](https://img.shields.io/github/v/release/giongto35/cloud-game.svg)](https://github.com/giongto35/cloud-game/releases/latest) @@ -13,7 +14,9 @@ Discord: [Join Us](https://discord.gg/sXRQZa2zeP) ![screenshot](https://user-images.githubusercontent.com/846874/235532552-8c8253df-aa8d-48c9-a58e-3f54e284f86e.jpg) ## Try it at **[cloudretro.io](https://cloudretro.io)** -Direct play an existing game: **[Pokemon Emerald](https://cloudretro.io/?id=1bd37d4b5dfda87c___Pokemon%20-%20Emerald%20Version%20(U))** + +Direct play an existing game: * +*[Pokemon Emerald](https://cloudretro.io/?id=1bd37d4b5dfda87c___Pokemon%20-%20Emerald%20Version%20(U))** ## Introduction @@ -85,17 +88,16 @@ __See the `docker-compose.yml` file for Xvfb example config.__ ## Run with Docker -Use makefile script: `make dev.run-docker` or Docker Compose directly: `docker-compose up --build` -(`CLOUD_GAME_GAMES_PATH` is env variable for games on your host). It will spawn a docker environment and you can access -the service on `localhost:8000`. +Use makefile script: `make dev.run-docker` or Docker Compose directly: `docker compose up --build`. +It will spawn a docker environment and you can access the service on `localhost:8000`. ## Configuration The default configuration file is stored in the [`pkg/configs/config.yaml`](pkg/config/config.yaml) file. This configuration file will be embedded into the applications and loaded automatically during startup. -In order to override (change) the default parameters you can specify environment variables with the `CLOUD_GAME_` prefix -(except list params), or place a custom `config.yaml` file into one of these places: just near the application or in the `configs` folder, -`.cr` folder in user's home, or specify own directory with `-w-conf` application param (`worker -w-conf /usr/conf`). +In order to change the default parameters you can specify environment variables with the `CLOUD_GAME_` prefix, or place +a custom `config.yaml` file into one of these places: just near the application, `.cr` folder in user's home, or +specify own directory with `-w-conf` application param (`worker -w-conf /usr/conf`). ## Deployment @@ -152,7 +154,6 @@ Thanks: # Announcement - **[CloudMorph](https://github.com/giongto35/cloud-morph) is a sibling project that offers a more generic to run any offline games/application on browser in Cloud Gaming approach: [https://github.com/giongto35/cloud-morph](https://github.com/giongto35/cloud-morph))** diff --git a/docker-compose.yml b/docker-compose.yml index 5fb3725c..491c7783 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,20 +7,28 @@ services: container_name: cloud-game-local environment: - DISPLAY=:99 - - MESA_GL_VERSION_OVERRIDE=3.3 + - MESA_GL_VERSION_OVERRIDE=4.5 - CLOUD_GAME_WEBRTC_SINGLEPORT=8443 - - CLOUD_GAME_WEBRTC_ICEIPMAP=127.0.0.1 + # - CLOUD_GAME_WEBRTC_ICEIPMAP=127.0.0.1 + - CLOUD_GAME_COORDINATOR_DEBUG=true + - CLOUD_GAME_WORKER_DEBUG=true # - PION_LOG_TRACE=all ports: - - 8000:8000 - - 9000:9000 - - 8443:8443/udp + - "8000:8000" + - "9000:9000" + - "8443:8443/udp" command: > - bash -c "Xvfb :99 & coordinator & worker" + bash -c "./coordinator & ./worker" volumes: - # keep cores persistent in the cloud-game_cores volume - - cores:/usr/local/share/cloud-game/assets/cores - - ${CLOUD_GAME_GAMES_PATH:-./assets/games}:/usr/local/share/cloud-game/assets/games + - ./assets/cores:/usr/local/share/cloud-game/assets/cores + - ./assets/games:/usr/local/share/cloud-game/assets/games + - x11:/tmp/.X11-unix + + xvfb: + image: kcollins/xvfb:latest + volumes: + - x11:/tmp/.X11-unix + command: [ ":99", "-screen", "0", "320x240x16" ] volumes: - cores: + x11: diff --git a/pkg/config/config.yaml b/pkg/config/config.yaml index c4f9b957..de9e4bcb 100644 --- a/pkg/config/config.yaml +++ b/pkg/config/config.yaml @@ -1,7 +1,4 @@ -LOL123L: yolo -# -# Application configuration file -# +# The main config file # for the compatibility purposes version: 3 diff --git a/scripts/install.sh b/scripts/install.sh deleted file mode 100755 index 550fbc37..00000000 --- a/scripts/install.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -deps="$1" - -echo This script should install application dependencies for Debian-based systems -if [ $(id -u) -ne 0 ] -then - echo "error: run with sudo or root" - exit 1 -fi - -apt-get -qq update -if [ "$deps" = "x11-only" ]; then - apt-get -qq install --no-install-recommends -y \ - ca-certificates \ - libgl1-mesa-dri \ - xvfb -else - apt-get -qq install --no-install-recommends -y \ - ca-certificates \ - libvpx7 \ - libx264-164 \ - libopus0 \ - libgl1-mesa-dri \ - xvfb -fi -apt-get clean -apt-get autoremove diff --git a/scripts/mkdirs.sh b/scripts/mkdirs.sh new file mode 100755 index 00000000..93e975b1 --- /dev/null +++ b/scripts/mkdirs.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +app="$1" + +echo Making application runtime directories +mkdir -p ./assets/cache +mkdir -p ./assets/games +mkdir -p ./.cr +if [ "$app" = "worker" ]; then + mkdir -p ./assets/cores + mkdir -p ./libretro +fi + +