Fixed deployment

This commit is contained in:
Kasper Juul Hermansen 2021-11-14 18:31:55 +01:00
parent 6ffc55f64e
commit b7a1a0be03
Signed by: kjuulh
GPG Key ID: 0F95C140730F2F23
16 changed files with 152 additions and 35 deletions

View File

@ -0,0 +1,3 @@
Dockerfile
bin/
obj/

View File

@ -23,5 +23,8 @@ RUN dotnet publish "Todo.Api.csproj" -c Release -o /app/publish
FROM base AS final FROM base AS final
WORKDIR /app WORKDIR /app
ENV ASPNETCORE_URLS=http://+:80
COPY --from=publish /app/publish . COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Todo.Api.dll"] ENTRYPOINT ["dotnet", "Todo.Api.dll"]

View File

@ -11,12 +11,10 @@ namespace Todo.Api
{ {
public class Program public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args) =>
{
CreateHostBuilder(args).Build().Run(); CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) => private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
} }

View File

@ -16,7 +16,12 @@
"launchUrl": "swagger", "launchUrl": "swagger",
"applicationUrl": "http://localhost:5000", "applicationUrl": "http://localhost:5000",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development",
"MONGODB__Username": "root",
"MONGODB__Password": "example",
"MONGODB__Database": "todo",
"MONGODB__Host": "localhost",
"MONGODB__Port": "27017"
} }
} }
} }

View File

@ -37,7 +37,7 @@ namespace Todo.Api
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Todo.Api", Version = "v1" }); c.SwaggerDoc("v1", new OpenApiInfo { Title = "Todo.Api", Version = "v1" });
}); });
services.AddPersistence(); services.AddPersistence(Configuration);
services.AddSignalR(); services.AddSignalR();
} }

View File

@ -7,5 +7,4 @@ namespace Todo.Core;
public static class DependencyInjection public static class DependencyInjection
{ {
} }

View File

@ -2,17 +2,31 @@ global using System;
global using System.Threading.Tasks; global using System.Threading.Tasks;
global using System.Linq; global using System.Linq;
global using System.Collections.Generic; global using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Todo.Core.Interfaces.Persistence; using Todo.Core.Interfaces.Persistence;
using Todo.Persistence.Mongo;
using Todo.Persistence.Mongo.Repositories; using Todo.Persistence.Mongo.Repositories;
namespace Todo.Persistence namespace Todo.Persistence
{ {
public static class DependencyInjection public static class DependencyInjection
{ {
public static IServiceCollection AddPersistence(this IServiceCollection services) => public static IServiceCollection AddPersistence(this IServiceCollection services, IConfiguration configuration)
{
var options = configuration.GetRequiredSection("MONGODB");
Console.WriteLine(options.Value);
services services
.AddOptions<MongoDbOptions>()
.Bind(options)
.ValidateDataAnnotations();
return services
.AddSingleton<MongoDbConnectionHandler>()
.AddScoped<IUserRepository, UserRepository>() .AddScoped<IUserRepository, UserRepository>()
.AddScoped<ITodoRepository, TodoRepository>(); .AddScoped<ITodoRepository, TodoRepository>();
}
} }
} }

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver; using MongoDB.Driver;
using Todo.Persistence.Mongo.Repositories.Dtos; using Todo.Persistence.Mongo.Repositories.Dtos;
@ -10,8 +11,8 @@ namespace Todo.Persistence.Mongo
{ {
Task.Run(async () => Task.Run(async () =>
{ {
var conn = new MongoClient("mongodb://root:example@localhost:27017"); var connectionHandler = app.ApplicationServices.GetRequiredService<MongoDbConnectionHandler>();
var database = conn.GetDatabase("todo"); var database = connectionHandler.CreateDatabaseConnection();
await CreateIndexes(database); await CreateIndexes(database);
}).Wait(10000); }).Wait(10000);

View File

@ -0,0 +1,30 @@
using Microsoft.Extensions.Options;
using MongoDB.Driver;
namespace Todo.Persistence.Mongo;
public class MongoDbConnectionHandler
{
private readonly IOptionsMonitor<MongoDbOptions> _optionsMonitor;
public MongoDbConnectionHandler(IOptionsMonitor<MongoDbOptions> optionsMonitor)
{
_optionsMonitor = optionsMonitor;
}
public IMongoDatabase CreateDatabaseConnection()
{
var options = _optionsMonitor.CurrentValue;
return CreateConnectionFromOptions(options);
}
private static IMongoDatabase CreateConnectionFromOptions(MongoDbOptions options)
{
var conn = new MongoClient(
$"mongodb://{options.Username}:{options.Password}@{options.Host}:{options.Port}");
var database = conn.GetDatabase(options.Database);
return database;
}
}

View File

@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
namespace Todo.Persistence.Mongo;
public class MongoDbOptions
{
public const string MongoDb = "MongoDb";
[Required] public string Username { get; set; }
[Required] public string Password { get; set; }
[Required] public string Host { get; set; }
[Required] public string Port { get; set; }
[Required] public string Database { get; set; }
}

View File

@ -8,10 +8,9 @@ public class TodoRepository : ITodoRepository
{ {
private readonly IMongoCollection<MongoTodo> _todosCollection; private readonly IMongoCollection<MongoTodo> _todosCollection;
public TodoRepository() public TodoRepository(MongoDbConnectionHandler mongoDbConnectionHandler)
{ {
var conn = new MongoClient("mongodb://root:example@localhost:27017"); var database = mongoDbConnectionHandler.CreateDatabaseConnection();
var database = conn.GetDatabase("todo");
_todosCollection = database.GetCollection<MongoTodo>("todos"); _todosCollection = database.GetCollection<MongoTodo>("todos");
} }

View File

@ -9,11 +9,9 @@ namespace Todo.Persistence.Mongo.Repositories
{ {
private readonly IMongoCollection<MongoUser> _usersCollection; private readonly IMongoCollection<MongoUser> _usersCollection;
public UserRepository() public UserRepository(MongoDbConnectionHandler mongoDbConnectionHandler)
{ {
var conn = new MongoClient("mongodb://root:example@localhost:27017"); var database = mongoDbConnectionHandler.CreateDatabaseConnection();
var database = conn.GetDatabase("todo");
_usersCollection = database.GetCollection<MongoUser>("users"); _usersCollection = database.GetCollection<MongoUser>("users");
} }

6
src/client/.dockerignore Normal file
View File

@ -0,0 +1,6 @@
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next

43
src/client/Dockerfile Normal file
View File

@ -0,0 +1,43 @@
# Install dependencies only when needed
FROM node:14-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
# Rebuild the source code only when needed
FROM node:14-alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN yarn build
# Production image, copy all the files and run next
FROM node:14-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# You only need to copy next.config.js if you are NOT using the default configuration
# COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/src/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
ENV PORT 3000
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
# ENV NEXT_TELEMETRY_DISABLED 1
CMD ["node_modules/.bin/next", "start"]

View File

@ -1,18 +0,0 @@
import { StatusState, Todo } from "@src/core/entities/todo";
export const createTodo = (name: string): Todo => ({
name,
status: StatusState.notDone,
});
const createDoneTodo = (name: string) => ({
...createTodo(name),
status: true,
});
const todos: Todo[] = [
createTodo("go to dentist"),
createTodo("Check e-Boks"),
createDoneTodo("Check and clean mail"),
];
export const getInboxTodos = () => todos;

View File

@ -1,3 +1,5 @@
version: "3"
services: services:
db: db:
build: build:
@ -7,3 +9,23 @@ services:
environment: environment:
MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example MONGO_INITDB_ROOT_PASSWORD: example
server:
build:
context: backend/server
ports:
- 5000:80
environment:
MONGODB__Username: root
MONGODB__Password: example
MONGODB__Host: db
MONGODB__Port: 27017
MONGODB__Database: todo
depends_on:
- db
client:
build:
context: client
ports:
- 3000:3000