native aot in container
This commit is contained in:
parent
0ca6a91a7e
commit
85ae3e302c
|
@ -22,4 +22,5 @@
|
||||||
**/secrets.dev.yaml
|
**/secrets.dev.yaml
|
||||||
**/values.dev.yaml
|
**/values.dev.yaml
|
||||||
LICENSE
|
LICENSE
|
||||||
README.md
|
README.md
|
||||||
|
**/node_modules
|
||||||
|
|
38
Dockerfile
Normal file
38
Dockerfile
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build-server
|
||||||
|
|
||||||
|
RUN apk add clang binutils musl-dev build-base zlib-static cmake openssl-dev openssl-libs-static openssl
|
||||||
|
|
||||||
|
WORKDIR /src/TanksServer
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
COPY TanksServer/TanksServer.csproj .
|
||||||
|
RUN dotnet restore --runtime linux-musl-x64 TanksServer.csproj
|
||||||
|
|
||||||
|
#build
|
||||||
|
COPY TanksServer .
|
||||||
|
RUN dotnet build TanksServer.csproj -c Release -o /app/build
|
||||||
|
RUN dotnet publish TanksServer.csproj -r linux-musl-x64 -c Release -o /app/publish
|
||||||
|
|
||||||
|
|
||||||
|
FROM node:21-alpine AS build-client
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
COPY tank-frontend/package.json .
|
||||||
|
COPY tank-frontend/package-lock.json .
|
||||||
|
RUN npm i
|
||||||
|
|
||||||
|
# build
|
||||||
|
env CONTAINERMODE 1
|
||||||
|
COPY tank-frontend .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS final
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=build-server /app/publish .
|
||||||
|
COPY --from=build-client /app/dist ./client
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
ENTRYPOINT ./TanksServer
|
|
@ -1,20 +0,0 @@
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
|
||||||
WORKDIR /app
|
|
||||||
EXPOSE 80
|
|
||||||
EXPOSE 443
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
|
||||||
WORKDIR /src
|
|
||||||
COPY ["TanksServer/TanksServer.csproj", "TanksServer/"]
|
|
||||||
RUN dotnet restore "TanksServer/TanksServer.csproj"
|
|
||||||
COPY . .
|
|
||||||
WORKDIR "/src/TanksServer"
|
|
||||||
RUN dotnet build "TanksServer.csproj" -c Release -o /app/build
|
|
||||||
|
|
||||||
FROM build AS publish
|
|
||||||
RUN dotnet publish "TanksServer.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
|
||||||
|
|
||||||
FROM base AS final
|
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=publish /app/publish .
|
|
||||||
ENTRYPOINT ["dotnet", "TanksServer.dll"]
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace TanksServer.Models;
|
namespace TanksServer.Models;
|
||||||
|
|
||||||
internal sealed class Player(string name)
|
internal sealed class Player(string name)
|
||||||
|
@ -6,18 +8,10 @@ internal sealed class Player(string name)
|
||||||
|
|
||||||
public Guid Id { get; } = Guid.NewGuid();
|
public Guid Id { get; } = Guid.NewGuid();
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public PlayerControls Controls { get; } = new();
|
public PlayerControls Controls { get; } = new();
|
||||||
|
|
||||||
public int Kills { get; set; }
|
public int Kills { get; set; }
|
||||||
|
|
||||||
public int Deaths { get; set; }
|
public int Deaths { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class PlayerControls
|
|
||||||
{
|
|
||||||
public bool Forward { get; set; }
|
|
||||||
public bool Backward { get; set; }
|
|
||||||
public bool TurnLeft { get; set; }
|
|
||||||
public bool TurnRight { get; set; }
|
|
||||||
public bool Shoot { get; set; }
|
|
||||||
}
|
|
10
TanksServer/Models/PlayerControls.cs
Normal file
10
TanksServer/Models/PlayerControls.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace TanksServer.Models;
|
||||||
|
|
||||||
|
internal sealed class PlayerControls
|
||||||
|
{
|
||||||
|
public bool Forward { get; set; }
|
||||||
|
public bool Backward { get; set; }
|
||||||
|
public bool TurnLeft { get; set; }
|
||||||
|
public bool TurnRight { get; set; }
|
||||||
|
public bool Shoot { get; set; }
|
||||||
|
}
|
|
@ -11,15 +11,12 @@ using TanksServer.ServicePointDisplay;
|
||||||
|
|
||||||
namespace TanksServer;
|
namespace TanksServer;
|
||||||
|
|
||||||
internal static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static async Task Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var app = Configure(args);
|
var app = Configure(args);
|
||||||
|
|
||||||
app.UseCors();
|
|
||||||
app.UseWebSockets();
|
|
||||||
|
|
||||||
var clientScreenServer = app.Services.GetRequiredService<ClientScreenServer>();
|
var clientScreenServer = app.Services.GetRequiredService<ClientScreenServer>();
|
||||||
var playerService = app.Services.GetRequiredService<PlayerServer>();
|
var playerService = app.Services.GetRequiredService<PlayerServer>();
|
||||||
var controlsServer = app.Services.GetRequiredService<ControlsServer>();
|
var controlsServer = app.Services.GetRequiredService<ControlsServer>();
|
||||||
|
@ -52,10 +49,10 @@ internal static class Program
|
||||||
|
|
||||||
using var ws = await context.WebSockets.AcceptWebSocketAsync();
|
using var ws = await context.WebSockets.AcceptWebSocketAsync();
|
||||||
await controlsServer.HandleClient(ws, player);
|
await controlsServer.HandleClient(ws, player);
|
||||||
return Results.Empty;
|
return Results.Ok();
|
||||||
});
|
});
|
||||||
|
|
||||||
await app.RunAsync();
|
app.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static WebApplication Configure(string[] args)
|
private static WebApplication Configure(string[] args)
|
||||||
|
@ -74,7 +71,7 @@ internal static class Program
|
||||||
options.SerializerOptions.TypeInfoResolverChain.Insert(0, new AppSerializerContext());
|
options.SerializerOptions.TypeInfoResolverChain.Insert(0, new AppSerializerContext());
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddOptions();
|
builder.Services.AddHttpLogging(_ => { });
|
||||||
|
|
||||||
builder.Services.AddSingleton<MapService>();
|
builder.Services.AddSingleton<MapService>();
|
||||||
builder.Services.AddSingleton<BulletManager>();
|
builder.Services.AddSingleton<BulletManager>();
|
||||||
|
@ -107,6 +104,12 @@ internal static class Program
|
||||||
builder.Services.Configure<ServicePointDisplayConfiguration>(
|
builder.Services.Configure<ServicePointDisplayConfiguration>(
|
||||||
builder.Configuration.GetSection("ServicePointDisplay"));
|
builder.Configuration.GetSection("ServicePointDisplay"));
|
||||||
|
|
||||||
return builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.UseCors();
|
||||||
|
app.UseWebSockets();
|
||||||
|
app.UseHttpLogging();
|
||||||
|
|
||||||
|
return app;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,7 @@ internal sealed class SendToServicePointDisplay : ITickStep, IDisposable
|
||||||
private readonly TextDisplayBuffer _scoresBuffer;
|
private readonly TextDisplayBuffer _scoresBuffer;
|
||||||
private readonly PlayerServer _players;
|
private readonly PlayerServer _players;
|
||||||
private readonly ILogger<SendToServicePointDisplay> _logger;
|
private readonly ILogger<SendToServicePointDisplay> _logger;
|
||||||
|
private DateTime _nextFailLog = DateTime.Now;
|
||||||
|
|
||||||
private const int ScoresWidth = 12;
|
private const int ScoresWidth = 12;
|
||||||
private const int ScoresHeight = 20;
|
private const int ScoresHeight = 20;
|
||||||
|
@ -70,7 +71,11 @@ internal sealed class SendToServicePointDisplay : ITickStep, IDisposable
|
||||||
}
|
}
|
||||||
catch (SocketException ex)
|
catch (SocketException ex)
|
||||||
{
|
{
|
||||||
_logger.LogWarning(ex, "could not send data to service point display");
|
if (DateTime.Now > _nextFailLog)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("could not send data to service point display: {}", ex.Message);
|
||||||
|
_nextFailLog = DateTime.Now + TimeSpan.FromSeconds(5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,25 +5,41 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
<ImplicitUsings>disable</ImplicitUsings>
|
||||||
<InvariantGlobalization>true</InvariantGlobalization>
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
<PublishAot>true</PublishAot>
|
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="..\.dockerignore">
|
|
||||||
<Link>.dockerignore</Link>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.3" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AnalysisMode>Recommended</AnalysisMode>
|
<AnalysisMode>Recommended</AnalysisMode>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<NoWarn>CA1805,CA1848</NoWarn>
|
<NoWarn>CA1805,CA1848</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsAotCompatible>true</IsAotCompatible>
|
||||||
|
<PublishAot>true</PublishAot>
|
||||||
|
|
||||||
|
<IlcDisableReflection>false</IlcDisableReflection>
|
||||||
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
|
<StaticExecutable>true</StaticExecutable>
|
||||||
|
<StripSymbols>true</StripSymbols>
|
||||||
|
<StaticallyLinked>true</StaticallyLinked>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0"/>
|
||||||
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.3"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="./assets/tank.png" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="Always" />
|
||||||
|
|
||||||
|
<Content Include="../Dockerfile">
|
||||||
|
<Link>..\Dockerfile</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="../.dockerignore">
|
||||||
|
<Link>../Dockerfile</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="../Makefile" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
16
tank-frontend/package-lock.json
generated
16
tank-frontend/package-lock.json
generated
|
@ -13,6 +13,7 @@
|
||||||
"react-use-websocket": "^4.8.1"
|
"react-use-websocket": "^4.8.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.12.7",
|
||||||
"@types/react": "^18.2.66",
|
"@types/react": "^18.2.66",
|
||||||
"@types/react-dom": "^18.2.22",
|
"@types/react-dom": "^18.2.22",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||||
|
@ -1240,6 +1241,15 @@
|
||||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.12.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
|
||||||
|
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~5.26.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.12",
|
"version": "15.7.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
||||||
|
@ -3143,6 +3153,12 @@
|
||||||
"node": ">=14.17"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "5.26.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.0.13",
|
"version": "1.0.13",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"react-use-websocket": "^4.8.1"
|
"react-use-websocket": "^4.8.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.12.7",
|
||||||
"@types/react": "^18.2.66",
|
"@types/react": "^18.2.66",
|
||||||
"@types/react-dom": "^18.2.22",
|
"@types/react-dom": "^18.2.22",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import {defineConfig} from 'vite';
|
import {ConfigEnv, defineConfig} from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig(() => {
|
||||||
plugins: [react()],
|
const isContainer = process.env.CONTAINERMODE;
|
||||||
|
return {
|
||||||
|
plugins: [react()],
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
outDir: '../TanksServer/client',
|
outDir: isContainer ? undefined : '../TanksServer/client',
|
||||||
emptyOutDir: true
|
emptyOutDir: true
|
||||||
}
|
}
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue