@@ -0,0 +1,33 @@
|
|||||||
|
# Copy to .env next to docker-compose.yml and edit. Compose reads it automatically;
|
||||||
|
# git ignores .env. Every value here is optional — the defaults in docker-compose.yml
|
||||||
|
# are what you get without it.
|
||||||
|
|
||||||
|
# --- Ports on your machine -----------------------------------------------------------
|
||||||
|
# Container-side ports are fixed (API 5000, nginx 80); only these move.
|
||||||
|
#LADOSE_WEB_PORT=8080
|
||||||
|
#LADOSE_API_PORT=5000
|
||||||
|
|
||||||
|
# --- Database ------------------------------------------------------------------------
|
||||||
|
# Overrides ConnectionStrings:DbContext from LaDOSE.Api/appsettings.json. The stack has
|
||||||
|
# no Postgres of its own, so this has to point at a reachable server.
|
||||||
|
#
|
||||||
|
# Postgres on the machine running the containers:
|
||||||
|
#LADOSE_DB_CONNECTION=Host=host.docker.internal;Username=tom;Password=tom;Database=ladoseapi
|
||||||
|
#
|
||||||
|
# Postgres elsewhere on the LAN — check the name resolves *inside* the container
|
||||||
|
# (`docker compose run --rm api getent hosts kafka.local`) and use the IP if it does not:
|
||||||
|
#LADOSE_DB_CONNECTION=Host=kafka.local;Username=tom;Password=tom;Database=ladoseapi
|
||||||
|
#
|
||||||
|
# Sql/dump_20240316.sql then Sql/2026-08-05_roles.sql populate an empty database.
|
||||||
|
|
||||||
|
# --- Secrets -------------------------------------------------------------------------
|
||||||
|
# appsettings.json carries placeholders for these. Any value works for JWT locally, but
|
||||||
|
# it must be at least 32 characters: Startup.cs feeds it to HMAC-SHA256 as raw ASCII.
|
||||||
|
#LADOSE_JWT_SECRET=dev-only-secret-not-for-any-deployed-environment
|
||||||
|
#LADOSE_SMASH_API_KEY=
|
||||||
|
#LADOSE_CHALLONGE_API_KEY=
|
||||||
|
|
||||||
|
# --- Frontend ------------------------------------------------------------------------
|
||||||
|
# Only needed if the API is not on http://localhost:${LADOSE_API_PORT}. Resolved by the
|
||||||
|
# browser, so container names like http://api:5000 will not work.
|
||||||
|
#LADOSE_API_BASE_URL=http://localhost:5000
|
||||||
@@ -4,7 +4,7 @@ on: [push]
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build:
|
Build:
|
||||||
runs-on: ubuntu-latest-real
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Update
|
- name: Update
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -328,3 +328,10 @@ ASALocalRun/
|
|||||||
|
|
||||||
# MFractors (Xamarin productivity tool) working folder
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
.mfractor/
|
.mfractor/
|
||||||
|
|
||||||
|
# Local docker-compose overrides: connection string, API keys, ports.
|
||||||
|
# .env.example is documentation and stays tracked.
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
docker-compose.override.yml
|
||||||
|
|||||||
@@ -1,2 +1,22 @@
|
|||||||
*/*/bin*
|
# Context for LaDOSE.Src/Dockerfile.
|
||||||
*/*/obj*
|
#
|
||||||
|
# The previous patterns here were */*/bin* and */*/obj*, which matched nothing: this
|
||||||
|
# context is rooted at LaDOSE.Src, so build output sits one level down (LaDOSE.Api/bin),
|
||||||
|
# not two.
|
||||||
|
**/bin/
|
||||||
|
**/obj/
|
||||||
|
|
||||||
|
# The frontend is a separate image with its own context (LaDOSE.WebApp/Dockerfile).
|
||||||
|
# Its node_modules alone was adding ~118 MB to every API build.
|
||||||
|
LaDOSE.WebApp/node_modules/
|
||||||
|
LaDOSE.WebApp/build/
|
||||||
|
LaDOSE.WebApp/.svelte-kit/
|
||||||
|
|
||||||
|
# Local state and editor noise. Note Libraries/ is NOT excluded: LaDOSE.Business
|
||||||
|
# references ChallongeCSharpDriver.dll from there by HintPath.
|
||||||
|
.git
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
|||||||
+40
-11
@@ -1,15 +1,44 @@
|
|||||||
FROM microsoft/dotnet:sdk AS build-env
|
# Builds the LaDOSE.Api image. Context is LaDOSE.Src (see .dockerignore next to this file).
|
||||||
|
#
|
||||||
|
# Only LaDOSE.Api is published. LaDOSE.linux.sln also carries the Avalonia desktop app,
|
||||||
|
# the Discord bot and LinuxTest, and `dotnet publish <sln> -o out` flattens every project
|
||||||
|
# into that one directory — which is why the previous version of this file copied from
|
||||||
|
# /app/LaDOSE.Api/out/ and found nothing there.
|
||||||
|
ARG DOTNET_VERSION=9.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} AS build
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
# Debug is deliberate for local work, and docker-compose.yml passes it: the OpenAPI
|
||||||
|
# document and the Scalar UI are gated behind `#if DEBUG` in Startup.cs *and* behind
|
||||||
|
# Condition="'$(Configuration)' == 'Debug'" on their PackageReferences in
|
||||||
|
# LaDOSE.Api.csproj. A Release image therefore serves no /openapi/v1.json, which is
|
||||||
|
# exactly what LaDOSE.WebApp's `npm run api:sync` reads. Default stays Release.
|
||||||
|
ARG BUILD_CONFIGURATION=Release
|
||||||
|
|
||||||
|
# Project files first so this layer survives every .cs edit. Restore has to run under
|
||||||
|
# the same Configuration as the publish below, or the conditional PackageReferences
|
||||||
|
# above make the two disagree about which packages the assets file should contain.
|
||||||
|
COPY global.json ./
|
||||||
|
COPY LaDOSE.Api/LaDOSE.Api.csproj LaDOSE.Api/
|
||||||
|
COPY LaDOSE.DTO/LaDOSE.DTO.csproj LaDOSE.DTO/
|
||||||
|
COPY LaDOSE.Entity/LaDOSE.Entity.csproj LaDOSE.Entity/
|
||||||
|
COPY LaDOSE.Service/LaDOSE.Business.csproj LaDOSE.Service/
|
||||||
|
RUN dotnet restore LaDOSE.Api/LaDOSE.Api.csproj -p:Configuration=${BUILD_CONFIGURATION}
|
||||||
|
|
||||||
|
# Libraries/ChallongeCSharpDriver.dll is a HintPath reference from LaDOSE.Business,
|
||||||
|
# so the build needs the whole tree, not just the projects listed above.
|
||||||
|
COPY . .
|
||||||
|
RUN dotnet publish LaDOSE.Api/LaDOSE.Api.csproj -c ${BUILD_CONFIGURATION} --no-restore -o /app/out
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:${DOTNET_VERSION}
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
COPY --from=build /app/out/ ./
|
||||||
|
|
||||||
# Copy everything else and build
|
# Fixed in the image on purpose. Program.cs binds Kestrel from appsettings.json's
|
||||||
COPY . ./
|
# AllowedHosts/Port through a ConfigurationBuilder that reads *only* that file, so a
|
||||||
|
# Port env var would not move the listener — remap on the host side instead.
|
||||||
RUN dotnet publish LaDOSE.linux.sln -c Release -o out
|
# Everything Startup.cs reads does honour env vars (ConnectionStrings__DbContext,
|
||||||
|
# ApiKey__SmashApiKey, ApiKey__ChallongeApiKey, JWTTokenSecret).
|
||||||
# Build runtime image
|
|
||||||
FROM microsoft/dotnet:aspnetcore-runtime
|
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=build-env /app/LaDOSE.Api/out/ .
|
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
ENTRYPOINT ["dotnet", "LaDOSE.Api.dll"]
|
ENTRYPOINT ["dotnet", "LaDOSE.Api.dll"]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# Local development stack: LaDOSE.Api + LaDOSE.WebApp, built from the two Dockerfiles
|
||||||
|
# already in the tree.
|
||||||
|
#
|
||||||
|
# docker compose up --build start both, rebuilding when a Dockerfile changed
|
||||||
|
# docker compose watch same, plus rebuild the service you are editing
|
||||||
|
# docker compose logs -f api follow the API
|
||||||
|
# docker compose down stop
|
||||||
|
#
|
||||||
|
# Then: webapp on http://localhost:8080, API on http://localhost:5000,
|
||||||
|
# Scalar API reference on http://localhost:5000/scalar.
|
||||||
|
#
|
||||||
|
# The database is NOT part of this stack — it stays wherever appsettings.json points.
|
||||||
|
# Copy .env.example to .env to change the ports, the connection string or the API keys.
|
||||||
|
name: ladose
|
||||||
|
|
||||||
|
services:
|
||||||
|
api:
|
||||||
|
build:
|
||||||
|
context: ./LaDOSE.Src
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
# Debug, not Release: /openapi/v1.json and /scalar are compiled out of a
|
||||||
|
# Release build. See the comment in LaDOSE.Src/Dockerfile.
|
||||||
|
BUILD_CONFIGURATION: Debug
|
||||||
|
environment:
|
||||||
|
# Startup.cs gates the developer exception page, MapOpenApi() and
|
||||||
|
# MapScalarApiReference() on IsDevelopment().
|
||||||
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
|
# Double underscore is the .NET section separator, so this overrides
|
||||||
|
# ConnectionStrings:DbContext from appsettings.json. Left unset in .env, the
|
||||||
|
# default below reproduces what is committed there.
|
||||||
|
ConnectionStrings__DbContext: ${LADOSE_DB_CONNECTION:-Host=kafka.local;Username=tom;Password=tom;Database=ladoseapi}
|
||||||
|
# appsettings.json ships placeholders for these three. Real values belong in
|
||||||
|
# .env, which git ignores.
|
||||||
|
JWTTokenSecret: ${LADOSE_JWT_SECRET:-dev-only-secret-not-for-any-deployed-environment}
|
||||||
|
ApiKey__SmashApiKey: ${LADOSE_SMASH_API_KEY:-}
|
||||||
|
ApiKey__ChallongeApiKey: ${LADOSE_CHALLONGE_API_KEY:-}
|
||||||
|
ports:
|
||||||
|
# Container side is pinned at 5000: Program.cs reads AllowedHosts/Port straight
|
||||||
|
# from appsettings.json, through a ConfigurationBuilder that ignores env vars.
|
||||||
|
- "${LADOSE_API_PORT:-5000}:5000"
|
||||||
|
extra_hosts:
|
||||||
|
# Lets LADOSE_DB_CONNECTION use Host=host.docker.internal to reach a Postgres
|
||||||
|
# running on the machine hosting the containers.
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
develop:
|
||||||
|
watch:
|
||||||
|
- action: rebuild
|
||||||
|
path: ./LaDOSE.Src
|
||||||
|
ignore:
|
||||||
|
- LaDOSE.WebApp/
|
||||||
|
- "**/bin/"
|
||||||
|
- "**/obj/"
|
||||||
|
|
||||||
|
web:
|
||||||
|
build:
|
||||||
|
context: ./LaDOSE.Src/LaDOSE.WebApp
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
# VITE_API_BASE_URL is deliberately not passed. Vite would inline it at build
|
||||||
|
# time; LADOSE_API_BASE_URL below is read at container start instead, so the
|
||||||
|
# port can change without rebuilding the image.
|
||||||
|
environment:
|
||||||
|
# docker-entrypoint.sh turns this into /config.js. It is resolved by the
|
||||||
|
# *browser*, so it must be a host-visible URL — not http://api:5000.
|
||||||
|
LADOSE_API_BASE_URL: ${LADOSE_API_BASE_URL:-http://localhost:${LADOSE_API_PORT:-5000}}
|
||||||
|
ports:
|
||||||
|
- "${LADOSE_WEB_PORT:-8080}:80"
|
||||||
|
depends_on:
|
||||||
|
# Ordering only. The SPA is served by nginx and talks to the API from the
|
||||||
|
# browser, so it comes up fine on its own; this just avoids a confusing
|
||||||
|
# first-load failure when starting both at once.
|
||||||
|
- api
|
||||||
|
develop:
|
||||||
|
watch:
|
||||||
|
- action: rebuild
|
||||||
|
path: ./LaDOSE.Src/LaDOSE.WebApp
|
||||||
|
ignore:
|
||||||
|
- node_modules/
|
||||||
|
- build/
|
||||||
|
- .svelte-kit/
|
||||||
Reference in New Issue
Block a user