From 46c43846e998c5eb3ebff3e7e2e71bf444b566c5 Mon Sep 17 00:00:00 2001
From: Ralex <95540504+Ralex91@users.noreply.github.com>
Date: Sat, 25 Oct 2025 13:41:29 +0200
Subject: [PATCH] feat(docker): update Dockerfile and compose configuration,
enhance README for deployment methods
---
.github/workflows/docker-release.yml | 69 +++++++
.gitignore | 4 +-
Dockerfile | 4 +-
README.md | 192 +++++++++++-------
compose.yml | 2 +-
.../src/app/game/manager/[gameId]/page.tsx | 1 -
.../web/src/components/game/states/Podium.tsx | 2 -
7 files changed, 198 insertions(+), 76 deletions(-)
create mode 100644 .github/workflows/docker-release.yml
diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml
new file mode 100644
index 0000000..e8d68fa
--- /dev/null
+++ b/.github/workflows/docker-release.yml
@@ -0,0 +1,69 @@
+name: Docker Release
+on:
+ release:
+ types: [published]
+
+env:
+ DOCKER_PLATFORMS: |
+ linux/amd64
+ linux/arm64
+
+jobs:
+ build-and-push:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Extract version and tags
+ run: |
+ if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then
+ VERSION=${GITHUB_REF_NAME#v}
+ echo "VERSION=$VERSION" >> $GITHUB_ENV
+
+ # Extract major.minor (ex: 1.2.3 -> 1.2)
+ MAJOR_MINOR=$(echo $VERSION | cut -d. -f1,2)
+ echo "MAJOR_MINOR=$MAJOR_MINOR" >> $GITHUB_ENV
+ else
+ echo "VERSION=latest" >> $GITHUB_ENV
+ echo "MAJOR_MINOR=latest" >> $GITHUB_ENV
+ fi
+
+ - name: Extract repository name (lowercase)
+ run: echo "REPO_NAME=$(basename ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ with:
+ platforms: ${{ env.DOCKER_PLATFORMS }}
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ with:
+ version: latest
+ install: true
+ platforms: ${{ env.DOCKER_PLATFORMS }}
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Build and push
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ platforms: ${{ env.DOCKER_PLATFORMS }}
+ push: true
+ tags: |
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ env.VERSION }}
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ env.MAJOR_MINOR }}
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:latest
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ build-args: |
+ BUILDKIT_INLINE_CACHE=1
diff --git a/.gitignore b/.gitignore
index 7af7f04..ed1665d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
/node_modules
-.env
\ No newline at end of file
+.env
+.secrets
+release.json
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 92e640c..02bec79 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:24-alpine AS base
+FROM node:22-alpine AS base
# Enable and prepare pnpm via Corepack
RUN corepack enable && corepack prepare pnpm@latest --activate
@@ -37,7 +37,7 @@ WORKDIR /app/packages/socket
RUN if [ -f "tsconfig.json" ]; then pnpm build; fi
# ----- RUNNER -----
-FROM node:24-alpine AS runner
+FROM node:22-alpine AS runner
WORKDIR /app
# Create a non-root user for better security
diff --git a/README.md b/README.md
index 93772a0..250b303 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,10 @@
-
+
+

+

+
## 🧩 What is this project?
@@ -12,93 +15,144 @@ Rahoot is a straightforward and open-source clone of the Kahoot! platform, allow
## ⚙️ Prerequisites
-- Node.js version 20 or higher
+Choose one of the following deployment methods:
+
+### Without Docker
+
+- Node.js : version 20 or higher
+- PNPM : Learn more about [here](https://pnpm.io/)
+
+### With Docker
+
+- Docker and Docker Compose
## 📖 Getting Started
-1. #### Clone the GitHub repository of your project.
- ```bash
- git clone https://github.com/Ralex91/Rahoot.git
- cd ./Rahoot
- ```
-2. #### Install the dependencies using your preferred package manager
+Choose your deployment method:
- ```bash
- npm install
- ```
+### 🐳 Using Docker (Recommended)
-
-
+Using Docker Compose (recommended):
-## 📦 Running the Application in Production Mode:
-
-1. #### Check websocket connfiguration in [config.mjs](config.mjs)
-
- If you want the client to connect directly to the websocket server, edit the [config.mjs](config.mjs) file and change the localhost to your public IP address.
-
- ```js
- export const WEBSOCKET_PUBLIC_URL = "http://1.2.3.4:3100/"
- export const WEBSOCKET_SERVER_PORT = 3100
-
- // Rest of the config ...
- ```
-
-2. #### Start the application
-
- ```bash
- npm run all
- ```
-
-## ⚙️ Running the Application in Development Mode:
+You can find the docker compose configuration in the repository:
+[docker-compose.yml](/compose.yml)
```bash
-npm run all-dev
+docker compose up -d
```
-## 🔧 Configuration
+Or using Docker directly:
-Configuration can be found in [config.mjs](config.mjs)
+```bash
+docker run -d \
+ -p 3000:3000 \
+ -p 3001:3001 \
+ -v ./config:/app/config \
+ -e WEB_ORIGIN=http://localhost:3000 \
+ -e SOCKET_URL=http://localhost:3001 \
+ ralex91/rahoot:latest
+```
-```js
-const QUIZZ_CONFIG = {
- password: "PASSWORD", // Manager password
- subject: "Adobe", // Subject of the quiz
- questions: [
- { // Example question
- question: "What is good answer ?", // Question
- answers: [ // Possible answers
- "No",
- "Yes",
- "No",
- "No",
- ],
- image:
- "https://images.unsplash.com/....", // Image URL (optional)
- solution: 1, // Index of the correct answer (index starts at 0)
- cooldown: 5, // Show question cooldown in seconds
- time: 15, // Time to answer in seconds
- },
- ...
- ],
+The application will be available at:
+
+- Web Interface: http://localhost:3000
+- WebSocket Server: ws://localhost:3001
+
+### 🛠️ Without Docker
+
+1. Clone the repository:
+
+```bash
+git clone https://github.com/Ralex91/Rahoot.git
+cd ./Rahoot
+```
+
+2. Install dependencies:
+
+```bash
+pnpm install
+```
+
+3. Change the environment variables in the `.env` file
+
+4. Build and start the application:
+
+```bash
+# Development mode
+pnpm run dev
+
+# Production mode
+pnpm run build
+pnpm start
+```
+
+## ⚙️ Configuration
+
+The configuration is split into two main parts:
+
+### 1. Game Configuration (`config/game.json`)
+
+Main game settings:
+
+```json
+{
+ "managerPassword": "PASSWORD",
+ "music": true
}
```
-## 🤔 How to use
+Options:
-- Go to [https://localhost:3000/manager](https://localhost:3000/manager) enter manager password.
+- `managerPassword`: The master password for accessing the manager interface
+- `music`: Enable/disable game music
-- Share link [https://localhost:3000/](https://localhost:3000/) and code on manager screen with your friends and get ready to play.
+### 2. Quiz Configuration (`config/quizz/*.json`)
-- Once everyone is ready, start the game with button on the top left of the screen of manager.
+Create your quiz files in the `config/quizz/` directory. You can have multiple quiz files and select which one to use when starting a game.
+
+Example quiz configuration (`config/quizz/example.json`):
+
+```json
+{
+ "subject": "Example Quiz",
+ "questions": [
+ {
+ "question": "What is the correct answer?",
+ "answers": ["No", "Yes", "No", "No"],
+ "image": "https://images.unsplash.com/....",
+ "solution": 1,
+ "cooldown": 5,
+ "time": 15
+ }
+ ]
+}
+```
+
+Quiz Options:
+
+- `subject`: Title/topic of the quiz
+- `questions`: Array of question objects containing:
+ - `question`: The question text
+ - `answers`: Array of possible answers (2-4 options)
+ - `image`: Optional URL for question image
+ - `solution`: Index of correct answer (0-based)
+ - `cooldown`: Time in seconds before showing the question
+ - `time`: Time in seconds allowed to answer
+
+## 🎮 How to Play
+
+1. Access the manager interface at http://localhost:3000/manager
+2. Enter the manager password (defined in quiz config)
+3. Share the game URL (http://localhost:3000) and room code with participants
+4. Wait for players to join
+5. Click the start button to begin the game
## 📝 Contributing
-- Create a fork
+1. Fork the repository
+2. Create a new branch (e.g., `feat/my-feature`)
+3. Make your changes
+4. Create a pull request
+5. Wait for review and merge
-- Create work branch (Example: githubUsername/featureName).
-
-- Commit and push your changes in the work branch.
-
-- Open a pull request.
-
-- Your pull request would be merged and changes will be reflected in the main repository.
+For bug reports or feature requests, please [create an issue](https://github.com/Ralex91/Rahoot/issues).
diff --git a/compose.yml b/compose.yml
index 46701b8..8db2259 100644
--- a/compose.yml
+++ b/compose.yml
@@ -2,7 +2,7 @@ version: "3.8"
services:
rahoot:
- image: rahoot
+ image: ralex91/rahoot:latest
ports:
- "3000:3000"
- "3001:3001"
diff --git a/packages/web/src/app/game/manager/[gameId]/page.tsx b/packages/web/src/app/game/manager/[gameId]/page.tsx
index b00d291..24bcddd 100644
--- a/packages/web/src/app/game/manager/[gameId]/page.tsx
+++ b/packages/web/src/app/game/manager/[gameId]/page.tsx
@@ -40,7 +40,6 @@ export default function ManagerGame() {
useEvent(
"manager:successReconnect",
({ gameId, status, players, currentQuestion }) => {
- console.log("manager:successReconnect", gameId)
setGameId(gameId)
setStatus(status.name, status.data)
setPlayers(players)
diff --git a/packages/web/src/components/game/states/Podium.tsx b/packages/web/src/components/game/states/Podium.tsx
index 7e4ed7c..8934713 100644
--- a/packages/web/src/components/game/states/Podium.tsx
+++ b/packages/web/src/components/game/states/Podium.tsx
@@ -39,8 +39,6 @@ export default function Podium({ data: { subject, top } }: Props) {
})
useEffect(() => {
- console.log(apparition)
-
switch (apparition) {
case 4:
sfxRoolStop()