Compare commits

..

3 commits
v1.0 ... main

Author SHA1 Message Date
9552007d53
patch: fixed css (#4)
- Plus button too close to Roll Fudge Dice button

Reviewed-on: #4
Co-authored-by: riomoo <alister@kamikishi.net>
Co-committed-by: riomoo <alister@kamikishi.net>
2026-01-13 10:27:12 -05:00
5941b1ae33
Correct Build instructions (#3)
Reviewed-on: #3
Co-authored-by: riomoo <alister@kamikishi.net>
Co-committed-by: riomoo <alister@kamikishi.net>
2026-01-13 09:38:46 -05:00
62daab494a
feat and dev merging (#2)
- Plus and Minus button added for modifier
- better WS:// and WSS:// implementation
- dev: readme adjusted

Reviewed-on: #2
Co-authored-by: riomoo <alister@kamikishi.net>
Co-committed-by: riomoo <alister@kamikishi.net>
2026-01-13 09:21:39 -05:00
5 changed files with 130 additions and 50 deletions

38
Containerfile Normal file
View file

@ -0,0 +1,38 @@
# Build stage
FROM golang:alpine AS builder
# Install build dependencies and UPX
RUN apk add --no-cache \
musl-dev \
gcc \
wget \
xz \
git
RUN wget https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-amd64_linux.tar.xz && \
tar -xf upx-5.0.2-amd64_linux.tar.xz && \
mv upx-5.0.2-amd64_linux/upx /usr/local/bin/upx && \
rm -r upx-5.0.2-amd64_linux upx-5.0.2-amd64_linux.tar.xz
WORKDIR /app
# Copy go mod files first for better layer caching
COPY go.mod ./
RUN go mod download
# Copy source code
COPY . .
# Create necessary directories, build, and compress with UPX
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w -extldflags '-static' -X main.GOMEMLIMIT=50MiB -X runtime.defaultGOGC=50" -trimpath -gcflags="-l=4" -asmflags=-trimpath -o bin/main app/gofudge/main.go
RUN upx --best --ultra-brute bin/main
RUN chmod +x bin/main
FROM scratch
WORKDIR /app
# Copy only the built binary and necessary directories
COPY --from=builder /app/bin/main ./bin/main
EXPOSE 8080
ENTRYPOINT ["/app/bin/main"]

View file

@ -1,36 +0,0 @@
# Build stage
FROM golang:bookworm AS builder
# Install UPX
RUN apt-get update && apt-get install -y wget xz-utils && rm -rf /var/lib/apt/lists/*
# Download the latest UPX binary directly from GitHub
RUN wget https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-amd64_linux.tar.xz
RUN tar -xf upx-5.0.2-amd64_linux.tar.xz && mv upx-5.0.2-amd64_linux/upx /usr/local/bin/upx && rm -r upx-5.0.2-amd64_linux upx-5.0.2-amd64_linux.tar.xz
# Create a simple Go web server
WORKDIR /app
# Copy go mod files first for better layer caching
COPY go.mod ./
RUN go mod download
# Copy source code
COPY . .
# Create necessary directories, build, and compress with UPX
RUN mkdir -p /var/sockets
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w -extldflags '-static' -X main.GOMEMLIMIT=50MiB -X runtime.defaultGOGC=150" -trimpath -gcflags="-l=4" -asmflags=-trimpath -o bin/main app/gofudge/main.go
RUN upx --best --ultra-brute bin/main
RUN chmod +x bin/main
# Final stage with Chainguard static
FROM cgr.dev/chainguard/static:latest
WORKDIR /app
# Copy only the built binary and necessary directories
COPY --from=builder /app/bin/main ./bin/main
EXPOSE 8080
USER nonroot:nonroot
CMD ["./bin/main"]

View file

@ -9,39 +9,97 @@ A Fudge Dice rolling room programmed in Go
## Prerequisites
[![Go](https://img.shields.io/badge/go-%2300ADD8.svg?style=for-the-badge&logo=go&logoColor=white)](https://golang.org/dl/)
- The version of **Go** used to test the code in this repository is **1.25.3**.
- Go 1.25.3+ (only needed to build)
- Or just download a pre-built binary from Releases (when available)
## Get started
- run the following commands: `go mod tidy; go build -o bin/main ./app/gofudge/main.go` then `./bin/main` to start the server on port 8080.
### Quick start (from source)
```bash
git clone https://codeberg.org/riomoo/gofudge.git
cd gofudge
go build -o gofudge app/gofudge/main.go
./gofudge
```
- Visit http://localhost:8080 in your browser.
- Upon visiting the URL you will be created with a username entry and Create room button. After that you will be in the room.
- (If you are hosting this publicly) You can copy the room link in the top right hand corner and share it to anyone. They will be prompted to also pick a username.
- From there you may increase/decrease the modifier as needed for the skill you are rolling for.
### Podman/Docker
- If you want to use this with Docker, replace all `podman` commands in `run.sh` instances with `docker`
- Use `run.sh` script which will start the site on port `12007` and to make it public change the `8080` port in the NGINX config to `12007` or change the port in the `run.sh` script how you like.
- To use it locally, same as above but visit http://localhost:12007 instead.
## If you want to use this with podman:
```bash
git clone https://codeberg.org/riomoo/gofudge.git
cd gofudge
./scripts-bash/run.sh
```
Then open http://localhost:12007 in your browser.
## Config for NGINX to use as a website:
```
upstream gofudge {
server 127.0.0.1:8080;
#server 127.0.0.1:12007; #For Podman instead
server [::1]:8080;
#server [::1]:12007; #For Podman instead
}
server {
listen 80;
listen [::1]:80;
server_name fudge.example.com;
location /ws {
proxy_pass http://gofudge;
proxy_http_version 1.1;
# WebSocket upgrade headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket timeout settings (increase for long-lived connections)
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
# Disable buffering for WebSocket
proxy_buffering off;
# Security headers
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
}
location / {
proxy_pass http://gofudge;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Connection keep-alive for better performance
proxy_http_version 1.1;
proxy_set_header Connection "";
# Timeouts optimized for your simple site
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
# Enable buffering for better compression
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# Security headers
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
}
}
```
@ -51,6 +109,7 @@ server {
## Software Used but not included
![Arch](https://img.shields.io/badge/Arch%20Linux-1793D1?logo=arch-linux&logoColor=fff&style=for-the-badge)
![Podman](https://img.shields.io/badge/-Podman-892CA0?style=flat-square&logo=podman&logoColor=white)
![Vim](https://img.shields.io/badge/VIM-%2311AB00.svg?style=for-the-badge&logo=vim&logoColor=white)
![Git](https://img.shields.io/badge/git-%23F05033.svg?style=for-the-badge&logo=git&logoColor=white)
![Forgejo](https://img.shields.io/badge/forgejo-%23FB923C.svg?style=for-the-badge&logo=forgejo&logoColor=white)

View file

@ -507,8 +507,12 @@ func handleRoom(w http.ResponseWriter, r *http.Request) {
<div class="roll-section">
<h2 style="margin-bottom: 15px;">Roll Dice</h2>
<div class="roll-controls">
<input type="number" id="modifier" placeholder="Modifier (±)" value="0">
<button onclick="rollDice()">Roll Fuge Dice</button>
<div style="display: flex; gap: 5px; align-items: center;">
<button onclick="adjustModifier(-1)" style="flex: 0 0 40px; padding: 10px;"></button>
<input type="text" id="modifier" class="modifier-input" placeholder="Modifier (±)" value="0" style="flex: 0 0 100px;">
<button onclick="adjustModifier(1)" style="flex: 0 0 40px; padding: 10px; margin: 5px 15px 5px 5px;">+</button>
</div>
<button onclick="rollDice()">Roll Fudge Dice</button>
</div>
</div>
@ -525,7 +529,7 @@ func handleRoom(w http.ResponseWriter, r *http.Request) {
<script>
const roomId = '{{.RoomID}}';
const username = '{{.Username}}';
const ws = new WebSocket('ws://' + window.location.host + '/ws?room=' + roomId + '&username=' + encodeURIComponent(username));
const ws = new WebSocket((window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host + '/ws?room=' + roomId + '&username=' + encodeURIComponent(username));
document.getElementById('inviteLink').textContent = window.location.origin + '/room/' + roomId;
@ -533,6 +537,21 @@ func handleRoom(w http.ResponseWriter, r *http.Request) {
navigator.clipboard.writeText(window.location.origin + '/room/' + roomId);
alert('Invite link copied!');
}
function adjustModifier(amount) {
const input = document.getElementById('modifier');
const currentValue = parseInt(input.value) || 0;
input.value = currentValue + amount;
}
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('modifier').addEventListener('input', function(e) {
// Allow empty, minus sign, and numbers
if (e.target.value !== '' && e.target.value !== '-' && isNaN(parseInt(e.target.value))) {
e.target.value = e.target.value.slice(0, -1);
}
});
});
ws.onmessage = function(event) {
const msg = JSON.parse(event.data);