Skip to content
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

Added Dockerfile and workflow #8

Merged
merged 6 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
30 changes: 30 additions & 0 deletions .github/workflows/docker-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Test Build-Env Docker Image

on:
pull_request:
KaruroChori marked this conversation as resolved.
Show resolved Hide resolved
branches: master
paths:
- '**Dockerfile'
- '**docker.yml'

jobs:
build-test-env-image:
runs-on: ubuntu-latest
env:
SOURCE_ROOT: ${{ github.workspace }}
IMAGE: test-image
ENTRYPOINT: ${{ github.workspace }}/docker/default-entry.sh
steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: sudo apt install -y docker-compose

- name: Build Docker image
run: docker build -t $IMAGE -f docker/Dockerfile ./docker

- name: Run commands in Docker container
run: |
export HOSTUID=$(id -u)
export HOSTGID=$(id -g)
docker-compose -f docker/docker-compose.yml run --rm dev
40 changes: 40 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Build-Env Docker Image

on:
push:
branches: master
KaruroChori marked this conversation as resolved.
Show resolved Hide resolved
paths:
- '**Dockerfile'
- '**docker.yml'
# workflow_dispatch:
# schedule:
# - cron: '30 11 20 */3 *'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often would you like this automatically built?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any suggestion for that?
I think once each fortnight is probably enough, possibly even too much.
I mean, if there are good reasons to have a new image asap we can just trigger it manually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first I thought a fortnight as well, although since I'm an American I actually thought two weeks. ;) But... monthly should be alright, because as you said, we can trigger it manually, or change the cron setting


env:
REGISTRY_IMAGE: ghcr.io/${{ github.repository_owner }}/vs-fltk

jobs:
build-env-image:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
file: ./Dockerfile
platforms: ${{ matrix.platform }}
cache-from: type=registry,ref=${{ env.REGISTRY_IMAGE }}:build-env-buildcache
cache-to: type=registry,ref=${{ env.REGISTRY_IMAGE }}:build-env-buildcache,mode=max
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ subprojects/*
/bun.lockb
/private
/logs
/.flatpak-builder
/.flatpak-builder

# Contains variables specific for the user
/docker/.env
41 changes: 41 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM debian:trixie-slim

ARG DEBIAN_FRONTEND=noninteractive
ENV DEBIAN_FRONTEND=$DEBIAN_FRONTEND

RUN \
apt update && apt upgrade -y && \
apt install -y \
build-essential \
ca-certificates \
clang-19 \
cmake \
curl \
freeglut3-dev \
git \
libpng-dev \
libsqlite3-0 \
libsqlitecpp-dev \
libtcc-dev \
lsb-release \
meson \
pkg-config \
sudo \
swiftlang \
unzip \
wget && \
update-ca-certificates -f

RUN useradd -m builder && passwd -d builder
RUN echo "builder ALL=(ALL) ALL" >> /etc/sudoers
WORKDIR /home/builder
USER builder

RUN curl -fsSL https://bun.sh/install | bash
RUN \
echo "export BUN_INSTALL=\"\$HOME/.bun\"" >> $HOME/.profile && \
echo "export PATH=\"\$BUN_INSTALL/bin:\$PATH\"" >> $HOME/.profile

USER root
WORKDIR /
CMD ["bash", "-l"]
139 changes: 139 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Docker
KaruroChori marked this conversation as resolved.
Show resolved Hide resolved

## Using docker-compose

You may build your changes by using the compose file. First create an `.env`
file in /docker. The contents should be similar to:

```text
HOSTUID=1000
HOSTGID=1000
IMAGE="ghcr.io/KaruroChori/vs-fltk:build-env"
ENTRYPOINT:$PWD/docker/default-entry.sh
SOURCE_ROOT=$PWD
```

Replace the values for HOSTUID and HOSTGID with your system uid and gid. Then,
from the source root:

docker-compose -f docker/docker-compose.yml run --rm dev

This will start the container and build the app.

To enter the build environment without actually building the app:

export ENTRYPOINT=$PWD/docker/shell-entry.sh
docker-compose -f docker/docker-compose.yml run --rm dev

Remember to unset ENTRYPOINT when you wish to use the default again.

<!--
This doesn't work unless the files are "mounted"
To run the image without using compose:

```sh
docker run -it --rm -v \
--entrypoint=$PWD/docker/default-entry.sh \
-v $PWD:/workspace \
ghcr.io/KaruroChori/vs-fltk:build-env
```
-->

All of the above methods will mount your current directory as */workspace*
inside the container. Your username will be *builder*. By default, you will
not have root privileges (which are not necessary to build and test). However,
you can use `sudo` if you need to run `apt` or any other commands that require
root access.

## Notes

In the examples above, we've included `--rm` as an argument. This normally
removes the container after it's exited. `docker ps -a` displays containers
that still exist so you may periodically want to make sure you don't have
unused or unwanted containers. See the official [Docker docs] for more
information about working with containers. You may, for example, want to
"reuse" a container, in which case, simply omit the `--rm`.

## Getting the image

You can pull the image manually:

docker pull ghcr.io/KaruroChori/vs-fltk:build-env

If you use `docker-compose` or `docker run ...` the image will be pulled
automatically the first time.

## Running the app from the container

Note the following instructions were adapted from instructions generated by
ChatGPT. The X11 instructions were tested on Manjaro Linux. Use at your own
risk. Please update these docs if you have any information about accuracy or
security-related considerations.

To run an application from a Docker container that requires access to the host
machine's graphics (such as a GUI application), you'll need to share certain
resources from the host with the container. This involves passing through the
host's display (X11 or Wayland, depending on your system) and sharing the
necessary devices. Here's a general guide:

### For X11-based systems (e.g., most Linux desktop environments)

1. **Install dependencies on the host:**
Make sure you have `xhost` installed, which allows you to control access to
the X server.

sudo apt install x11-xserver-utils # For Ubuntu/Debian
sudo pacman -S xorg-xhost # For Arch-based


2. **Allow access to X server:**
Before running the container, allow Docker to access your X server:

xhost +local:docker


3. **Run the container with access to the display:**
When starting the container, pass the display environment variable
(`$DISPLAY`) and mount the X11 socket. Instead of *dev" for the last
argument of `docker-compose` (see above), use *xgui*, which essentially
adds these three arguments (through the compose configuration):

```sh
--env="DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw"
```

- `--env="DISPLAY"`: Passes the display from the host to the container.
- `--env="QT_X11_NO_MITSHM=1"`: Some applications may need this to avoid shared memory issues.
- `--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw"`: Shares the X11 socket.

4. **Run the graphical application inside the container:**
Once inside the container, running the app should open its GUI on your host's screen.

### For Wayland-based systems (e.g., some modern Linux environments):

1. **Share the Wayland display:**
If your system uses Wayland, you need to pass the Wayland display and devices:

```sh
--env="WAYLAND_DISPLAY=$WAYLAND_DISPLAY" \
--volume="/run/user/$(id -u)/wayland:/run/user/$(id -u)/wayland" \
--device=/dev/dri \
```

- `--env="WAYLAND_DISPLAY=$WAYLAND_DISPLAY"`: Passes the Wayland display variable.
- `--volume="/run/user/$(id -u)/wayland:/run/user/$(id -u)/wayland"`: Shares the Wayland display socket.
- `--device=/dev/dri`: Provides access to GPU devices (for rendering).

### Additional considerations:

- **GPU access**: If your application requires GPU acceleration (e.g.,
OpenGL), you may also need to pass through GPU devices to the container. For
example, with NVIDIA, you can use the NVIDIA Docker runtime:

--gpus all -it

- **X11 access security**: Allowing Docker to connect to your X server with `xhost +local:docker` is not secure. After you're done, revoke access:

xhost -local:docker
12 changes: 12 additions & 0 deletions docker/default-entry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -e
/docker/main_entry.sh

su builder -c "bash -l -c '\
cd /workspace && \
bun install &&
bun run codegen &&
bun run meson-setup.clang-release &&
meson compile -C build/ vs:executable
'"
37 changes: 37 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
services:
dev:
image: $IMAGE
container_name: vs-fltk-env
entrypoint: $ENTRYPOINT
volumes:
- $SOURCE_ROOT:/workspace
- $ENTRYPOINT:$ENTRYPOINT
- ${PWD}/docker/main_entry.sh:/docker/main_entry.sh
environment:
HOSTUID: $HOSTUID
HOSTGID: $HOSTGID
ENTRYPOINT: $ENTRYPOINT
working_dir: /workspace
stdin_open: true # Allows interactive mode
tty: true # Allocate a pseudo-TTY
restart: "no"

xgui:
image: $IMAGE
container_name: vs-fltk-gui
entrypoint: $ENTRYPOINT
volumes:
- $SOURCE_ROOT:/workspace
- $ENTRYPOINT:$ENTRYPOINT
- ${PWD}/docker/main_entry.sh:/docker/main_entry.sh
- /tmp/.X11-unix:/tmp/.X11-unix:rw
environment:
HOSTUID: $HOSTUID
HOSTGID: $HOSTGID
ENTRYPOINT: $ENTRYPOINT
DISPLAY: $DISPLAY
QT_X11_NO_MITSHM: 1
working_dir: /workspace
stdin_open: true # Allows interactive mode
tty: true # Allocate a pseudo-TTY
restart: "no"
20 changes: 20 additions & 0 deletions docker/main_entry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
# main_entry.sh

set -e

OLDPWD=$PWD

if [ -z "$HOSTUID" ]; then
echo "HOSTUID is not set."
exit 1
fi

if [ -z "$HOSTGID" ]; then
echo "HOSTGID is not set."
exit 1
fi

usermod -u $HOSTUID builder
groupmod -g $HOSTGID builder
chown -R $HOSTUID:$HOSTGID /home/builder
6 changes: 6 additions & 0 deletions docker/shell-entry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

set -e
/docker/main_entry.sh

su builder -l -c "cd /workspace && bash"
6 changes: 6 additions & 0 deletions docs/for-developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ To run the dev demo where features under development are usually being tested:
bun run vs.example
```

### Docker
andy5995 marked this conversation as resolved.
Show resolved Hide resolved

A docker image is available that contains all the build dependencies. See
[docker/README.md](https://github.com/KaruroChori/vs-fltk/docker/README.md)

### Patches

Notice: this issue was only observed with `zig` as the backend and cannot be easily reproduced.
Expand Down Expand Up @@ -157,6 +162,7 @@ Exceptions should only be used in those cases when the application **must** stop

As for memory allocations, spawning small dynamic objects is also discouraged. If possible, stack allocations are a better alternative. Arrays with variable length on stack are totally fine to be used in place of local objects allocated on heap.
`std::string` is also highly discouraged, make sure `std::string_view` is used instead whenever possible.
<<<<<<< HEAD
KaruroChori marked this conversation as resolved.
Show resolved Hide resolved

### About log levels

Expand Down