Skip to content

add docker + docker compose #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
FROM alpine:3.20 AS cpp-buildenv

WORKDIR /tmp

RUN apk update --no-cache && \
apk add --no-cache ca-certificates \
samurai git openssl-dev openssl pkgconf cmake \
clang18 clang18-extra-tools && \
git clone https://github.com/OpenBrickProtocolFoundation/simulator simulator

ENV CC=clang-18
ENV CXX=clang++-18
ENV LD=clang-18

WORKDIR /tmp/simulator/

RUN cmake -B build -G "Ninja" \
-DCMAKE_BUILD_TYPE=Release \
-Dobpf_build_tests=OFF \
-Dobpf_simulator_enable_undefined_behavior_sanitizer=OFF \
-Dobpf_simulator_enable_address_sanitizer=OFF \
-Dobpf_simulator_warnings_as_errors=ON \
-Dobpf_simulator_build_shared_libs=OFF && \
cmake --build build



# final image starts here

FROM python:3.12-alpine

WORKDIR /app


# install python dependencies

COPY requirements.txt requirements.txt

RUN pip3 install --no-cache-dir -r requirements.txt

COPY lobby/ lobby/

# copy game server

ENV OBBF_CONFIG_PATH=/app/config/config.json
ENV OBBF_GAMESERVER_EXECUTABLE=/app/gameserver/server
ENV OBBF_SIMULATOR_LIBRARY_PATH=/app/gameserver/
ENV OBPF_IS_DOCKER=true

ENV PYTHONPATH="${PYTHONPATH}:/app/"

COPY --from=cpp-buildenv /tmp/simulator/build/bin/server/server /app/gameserver/

## add finalization arguments

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 CMD curl -f -X GET http://localhost:1717/health

EXPOSE 1717

CMD [ "python3", "lobby/main.py", "production"]
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,32 @@
# The Lob(b)y Server Everybody Asked For!

More to come here...

## Deploy with docker compose

You need a running docker service and docker compose installed

Then build the image with docker compose:

```bash
docker compose build
```

After this you can run the whole app with docker compose:

```bash
docker compose up -d
```

Note: the port is 1717 to proxy it through something like e.g. nginx.

There are two volumes defined:

```yaml
./files/:/app/files/
./config.json:/app/config/config.json
```

The first one maps the database content out of the container, so that it's persistent, You can inspect the database there if you want to.
The second one is for you to provide a config.json in the root folder. To see the exact schema look into `lobby/config.py`
NOTE: `SIMULATOR_LIBRARY_PATH` and `GAMESERVER_EXECUTABLE` don't need to be set, as the docker environment provides thos and sets them via environment variables.
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: "3.8"
name: "obpf-lobby"
services:
flask:
container_name: obpf-lobby
build:
context: .
ports:
- "1717:1717"
volumes:
- "./files/:/app/files/"
- ./config.json:/app/config/config.json
23 changes: 20 additions & 3 deletions lobby/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from dataclasses import dataclass
from enum import Enum
from typing import Self
import os

from dataclasses_jsonschema import JsonSchemaMixin

Expand All @@ -13,13 +14,29 @@ class ConfigValue(Enum):


@dataclass
class Config(JsonSchemaMixin):
class BaseConfig(JsonSchemaMixin):
jwt_secret: str
gameserver_executable: str
simulator_library_path: str

@classmethod
def from_file(cls, filename: str) -> Self:
with open(filename) as file:
data = json.load(file)
return cls.from_dict(data)

@dataclass
class Config(BaseConfig):
gameserver_executable: str
simulator_library_path: str

@classmethod
def from_file(cls, filename: str) -> Self:
is_docker = len(os.environ.get("OBPF_IS_DOCKER",""))>= 1
if is_docker:
data = BaseConfig.from_file(filename).to_dict()
data[ConfigValue.GAMESERVER_EXECUTABLE.value] = os.environ["OBBF_GAMESERVER_EXECUTABLE"]
data[ConfigValue.SIMULATOR_LIBRARY_PATH.value] = os.environ["OBBF_SIMULATOR_LIBRARY_PATH"]
return cls.from_dict(data)
else:
with open(filename) as file:
data = json.load(file)
return cls.from_dict(data)
8 changes: 7 additions & 1 deletion lobby/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ def try_authenticate(client_request: Request) -> User | tuple[Response, HTTPStat
return user



@app.route("/health", methods=["GET"])
def health_check():
return create_ok_response({})


@app.route("/lobbies", methods=["GET"])
def lobby_list() -> tuple[Response, HTTPStatus]:
@dataclass
Expand Down Expand Up @@ -488,7 +494,7 @@ class SetClientReadyResponse(JsonSchemaMixin):


def main() -> None:
config = Config.from_file("config.json")
config = Config.from_file(os.environ.get("OBBF_CONFIG_PATH","config.json"))
app.config.update(config.to_dict())
pprint.pprint(app.config)
if len(sys.argv) >= 2 and sys.argv[1] == "production":
Expand Down
Loading