mirror of
https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
synced 2025-10-29 17:25:32 +00:00
+Docker
This commit is contained in:
11
.dockerignore
Normal file
11
.dockerignore
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
**/bin/
|
||||||
|
**/obj/
|
||||||
|
**/node_modules/
|
||||||
|
**/testdata/
|
||||||
|
**/.git/
|
||||||
|
**/.vscode/
|
||||||
|
**/.vs/
|
||||||
|
**/wwwroot/dist/
|
||||||
|
*.md
|
||||||
|
.gitignore
|
||||||
|
.editorconfig
|
||||||
128
DOCKER.md
Normal file
128
DOCKER.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# Docker Deployment for HaWeb
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### 1. Create the external volume
|
||||||
|
```bash
|
||||||
|
docker volume create hamann_data
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Set webhook secret (optional)
|
||||||
|
```bash
|
||||||
|
export WEBHOOK_SECRET="your-secret-here"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Build and run
|
||||||
|
```bash
|
||||||
|
docker-compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. View logs
|
||||||
|
```bash
|
||||||
|
docker-compose logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The application runs with the following defaults:
|
||||||
|
- **HTTP Port**: 5000
|
||||||
|
- **HTTPS Port**: 5001 (self-signed cert)
|
||||||
|
- **Data Path**: `/app/data` (mounted to `hamann_data` volume)
|
||||||
|
- **Repository**: https://github.com/Theodor-Springmann-Stiftung/hamann-xml
|
||||||
|
- **Branch**: main
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
Override in `docker-compose.yml` or set before running:
|
||||||
|
|
||||||
|
- `DOTNET_ENVIRONMENT`: `Production`, `Staging`, or `Development`
|
||||||
|
- `FileStoragePath`: Base path for data storage (default: `/app/data`)
|
||||||
|
- `RepositoryBranch`: Git branch to track
|
||||||
|
- `RepositoryURL`: Git repository URL
|
||||||
|
- `WebhookSecret`: GitHub webhook secret for signature validation
|
||||||
|
|
||||||
|
## Data Structure
|
||||||
|
|
||||||
|
Inside the `hamann_data` volume:
|
||||||
|
```
|
||||||
|
/app/data/
|
||||||
|
├── GIT/ # Git repository with XML sources
|
||||||
|
└── HAMANN/ # Compiled Hamann.xml files
|
||||||
|
```
|
||||||
|
|
||||||
|
## Webhook Setup
|
||||||
|
|
||||||
|
Configure GitHub webhook to POST to:
|
||||||
|
```
|
||||||
|
http://your-server:5000/api/webhook/git
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with reverse proxy:
|
||||||
|
```
|
||||||
|
https://your-domain.com/api/webhook/git
|
||||||
|
```
|
||||||
|
|
||||||
|
Set Content-Type to `application/json` and add your webhook secret.
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### With Reverse Proxy (Recommended)
|
||||||
|
|
||||||
|
Add to your nginx/traefik config:
|
||||||
|
```nginx
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:5000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update docker-compose.yml
|
||||||
|
|
||||||
|
Remove port exposure if using reverse proxy:
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: .
|
||||||
|
volumes:
|
||||||
|
- hamann_data:/app/data
|
||||||
|
# ports: # Comment out for reverse proxy
|
||||||
|
# - "5000:5000"
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_URLS=http://+:5000
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### View application logs
|
||||||
|
```bash
|
||||||
|
docker-compose logs -f web
|
||||||
|
```
|
||||||
|
|
||||||
|
### Access container shell
|
||||||
|
```bash
|
||||||
|
docker-compose exec web /bin/bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check data volume
|
||||||
|
```bash
|
||||||
|
docker volume inspect hamann_data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rebuild from scratch
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
docker-compose up -d --build --force-recreate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Git operations
|
||||||
|
```bash
|
||||||
|
docker-compose exec web /bin/bash
|
||||||
|
cd /app/data/GIT
|
||||||
|
git status
|
||||||
|
```
|
||||||
66
Dockerfile
66
Dockerfile
@@ -1,23 +1,51 @@
|
|||||||
# PREREQUISITES
|
# Build frontend assets
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
FROM node:18 AS frontend
|
||||||
RUN apt update
|
WORKDIR /app/HaWeb
|
||||||
RUN apt install openssh-server nodejs npm -y
|
COPY HaWeb/package*.json ./
|
||||||
|
|
||||||
# CLONE & SETUP
|
|
||||||
COPY . .
|
|
||||||
RUN mkdir /data/
|
|
||||||
RUN mkdir /data/hamann/
|
|
||||||
RUN mkdir /data/xml/
|
|
||||||
RUN git clone https://github.com/Theodor-Springmann-Stiftung/hamann-xml.git /data/xml/
|
|
||||||
|
|
||||||
# COMPILE & PUBLISH
|
|
||||||
WORKDIR HaWeb/
|
|
||||||
RUN dotnet restore
|
|
||||||
RUN npm install
|
RUN npm install
|
||||||
RUN npm run css_build
|
COPY HaWeb/ ./
|
||||||
RUN dotnet publish --no-restore -o /app
|
RUN npm run build
|
||||||
|
|
||||||
# RUN
|
# Build .NET application
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN DOTNET_ENVIRONMENT=Docker dotnet HaWeb.dll
|
|
||||||
|
# Copy project files and restore dependencies
|
||||||
|
COPY HaDocumentV6/HaDocumentV6.csproj ./HaDocumentV6/
|
||||||
|
COPY HaXMLReaderV6/HaXMLReaderV6.csproj ./HaXMLReaderV6/
|
||||||
|
COPY HaWeb/HaWeb.csproj ./HaWeb/
|
||||||
|
RUN dotnet restore HaWeb/HaWeb.csproj
|
||||||
|
|
||||||
|
# Copy all source files
|
||||||
|
COPY HaDocumentV6/ ./HaDocumentV6/
|
||||||
|
COPY HaXMLReaderV6/ ./HaXMLReaderV6/
|
||||||
|
COPY HaWeb/ ./HaWeb/
|
||||||
|
|
||||||
|
# Copy built frontend assets (overwrites the source wwwroot/dist)
|
||||||
|
COPY --from=frontend /app/HaWeb/wwwroot/dist/ ./HaWeb/wwwroot/dist/
|
||||||
|
|
||||||
|
# Build application
|
||||||
|
WORKDIR /app/HaWeb
|
||||||
|
RUN dotnet publish -c Release -o /app/publish
|
||||||
|
|
||||||
|
# Runtime image
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:6.0
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install git for LibGit2Sharp
|
||||||
|
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY --from=build /app/publish .
|
||||||
|
|
||||||
|
# Create data directory
|
||||||
|
RUN mkdir -p /app/data
|
||||||
|
|
||||||
|
# Expose ports for HTTP, HTTPS
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
EXPOSE 5001
|
||||||
|
|
||||||
|
ENV ASPNETCORE_URLS="http://+:5000;https://+:5001"
|
||||||
|
ENV DOTNET_ENVIRONMENT="Production"
|
||||||
|
ENV FileStoragePath="/app/data"
|
||||||
|
|
||||||
|
CMD ["dotnet", "HaWeb.dll"]
|
||||||
@@ -32,7 +32,17 @@ npm run build # Build CSS/JS first (required!)
|
|||||||
dotnet build HaWeb.csproj # Build the web application
|
dotnet build HaWeb.csproj # Build the web application
|
||||||
```
|
```
|
||||||
|
|
||||||
### Production Deployment (Linux)
|
### Production Deployment
|
||||||
|
|
||||||
|
**Docker (Recommended)**:
|
||||||
|
```bash
|
||||||
|
# From repository root
|
||||||
|
docker volume create hamann_data
|
||||||
|
docker-compose up -d --build
|
||||||
|
```
|
||||||
|
See `DOCKER.md` for detailed Docker deployment instructions.
|
||||||
|
|
||||||
|
**Manual (Linux)**:
|
||||||
```bash
|
```bash
|
||||||
npm run build
|
npm run build
|
||||||
dotnet publish --runtime linux-x64 -c Release
|
dotnet publish --runtime linux-x64 -c Release
|
||||||
|
|||||||
@@ -121,10 +121,35 @@ public class GitService : IGitService {
|
|||||||
|
|
||||||
// Checkout the specified branch if it's not the default
|
// Checkout the specified branch if it's not the default
|
||||||
using var repo = new Repository(_repositoryPath);
|
using var repo = new Repository(_repositoryPath);
|
||||||
|
|
||||||
|
// Log diagnostic information
|
||||||
|
_logger?.LogInformation("HEAD: {Head}, IsDetached: {IsDetached}, Tip: {Tip}",
|
||||||
|
repo.Head?.FriendlyName ?? "null",
|
||||||
|
repo.Head?.IsRemote.ToString() ?? "null",
|
||||||
|
repo.Head?.Tip?.Sha.Substring(0, 7) ?? "null");
|
||||||
|
|
||||||
|
_logger?.LogInformation("Available branches: {Branches}",
|
||||||
|
string.Join(", ", repo.Branches.Select(b => $"{b.FriendlyName} (Remote: {b.IsRemote})")));
|
||||||
|
|
||||||
var branch = repo.Branches[_branch] ?? repo.Branches[$"origin/{_branch}"];
|
var branch = repo.Branches[_branch] ?? repo.Branches[$"origin/{_branch}"];
|
||||||
|
|
||||||
|
if (branch == null) {
|
||||||
|
_logger?.LogWarning("Branch {Branch} not found. Attempting to create local tracking branch from origin/{Branch}", _branch, _branch);
|
||||||
|
var remoteBranch = repo.Branches[$"origin/{_branch}"];
|
||||||
|
if (remoteBranch != null) {
|
||||||
|
branch = repo.CreateBranch(_branch, remoteBranch.Tip);
|
||||||
|
repo.Branches.Update(branch, b => b.TrackedBranch = remoteBranch.CanonicalName);
|
||||||
|
_logger?.LogInformation("Created local tracking branch {Branch}", _branch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (branch != null && branch.FriendlyName != repo.Head.FriendlyName) {
|
if (branch != null && branch.FriendlyName != repo.Head.FriendlyName) {
|
||||||
Commands.Checkout(repo, branch);
|
Commands.Checkout(repo, branch);
|
||||||
_logger?.LogInformation("Checked out branch {Branch}", _branch);
|
_logger?.LogInformation("Checked out branch {Branch}", _branch);
|
||||||
|
} else if (branch != null) {
|
||||||
|
_logger?.LogInformation("Already on branch {Branch}", _branch);
|
||||||
|
} else {
|
||||||
|
_logger?.LogError("Could not find or create branch {Branch}", _branch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
// Create File Lists; Here and in xmlservice, which does preliminary checking
|
// Create File Lists; Here and in xmlservice, which does preliminary checking
|
||||||
Scan();
|
Scan();
|
||||||
if (_WorkingTreeFiles != null && _WorkingTreeFiles.Any()) {
|
if (_WorkingTreeFiles != null && _WorkingTreeFiles.Any()) {
|
||||||
var state = xmlservice.Collect(_WorkingTreeFiles, xmlservice.GetRootDefs());
|
var initialState = xmlservice.Collect(_WorkingTreeFiles, xmlservice.GetRootDefs());
|
||||||
xmlservice.SetState(state);
|
xmlservice.SetState(initialState);
|
||||||
}
|
}
|
||||||
_HamannFiles = _ScanHamannFiles();
|
_HamannFiles = _ScanHamannFiles();
|
||||||
|
|
||||||
@@ -64,8 +64,10 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -> NO: Try to create a new file
|
// -> NO: Try to create a new file (only if we have a valid git state and XML files)
|
||||||
var created = _XMLService.TryCreate(_XMLService.GetState());
|
var currentState = _XMLService.GetState();
|
||||||
|
if (currentState != null && _GitState != null) {
|
||||||
|
var created = _XMLService.TryCreate(currentState);
|
||||||
if (created != null) {
|
if (created != null) {
|
||||||
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
@@ -73,20 +75,16 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// It failed, so use the last best File:
|
// It failed, so use the last best File:
|
||||||
else if (_HamannFiles != null && _HamannFiles.Any()) {
|
if (_HamannFiles != null && _HamannFiles.Any()) {
|
||||||
_Lib.SetLibrary(_HamannFiles.First(), null, null);
|
_Lib.SetLibrary(_HamannFiles.First(), null, null);
|
||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -> There is none? Use Fallback:
|
// No valid data available
|
||||||
else {
|
throw new Exception("Keine gültige Hamann.xml Datei gefunden. Repository konnte nicht geklont oder geparst werden.");
|
||||||
var options = new HaWeb.Settings.HaDocumentOptions();
|
|
||||||
if (_Lib.SetLibrary(null, null, null) == null) {
|
|
||||||
throw new Exception("Die Fallback Hamann.xml unter " + options.HamannXMLFilePath + " kann nicht geparst werden.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParseConfiguration(IConfiguration config) {
|
public void ParseConfiguration(IConfiguration config) {
|
||||||
@@ -111,8 +109,10 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -> NO: Try to create a new file
|
// -> NO: Try to create a new file (only if we have a valid git state and XML files)
|
||||||
var created = _XMLService.TryCreate(_XMLService.GetState());
|
var configState = _XMLService.GetState();
|
||||||
|
if (configState != null && _GitState != null) {
|
||||||
|
var created = _XMLService.TryCreate(configState);
|
||||||
if (created != null) {
|
if (created != null) {
|
||||||
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
@@ -120,20 +120,16 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// It failed, so use the last best File:
|
// It failed, so use the last best File:
|
||||||
else if (_HamannFiles != null && _HamannFiles.Any()) {
|
if (_HamannFiles != null && _HamannFiles.Any()) {
|
||||||
_Lib.SetLibrary(_HamannFiles.First(), null, null);
|
_Lib.SetLibrary(_HamannFiles.First(), null, null);
|
||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -> There is none? Use Fallback:
|
// No valid data available
|
||||||
else {
|
throw new Exception("Keine gültige Hamann.xml Datei gefunden. Repository konnte nicht geklont oder geparst werden.");
|
||||||
var options = new HaWeb.Settings.HaDocumentOptions();
|
|
||||||
if (_Lib.SetLibrary(null, null, null) == null) {
|
|
||||||
throw new Exception("Die Fallback Hamann.xml unter " + options.HamannXMLFilePath + " kann nicht geparst werden.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
@@ -180,8 +176,10 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to create a new file
|
// Try to create a new file (only if we have a valid git state and XML files)
|
||||||
var created = _XMLService.TryCreate(_XMLService.GetState());
|
var reloadState = _XMLService.GetState();
|
||||||
|
if (reloadState != null && _GitState != null) {
|
||||||
|
var created = _XMLService.TryCreate(reloadState);
|
||||||
if (created != null) {
|
if (created != null) {
|
||||||
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
@@ -192,6 +190,7 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// It failed, so use the last best File:
|
// It failed, so use the last best File:
|
||||||
if (_HamannFiles != null && _HamannFiles.Any()) {
|
if (_HamannFiles != null && _HamannFiles.Any()) {
|
||||||
@@ -202,12 +201,8 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Fallback:
|
// No valid data available
|
||||||
var options = new HaWeb.Settings.HaDocumentOptions();
|
throw new Exception("Keine gültige Hamann.xml Datei gefunden. Repository konnte nicht geklont oder geparst werden.");
|
||||||
if (_Lib.SetLibrary(null, null, null) == null) {
|
|
||||||
throw new Exception("Die Fallback Hamann.xml unter " + options.HamannXMLFilePath + " kann nicht geparst werden.");
|
|
||||||
}
|
|
||||||
OnNewData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IFileInfo? SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary? ModelState) {
|
public IFileInfo? SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary? ModelState) {
|
||||||
|
|||||||
@@ -56,9 +56,6 @@ app.UseMiddleware<WebSocketMiddleware>();
|
|||||||
// Production Options
|
// Production Options
|
||||||
if (!app.Environment.IsDevelopment()) {
|
if (!app.Environment.IsDevelopment()) {
|
||||||
app.UseExceptionHandler("/Home/Error");
|
app.UseExceptionHandler("/Home/Error");
|
||||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
|
||||||
app.UseHsts();
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto });
|
app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,11 +63,17 @@ app.UseAuthorization();
|
|||||||
|
|
||||||
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
|
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
|
||||||
app.UseStaticFiles(new StaticFileOptions {
|
app.UseStaticFiles(new StaticFileOptions {
|
||||||
// Set ETag:
|
|
||||||
OnPrepareResponse = ctx => {
|
OnPrepareResponse = ctx => {
|
||||||
ctx.Context.Response.Headers.Add("Cache-Control", "public, max-age=" + cacheMaxAgeOneWeek);
|
ctx.Context.Response.Headers.Add("Cache-Control", "public, max-age=" + cacheMaxAgeOneWeek);
|
||||||
},
|
|
||||||
ServeUnknownFileTypes = true,
|
// Ensure correct MIME types
|
||||||
|
var path = ctx.File.PhysicalPath;
|
||||||
|
if (path?.EndsWith(".css") == true) {
|
||||||
|
ctx.Context.Response.ContentType = "text/css";
|
||||||
|
} else if (path?.EndsWith(".js") == true) {
|
||||||
|
ctx.Context.Response.ContentType = "application/javascript";
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"FileStoragePath": "/home/simon/source/hamann-ausgabe-core/HaWeb/testdata/",
|
"FileStoragePath": "/home/simon/source/hamann-ausgabe-core/HaWeb/testdata/",
|
||||||
"RepositoryBranch": "Main",
|
"RepositoryBranch": "Main",
|
||||||
"RepositoryURL": "https://github.com/Theodor-Springmann-Stiftung/hamann-xml",
|
"RepositoryURL": "https://github.com/Theodor-Springmann-Stiftung/hamann-xml.git",
|
||||||
"WebhookSecret": "secret",
|
"WebhookSecret": "secret",
|
||||||
"FileSizeLimit": 52428800,
|
"FileSizeLimit": 52428800,
|
||||||
"AvailableStartYear": 1700,
|
"AvailableStartYear": 1700,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
"AllowedWebSocketConnections": "*",
|
"AllowedWebSocketConnections": "*",
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"FileStoragePath": "/var/www/vhosts/development.hamann-ausgabe.de/httpdocs/Storage/",
|
"FileStoragePath": "/app/data",
|
||||||
"RepositoryBranch": "main",
|
"RepositoryBranch": "main",
|
||||||
"RepositoryURL": "https://github.com/Theodor-Springmann-Stiftung/hamann-xml",
|
"RepositoryURL": "https://github.com/Theodor-Springmann-Stiftung/hamann-xml",
|
||||||
"WebhookSecret": "",
|
"WebhookSecret": "",
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
},
|
},
|
||||||
"AllowedWebSocketConnections": "*",
|
"AllowedWebSocketConnections": "*",
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"FileStoragePath": "/var/www/vhosts/hamann-ausgabe.de/httpdocs/Storage/",
|
"FileStoragePath": "/app/data",
|
||||||
"RepositoryBranch": "main",
|
"RepositoryBranch": "Release",
|
||||||
"RepositoryURL": "",
|
"RepositoryURL": "https://github.com/Theodor-Springmann-Stiftung/hamann-xml.git",
|
||||||
"WebhookSecret": ""
|
"WebhookSecret": ""
|
||||||
}
|
}
|
||||||
|
|||||||
20
docker-compose.yml
Normal file
20
docker-compose.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: hamann-ausgabe
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: .
|
||||||
|
volumes:
|
||||||
|
- hamann_data:/app/data
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_URLS=http://+:5000
|
||||||
|
- DOTNET_ENVIRONMENT=Production
|
||||||
|
- FileStoragePath=/app/data
|
||||||
|
- RepositoryBranch=Release
|
||||||
|
- RepositoryURL=https://github.com/Theodor-Springmann-Stiftung/hamann-xml
|
||||||
|
- WebhookSecret=${WEBHOOK_SECRET:-}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
hamann_data:
|
||||||
|
external: true
|
||||||
Reference in New Issue
Block a user