feat: Initial setup for LaTeX Docker Builder
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
.git
|
||||
.gitignore
|
||||
*.md
|
||||
docker-compose.yml
|
||||
build-seminar.ps1
|
||||
build-seminar.sh
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
# OS-Dateien
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
|
||||
# LaTeX temporäre Dateien (falls hier getestet)
|
||||
*.aux
|
||||
*.bbl
|
||||
*.bcf
|
||||
*.blg
|
||||
*.fdb_latexmk
|
||||
*.fls
|
||||
*.log
|
||||
*.out
|
||||
*.run.xml
|
||||
*.synctex.gz
|
||||
*.toc
|
||||
out/
|
||||
|
||||
# Lokale Overrides / ENV
|
||||
.env
|
||||
.env.local
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
# ==============================================================================
|
||||
# LaTeX Docker Builder
|
||||
# Repository: https://git.djnizz.at/Nizz05/latex-docker.git
|
||||
# Basis: TeX Live Full (inkl. latexmk, biber, biblatex, koma-script, tikz etc.)
|
||||
# ==============================================================================
|
||||
|
||||
FROM texlive/texlive:latest
|
||||
|
||||
LABEL org.opencontainers.image.title="LaTeX Docker Builder" \
|
||||
org.opencontainers.image.description="Docker Image zum Kompilieren von LaTeX-Dokumenten (Seminararbeit, Thesis) mit latexmk & biber" \
|
||||
org.opencontainers.image.source="https://git.djnizz.at/Nizz05/latex-docker" \
|
||||
maintainer="Nizz05"
|
||||
|
||||
# Arbeitsverzeichnis für das gemountete Projekt
|
||||
WORKDIR /workspace
|
||||
|
||||
# Entrypoint-Skript kopieren und ausführbar machen
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
CMD ["build"]
|
||||
@@ -0,0 +1,34 @@
|
||||
IMAGE ?= latex-docker:latest
|
||||
REMOTE_IMAGE ?= git.djnizz.at/nizz05/latex-docker:latest
|
||||
PROJECT_DIR ?= $(CURDIR)/../Seminar_Arbeit_BITI_Gruber
|
||||
|
||||
.PHONY: all build clean watch image push shell help
|
||||
|
||||
all: build
|
||||
|
||||
help:
|
||||
@echo "Verfügbare Befehle:"
|
||||
@echo " make image - Baut das Docker-Image ($(IMAGE))"
|
||||
@echo " make build - Kompiliert die Seminararbeit im Container"
|
||||
@echo " make clean - Bereinigt temporäre LaTeX-Dateien (latexmk -C)"
|
||||
@echo " make watch - Startet kontinuierlichen Watch-Modus"
|
||||
@echo " make shell - Öffnet eine interaktive Bash-Shell im Container"
|
||||
@echo " make push - Pusht das Image zum Remote Registry ($(REMOTE_IMAGE))"
|
||||
|
||||
image:
|
||||
docker build -t $(IMAGE) -t $(REMOTE_IMAGE) .
|
||||
|
||||
build:
|
||||
docker run --rm -v "$(PROJECT_DIR):/workspace" -w /workspace $(IMAGE) build
|
||||
|
||||
clean:
|
||||
docker run --rm -v "$(PROJECT_DIR):/workspace" -w /workspace $(IMAGE) clean
|
||||
|
||||
watch:
|
||||
docker run --rm -it -v "$(PROJECT_DIR):/workspace" -w /workspace $(IMAGE) watch
|
||||
|
||||
shell:
|
||||
docker run --rm -it -v "$(PROJECT_DIR):/workspace" -w /workspace $(IMAGE) bash
|
||||
|
||||
push:
|
||||
docker push $(REMOTE_IMAGE)
|
||||
@@ -0,0 +1,181 @@
|
||||
# LaTeX Docker Builder
|
||||
|
||||
Docker-Image und Build-Umgebung zum plattformunabhängigen, reproduzierbaren Kompilieren von LaTeX-Dokumenten (wie der Seminararbeit oder Masterthesis an der Fachhochschule Burgenland).
|
||||
|
||||
- **Git-Repository:** [https://git.djnizz.at/Nizz05/latex-docker.git](https://git.djnizz.at/Nizz05/latex-docker.git)
|
||||
- **Basis-Image:** `texlive/texlive:latest` (Vollständige TeX Live Distribution inkl. `latexmk`, `biber`, `biblatex`, `koma-script`, `mathpazo`, `tikz` etc.)
|
||||
|
||||
---
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
|
||||
- [Voraussetzungen](#voraussetzungen)
|
||||
- [Schnellstart](#schnellstart)
|
||||
- [1. PowerShell (Windows)](#1-powershell-windows)
|
||||
- [2. Bash / Linux / macOS / WSL](#2-bash--linux--macos--wsl)
|
||||
- [3. Docker Compose](#3-docker-compose)
|
||||
- [4. Reines Docker CLI](#4-reines-docker-cli)
|
||||
- [5. Makefile](#5-makefile)
|
||||
- [Image selbst bauen](#image-selbst-bauen)
|
||||
- [Git Remote & Image Registry](#git-remote--image-registry)
|
||||
- [Code ins Git-Repo pushen](#code-ins-git-repo-pushen)
|
||||
- [Image zur Registry pushen (optional)](#image-zur-registry-pushen-optional)
|
||||
- [Beispiel für CI/CD (Gitea Actions / Woodpecker)](#beispiel-f%C3%BCr-cicd-gitea-actions--woodpecker)
|
||||
|
||||
---
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) (oder Docker Engine unter Linux) läuft auf Ihrem System.
|
||||
- Keine lokale TeX-Live- oder MiKTeX-Installation auf dem Host erforderlich!
|
||||
|
||||
---
|
||||
|
||||
## Schnellstart
|
||||
|
||||
### 1. PowerShell (Windows)
|
||||
|
||||
Das mitgelieferte Skript `build-seminar.ps1` vereinfacht alle Abläufe:
|
||||
|
||||
```powershell
|
||||
# Seminararbeit kompilieren
|
||||
.\build-seminar.ps1
|
||||
|
||||
# Bereinigen (löscht temporäre Dateien im out/-Ordner)
|
||||
.\build-seminar.ps1 -Clean
|
||||
|
||||
# Kontinuierlicher Watch-Modus (baut bei jeder Dateiänderung neu)
|
||||
.\build-seminar.ps1 -Watch
|
||||
|
||||
# Anderes Dokument kompilieren
|
||||
.\build-seminar.ps1 -File "meinDokument.tex"
|
||||
```
|
||||
|
||||
### 2. Bash / Linux / macOS / WSL
|
||||
|
||||
```bash
|
||||
# Ausführbar machen
|
||||
chmod +x build-seminar.sh
|
||||
|
||||
# Kompilieren
|
||||
./build-seminar.sh
|
||||
|
||||
# Bereinigen
|
||||
./build-seminar.sh ../Seminar_Arbeit_BITI_Gruber clean
|
||||
|
||||
# Watch-Modus
|
||||
./build-seminar.sh ../Seminar_Arbeit_BITI_Gruber watch
|
||||
```
|
||||
|
||||
### 3. Docker Compose
|
||||
|
||||
```bash
|
||||
# Bauen
|
||||
docker compose run --rm builder
|
||||
|
||||
# Bereinigen
|
||||
docker compose run --rm clean
|
||||
|
||||
# Watch-Modus
|
||||
docker compose run --rm watch
|
||||
```
|
||||
|
||||
### 4. Reines Docker CLI
|
||||
|
||||
Direkt ohne Hilfsskripte:
|
||||
|
||||
```bash
|
||||
# Windows PowerShell:
|
||||
docker run --rm -v "${PWD}/../Seminar_Arbeit_BITI_Gruber:/workspace" -w /workspace latex-docker:latest
|
||||
|
||||
# Linux / macOS / WSL:
|
||||
docker run --rm -v "$(pwd)/../Seminar_Arbeit_BITI_Gruber:/workspace" -w /workspace latex-docker:latest
|
||||
```
|
||||
|
||||
Beliebige LaTeX-Befehle übergeben:
|
||||
|
||||
```bash
|
||||
# Bereinigen
|
||||
docker run --rm -v "${PWD}/../Seminar_Arbeit_BITI_Gruber:/workspace" latex-docker:latest clean
|
||||
|
||||
# Spezifischen latexmk-Befehl ausführen
|
||||
docker run --rm -v "${PWD}/../Seminar_Arbeit_BITI_Gruber:/workspace" latex-docker:latest latexmk -pdf seminararbeit.tex
|
||||
```
|
||||
|
||||
### 5. Makefile
|
||||
|
||||
```bash
|
||||
make image # Image bauen
|
||||
make build # Seminararbeit kompilieren
|
||||
make clean # Temporäre Dateien löschen
|
||||
make watch # Kontinuierlich bauen
|
||||
make shell # Interaktive Bash-Shell im Container öffnen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Image selbst bauen
|
||||
|
||||
Das Image lokal bauen und mit Tags versehen:
|
||||
|
||||
```bash
|
||||
docker build -t latex-docker:latest -t git.djnizz.at/nizz05/latex-docker:latest .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Git Remote & Image Registry
|
||||
|
||||
### Code ins Git-Repo pushen
|
||||
|
||||
Der Ordner ist bereits mit der Remote-URL `https://git.djnizz.at/Nizz05/latex-docker.git` verknüpft:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: Initial commit of latex docker builder environment"
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
### Image zur Registry pushen (optional)
|
||||
|
||||
Falls Ihre Gitea/Forgejo-Instanz die Docker-Container-Registry aktiviert hat:
|
||||
|
||||
```bash
|
||||
docker login git.djnizz.at
|
||||
docker push git.djnizz.at/nizz05/latex-docker:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Beispiel für CI/CD (Gitea Actions / Woodpecker)
|
||||
|
||||
### Gitea / GitHub Actions (`.gitea/workflows/build.yml`)
|
||||
|
||||
```yaml
|
||||
name: Build Seminararbeit
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: texlive/texlive:latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Compile LaTeX
|
||||
run: |
|
||||
latexmk -pdf seminararbeit.tex
|
||||
|
||||
- name: Upload PDF Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: seminararbeit-pdf
|
||||
path: out/seminararbeit.pdf
|
||||
```
|
||||
@@ -0,0 +1,113 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Kompiliert die Seminararbeit mithilfe des LaTeX Docker Containers.
|
||||
.DESCRIPTION
|
||||
Skript zum bequemen Bauen, Säubern oder Überwachen der LaTeX-Seminararbeit via Docker.
|
||||
.PARAMETER Clean
|
||||
Führt ein 'clean' durch (latexmk -C), um temporäre Build-Dateien zu löschen.
|
||||
.PARAMETER Watch
|
||||
Startet den kontinuierlichen Überwachungsmodus (latexmk -pvc).
|
||||
.PARAMETER RebuildImage
|
||||
Erzwingt das erneute Erstellen des Docker-Images vor dem LaTeX-Build.
|
||||
.PARAMETER ProjectPath
|
||||
Pfad zum LaTeX-Projektverzeichnis (Standard: '../Seminar_Arbeit_BITI_Gruber').
|
||||
.PARAMETER File
|
||||
Spezifische LaTeX-Datei zum Kompilieren (Standard: 'seminararbeit.tex').
|
||||
.EXAMPLE
|
||||
.\build-seminar.ps1
|
||||
.EXAMPLE
|
||||
.\build-seminar.ps1 -Clean
|
||||
.EXAMPLE
|
||||
.\build-seminar.ps1 -Watch
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[switch]$Clean,
|
||||
[switch]$Watch,
|
||||
[switch]$RebuildImage,
|
||||
[string]$ProjectPath = "",
|
||||
[string]$File = "seminararbeit.tex"
|
||||
)
|
||||
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
if ([string]::IsNullOrWhiteSpace($ProjectPath)) {
|
||||
$ProjectPath = Join-Path $ScriptDir "..\Seminar_Arbeit_BITI_Gruber"
|
||||
} elseif (-not [System.IO.Path]::IsPathRooted($ProjectPath)) {
|
||||
$ProjectPath = Join-Path $ScriptDir $ProjectPath
|
||||
}
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Prüfen, ob Docker erreichbar ist
|
||||
$dockerCmd = Get-Command docker -ErrorAction SilentlyContinue
|
||||
if (-not $dockerCmd) {
|
||||
Write-Error "Docker ist nicht in PATH verfügbar."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$oldEAP = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
& docker info 2>&1 | Out-Null
|
||||
$dockerOk = ($LASTEXITCODE -eq 0)
|
||||
$ErrorActionPreference = $oldEAP
|
||||
|
||||
if (-not $dockerOk) {
|
||||
Write-Error "Docker Desktop ist anscheinend nicht gestartet oder nicht erreichbar."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$ImageName = "latex-docker:latest"
|
||||
$FullProjectPath = [System.IO.Path]::GetFullPath($ProjectPath)
|
||||
|
||||
if (-not (Test-Path $FullProjectPath)) {
|
||||
Write-Error "Projektverzeichnis existiert nicht: $FullProjectPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Image prüfen bzw. bauen
|
||||
$imageExists = docker images -q $ImageName
|
||||
if (-not $imageExists -or $RebuildImage) {
|
||||
Write-Host "==> Erstelle Docker Image '$ImageName'..." -ForegroundColor Cyan
|
||||
docker build -t $ImageName -t "git.djnizz.at/nizz05/latex-docker:latest" "$PSScriptRoot"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Docker Build fehlgeschlagen."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Befehl bestimmen
|
||||
$cmdArgs = @()
|
||||
if ($Clean) {
|
||||
Write-Host "==> Bereinige Projektverzeichnis: $FullProjectPath" -ForegroundColor Yellow
|
||||
$cmdArgs += "clean"
|
||||
} elseif ($Watch) {
|
||||
Write-Host "==> Starte Watch-Modus für: $File" -ForegroundColor Cyan
|
||||
$cmdArgs += "watch"
|
||||
$cmdArgs += $File
|
||||
} else {
|
||||
Write-Host "==> Kompiliere Seminararbeit: $File" -ForegroundColor Green
|
||||
$cmdArgs += "build"
|
||||
$cmdArgs += $File
|
||||
}
|
||||
|
||||
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
|
||||
docker run --rm -v "${FullProjectPath}:/workspace" -w /workspace $ImageName @cmdArgs
|
||||
|
||||
$stopwatch.Stop()
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
if (-not $Clean -and -not $Watch) {
|
||||
$pdfPath = Join-Path $FullProjectPath "out\seminararbeit.pdf"
|
||||
Write-Host "`n[OK] Build erfolgreich abgeschlossen in $([math]::Round($stopwatch.Elapsed.TotalSeconds, 1))s!" -ForegroundColor Green
|
||||
if (Test-Path $pdfPath) {
|
||||
$pdfItem = Get-Item $pdfPath
|
||||
Write-Host "PDF generiert: $pdfPath ($([math]::Round($pdfItem.Length / 1KB, 1)) KB)" -ForegroundColor Cyan
|
||||
}
|
||||
} else {
|
||||
Write-Host "`n[OK] Aktion erfolgreich beendet!" -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Error "`n[FEHLER] LaTeX Build ist fehlgeschlagen mit Exit Code $LASTEXITCODE."
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
# ==============================================================================
|
||||
# LaTeX Docker Build Skript (Bash / Linux / macOS / WSL)
|
||||
# ==============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="${1:-"${SCRIPT_DIR}/../Seminar_Arbeit_BITI_Gruber"}"
|
||||
IMAGE_NAME="latex-docker:latest"
|
||||
|
||||
ACTION="${2:-build}"
|
||||
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "Fehler: Docker ist nicht installiert oder nicht in PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJECT_FULL_PATH="$(cd "$PROJECT_DIR" && pwd)"
|
||||
|
||||
echo "==> Projektpfad: $PROJECT_FULL_PATH"
|
||||
echo "==> Aktion: $ACTION"
|
||||
|
||||
case "$ACTION" in
|
||||
clean)
|
||||
docker run --rm -v "${PROJECT_FULL_PATH}:/workspace" -w /workspace "$IMAGE_NAME" clean
|
||||
;;
|
||||
watch)
|
||||
docker run --rm -it -v "${PROJECT_FULL_PATH}:/workspace" -w /workspace "$IMAGE_NAME" watch
|
||||
;;
|
||||
build)
|
||||
docker run --rm -v "${PROJECT_FULL_PATH}:/workspace" -w /workspace "$IMAGE_NAME" build
|
||||
;;
|
||||
*)
|
||||
docker run --rm -v "${PROJECT_FULL_PATH}:/workspace" -w /workspace "$IMAGE_NAME" "$ACTION" "${@:3}"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "==> Fertig!"
|
||||
@@ -0,0 +1,27 @@
|
||||
services:
|
||||
builder:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: latex-docker:latest
|
||||
container_name: latex-docker-builder
|
||||
volumes:
|
||||
- ${PROJECT_DIR:-../Seminar_Arbeit_BITI_Gruber}:/workspace
|
||||
working_dir: /workspace
|
||||
command: ["build"]
|
||||
|
||||
# Dienst zum Aufräumen (docker compose run --rm clean)
|
||||
clean:
|
||||
image: latex-docker:latest
|
||||
volumes:
|
||||
- ${PROJECT_DIR:-../Seminar_Arbeit_BITI_Gruber}:/workspace
|
||||
working_dir: /workspace
|
||||
command: ["clean"]
|
||||
|
||||
# Dienst für kontinuierlichen Watch-Modus (docker compose run --rm watch)
|
||||
watch:
|
||||
image: latex-docker:latest
|
||||
volumes:
|
||||
- ${PROJECT_DIR:-../Seminar_Arbeit_BITI_Gruber}:/workspace
|
||||
working_dir: /workspace
|
||||
command: ["watch"]
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# LaTeX Docker Builder Entrypoint
|
||||
# Unterstützt Befehle:
|
||||
# build [datei.tex] (Standard: baut seminararbeit.tex oder main.tex)
|
||||
# clean (Führt latexmk -C aus)
|
||||
# watch [datei.tex] (Kontinuierlicher Rebuild mit latexmk -pvc)
|
||||
# Beliebiger Befehl (z.B. latexmk -pdf ...)
|
||||
|
||||
resolve_target() {
|
||||
if [ -n "$1" ]; then
|
||||
echo "$1"
|
||||
elif [ -f "seminararbeit.tex" ]; then
|
||||
echo "seminararbeit.tex"
|
||||
elif [ -f "main.tex" ]; then
|
||||
echo "main.tex"
|
||||
else
|
||||
# Fallback auf alle tex-Dateien oder Standard-latexmk-Verhalten
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
COMMAND="${1:-build}"
|
||||
|
||||
case "$COMMAND" in
|
||||
build)
|
||||
shift || true
|
||||
TARGET=$(resolve_target "$1")
|
||||
echo "==> Starte LaTeX Build..."
|
||||
if [ -n "$TARGET" ]; then
|
||||
echo "==> Kompiliere: $TARGET"
|
||||
exec latexmk -pdf "$TARGET"
|
||||
else
|
||||
echo "==> Keine Hauptdatei angegeben, führe latexmk -pdf aus..."
|
||||
exec latexmk -pdf
|
||||
fi
|
||||
;;
|
||||
|
||||
clean)
|
||||
shift || true
|
||||
echo "==> Bereinige Ausgabedateien (latexmk -C)..."
|
||||
exec latexmk -C "$@"
|
||||
;;
|
||||
|
||||
watch)
|
||||
shift || true
|
||||
TARGET=$(resolve_target "$1")
|
||||
echo "==> Starte kontinuierlichen Watch-Modus (latexmk -pvc)..."
|
||||
if [ -n "$TARGET" ]; then
|
||||
exec latexmk -pvc -pdf "$TARGET"
|
||||
else
|
||||
exec latexmk -pvc -pdf
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
exec "$@"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user