Refactor docker-compose: single deployable file + local override
Build and Push Docker Images / build (push) Successful in 11s
Build and Push Docker Images / build (push) Successful in 11s
- docker-compose.yml is now the single file for Portainer (staging and prod).
Uses registry images with ${IMAGE_TAG:-staging}, ${LOGS_PATH:-/opt/myai/logs},
and ${FILES_PATH:-/opt/myai/files} so the same file works for all environments.
- docker-compose.override.yml adds build context, ports, and env_file for local dev
and is auto-merged by "docker compose up" (no extra flags needed).
- .env.template documents IMAGE_TAG, LOGS_PATH, FILES_PATH alongside existing vars.
- docker-compose.dcproj updated so override file nests under docker-compose.yml in
Solution Explorer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,17 @@
|
|||||||
# Copy this file to `.env` (local), `.env.staging`, or `.env.production` and fill the secret values.
|
# Copy this file to `.env` (local), `.env.staging`, or `.env.production` and fill the secret values.
|
||||||
# Do NOT commit your `.env.*` files containing real secrets.
|
# Do NOT commit your `.env.*` files containing real secrets.
|
||||||
|
|
||||||
|
# Docker image tag — must match the tag CI pushes to the registry for this environment.
|
||||||
|
# "staging" for the staging Portainer stack, "production" for the production stack.
|
||||||
|
# For local dev this is ignored (docker-compose.override.yml builds images locally).
|
||||||
|
IMAGE_TAG=staging
|
||||||
|
|
||||||
|
# Volume base paths — controls where logs and uploaded files are stored on the host.
|
||||||
|
# Portainer (staging/prod): leave unset to use the /opt/myai defaults.
|
||||||
|
# Local dev: set to relative paths so logs and files land in the repo tree.
|
||||||
|
LOGS_PATH=./logs
|
||||||
|
FILES_PATH=../Apis/api/Files
|
||||||
|
|
||||||
# Common
|
# Common
|
||||||
ASPNETCORE_ENVIRONMENT=Development
|
ASPNETCORE_ENVIRONMENT=Development
|
||||||
|
|
||||||
@@ -81,6 +92,15 @@ Jobs__CvStorageCleanupEnabled=true
|
|||||||
Jobs__CvStorageCleanupInterval=01:00:00
|
Jobs__CvStorageCleanupInterval=01:00:00
|
||||||
Jobs__CvStorageMaxTotalSizeMegabytes=40
|
Jobs__CvStorageMaxTotalSizeMegabytes=40
|
||||||
|
|
||||||
|
# CV search job (job board scraper — triggered by one-click email link)
|
||||||
|
Jobs__CvSearchEnabled=true
|
||||||
|
Jobs__CvSearchInterval=00:00:30
|
||||||
|
JobSearch__Enabled=true
|
||||||
|
JobSearch__JobSearchLinkBaseUrl=https://myai.ro
|
||||||
|
JobSearch__TokenExpiryDays=7
|
||||||
|
JobSearch__MinMatchScore=15
|
||||||
|
JobSearch__MaxJobsToMatch=15
|
||||||
|
|
||||||
# File Storage
|
# File Storage
|
||||||
FileStorage__Path=Files
|
FileStorage__Path=Files
|
||||||
FileStorage__DefaultFileName=
|
FileStorage__DefaultFileName=
|
||||||
|
|||||||
@@ -20,5 +20,8 @@
|
|||||||
<DependentUpon>.env</DependentUpon>
|
<DependentUpon>.env</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
<None Include="docker-compose.yml" />
|
<None Include="docker-compose.yml" />
|
||||||
|
<None Include="docker-compose.override.yml">
|
||||||
|
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Local development overrides — auto-merged by "docker compose up".
|
||||||
|
# Do NOT paste this into Portainer. It only adds build context, port mappings,
|
||||||
|
# and env_file loading on top of docker-compose.yml.
|
||||||
|
|
||||||
|
services:
|
||||||
|
rag-api:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: Apis/rag-api/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "8081:8080"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
cv-matcher-api:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: Apis/cv-matcher-api/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "8082:8080"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
api:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: Apis/api/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
cv-cleanup-job:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: Jobs/cv-cleanup-job/Dockerfile
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
cv-search-job:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: Jobs/cv-search-job/Dockerfile
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
web:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: web/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "5000:8080"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
@@ -1,21 +1,12 @@
|
|||||||
services:
|
services:
|
||||||
rag-api:
|
rag-api:
|
||||||
build:
|
image: registry.easysoft.ro/apps/myai-rag-api:${IMAGE_TAG:-staging}
|
||||||
context: ..
|
|
||||||
dockerfile: Apis/rag-api/Dockerfile
|
|
||||||
container_name: myai-rag-api
|
container_name: myai-rag-api
|
||||||
ports:
|
|
||||||
- "8081:8080"
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
# ASP.NET
|
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Staging}
|
||||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
|
|
||||||
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
||||||
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
|
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.staging}
|
||||||
- LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}
|
|
||||||
|
|
||||||
# Database: matches rag-api appsettings Database section
|
|
||||||
- Database__Host=${Database__Host:-sqlserver}
|
- Database__Host=${Database__Host:-sqlserver}
|
||||||
- Database__Port=${Database__Port:-1433}
|
- Database__Port=${Database__Port:-1433}
|
||||||
- Database__Name=${Database__Name:-MyAiDb}
|
- Database__Name=${Database__Name:-MyAiDb}
|
||||||
@@ -23,11 +14,9 @@ services:
|
|||||||
- Database__Password=${Database__Password:-}
|
- Database__Password=${Database__Password:-}
|
||||||
- Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}
|
- Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}
|
||||||
|
|
||||||
# InternalApi: matches rag-api appsettings InternalApi section
|
- InternalApi__ApiKey=${RagApi__InternalApiKey:-}
|
||||||
- InternalApi__ApiKey=${RagApi__InternalApiKey:-change-this-internal-key}
|
- InternalApi__RequireApiKey=${RagApi__RequireApiKey:-true}
|
||||||
- InternalApi__RequireApiKey=${RagApi__RequireApiKey:-false}
|
|
||||||
|
|
||||||
# Rag: matches rag-api appsettings Rag section
|
|
||||||
- Rag__MaxFileSizeMb=${Rag__MaxFileSizeMb:-8}
|
- Rag__MaxFileSizeMb=${Rag__MaxFileSizeMb:-8}
|
||||||
- Rag__ChunkSize=${Rag__ChunkSize:-900}
|
- Rag__ChunkSize=${Rag__ChunkSize:-900}
|
||||||
- Rag__ChunkOverlap=${Rag__ChunkOverlap:-150}
|
- Rag__ChunkOverlap=${Rag__ChunkOverlap:-150}
|
||||||
@@ -36,7 +25,6 @@ services:
|
|||||||
- Rag__MaxTopK=${Rag__MaxTopK:-50}
|
- Rag__MaxTopK=${Rag__MaxTopK:-50}
|
||||||
- Rag__ClassifyWithAi=${Rag__ClassifyWithAi:-false}
|
- Rag__ClassifyWithAi=${Rag__ClassifyWithAi:-false}
|
||||||
|
|
||||||
# Ai: matches rag-api appsettings Ai section
|
|
||||||
- Ai__Provider=${Ai__Provider:-OpenAI}
|
- Ai__Provider=${Ai__Provider:-OpenAI}
|
||||||
- Ai__OpenAI__ApiKey=${Ai__OpenAI__ApiKey:-}
|
- Ai__OpenAI__ApiKey=${Ai__OpenAI__ApiKey:-}
|
||||||
- Ai__OpenAI__ChatModel=${Ai__OpenAI__ChatModel:-gpt-4o-mini}
|
- Ai__OpenAI__ChatModel=${Ai__OpenAI__ChatModel:-gpt-4o-mini}
|
||||||
@@ -47,11 +35,6 @@ services:
|
|||||||
- Ai__Ollama__EmbeddingModel=${Ai__Ollama__EmbeddingModel:-nomic-embed-text}
|
- Ai__Ollama__EmbeddingModel=${Ai__Ollama__EmbeddingModel:-nomic-embed-text}
|
||||||
- Ai__Ollama__TimeoutSeconds=${Ai__Ollama__TimeoutSeconds:-180}
|
- Ai__Ollama__TimeoutSeconds=${Ai__Ollama__TimeoutSeconds:-180}
|
||||||
|
|
||||||
# Logging / Serilog
|
|
||||||
- Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
|
|
||||||
- Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
|
|
||||||
- Logging__LogLevel__Microsoft__AspNetCore=${Logging__LogLevel__Microsoft__AspNetCore:-Warning}
|
|
||||||
- Logging__LogLevel__Api=${Logging__LogLevel__Api:-Information}
|
|
||||||
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
||||||
@@ -60,8 +43,7 @@ services:
|
|||||||
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
||||||
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
||||||
volumes:
|
volumes:
|
||||||
- ../Apis/api/logs:/app/logs
|
- ${LOGS_PATH:-/opt/myai/logs}/rag-api:/app/logs
|
||||||
- ../Apis/api/Files:/app/Files
|
|
||||||
networks:
|
networks:
|
||||||
- myai-network
|
- myai-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -69,24 +51,15 @@ services:
|
|||||||
- "com.centurylinklabs.watchtower.enable=true"
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
cv-matcher-api:
|
cv-matcher-api:
|
||||||
build:
|
image: registry.easysoft.ro/apps/myai-cv-matcher-api:${IMAGE_TAG:-staging}
|
||||||
context: ..
|
|
||||||
dockerfile: Apis/cv-matcher-api/Dockerfile
|
|
||||||
container_name: myai-cv-matcher-api
|
container_name: myai-cv-matcher-api
|
||||||
depends_on:
|
depends_on:
|
||||||
- rag-api
|
- rag-api
|
||||||
ports:
|
|
||||||
- "8082:8080"
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
# ASP.NET
|
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Staging}
|
||||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
|
|
||||||
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
||||||
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
|
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.staging}
|
||||||
- LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}
|
|
||||||
|
|
||||||
# Database: matches cv-matcher-api appsettings Database section
|
|
||||||
- Database__Host=${Database__Host:-sqlserver}
|
- Database__Host=${Database__Host:-sqlserver}
|
||||||
- Database__Port=${Database__Port:-1433}
|
- Database__Port=${Database__Port:-1433}
|
||||||
- Database__Name=${Database__Name:-MyAiDb}
|
- Database__Name=${Database__Name:-MyAiDb}
|
||||||
@@ -94,15 +67,12 @@ services:
|
|||||||
- Database__Password=${Database__Password:-}
|
- Database__Password=${Database__Password:-}
|
||||||
- Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}
|
- Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}
|
||||||
|
|
||||||
# InternalApi: matches cv-matcher-api appsettings InternalApi section
|
- InternalApi__ApiKey=${CvMatcherApi__InternalApiKey:-}
|
||||||
- InternalApi__ApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}
|
- InternalApi__RequireApiKey=${CvMatcherApi__RequireApiKey:-true}
|
||||||
- InternalApi__RequireApiKey=${CvMatcherApi__RequireApiKey:-false}
|
|
||||||
|
|
||||||
# RagApi: matches cv-matcher-api appsettings RagApi section
|
|
||||||
- RagApi__BaseUrl=${RagApi__BaseUrl:-http://rag-api:8080}
|
- RagApi__BaseUrl=${RagApi__BaseUrl:-http://rag-api:8080}
|
||||||
- RagApi__InternalApiKey=${RagApi__InternalApiKey:-change-this-internal-key}
|
- RagApi__InternalApiKey=${RagApi__InternalApiKey:-}
|
||||||
|
|
||||||
# Ai: matches cv-matcher-api appsettings Ai section
|
|
||||||
- Ai__Provider=${Ai__Provider:-OpenAI}
|
- Ai__Provider=${Ai__Provider:-OpenAI}
|
||||||
- Ai__OpenAI__ApiKey=${Ai__OpenAI__ApiKey:-}
|
- Ai__OpenAI__ApiKey=${Ai__OpenAI__ApiKey:-}
|
||||||
- Ai__OpenAI__ChatModel=${Ai__OpenAI__ChatModel:-gpt-4o-mini}
|
- Ai__OpenAI__ChatModel=${Ai__OpenAI__ChatModel:-gpt-4o-mini}
|
||||||
@@ -111,16 +81,10 @@ services:
|
|||||||
- Ai__Ollama__ChatModel=${Ai__Ollama__ChatModel:-llama3.1:8b}
|
- Ai__Ollama__ChatModel=${Ai__Ollama__ChatModel:-llama3.1:8b}
|
||||||
- Ai__Ollama__TimeoutSeconds=${Ai__Ollama__TimeoutSeconds:-180}
|
- Ai__Ollama__TimeoutSeconds=${Ai__Ollama__TimeoutSeconds:-180}
|
||||||
|
|
||||||
# Matcher: matches cv-matcher-api appsettings Matcher section
|
|
||||||
- Matcher__TopK=${Matcher__TopK:-10}
|
- Matcher__TopK=${Matcher__TopK:-10}
|
||||||
- Matcher__DeepScoreTopN=${Matcher__DeepScoreTopN:-5}
|
- Matcher__DeepScoreTopN=${Matcher__DeepScoreTopN:-5}
|
||||||
- Matcher__MaxJobTextChars=${Matcher__MaxJobTextChars:-60000}
|
- Matcher__MaxJobTextChars=${Matcher__MaxJobTextChars:-60000}
|
||||||
|
|
||||||
# Logging / Serilog
|
|
||||||
- Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
|
|
||||||
- Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
|
|
||||||
- Logging__LogLevel__Microsoft__AspNetCore=${Logging__LogLevel__Microsoft__AspNetCore:-Warning}
|
|
||||||
- Logging__LogLevel__Api=${Logging__LogLevel__Api:-Information}
|
|
||||||
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
||||||
@@ -129,7 +93,7 @@ services:
|
|||||||
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
||||||
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
||||||
volumes:
|
volumes:
|
||||||
- ../Apis/api/logs:/app/logs
|
- ${LOGS_PATH:-/opt/myai/logs}/cv-matcher-api:/app/logs
|
||||||
networks:
|
networks:
|
||||||
- myai-network
|
- myai-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -137,64 +101,43 @@ services:
|
|||||||
- "com.centurylinklabs.watchtower.enable=true"
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
api:
|
api:
|
||||||
build:
|
image: registry.easysoft.ro/apps/myai-api:${IMAGE_TAG:-staging}
|
||||||
context: ..
|
|
||||||
dockerfile: Apis/api/Dockerfile
|
|
||||||
container_name: myai-api
|
container_name: myai-api
|
||||||
depends_on:
|
depends_on:
|
||||||
- cv-matcher-api
|
- cv-matcher-api
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
# Keep this only if Apis/api/.env contains api-specific overrides not present in docker-compose/.env.
|
|
||||||
# - ../Apis/api/.env
|
|
||||||
environment:
|
environment:
|
||||||
# ASP.NET
|
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Staging}
|
||||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
|
|
||||||
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
||||||
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
|
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.staging}
|
||||||
- LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}
|
|
||||||
|
|
||||||
# Google: matches api appsettings Google section
|
|
||||||
- Google__TagManagerId=${Google__TagManagerId:-}
|
- Google__TagManagerId=${Google__TagManagerId:-}
|
||||||
- Google__MapKey=${Google__MapKey:-}
|
- Google__MapKey=${Google__MapKey:-}
|
||||||
|
|
||||||
# Contact / Subscribe: matches api appsettings Contact and Subscribe sections
|
|
||||||
- Contact__ToEmail=${Contact__ToEmail:-}
|
- Contact__ToEmail=${Contact__ToEmail:-}
|
||||||
- Contact__FromEmail=${Contact__FromEmail:-${Smtp__Username:-}}
|
- Contact__FromEmail=${Contact__FromEmail:-}
|
||||||
- Contact__SubjectPrefix=${Contact__SubjectPrefix:-}
|
- Contact__SubjectPrefix=${Contact__SubjectPrefix:-}
|
||||||
- Subscribe__ToEmail=${Subscribe__ToEmail:-}
|
- Subscribe__ToEmail=${Subscribe__ToEmail:-}
|
||||||
- Subscribe__SubjectPrefix=${Subscribe__SubjectPrefix:-}
|
- Subscribe__SubjectPrefix=${Subscribe__SubjectPrefix:-}
|
||||||
|
|
||||||
# SMTP: matches api appsettings Smtp section
|
- Smtp__Host=${Smtp__Host:-}
|
||||||
- Smtp__Host=${Smtp__Host:-mail.example.com}
|
|
||||||
- Smtp__Port=${Smtp__Port:-587}
|
- Smtp__Port=${Smtp__Port:-587}
|
||||||
- Smtp__Username=${Smtp__Username:-}
|
- Smtp__Username=${Smtp__Username:-}
|
||||||
- Smtp__Password=${Smtp__Password:-}
|
- Smtp__Password=${Smtp__Password:-}
|
||||||
- Smtp__UseStartTls=${Smtp__UseStartTls:-false}
|
- Smtp__UseStartTls=${Smtp__UseStartTls:-false}
|
||||||
|
|
||||||
# Captcha: matches api appsettings Captcha section
|
|
||||||
- Captcha__Provider=${Captcha__Provider:-Recaptcha}
|
- Captcha__Provider=${Captcha__Provider:-Recaptcha}
|
||||||
- Captcha__SecretKey=${Captcha__SecretKey:-}
|
- Captcha__SecretKey=${Captcha__SecretKey:-}
|
||||||
- Captcha__PublicKey=${Captcha__PublicKey:-}
|
- Captcha__PublicKey=${Captcha__PublicKey:-}
|
||||||
- Captcha__MinimumScore=${Captcha__MinimumScore:-0.5}
|
- Captcha__MinimumScore=${Captcha__MinimumScore:-0.5}
|
||||||
|
|
||||||
# FileStorage: matches api appsettings FileStorage section
|
|
||||||
- FileStorage__Path=${FileStorage__Path:-Files}
|
- FileStorage__Path=${FileStorage__Path:-Files}
|
||||||
- FileStorage__DefaultFileName=${FileStorage__DefaultFileName:-}
|
- FileStorage__DefaultFileName=${FileStorage__DefaultFileName:-}
|
||||||
- FileStorage__ToEmail=${FileStorage__ToEmail:-}
|
|
||||||
- FileStorage__FromEmail=${FileStorage__FromEmail:-${Smtp__Username:-}}
|
|
||||||
- FileStorage__SubjectPrefix=${FileStorage__SubjectPrefix:-[File Download]}
|
|
||||||
|
|
||||||
# CvMatcherApi: matches api appsettings CvMatcherApi section
|
|
||||||
- CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
|
- CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
|
||||||
- CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}
|
- CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-}
|
||||||
|
|
||||||
# JobSearch: base URL used to build the job search link in match emails
|
|
||||||
- JobSearch__BaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}
|
- JobSearch__BaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}
|
||||||
|
|
||||||
# Rate Limiting: matches api appsettings RateLimiting section
|
|
||||||
- RateLimiting__Global__PermitLimit=${RateLimiting__Global__PermitLimit:-120}
|
- RateLimiting__Global__PermitLimit=${RateLimiting__Global__PermitLimit:-120}
|
||||||
- RateLimiting__Global__Window=${RateLimiting__Global__Window:-00:01:00}
|
- RateLimiting__Global__Window=${RateLimiting__Global__Window:-00:01:00}
|
||||||
- RateLimiting__Global__QueueLimit=${RateLimiting__Global__QueueLimit:-0}
|
- RateLimiting__Global__QueueLimit=${RateLimiting__Global__QueueLimit:-0}
|
||||||
@@ -205,15 +148,9 @@ services:
|
|||||||
- RateLimiting__Policies__cvMatcher__Window=${RateLimiting__Policies__cvMatcher__Window:-00:10:00}
|
- RateLimiting__Policies__cvMatcher__Window=${RateLimiting__Policies__cvMatcher__Window:-00:10:00}
|
||||||
- RateLimiting__Policies__cvMatcher__QueueLimit=${RateLimiting__Policies__cvMatcher__QueueLimit:-0}
|
- RateLimiting__Policies__cvMatcher__QueueLimit=${RateLimiting__Policies__cvMatcher__QueueLimit:-0}
|
||||||
|
|
||||||
# CORS: not in the uploaded api appsettings, but used by your API startup config.
|
- Cors__AllowedOrigins__0=${Cors__AllowedOrigins__0:-}
|
||||||
- Cors__AllowedOrigins__0=${Cors__AllowedOrigins__0:-http://localhost:5000}
|
- Cors__AllowedOrigins__1=${Cors__AllowedOrigins__1:-}
|
||||||
- Cors__AllowedOrigins__1=${Cors__AllowedOrigins__1:-http://web:8080}
|
|
||||||
|
|
||||||
# Logging / Serilog
|
|
||||||
- Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
|
|
||||||
- Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
|
|
||||||
- Logging__LogLevel__Microsoft__AspNetCore=${Logging__LogLevel__Microsoft__AspNetCore:-Warning}
|
|
||||||
- Logging__LogLevel__Api=${Logging__LogLevel__Api:-Information}
|
|
||||||
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
||||||
@@ -222,8 +159,8 @@ services:
|
|||||||
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
||||||
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
||||||
volumes:
|
volumes:
|
||||||
- ../Apis/api/logs:/app/logs
|
- ${LOGS_PATH:-/opt/myai/logs}/api:/app/logs
|
||||||
- ../Apis/api/Files:/app/Files
|
- ${FILES_PATH:-/opt/myai/files}:/app/Files
|
||||||
networks:
|
networks:
|
||||||
- myai-network
|
- myai-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -231,36 +168,20 @@ services:
|
|||||||
- "com.centurylinklabs.watchtower.enable=true"
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
cv-cleanup-job:
|
cv-cleanup-job:
|
||||||
build:
|
image: registry.easysoft.ro/apps/myai-cv-cleanup-job:${IMAGE_TAG:-staging}
|
||||||
context: ..
|
|
||||||
dockerfile: Jobs/cv-cleanup-job/Dockerfile
|
|
||||||
container_name: myai-cv-cleanup-job
|
container_name: myai-cv-cleanup-job
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
# Worker + diagnostics (matches Jobs/cv-cleanup-job appsettings)
|
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Staging}
|
||||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
|
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.staging}
|
||||||
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
|
|
||||||
- LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}
|
|
||||||
|
|
||||||
# FileStorage: matches cv-cleanup-job appsettings FileStorage section
|
|
||||||
- FileStorage__Path=${FileStorage__Path:-Files}
|
- FileStorage__Path=${FileStorage__Path:-Files}
|
||||||
|
|
||||||
# Jobs: matches cv-cleanup-job appsettings Jobs:Tasks
|
|
||||||
- Jobs__Tasks__0__Enabled=${Jobs__CvStorageCleanupEnabled:-true}
|
- Jobs__Tasks__0__Enabled=${Jobs__CvStorageCleanupEnabled:-true}
|
||||||
- Jobs__Tasks__0__Interval=${Jobs__CvStorageCleanupInterval:-01:00:00}
|
- Jobs__Tasks__0__Interval=${Jobs__CvStorageCleanupInterval:-01:00:00}
|
||||||
- Jobs__Tasks__0__Parameters__MaxTotalSizeMegabytes=${Jobs__CvStorageMaxTotalSizeMegabytes:-40}
|
- Jobs__Tasks__0__Parameters__MaxTotalSizeMegabytes=${Jobs__CvStorageMaxTotalSizeMegabytes:-40}
|
||||||
|
|
||||||
# Logging / Serilog (matches Jobs/cv-cleanup-job appsettings Serilog section; WriteTo index 2 = Email)
|
|
||||||
- Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
|
|
||||||
- Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
|
|
||||||
- Logging__LogLevel__Microsoft__Hosting__Lifetime=${Logging__LogLevel__Microsoft__Hosting__Lifetime:-Information}
|
|
||||||
- Logging__LogLevel__CvCleanupJob=${Logging__LogLevel__CvCleanupJob:-Information}
|
|
||||||
- Logging__LogLevel__JobScheduler=${Logging__LogLevel__JobScheduler:-Information}
|
|
||||||
- Serilog__MinimumLevel__Override__CvCleanupJob=${Serilog__MinimumLevel__Override__CvCleanupJob:-Information}
|
|
||||||
- Serilog__MinimumLevel__Override__JobScheduler=${Serilog__MinimumLevel__Override__JobScheduler:-Information}
|
|
||||||
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
||||||
@@ -269,8 +190,8 @@ services:
|
|||||||
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
||||||
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
||||||
volumes:
|
volumes:
|
||||||
- ../Jobs/cv-cleanup-job/logs:/app/logs
|
- ${LOGS_PATH:-/opt/myai/logs}/cv-cleanup-job:/app/logs
|
||||||
- ../Apis/api/Files:/app/Files
|
- ${FILES_PATH:-/opt/myai/files}:/app/Files
|
||||||
networks:
|
networks:
|
||||||
- myai-network
|
- myai-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -278,21 +199,14 @@ services:
|
|||||||
- "com.centurylinklabs.watchtower.enable=true"
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
cv-search-job:
|
cv-search-job:
|
||||||
build:
|
image: registry.easysoft.ro/apps/myai-cv-search-job:${IMAGE_TAG:-staging}
|
||||||
context: ..
|
|
||||||
dockerfile: Jobs/cv-search-job/Dockerfile
|
|
||||||
container_name: myai-cv-search-job
|
container_name: myai-cv-search-job
|
||||||
depends_on:
|
depends_on:
|
||||||
- cv-matcher-api
|
- cv-matcher-api
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
# Worker + diagnostics
|
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Staging}
|
||||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
|
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.staging}
|
||||||
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
|
|
||||||
- LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}
|
|
||||||
|
|
||||||
# Database
|
|
||||||
- Database__Host=${Database__Host:-sqlserver}
|
- Database__Host=${Database__Host:-sqlserver}
|
||||||
- Database__Port=${Database__Port:-1433}
|
- Database__Port=${Database__Port:-1433}
|
||||||
- Database__Name=${Database__Name:-MyAiDb}
|
- Database__Name=${Database__Name:-MyAiDb}
|
||||||
@@ -300,39 +214,29 @@ services:
|
|||||||
- Database__Password=${Database__Password:-}
|
- Database__Password=${Database__Password:-}
|
||||||
- Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}
|
- Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}
|
||||||
|
|
||||||
# CvMatcherApi (internal)
|
|
||||||
- CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
|
- CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
|
||||||
- CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}
|
- CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-}
|
||||||
|
|
||||||
# SMTP
|
|
||||||
- Smtp__Host=${Smtp__Host:-}
|
- Smtp__Host=${Smtp__Host:-}
|
||||||
- Smtp__Port=${Smtp__Port:-587}
|
- Smtp__Port=${Smtp__Port:-587}
|
||||||
- Smtp__Username=${Smtp__Username:-}
|
- Smtp__Username=${Smtp__Username:-}
|
||||||
- Smtp__Password=${Smtp__Password:-}
|
- Smtp__Password=${Smtp__Password:-}
|
||||||
- Smtp__UseStartTls=${Smtp__UseStartTls:-false}
|
- Smtp__UseStartTls=${Smtp__UseStartTls:-false}
|
||||||
|
|
||||||
# Contact
|
|
||||||
- Contact__ToEmail=${Contact__ToEmail:-}
|
- Contact__ToEmail=${Contact__ToEmail:-}
|
||||||
|
|
||||||
# FileStorage (shared volume path must match api container)
|
|
||||||
- FileStorage__Path=${FileStorage__Path:-Files}
|
- FileStorage__Path=${FileStorage__Path:-Files}
|
||||||
|
|
||||||
# JobSearch settings
|
|
||||||
- JobSearch__Enabled=${JobSearch__Enabled:-true}
|
- JobSearch__Enabled=${JobSearch__Enabled:-true}
|
||||||
- JobSearch__JobSearchLinkBaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}
|
- JobSearch__JobSearchLinkBaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}
|
||||||
- JobSearch__TokenExpiryDays=${JobSearch__TokenExpiryDays:-7}
|
- JobSearch__TokenExpiryDays=${JobSearch__TokenExpiryDays:-7}
|
||||||
- JobSearch__MinMatchScore=${JobSearch__MinMatchScore:-15}
|
- JobSearch__MinMatchScore=${JobSearch__MinMatchScore:-15}
|
||||||
- JobSearch__MaxJobsToMatch=${JobSearch__MaxJobsToMatch:-15}
|
- JobSearch__MaxJobsToMatch=${JobSearch__MaxJobsToMatch:-15}
|
||||||
|
|
||||||
# Job task schedule
|
|
||||||
- Jobs__Tasks__0__TaskType=CvSearch
|
- Jobs__Tasks__0__TaskType=CvSearch
|
||||||
- Jobs__Tasks__0__Enabled=${Jobs__CvSearchEnabled:-true}
|
- Jobs__Tasks__0__Enabled=${Jobs__CvSearchEnabled:-true}
|
||||||
- Jobs__Tasks__0__Interval=${Jobs__CvSearchInterval:-00:00:30}
|
- Jobs__Tasks__0__Interval=${Jobs__CvSearchInterval:-00:00:30}
|
||||||
|
|
||||||
# Logging / Serilog
|
|
||||||
- Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
|
|
||||||
- Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
|
|
||||||
- Logging__LogLevel__Microsoft__Hosting__Lifetime=${Logging__LogLevel__Microsoft__Hosting__Lifetime:-Information}
|
|
||||||
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
|
||||||
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
|
||||||
@@ -341,8 +245,8 @@ services:
|
|||||||
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
|
||||||
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
|
||||||
volumes:
|
volumes:
|
||||||
- ../Jobs/cv-search-job/logs:/app/logs
|
- ${LOGS_PATH:-/opt/myai/logs}/cv-search-job:/app/logs
|
||||||
- ../Apis/api/Files:/app/Files
|
- ${FILES_PATH:-/opt/myai/files}:/app/Files
|
||||||
networks:
|
networks:
|
||||||
- myai-network
|
- myai-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -350,22 +254,15 @@ services:
|
|||||||
- "com.centurylinklabs.watchtower.enable=true"
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
web:
|
web:
|
||||||
build:
|
image: registry.easysoft.ro/apps/myai-web:${IMAGE_TAG:-staging}
|
||||||
context: ..
|
|
||||||
dockerfile: web/Dockerfile
|
|
||||||
container_name: myai-web
|
container_name: myai-web
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
ports:
|
|
||||||
- "5000:8080"
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
|
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Staging}
|
||||||
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
|
||||||
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
|
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.staging}
|
||||||
|
|
||||||
# Site: matches web appsettings Site section (Normal, UnderConstruction, Unavailable)
|
|
||||||
- Site__Mode=${Site__Mode:-Normal}
|
- Site__Mode=${Site__Mode:-Normal}
|
||||||
networks:
|
networks:
|
||||||
- myai-network
|
- myai-network
|
||||||
|
|||||||
Reference in New Issue
Block a user