feat: add Docker Compose deployment and serve assets via StaticFS
Embed full assets directory and serve with via's StaticFS instead of a custom HTTP handler. Move SQLite DB to data/c4.db for clean volume mounting. Add multi-stage Dockerfile, docker-compose.yml, and .dockerignore.
This commit is contained in:
10
.dockerignore
Normal file
10
.dockerignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
c4
|
||||||
|
c4.db
|
||||||
|
data/
|
||||||
|
deploy/
|
||||||
|
.env
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
assets/css/output.css
|
||||||
|
c4-deploy-*.tar.gz
|
||||||
|
c4-deploy-*_b64*.txt
|
||||||
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
FROM golang:1.25.4-bookworm AS build
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN go tool gotailwind -i assets/css/input.css -o assets/css/output.css --minify
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /c4 .
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends ca-certificates wget && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY --from=build /c4 /usr/local/bin/c4
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
RUN mkdir data && chown games:games data
|
||||||
|
|
||||||
|
USER games
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
||||||
|
CMD wget -qO /dev/null http://localhost:8080/
|
||||||
|
|
||||||
|
CMD ["c4"]
|
||||||
17
docker-compose.yml
Normal file
17
docker-compose.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
services:
|
||||||
|
c4:
|
||||||
|
build: .
|
||||||
|
container_name: c4
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
- PORT=8080
|
||||||
|
volumes:
|
||||||
|
- c4-data:/app/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
c4-data:
|
||||||
25
main.go
25
main.go
@@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
_ "embed"
|
"embed"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -32,17 +32,14 @@ var (
|
|||||||
queries *gen.Queries
|
queries *gen.Queries
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed assets/css/output.css
|
//go:embed assets
|
||||||
var daisyUICSS []byte
|
var assets embed.FS
|
||||||
|
|
||||||
func DaisyUIPlugin(v *via.V) {
|
func DaisyUIPlugin(v *via.V) {
|
||||||
sum := md5.Sum(daisyUICSS)
|
css, _ := fs.ReadFile(assets, "assets/css/output.css")
|
||||||
|
sum := md5.Sum(css)
|
||||||
version := hex.EncodeToString(sum[:4])
|
version := hex.EncodeToString(sum[:4])
|
||||||
v.HTTPServeMux().HandleFunc("GET /_plugins/daisyui/style.css", func(w http.ResponseWriter, r *http.Request) {
|
v.AppendToHead(h.Link(h.Rel("stylesheet"), h.Href("/assets/css/output.css?v="+version)))
|
||||||
w.Header().Set("Content-Type", "text/css")
|
|
||||||
_, _ = w.Write(daisyUICSS)
|
|
||||||
})
|
|
||||||
v.AppendToHead(h.Link(h.Rel("stylesheet"), h.Href("/_plugins/daisyui/style.css?v="+version)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func port() string {
|
func port() string {
|
||||||
@@ -55,7 +52,10 @@ func port() string {
|
|||||||
func main() {
|
func main() {
|
||||||
_ = godotenv.Load()
|
_ = godotenv.Load()
|
||||||
|
|
||||||
if err := db.Init("c4.db"); err != nil {
|
if err := os.MkdirAll("data", 0o755); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := db.Init("data/c4.db"); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
queries = gen.New(db.DB)
|
queries = gen.New(db.DB)
|
||||||
@@ -76,6 +76,9 @@ func main() {
|
|||||||
Plugins: []via.Plugin{DaisyUIPlugin},
|
Plugins: []via.Plugin{DaisyUIPlugin},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
subFS, _ := fs.Sub(assets, "assets")
|
||||||
|
v.StaticFS("/assets/", subFS)
|
||||||
|
|
||||||
store.SetPubSub(v.PubSub())
|
store.SetPubSub(v.PubSub())
|
||||||
snakeStore.SetPubSub(v.PubSub())
|
snakeStore.SetPubSub(v.PubSub())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user