mirror of
https://github.com/HexCardGames/HexDeck.git
synced 2025-09-03 18:48:38 +02:00
Merge branch 'dev' into feature/game-view
This commit is contained in:
20
Dockerfile
Normal file
20
Dockerfile
Normal file
@ -0,0 +1,20 @@
|
||||
FROM node:23-alpine AS frontend
|
||||
WORKDIR /frontend
|
||||
COPY frontend/package*.json /frontend
|
||||
RUN npm ci
|
||||
RUN npm i @tailwindcss/oxide-linux-x64-musl
|
||||
COPY frontend/ /frontend
|
||||
RUN npm run build
|
||||
|
||||
FROM golang:1.24-alpine AS backend
|
||||
WORKDIR /backend
|
||||
COPY backend/go.* /backend/
|
||||
RUN go mod download
|
||||
COPY backend/ /backend
|
||||
COPY --from=frontend /frontend/dist/client/ /backend/public/
|
||||
RUN go build -o HexDeck
|
||||
|
||||
FROM scratch
|
||||
WORKDIR /app
|
||||
COPY --from=backend /backend/HexDeck .
|
||||
CMD ["/app/HexDeck"]
|
1
backend/.dockerignore
Normal file
1
backend/.dockerignore
Normal file
@ -0,0 +1 @@
|
||||
HexDeck
|
@ -1,16 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/HexCardGames/HexDeck/db"
|
||||
"github.com/HexCardGames/HexDeck/game"
|
||||
"github.com/HexCardGames/HexDeck/types"
|
||||
"github.com/HexCardGames/HexDeck/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@ -37,10 +33,7 @@ type LeaveRoomRequest struct {
|
||||
SessionToken string
|
||||
}
|
||||
|
||||
func InitApi() {
|
||||
server := gin.Default()
|
||||
server.SetTrustedProxies(nil)
|
||||
|
||||
func RegisterApi(server *gin.Engine) {
|
||||
server.GET("/api/stats", func(c *gin.Context) {
|
||||
stats := game.CalculateStats()
|
||||
c.JSON(http.StatusOK, StatsReply{
|
||||
@ -142,12 +135,4 @@ func InitApi() {
|
||||
// Handle WebSocket connections using Socket.io
|
||||
wsHandler := initWS()
|
||||
server.Any("/socket.io/", gin.WrapH(wsHandler))
|
||||
|
||||
listenHost := utils.Getenv("LISTEN_HOST", "0.0.0.0")
|
||||
listenPort, err := strconv.Atoi(utils.Getenv("LISTEN_PORT", "3000"))
|
||||
if err != nil {
|
||||
log.Fatal("Value of variable PORT is not a valid integer!")
|
||||
}
|
||||
slog.Info(fmt.Sprintf("HexDeck server listening on http://%s:%d", listenHost, listenPort))
|
||||
server.Run(fmt.Sprintf("%s:%d", listenHost, listenPort))
|
||||
}
|
||||
|
26
backend/api/static.go
Normal file
26
backend/api/static.go
Normal file
@ -0,0 +1,26 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func SPAMiddleware(fs embed.FS, prefix string, notFoundPath string) gin.HandlerFunc {
|
||||
fileServer := http.FileServerFS(fs)
|
||||
|
||||
return func(c *gin.Context) {
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/api/") {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
c.Request.URL.Path = prefix + c.Request.URL.Path
|
||||
_, err := fs.Open(c.Request.URL.Path)
|
||||
if err != nil {
|
||||
c.Request.URL.Path = prefix + notFoundPath
|
||||
}
|
||||
fileServer.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
@ -70,13 +70,22 @@ func (conn *DatabaseConnection) QueryGlobalStats() GlobalStatsCollection {
|
||||
return stats
|
||||
}
|
||||
|
||||
func CreateDBConnection(uri string) DatabaseConnection {
|
||||
client, _ := mongo.Connect(options.Client().ApplyURI(uri))
|
||||
return DatabaseConnection{client}
|
||||
func CreateDBConnection(uri string) *DatabaseConnection {
|
||||
client, err := mongo.Connect(options.Client().ApplyURI(uri))
|
||||
if err != nil {
|
||||
slog.Error("MongoDB connection failed", "error", err)
|
||||
return nil
|
||||
}
|
||||
return &DatabaseConnection{client}
|
||||
}
|
||||
|
||||
var Conn DatabaseConnection
|
||||
|
||||
func InitDB(uri string) {
|
||||
Conn = CreateDBConnection(uri)
|
||||
func InitDB(uri string) bool {
|
||||
dbConn := CreateDBConnection(uri)
|
||||
if dbConn == nil {
|
||||
return false
|
||||
}
|
||||
Conn = *dbConn
|
||||
return true
|
||||
}
|
||||
|
@ -1,16 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/HexCardGames/HexDeck/api"
|
||||
"github.com/HexCardGames/HexDeck/db"
|
||||
"github.com/HexCardGames/HexDeck/game"
|
||||
"github.com/HexCardGames/HexDeck/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
//go:embed all:public/*
|
||||
var public embed.FS
|
||||
|
||||
func main() {
|
||||
logHandler := slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
|
||||
Level: slog.LevelDebug,
|
||||
@ -22,7 +30,11 @@ func main() {
|
||||
slog.Error("MONGO_URI environment variable not set!")
|
||||
return
|
||||
}
|
||||
db.InitDB(mongoUri)
|
||||
ok := db.InitDB(mongoUri)
|
||||
if !ok {
|
||||
slog.Error("Initializing MongoDB database failed")
|
||||
return
|
||||
}
|
||||
game.LoadRooms()
|
||||
|
||||
roomTicker := time.NewTicker(1 * time.Second)
|
||||
@ -35,5 +47,17 @@ func main() {
|
||||
}
|
||||
}()
|
||||
|
||||
api.InitApi()
|
||||
server := gin.Default()
|
||||
server.SetTrustedProxies(nil)
|
||||
|
||||
api.RegisterApi(server)
|
||||
server.Use(api.SPAMiddleware(public, "public", "/"))
|
||||
|
||||
listenHost := utils.Getenv("LISTEN_HOST", "0.0.0.0")
|
||||
listenPort, err := strconv.Atoi(utils.Getenv("LISTEN_PORT", "3000"))
|
||||
if err != nil {
|
||||
log.Fatal("Value of variable PORT is not a valid integer!")
|
||||
}
|
||||
slog.Info(fmt.Sprintf("HexDeck server listening on http://%s:%d", listenHost, listenPort))
|
||||
server.Run(fmt.Sprintf("%s:%d", listenHost, listenPort))
|
||||
}
|
||||
|
7
backend/public/README.md
Normal file
7
backend/public/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Static Frontend Hosting
|
||||
|
||||
All files in this directory will be merged into the server binary and served as static assets by the HexDeck server.
|
||||
|
||||
When building with docker, the compiled frontend will be copied here automatically.
|
||||
|
||||
If you are building manually, you can copy the contents of the `dist/client/` folder here after building the frontend.
|
16
docker-compose.yml
Normal file
16
docker-compose.yml
Normal file
@ -0,0 +1,16 @@
|
||||
services:
|
||||
mongodb:
|
||||
user: "1000"
|
||||
volumes:
|
||||
- ./data/mongodb/:/data/db/
|
||||
image: mongodb/mongodb-community-server:latest
|
||||
command: mongod --bind_ip_all
|
||||
hexdeck:
|
||||
user: "1000"
|
||||
ports:
|
||||
- 3000:3000
|
||||
environment:
|
||||
- MONGO_URI=mongodb://mongodb:27017/
|
||||
depends_on:
|
||||
- mongodb
|
||||
build: .
|
26
frontend/.dockerignore
Normal file
26
frontend/.dockerignore
Normal file
@ -0,0 +1,26 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
.routify/*
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
Reference in New Issue
Block a user