mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Use a service to run migrations (#358)
This commit is contained in:
commit
bd7991942a
15
.github/workflows/docker.yml
vendored
15
.github/workflows/docker.yml
vendored
@ -17,18 +17,32 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- context: ./back
|
- context: ./back
|
||||||
|
dockerfile: Dockerfile
|
||||||
label: back
|
label: back
|
||||||
image: zoriya/kyoo_back
|
image: zoriya/kyoo_back
|
||||||
|
|
||||||
|
- context: ./back
|
||||||
|
dockerfile: Dockerfile.migrations
|
||||||
|
label: migrations
|
||||||
|
image: zoriya/kyoo_migrations
|
||||||
|
|
||||||
- context: ./front
|
- context: ./front
|
||||||
|
dockerfile: Dockerfile
|
||||||
label: front
|
label: front
|
||||||
image: zoriya/kyoo_front
|
image: zoriya/kyoo_front
|
||||||
|
|
||||||
- context: ./scanner
|
- context: ./scanner
|
||||||
|
dockerfile: Dockerfile
|
||||||
label: scanner
|
label: scanner
|
||||||
image: zoriya/kyoo_scanner
|
image: zoriya/kyoo_scanner
|
||||||
|
|
||||||
- context: ./autosync
|
- context: ./autosync
|
||||||
|
dockerfile: Dockerfile
|
||||||
label: autosync
|
label: autosync
|
||||||
image: zoriya/kyoo_autosync
|
image: zoriya/kyoo_autosync
|
||||||
|
|
||||||
- context: ./transcoder
|
- context: ./transcoder
|
||||||
|
dockerfile: Dockerfile
|
||||||
label: transcoder
|
label: transcoder
|
||||||
image: zoriya/kyoo_transcoder
|
image: zoriya/kyoo_transcoder
|
||||||
name: Build ${{matrix.label}}
|
name: Build ${{matrix.label}}
|
||||||
@ -77,6 +91,7 @@ jobs:
|
|||||||
if: steps.filter.outputs.should_run == 'true' || github.event_name == 'workflow_dispatch'
|
if: steps.filter.outputs.should_run == 'true' || github.event_name == 'workflow_dispatch'
|
||||||
with:
|
with:
|
||||||
context: ${{matrix.context}}
|
context: ${{matrix.context}}
|
||||||
|
file: ${{matrix.context}}/${{matrix.dockerfile}}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
build-args: |
|
build-args: |
|
||||||
VERSION=0.0.0
|
VERSION=0.0.0
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"dotnet-ef": {
|
"dotnet-ef": {
|
||||||
"version": "7.0.9",
|
"version": "8.0.3",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-ef"
|
"dotnet-ef"
|
||||||
]
|
]
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
Dockerfile
|
Dockerfile
|
||||||
Dockerfile.dev
|
Dockerfile.dev
|
||||||
|
Dockerfile.*
|
||||||
.dockerignore
|
.dockerignore
|
||||||
.gitignore
|
.gitignore
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
README.md
|
README.md
|
||||||
**/build
|
**/build
|
||||||
**/dist
|
**/dist
|
||||||
src/Kyoo.WebApp/Front/nodes_modules
|
|
||||||
**/bin
|
**/bin
|
||||||
**/obj
|
**/obj
|
||||||
out
|
out
|
||||||
docs
|
docs
|
||||||
tests
|
tests
|
||||||
!tests/Kyoo.Tests/Kyoo.Tests.csproj
|
|
||||||
front
|
front
|
||||||
video
|
video
|
||||||
nginx.conf.template
|
nginx.conf.template
|
||||||
|
@ -19,7 +19,7 @@ COPY . .
|
|||||||
ARG VERSION
|
ARG VERSION
|
||||||
RUN dotnet publish -a $TARGETARCH --no-restore -c Release -o /app "-p:Version=${VERSION:-"0.0.0-dev"}" src/Kyoo.Host
|
RUN dotnet publish -a $TARGETARCH --no-restore -c Release -o /app "-p:Version=${VERSION:-"0.0.0-dev"}" src/Kyoo.Host
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:7.0
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||||||
RUN apt-get update && apt-get install -y curl
|
RUN apt-get update && apt-get install -y curl
|
||||||
COPY --from=builder /app /app
|
COPY --from=builder /app /app
|
||||||
|
|
||||||
|
13
back/Dockerfile.migrations
Normal file
13
back/Dockerfile.migrations
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 as builder
|
||||||
|
ARG TARGETARCH
|
||||||
|
WORKDIR /kyoo
|
||||||
|
|
||||||
|
COPY .config/dotnet-tools.json .config/dotnet-tools.json
|
||||||
|
RUN dotnet tool restore
|
||||||
|
COPY . .
|
||||||
|
RUN dotnet ef migrations bundle --self-contained -f -o /app/migrate -p src/Kyoo.Postgresql --verbose
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0
|
||||||
|
COPY --from=builder /app/migrate /app/migrate
|
||||||
|
|
||||||
|
ENTRYPOINT /app/migrate --connection "USER ID=${POSTGRES_USER};PASSWORD=${POSTGRES_PASSWORD};SERVER=postgres;PORT=5432;DATABASE=${POSTGRES_DB};"
|
@ -23,11 +23,6 @@
|
|||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<BaseIntermediateOutputPath>$(MsBuildThisFileDirectory)/../out/obj/$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
|
||||||
<BaseOutputPath>$(MsBuildThisFileDirectory)/../out/bin/$(MSBuildProjectName)</BaseOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<CheckCodingStyle Condition="$(CheckCodingStyle) == ''">true</CheckCodingStyle>
|
<CheckCodingStyle Condition="$(CheckCodingStyle) == ''">true</CheckCodingStyle>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -103,7 +103,6 @@ public class Application
|
|||||||
|
|
||||||
await using (AsyncServiceScope scope = host.Services.CreateAsyncScope())
|
await using (AsyncServiceScope scope = host.Services.CreateAsyncScope())
|
||||||
{
|
{
|
||||||
PostgresModule.Initialize(scope.ServiceProvider);
|
|
||||||
await MeilisearchModule.Initialize(scope.ServiceProvider);
|
await MeilisearchModule.Initialize(scope.ServiceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,13 +26,11 @@ using static System.Text.Json.JsonNamingPolicy;
|
|||||||
|
|
||||||
namespace Kyoo.Meiliseach;
|
namespace Kyoo.Meiliseach;
|
||||||
|
|
||||||
public class MeilisearchModule : IPlugin
|
public class MeilisearchModule(IConfiguration configuration) : IPlugin
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Name => "Meilisearch";
|
public string Name => "Meilisearch";
|
||||||
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
|
|
||||||
public static Dictionary<string, Settings> IndexSettings =>
|
public static Dictionary<string, Settings> IndexSettings =>
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
@ -122,11 +120,6 @@ public class MeilisearchModule : IPlugin
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
public MeilisearchModule(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Init meilisearch indexes.
|
/// Init meilisearch indexes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -139,27 +132,6 @@ public class MeilisearchModule : IPlugin
|
|||||||
await _CreateIndex(client, "items", true);
|
await _CreateIndex(client, "items", true);
|
||||||
await _CreateIndex(client, nameof(Episode), false);
|
await _CreateIndex(client, nameof(Episode), false);
|
||||||
await _CreateIndex(client, nameof(Studio), false);
|
await _CreateIndex(client, nameof(Studio), false);
|
||||||
|
|
||||||
IndexStats info = await client.Index("items").GetStatsAsync();
|
|
||||||
// If there is no documents in meilisearch, if a db exist and is not empty, add items to meilisearch.
|
|
||||||
if (info.NumberOfDocuments == 0)
|
|
||||||
{
|
|
||||||
ILibraryManager database = provider.GetRequiredService<ILibraryManager>();
|
|
||||||
MeiliSync search = provider.GetRequiredService<MeiliSync>();
|
|
||||||
|
|
||||||
// This is a naive implementation that absolutly does not care about performances.
|
|
||||||
// This will run only once on users that already had a database when they upgrade.
|
|
||||||
foreach (Movie movie in await database.Movies.GetAll(limit: 0))
|
|
||||||
await search.CreateOrUpdate("items", movie, nameof(Movie));
|
|
||||||
foreach (Show show in await database.Shows.GetAll(limit: 0))
|
|
||||||
await search.CreateOrUpdate("items", show, nameof(Show));
|
|
||||||
foreach (Collection collection in await database.Collections.GetAll(limit: 0))
|
|
||||||
await search.CreateOrUpdate("items", collection, nameof(Collection));
|
|
||||||
foreach (Episode episode in await database.Episodes.GetAll(limit: 0))
|
|
||||||
await search.CreateOrUpdate(nameof(Episode), episode);
|
|
||||||
foreach (Studio studio in await database.Studios.GetAll(limit: 0))
|
|
||||||
await search.CreateOrUpdate(nameof(Studio), studio);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task _CreateIndex(MeilisearchClient client, string index, bool hasKind)
|
private static async Task _CreateIndex(MeilisearchClient client, string index, bool hasKind)
|
||||||
@ -178,8 +150,8 @@ public class MeilisearchModule : IPlugin
|
|||||||
builder
|
builder
|
||||||
.RegisterInstance(
|
.RegisterInstance(
|
||||||
new MeilisearchClient(
|
new MeilisearchClient(
|
||||||
_configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"),
|
configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"),
|
||||||
_configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.SingleInstance();
|
.SingleInstance();
|
||||||
|
@ -38,45 +38,13 @@ namespace Kyoo.Postgresql;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A module to add postgresql capacity to the app.
|
/// A module to add postgresql capacity to the app.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PostgresModule : IPlugin
|
public class PostgresModule(IConfiguration configuration, IWebHostEnvironment environment) : IPlugin
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Name => "Postgresql";
|
public string Name => "Postgresql";
|
||||||
|
|
||||||
/// <summary>
|
static PostgresModule()
|
||||||
/// The configuration to use. The database connection string is pulled from it.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The host environment to check if the app is in debug mode.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IWebHostEnvironment _environment;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new postgres module instance and use the given configuration and environment.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="configuration">The configuration to use</param>
|
|
||||||
/// <param name="env">The environment that will be used (if the env is in development mode, more information will be displayed on errors.</param>
|
|
||||||
public PostgresModule(IConfiguration configuration, IWebHostEnvironment env)
|
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
|
||||||
_environment = env;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Migrate the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="provider">The service list to retrieve the database context</param>
|
|
||||||
public static void Initialize(IServiceProvider provider)
|
|
||||||
{
|
|
||||||
DatabaseContext context = provider.GetRequiredService<DatabaseContext>();
|
|
||||||
context.Database.Migrate();
|
|
||||||
|
|
||||||
using NpgsqlConnection conn = (NpgsqlConnection)context.Database.GetDbConnection();
|
|
||||||
conn.Open();
|
|
||||||
conn.ReloadTypes();
|
|
||||||
|
|
||||||
SqlMapper.TypeMapProvider = (type) =>
|
SqlMapper.TypeMapProvider = (type) =>
|
||||||
{
|
{
|
||||||
return new CustomPropertyTypeMap(
|
return new CustomPropertyTypeMap(
|
||||||
@ -118,11 +86,11 @@ public class PostgresModule : IPlugin
|
|||||||
DbConnectionStringBuilder builder =
|
DbConnectionStringBuilder builder =
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
["USER ID"] = _configuration.GetValue("POSTGRES_USER", "KyooUser"),
|
["USER ID"] = configuration.GetValue("POSTGRES_USER", "KyooUser"),
|
||||||
["PASSWORD"] = _configuration.GetValue("POSTGRES_PASSWORD", "KyooPassword"),
|
["PASSWORD"] = configuration.GetValue("POSTGRES_PASSWORD", "KyooPassword"),
|
||||||
["SERVER"] = _configuration.GetValue("POSTGRES_SERVER", "db"),
|
["SERVER"] = configuration.GetValue("POSTGRES_SERVER", "db"),
|
||||||
["PORT"] = _configuration.GetValue("POSTGRES_PORT", "5432"),
|
["PORT"] = configuration.GetValue("POSTGRES_PORT", "5432"),
|
||||||
["DATABASE"] = _configuration.GetValue("POSTGRES_DB", "kyooDB"),
|
["DATABASE"] = configuration.GetValue("POSTGRES_DB", "kyooDB"),
|
||||||
["POOLING"] = "true",
|
["POOLING"] = "true",
|
||||||
["MAXPOOLSIZE"] = "95",
|
["MAXPOOLSIZE"] = "95",
|
||||||
["TIMEOUT"] = "30"
|
["TIMEOUT"] = "30"
|
||||||
@ -132,7 +100,7 @@ public class PostgresModule : IPlugin
|
|||||||
x =>
|
x =>
|
||||||
{
|
{
|
||||||
x.UseNpgsql(builder.ConnectionString).UseProjectables();
|
x.UseNpgsql(builder.ConnectionString).UseProjectables();
|
||||||
if (_environment.IsDevelopment())
|
if (environment.IsDevelopment())
|
||||||
x.EnableDetailedErrors().EnableSensitiveDataLogging();
|
x.EnableDetailedErrors().EnableSensitiveDataLogging();
|
||||||
},
|
},
|
||||||
ServiceLifetime.Transient
|
ServiceLifetime.Transient
|
||||||
|
@ -35,11 +35,24 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
migrations:
|
||||||
|
condition: service_completed_successfully
|
||||||
volumes:
|
volumes:
|
||||||
- ./back:/app
|
- ./back:/app
|
||||||
- /app/out/
|
- /app/out/
|
||||||
- kyoo:/kyoo
|
- kyoo:/kyoo
|
||||||
|
|
||||||
|
migrations:
|
||||||
|
build:
|
||||||
|
context: ./back
|
||||||
|
dockerfile: Dockerfile.migrations
|
||||||
|
restart: "no"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- ./.env
|
||||||
|
|
||||||
front:
|
front:
|
||||||
build:
|
build:
|
||||||
context: ./front
|
context: ./front
|
||||||
|
@ -26,9 +26,20 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
migrations:
|
||||||
|
condition: service_completed_successfully
|
||||||
volumes:
|
volumes:
|
||||||
- kyoo:/kyoo
|
- kyoo:/kyoo
|
||||||
|
|
||||||
|
migrations:
|
||||||
|
image: zoriya/kyoo_migrations:edge
|
||||||
|
restart: "no"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- ./.env
|
||||||
|
|
||||||
front:
|
front:
|
||||||
image: zoriya/kyoo_front:edge
|
image: zoriya/kyoo_front:edge
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
@ -25,9 +25,22 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
migrations:
|
||||||
|
condition: service_completed_successfully
|
||||||
volumes:
|
volumes:
|
||||||
- kyoo:/kyoo
|
- kyoo:/kyoo
|
||||||
|
|
||||||
|
migrations:
|
||||||
|
build:
|
||||||
|
context: ./back
|
||||||
|
dockerfile: Dockerfile.migrations
|
||||||
|
restart: "no"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- ./.env
|
||||||
|
|
||||||
front:
|
front:
|
||||||
build: ./front
|
build: ./front
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
|
Loading…
x
Reference in New Issue
Block a user