Test für Git AutoClone
All checks were successful
release-tag / release-image (push) Successful in 2m14s

This commit is contained in:
2025-05-11 16:16:52 +02:00
parent 4c41bb8838
commit ca22dd8596
3 changed files with 225 additions and 4 deletions

View File

@@ -41,7 +41,7 @@ FROM debian:bookworm-slim
# (optional) MySQLClient für später # (optional) MySQLClient für später
RUN apt-get update && apt-get install -y --no-install-recommends \ RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \ ca-certificates git \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# ─── Binärdatei ───── # ─── Binärdatei ─────
@@ -60,6 +60,11 @@ ENV BLOG_STATIC_DIR=/static
ENV BLOG_PAGES_DIR=/pages ENV BLOG_PAGES_DIR=/pages
ENV BLOG_TEMPLATES_DIR=/templates ENV BLOG_TEMPLATES_DIR=/templates
ENV BLOG_TICKS_DIR=/ticks ENV BLOG_TICKS_DIR=/ticks
ENV GIT_ENABLE=false
ENV GIT_REPO=null
ENV GIT_BRANCH=main
ENV GIT_DIR=/git-temp
ENV GIT_INTERVAL=10
EXPOSE 8080 EXPOSE 8080
CMD ["blog"] CMD ["blog"]

41
Dockerfile_Slim Normal file
View File

@@ -0,0 +1,41 @@
############################
# 1) GoBuild
############################
FROM golang:1.23.1 AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /blog ./cmd/blog
############################
# 3) RuntimeImage
############################
FROM debian:bookworm-slim
# (optional) MySQLClient für später
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
# ─── Binärdatei ─────
COPY --from=build /blog /usr/local/bin/blog
# ─── Content + Assets ───
RUN mkdir -p /content /static /pages /app /templates /ticks /git-temp
COPY . /app
ENV BLOG_CONTENT_DIR=/content
ENV BLOG_STATIC_DIR=/static
ENV BLOG_PAGES_DIR=/pages
ENV BLOG_TEMPLATES_DIR=/templates
ENV BLOG_TICKS_DIR=/ticks
ENV GIT_ENABLE=false
ENV GIT_REPO=null
ENV GIT_BRANCH=main
ENV GIT_DIR=/git-temp
ENV GIT_INTERVAL=10
EXPOSE 8080
CMD ["blog"]

View File

@@ -4,9 +4,12 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"html/template" "html/template"
"io"
"net/http" "net/http"
"os" "os"
"os/exec"
"os/signal" "os/signal"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@@ -93,6 +96,8 @@ var (
tplArticle *template.Template tplArticle *template.Template
) )
var Xarticles []article.Article
func main() { func main() {
// Signal-Kanal einrichten // Signal-Kanal einrichten
@@ -113,6 +118,11 @@ func main() {
pagesDir := getenv("BLOG_PAGES_DIR", "/pages") pagesDir := getenv("BLOG_PAGES_DIR", "/pages")
templatesDir := getenv("BLOG_TEMPLATES_DIR", "/templates") templatesDir := getenv("BLOG_TEMPLATES_DIR", "/templates")
ticksDir := getenv("BLOG_TICKS_DIR", "/ticks") ticksDir := getenv("BLOG_TICKS_DIR", "/ticks")
gitEnable := enabled("GIT_ENABLE", false)
gitRepo := getenv("GIT_REPO", "null")
gitBranch := getenv("GIT_BRANCH", "main")
gitDir := getenv("GIT_DIR", "/git-temp")
gitInterval := getenv("GIT_INTERVAL", "10")
TickCatalog = nil TickCatalog = nil
if err := LoadTickCatalog(ticksDir + "/ticks.json"); err != nil { if err := LoadTickCatalog(ticksDir + "/ticks.json"); err != nil {
@@ -146,6 +156,8 @@ func main() {
fmt.Println(err) fmt.Println(err)
} }
Xarticles = articles
staticPages, err := article.LoadStatic(pagesDir) staticPages, err := article.LoadStatic(pagesDir)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@@ -206,9 +218,13 @@ func main() {
} }
}) })
mux.Handle("/static/", mux.Handle("/static/", cacheControl(http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir)))))
cacheControl(http.StripPrefix("/static/",
http.FileServer(http.Dir(staticDir))))) if gitEnable {
xMinute, _ := strconv.Atoi(gitInterval)
xDuration := time.Duration(xMinute) * time.Minute
startAutoClone(gitRepo, gitBranch, gitDir, xDuration)
}
StopServer(http.ListenAndServe(":8080", mux)) StopServer(http.ListenAndServe(":8080", mux))
@@ -228,3 +244,162 @@ func StopServer(e error) {
prepareExit() prepareExit()
fmt.Println("~", "Server stopped!") fmt.Println("~", "Server stopped!")
} }
func cloneRepo(repoURL, branch, dir string) {
fmt.Printf("Starte Klonvorgang für Branch '%s'...\n", branch)
// Verzeichnis löschen
if err := os.RemoveAll(dir); err != nil {
fmt.Println("Fehler beim Löschen des Verzeichnisses:", err)
return
}
// Git-Clone mit Branch
cmd := exec.Command("git", "clone", "--branch", branch, "--single-branch", repoURL, dir)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Println("Fehler beim Klonen:", err)
} else {
fmt.Println("Repo erfolgreich geklont.")
}
contentDir := getenv("BLOG_CONTENT_DIR", "/content")
articles, err := article.LoadDir(contentDir)
if err != nil {
fmt.Println(err)
}
err = os.Remove("/content")
if err != nil {
fmt.Println(err, "/content")
}
err = os.Remove("/static")
if err != nil {
fmt.Println(err, "/static")
}
err = os.Remove("/pages")
if err != nil {
fmt.Println(err, "/pages")
}
err = os.Remove("/templates")
if err != nil {
fmt.Println(err, "/templates")
}
if err := os.MkdirAll("/content", 0755); err != nil {
fmt.Println("Fehler beim Erstellen des Zielordners:", err)
return
}
if err := os.MkdirAll("/static", 0755); err != nil {
fmt.Println("Fehler beim Erstellen des Zielordners:", err)
return
}
if err := os.MkdirAll("/pages", 0755); err != nil {
fmt.Println("Fehler beim Erstellen des Zielordners:", err)
return
}
if err := os.MkdirAll("/templates", 0755); err != nil {
fmt.Println("Fehler beim Erstellen des Zielordners:", err)
return
}
if err := copyDirContents("/git-temp/content", "/content"); err != nil {
fmt.Println("Fehler beim Kopieren:", err)
} else {
fmt.Println("Kopieren abgeschlossen.")
}
if err := copyDirContents("/git-temp/static", "/static"); err != nil {
fmt.Println("Fehler beim Kopieren:", err)
} else {
fmt.Println("Kopieren abgeschlossen.")
}
if err := copyDirContents("/git-temp/pages", "/pages"); err != nil {
fmt.Println("Fehler beim Kopieren:", err)
} else {
fmt.Println("Kopieren abgeschlossen.")
}
if err := copyDirContents("/git-temp/templates", "/templates"); err != nil {
fmt.Println("Fehler beim Kopieren:", err)
} else {
fmt.Println("Kopieren abgeschlossen.")
}
Xarticles = articles
}
func copyDirContents(srcDir, destDir string) error {
entries, err := os.ReadDir(srcDir)
if err != nil {
return fmt.Errorf("Fehler beim Lesen von %s: %w", srcDir, err)
}
for _, entry := range entries {
srcPath := filepath.Join(srcDir, entry.Name())
destPath := filepath.Join(destDir, entry.Name())
info, err := entry.Info()
if err != nil {
return err
}
if info.IsDir() {
if err := os.MkdirAll(destPath, info.Mode()); err != nil {
return fmt.Errorf("Fehler beim Erstellen von Ordner %s: %w", destPath, err)
}
// rekursiv kopieren
if err := copyDirContents(srcPath, destPath); err != nil {
return err
}
} else {
if err := copyFile(srcPath, destPath, info); err != nil {
return err
}
}
}
return nil
}
func copyFile(src, dest string, info os.FileInfo) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dest)
if err != nil {
return err
}
defer out.Close()
if _, err := io.Copy(out, in); err != nil {
return err
}
return os.Chmod(dest, info.Mode())
}
func startAutoClone(repoURL, branch, dir string, interval time.Duration) {
go cloneRepo(repoURL, branch, dir) // sofortiger Start
ticker := time.NewTicker(interval)
defer ticker.Stop()
for range ticker.C {
go cloneRepo(repoURL, branch, dir)
}
}