Skip to content

Commit

Permalink
Added Dockerfile and workflow (#8)
Browse files Browse the repository at this point in the history
* Added Dockerfile and workflow

Closes #7

* Usermod builder

* Update the docs, use entrypoint.sh

* Remove duplicate build

* Simplify

---------

Co-authored-by: KaruroChori <[email protected]>
  • Loading branch information
andy5995 and KaruroChori authored Nov 21, 2024
1 parent 2b29af8 commit 74c633c
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 1 deletion.
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:
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
paths:
- '**Dockerfile'
- '**docker.yml'
# workflow_dispatch:
# schedule:
# - cron: '30 11 20 */3 *'

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

## 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"

0 comments on commit 74c633c

Please sign in to comment.