Skip to content

Commit

Permalink
Merge branch 'DOCKERIZED-FINAL-fullstack-app' into FINAL-fullstack-app
Browse files Browse the repository at this point in the history
  • Loading branch information
Nomi authored Feb 18, 2024
2 parents e063c0b + 95fa5f2 commit 59dc1af
Show file tree
Hide file tree
Showing 19 changed files with 751 additions and 49 deletions.
32 changes: 32 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/

**/.DS_Store
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/docker-compose*
**/compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
1 change: 1 addition & 0 deletions .secrets/db/password.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TarnishedPluto2023!
139 changes: 139 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# syntax=docker/dockerfile:1

#################################################################################
#
## Create a stage for building the application.
#FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
#
#COPY . /source
#
#WORKDIR /source/TripPlannerAPI
#
## This is the architecture you’re building for, which is passed in by the builder.
## Placing it here allows the previous steps to be cached across architectures.
#ARG TARGETARCH
#
## Build the application.
## Leverage a cache mount to /root/.nuget/packages so that subsequent builds don't have to re-download packages.
## If TARGETARCH is "amd64", replace it with "x64" - "x64" is .NET's canonical name for this and "amd64" doesn't
## work in .NET 6.0.
#RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
#dotnet publish -a ${TARGETARCH/amd64/x64} --use-current-runtime --self-contained false -o /app
#
#################################################################################
## Create a new stage for running EF Core migrations.
#FROM build AS migrate
#
## Install the dotnet-ef tool
#RUN dotnet tool install --global dotnet-ef --version 6.0.27
#
## Restore the solution
#RUN dotnet restore
#
## Add migrations
##RUN dotnet ef migrations add initial
#RUN /root/.dotnet/tools/dotnet-ef migrations add mig
#
## Run EF Core migrations
##RUN dotnet ef database update
#RUN /root/.dotnet/tools/dotnet-ef database update
#
#################################################################################
## Create a new stage for running the application that contains the minimal
## runtime dependencies for the application. This often uses a different base
## image from the build stage where the necessary files are copied from the build
## stage.
#FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS final
#WORKDIR /app
#
## Copy everything needed to run the app from the "build" stage.
#COPY --from=build /app .
#
## Copy the migrated database from the "migrate" stage.
#COPY --from=migrate /source/TripPlannerAPI .
#
## Create a non-privileged user that the app will run under.
## See https://docs.docker.com/go/dockerfile-user-best-practices/
#ARG UID=10001
#RUN adduser \
#--disabled-password \
#--gecos "" \
#--home "/nonexistent" \
#--shell "/sbin/nologin" \
#--no-create-home \
#--uid "${UID}" \
#appuser
#USER appuser
#
#ENTRYPOINT ["dotnet", "TripPlannerAPI.dll"]


### OLD STUFF:
# syntax=docker/dockerfile:1

# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/

# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7

################################################################################

# Learn about building .NET container images:
# https://github.com/dotnet/dotnet-docker/blob/main/samples/README.md

# Create a stage for building the application.
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build

COPY . /source

WORKDIR /source/TripPlannerAPI

# This is the architecture you’re building for, which is passed in by the builder.
# Placing it here allows the previous steps to be cached across architectures.
ARG TARGETARCH

# Build the application.
# Leverage a cache mount to /root/.nuget/packages so that subsequent builds don't have to re-download packages.
# If TARGETARCH is "amd64", replace it with "x64" - "x64" is .NET's canonical name for this and "amd64" doesn't
# work in .NET 6.0.
RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
dotnet publish -a ${TARGETARCH/amd64/x64} --use-current-runtime --self-contained false -o /app

# If you need to enable globalization and time zones:
# https://github.com/dotnet/dotnet-docker/blob/main/samples/enable-globalization.md
################################################################################
# Create a new stage for running the application that contains the minimal
# runtime dependencies for the application. This often uses a different base
# image from the build stage where the necessary files are copied from the build
# stage.
#
# The example below uses an aspnet alpine image as the foundation for running the app.
# It will also use whatever happens to be the most recent version of that tag when you
# build your Dockerfile. If reproducability is important, consider using a more specific
# version (e.g., aspnet:7.0.10-alpine-3.18),
# or SHA (e.g., mcr.microsoft.com/dotnet/aspnet@sha256:f3d99f54d504a21d38e4cc2f13ff47d67235efeeb85c109d3d1ff1808b38d034).
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS final
WORKDIR /app

RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib

ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false

# Copy everything needed to run the app from the "build" stage.
COPY --from=build /app .

# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser

ENTRYPOINT ["dotnet", "TripPlannerAPI.dll"]
24 changes: 24 additions & 0 deletions README.Docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
### Building and running your application

When you're ready, start your application by running:
`docker compose up --build`.

Your application will be available at http://localhost:8080.

### Deploying your application to the cloud

First, build your image, e.g.: `docker build -t myapp .`.
If your cloud uses a different CPU architecture than your development
machine (e.g., you are on a Mac M1 and your cloud provider is amd64),
you'll want to build the image for that platform, e.g.:
`docker build --platform=linux/amd64 -t myapp .`.

Then, push it to your registry, e.g. `docker push myregistry.com/myapp`.

Consult Docker's [getting started](https://docs.docker.com/go/get-started-sharing/)
docs for more detail on building and pushing.

### References
* [Docker's .NET guide](https://docs.docker.com/language/dotnet/)
* The [dotnet-docker](https://github.com/dotnet/dotnet-docker/tree/main/samples)
repository has many relevant samples and docs.
30 changes: 7 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
# TripPlanner (full-stack)
# TripPlanner (full-stack) (with Docker Compose)
[![Build and Deploy](https://github.com/Nomi/TripPlanner-back-end/actions/workflows/TripPlannerAPI20221213230613.yml/badge.svg)](https://github.com/Nomi/TripPlanner-back-end/actions/workflows/TripPlannerAPI20221213230613.yml)
## Table of Contents
1. [Introduction](#introduction)

2. [How to build and run server:](#how-to-build-and-run-server)
- [Prerequisites](#prerequisites)
- [Database creation and migration:](#database-creation-and-migration)
- [Build](#build)
- [Run](#run)
- [Build and Run](#build-and-run)

3. [How to access the application:](#how-to-access-the-appliation)
- [API Spec](#api-spec)
- [Front-end](#front-end)
- [Front-end (Admin Panel)](#front-end-admin-panel)

## Introduction
(this version uses Docker Compose.)
The full-stack version of the TripPlanner API Web Application. A social network for people who love road trips.
Built using the following stack: C# (.NET 5), Entity Framework (the ORM), JavaSript, ReactJS, and MS SQL Server, among others.

Expand All @@ -25,26 +23,12 @@ Built using the following stack: C# (.NET 5), Entity Framework (the ORM), JavaSr

### Prerequisites
Before you begin, ensure you have the following prerequisites installed:
- .NET SDK: You can download and install it from [here](https://dotnet.microsoft.com/download).
- MS SQL Server (**change connection string as needed**).
- dotnet Entity Framework Core tools.
- Docker


### Database creation and migration
You will need to do this process on the first run, **BUT, also** after any changes to the Model.
```bash
dotnet ef migrations add *REPLACE_WITH_NAME_FOR_MIGRATION*
```
```bash
dotnet ef database update
```
### Build
```bash
dotnet build
```
### Run
### Build and Run
In the base directory:
```bash
dotnet run
docker compose --build
```

## How to access the appliation
Expand Down
7 changes: 7 additions & 0 deletions TripPlannerAPI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TripPlannerAPI", "TripPlann
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TripPlannerAPI.Tests.Unit", "TripPlannerAPI.Tests\TripPlannerAPI.Tests.Unit.csproj", "{4ED4F525-D189-4EEE-92D3-0989C434775B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2A8E1E7A-0DEA-4372-8698-42FE0F4A5B15}"
ProjectSection(SolutionItems) = preProject
compose.yaml = compose.yaml
Dockerfile = Dockerfile
.secrets\db\password.txt = .secrets\db\password.txt
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
1 change: 0 additions & 1 deletion TripPlannerAPI/Data/AppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public class AppDbContext : IdentityDbContext<User>
public AppDbContext(DbContextOptions options) : base(options)
{
}

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
Expand Down
10 changes: 5 additions & 5 deletions TripPlannerAPI/Migrations/AppDbContextModelSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("ProductVersion", "7.0.16")
.HasAnnotation("Relational:MaxIdentifierLength", 128);

SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
Expand Down Expand Up @@ -51,15 +51,15 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.HasData(
new
{
Id = "522a963a-74a5-4b90-a087-df0c0056c119",
ConcurrencyStamp = "f00b2976-7722-428d-95f3-f36bf477f966",
Id = "1ffd3fa0-7784-4e9f-91ef-a0ee5434ac48",
ConcurrencyStamp = "c577c01b-e034-427c-8ecb-173139f2d22c",
Name = "User",
NormalizedName = "USER"
},
new
{
Id = "3d19bc9a-8f90-49a8-b704-e87a9ee61b75",
ConcurrencyStamp = "799778ef-dcd4-431f-9997-df1558a3045a",
Id = "d14f6ba9-d3c2-4c3e-b749-40f5b787a59b",
ConcurrencyStamp = "459ac5c5-8227-459d-ab47-f873bc5068b8",
Name = "Admin",
NormalizedName = "ADMIN"
});
Expand Down
3 changes: 1 addition & 2 deletions TripPlannerAPI/Models/Location.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Data.Entity;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.OpenApi.Validations.Rules;
using System.Text.Json.Serialization;
Expand Down
4 changes: 1 addition & 3 deletions TripPlannerAPI/Models/Trip.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System.Data.Entity;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;

Expand Down
8 changes: 6 additions & 2 deletions TripPlannerAPI/Repositories/UserRatingRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ public async Task<int> EnsureCreated_AdminAt101()
string admRoleName = "admin";
//Check if the initialization is needed:
var adminAt101 = _appDbContext.Users.Where(u => (u.UserName == admUsrName)).FirstOrDefault();
var adminRole = _appDbContext.Roles.Where(r => (r.Name == admRoleName)).FirstOrDefault(); //The role should already be there (refer to AppDbContext class).
var adminRole = _appDbContext.Roles.Where(r => (r.Name.ToLower() == admRoleName.ToLower())).FirstOrDefault(); //The role should already be there (refer to AppDbContext class).
if(adminRole== null)
{
throw new Exception("Admin role either does not exist or the hardcoded string in this function is outdated.");
}
if (adminAt101 != null && _appDbContext.UserRoles.Any(x => ((x.UserId == adminAt101.Id) && (x.RoleId == adminRole.Id)))) ///TODO: need to remove it being hardcoded.
{
return 1; // DB has already been seeded
Expand All @@ -65,8 +69,8 @@ public async Task<int> EnsureCreated_AdminAt101()

var result = await _userManager.CreateAsync(adminAt101, admPass);
}
_appDbContext.SaveChanges();
var roleResult = await _userManager.AddToRoleAsync(adminAt101, adminRole.Name);
_appDbContext.SaveChanges();
return 0;
}
}
Expand Down
14 changes: 13 additions & 1 deletion TripPlannerAPI/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

var builder = WebApplication.CreateBuilder(args);



// Add services to the container.

builder.Services.AddControllers().AddJsonOptions(options =>
Expand Down Expand Up @@ -68,7 +70,10 @@
//);

builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("LOCAL_DB")));//("AZURE_SQL_CONNECTIONSTRING"))); //("LOCAL_DB")));
options.UseSqlServer(builder.Configuration.GetConnectionString("DOCKER_MSSQLSERVER_LOCAL_DB"))
//options.UseNpgsql(builder.Configuration.GetConnectionString("DOCKER_POSTGRES_LOCAL_DB"))
);//("AZURE_SQL_CONNECTIONSTRING"))); //("LOCAL_DB")));

//builder.Services.AddDbContext<AppDbContext>(opt =>
//{
// //System.Diagnostics.Debug.WriteLine(builder.Configuration.GetConnectionString("DefaultConnection"));
Expand Down Expand Up @@ -128,7 +133,14 @@
c.RoutePrefix = "api";
});
}
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
//db.Database.EnsureDeleted();
//db.Database.EnsureCreated();
await db.Database.MigrateAsync();

}
//app.UseHttpsRedirection();


Expand Down
Loading

0 comments on commit 59dc1af

Please sign in to comment.