Merge pull request 'staging' (#10) from staging into main
All checks were successful
release-tag / release-image (push) Successful in 2m21s
All checks were successful
release-tag / release-image (push) Successful in 2m21s
Reviewed-on: #10
This commit is contained in:
@@ -41,7 +41,7 @@ FROM debian:bookworm-slim
|
||||
|
||||
# (optional) MySQL‑Client für später
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
ca-certificates git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ─── Binärdatei ─────
|
||||
@@ -60,6 +60,11 @@ 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"]
|
||||
|
41
Dockerfile_Slim
Normal file
41
Dockerfile_Slim
Normal file
@@ -0,0 +1,41 @@
|
||||
############################
|
||||
# 1) Go‑Build
|
||||
############################
|
||||
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) Runtime‑Image
|
||||
############################
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
# (optional) MySQL‑Client 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"]
|
189
cmd/blog/main.go
189
cmd/blog/main.go
@@ -4,9 +4,12 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -93,6 +96,8 @@ var (
|
||||
tplArticle *template.Template
|
||||
)
|
||||
|
||||
var Xarticles []article.Article
|
||||
|
||||
func main() {
|
||||
|
||||
// Signal-Kanal einrichten
|
||||
@@ -113,6 +118,11 @@ func main() {
|
||||
pagesDir := getenv("BLOG_PAGES_DIR", "/pages")
|
||||
templatesDir := getenv("BLOG_TEMPLATES_DIR", "/templates")
|
||||
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
|
||||
if err := LoadTickCatalog(ticksDir + "/ticks.json"); err != nil {
|
||||
@@ -146,6 +156,8 @@ func main() {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
Xarticles = articles
|
||||
|
||||
staticPages, err := article.LoadStatic(pagesDir)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -162,8 +174,8 @@ func main() {
|
||||
|
||||
/* */
|
||||
|
||||
for a, b := range articles {
|
||||
articles[a].Counter = getTick(b.Slug)
|
||||
for a, b := range Xarticles {
|
||||
Xarticles[a].Counter = getTick(b.Slug)
|
||||
}
|
||||
|
||||
/* */
|
||||
@@ -171,7 +183,7 @@ func main() {
|
||||
if err := tplList.ExecuteTemplate(w, "layout", article.ListPage{
|
||||
Title: "Startseite",
|
||||
Description: "Alle Artikel im Überblick",
|
||||
Articles: articles,
|
||||
Articles: Xarticles,
|
||||
}); err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
}
|
||||
@@ -179,7 +191,7 @@ func main() {
|
||||
|
||||
mux.HandleFunc("/post/", func(w http.ResponseWriter, r *http.Request) {
|
||||
slug := strings.TrimPrefix(r.URL.Path, "/post/")
|
||||
for _, a := range articles {
|
||||
for _, a := range Xarticles {
|
||||
if a.Slug == slug {
|
||||
IncTick(slug)
|
||||
t := getTick(slug)
|
||||
@@ -206,9 +218,13 @@ func main() {
|
||||
}
|
||||
})
|
||||
|
||||
mux.Handle("/static/",
|
||||
cacheControl(http.StripPrefix("/static/",
|
||||
http.FileServer(http.Dir(staticDir)))))
|
||||
mux.Handle("/static/", cacheControl(http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir)))))
|
||||
|
||||
if gitEnable {
|
||||
xMinute, _ := strconv.Atoi(gitInterval)
|
||||
xDuration := time.Duration(xMinute) * time.Minute
|
||||
go startAutoClone(gitRepo, gitBranch, gitDir, xDuration)
|
||||
}
|
||||
|
||||
StopServer(http.ListenAndServe(":8080", mux))
|
||||
|
||||
@@ -228,3 +244,162 @@ func StopServer(e error) {
|
||||
prepareExit()
|
||||
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")
|
||||
|
||||
err := os.RemoveAll("/content")
|
||||
if err != nil {
|
||||
fmt.Println(err, "/content")
|
||||
}
|
||||
|
||||
err = os.RemoveAll("/static")
|
||||
if err != nil {
|
||||
fmt.Println(err, "/static")
|
||||
}
|
||||
|
||||
err = os.RemoveAll("/pages")
|
||||
if err != nil {
|
||||
fmt.Println(err, "/pages")
|
||||
}
|
||||
|
||||
err = os.RemoveAll("/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/articles", "/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.")
|
||||
}
|
||||
|
||||
articles, err := article.LoadDir(contentDir)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user