deployment stuff

This commit is contained in:
2026-02-21 12:01:36 -08:00
parent fb1eea6d08
commit 531c6258e6
9 changed files with 174 additions and 4 deletions
+5
View File
@@ -0,0 +1,5 @@
bin/
obj/
design/
*.user
.vs/
+17
View File
@@ -0,0 +1,17 @@
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY api.csproj ./
RUN dotnet restore api.csproj
COPY . ./
RUN dotnet publish api.csproj -c Release -o /app/publish --no-restore
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
ENV ASPNETCORE_URLS=http://+:8005
EXPOSE 8005
ENTRYPOINT ["dotnet", "api.dll"]
+1 -1
View File
@@ -1,6 +1,6 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Port=3306;Database=win_student_goal_tracker;Uid=root;Pwd=change_me;"
"DefaultConnection": "Server=localhost;Port=3306;Database=winstudentgoaltracker;Uid=root;Pwd=change_me;"
},
"Logging": {
"LogLevel": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Port=3306;Database=win_student_goal_tracker;Uid=root;Pwd=change_me;"
"DefaultConnection": "Server=localhost;Port=3306;Database=winstudentgoaltracker;Uid=root;Pwd=change_me;"
},
"Jwt": {
"Key": "super_secret_key_change_me_in_production_123!",
+60
View File
@@ -0,0 +1,60 @@
#!/bin/bash
# Initializes the database schema from db/Objects SQL files.
# Runs in order: tables (FK checks off) → functions → views → procedures.
set -e
DB="${MYSQL_DATABASE}"
OBJECTS_DIR="/db-objects"
mysql_exec() {
mysql -u root -p"${MYSQL_ROOT_PASSWORD}" "$DB" "$@"
}
echo "=== Initializing database schema ==="
# ── Tables (all in one session with FK checks disabled) ──────────────────────
if [ -d "$OBJECTS_DIR/tables" ] && ls "$OBJECTS_DIR/tables"/*.sql &>/dev/null; then
echo "Loading tables..."
{
echo "SET FOREIGN_KEY_CHECKS=0;"
for f in "$OBJECTS_DIR/tables"/*.sql; do
[ -f "$f" ] || continue
cat "$f"
echo
done
echo "SET FOREIGN_KEY_CHECKS=1;"
} | mysql_exec
echo " Tables done."
fi
# ── Functions ─────────────────────────────────────────────────────────────────
if [ -d "$OBJECTS_DIR/functions" ] && ls "$OBJECTS_DIR/functions"/*.sql &>/dev/null; then
echo "Loading functions..."
for f in "$OBJECTS_DIR/functions"/*.sql; do
[ -f "$f" ] || continue
mysql_exec < "$f"
done
echo " Functions done."
fi
# ── Views ─────────────────────────────────────────────────────────────────────
if [ -d "$OBJECTS_DIR/views" ] && ls "$OBJECTS_DIR/views"/*.sql &>/dev/null; then
echo "Loading views..."
for f in "$OBJECTS_DIR/views"/*.sql; do
[ -f "$f" ] || continue
mysql_exec < "$f"
done
echo " Views done."
fi
# ── Stored Procedures ─────────────────────────────────────────────────────────
if [ -d "$OBJECTS_DIR/procedures" ] && ls "$OBJECTS_DIR/procedures"/*.sql &>/dev/null; then
echo "Loading procedures..."
for f in "$OBJECTS_DIR/procedures"/*.sql; do
[ -f "$f" ] || continue
mysql_exec < "$f"
done
echo " Procedures done."
fi
echo "=== Schema initialization complete ==="
+60
View File
@@ -9,6 +9,66 @@ services:
- "3309:3306"
volumes:
- win_mysql_data:/var/lib/mysql
- ./db/docker-init:/docker-entrypoint-initdb.d:ro
- ./db/Objects:/db-objects:ro
healthcheck:
# Uses TCP (-h 127.0.0.1) so it only passes after init scripts complete
# and MySQL starts listening on the network.
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 10s
timeout: 5s
retries: 15
start_period: 30s
networks:
- backend
api:
build:
context: ./api
dockerfile: Dockerfile
container_name: winstudent-api
restart: unless-stopped
environment:
- ASPNETCORE_URLS=http://+:8005
- ConnectionStrings__DefaultConnection=Server=mysql;Port=3306;Database=${MYSQL_DATABASE};Uid=${MYSQL_USER};Pwd=${MYSQL_PASSWORD};
- Jwt__Key=${JWT_KEY}
- Jwt__Issuer=WinStudentGoalTrackerAPI
depends_on:
mysql:
condition: service_healthy
networks:
- backend
- web
labels:
- "traefik.enable=true"
- "traefik.http.routers.winstudent-api.rule=Host(`winapi.opelly.me`)"
- "traefik.http.routers.winstudent-api.entrypoints=websecure"
- "traefik.http.routers.winstudent-api.tls.certresolver=letsencrypt"
- "traefik.http.services.winstudent-api.loadbalancer.server.port=8005"
- "traefik.http.routers.winstudent-api.middlewares=gzip@file,security-headers@file"
ui:
build:
context: ./ui/winstudentgoaltracker
dockerfile: Dockerfile
container_name: winstudent-ui
restart: unless-stopped
depends_on:
- api
networks:
- web
labels:
- "traefik.enable=true"
- "traefik.http.routers.winstudent-ui.rule=Host(`win.opelly.me`)"
- "traefik.http.routers.winstudent-ui.entrypoints=websecure"
- "traefik.http.routers.winstudent-ui.tls.certresolver=letsencrypt"
- "traefik.http.services.winstudent-ui.loadbalancer.server.port=8006"
- "traefik.http.routers.winstudent-ui.middlewares=gzip@file,security-headers@file"
networks:
backend:
web:
external: true
volumes:
win_mysql_data:
+3
View File
@@ -0,0 +1,3 @@
node_modules/
dist/
.angular/
+14
View File
@@ -0,0 +1,14 @@
FROM node:22-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . ./
RUN npm run build
FROM nginx:alpine AS runtime
COPY --from=build /app/dist/winstudentgoaltracker/browser /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 8006
+11
View File
@@ -0,0 +1,11 @@
server {
listen 8006;
root /usr/share/nginx/html;
index index.html;
# Angular SPA fallback routing
location / {
try_files $uri $uri/ /index.html;
}
}