Skip to content

Commit

Permalink
πŸ‘©πŸΌβ€πŸ’» Containerise solution (#574)
Browse files Browse the repository at this point in the history
* Add Docker Compose

* Web API Hosting on Docker

* Add Docker Compose

* Remove example web app

* Running Admin in Https

* Add Profiles

* Update F5 Experience

* Update Default Appsettings

* Update with new shared projects
  • Loading branch information
tkapa authored Jan 16, 2024
1 parent 5c1b9ac commit f392929
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 71 deletions.
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.idea
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
137 changes: 70 additions & 67 deletions _docs/Instructions-Compile.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,97 @@
## Getting Started
# The F5 Experience

**TODO** VS for Mac is EOL - Look into VS Code development method (C# + Maui Extensions)
## Requirements
**TODO** Find Azurite seed data for the API (Tylah might be blind)

### Required Tools

Microsoft Learn has a great step-by-step process to get your first .NET MAUI project up and running, this will should allow you to run the UI with out much issue! https://learn.microsoft.com/en-us/dotnet/maui/get-started/first-app?view=net-maui-8.0&tabs=vsmac&pivots=devices-android

- Ensure you have .NET 8 installed https://dotnet.microsoft.com/en-us/download/dotnet/8.0

- Visual Studio 2022
- .NET 8 https://dotnet.microsoft.com/en-us/download/dotnet/8.0
- IDE - Visual Studio Enterprise Latest // Jetbrains Rider // VS Code
- Android SDK setup/ installed w/ Xamarin (https://docs.microsoft.com/en-us/xamarin/android/get-started/installation/android-sdk)
- iOS SDK setup/installed w/ Xamarin (https://docs.microsoft.com/en-us/xamarin/ios/get-started/installation/)
- [Azurite - Previously Azure Storage Emulator](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio,blob-storage) (Automatically part of Visual Studio 2022)
- [Azure Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/) (Easy way to upload and download files (see Local Emulator Database)
- [Azure Data Studio](https://azure.microsoft.com/en-us/products/data-studio/) (Not required, can use IDE Tools for DB Querying)

- Install Dev Tunnels or Ngrok see the rule https://ssw.com.au/rules/port-forwarding/
- [dev tunnels](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=macos) (Recommended)
- [ngrok](https://ngrok.com/) (Api and Mobile communication)
****
- [dev tunnels](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=macos) (Recommended)
- [ngrok](https://ngrok.com/)

### Required Tools (for Mac)

- XCode v15.0.1+
- Check or set `Command Line Tools` location
- **Preferences** | **Locations** | **Command Line Tools**
- Visual Studio for Mac 2022 (EOL - April 2024)
- Enable .NET 8 SDK in **Preferences** | **Other** | **Preview Features**
- [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio,blob-storage) (For Docker or Visual Studio Code)

## The F5 Experience

### Web API

1. Clone the repository
1. `git clone https://github.com/SSWConsulting/SSW.Rewards.Mobile.git`
3. Grab connection strings from an existing dev to create local `secrets.json` file (https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.0&tabs=windows)
4. Update `WebAPI` `appsettings.json` and `appsettings.development.json` with the proper secrets
5. Install / Run `Azure Storage Emulator` (Run the .exe or use the "start" command)
6. Install / Run [Azure Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/#overview)
7. Start Explorer (**On First Install** - See steps below)
1. Sign in using the "Subscription" option
2. Select the "Azure" option
3. Next (Sign in with your account that has access to ssw1 DevOps)
8. Inside the Explorer - **Local & Attached** | **Storage Accounts** | **Emulator** | **Blob Containers**
9. Create a **new container** called `profile`
10. Copy over all files in `SeedData/profiles` (images + .xlsx) into the newly created `profile` container
11. Press f5
12. Test that you can access the swagger docs @ `https://localhost:5001/swagger/`

**(Optional)** - If you need to run the api and mobile app locally.
1. Run dev tunnels `devtunnel host -p 5001`

## Setting up the Repo for Development
### To work on the API + Admin UI
1. Pull this Repo
2. Grab the Secrets from Keeper
1. **Client Secrets | SSW | SSW.Rewards | Developer Secrets**
2. Add them as .NET User Secrets for `WebAPI.csproj`
3. Update `appsettings.*.json` files accordingly
3. Create a Developer Certificate https://learn.microsoft.com/en-us/aspnet/core/security/docker-https?view=aspnetcore-8.0#certificates
1. Create `WebAPI.pfx` with a password of `ThisPassword` (You can change change this, but the `docker-compose.yml` should be updated appropriately)

**Windows**
```bash
dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\WebAPI.pfx -p ThisPassword
dotnet dev-certs https --trust
```

**Mac**
```bash
dotnet dev-certs https -ep ${HOME}/.aspnet/https/WebAPI.pfx -p ThisPassword
dotnet dev-certs https --trust
```


4. Cd into the Repo
5. Run the Docker Containers
```bash
docker compose build
docker compose --profile all up -d
```

You should now be able to access the AdminUI hosted locally at https://localhost:7137


You should now be able to access the WebAPI Swagger docs at https://localhost:5001/swagger/index.html


**Note:** You can run only the WebAPI or AdminUI by running:
```bash
docker compose --profile webapi up -d
OR
1. Run NGrok `ngrok http https://localhost:5001`

### Mobile App Android

1. Get the source code
1. `git clone https://github.com/SSWConsulting/SSW.Rewards.Mobile.git`
2. Connect Android Device or Emulator (https://docs.microsoft.com/en-us/xamarin/android/get-started/installation/android-emulator/)
3. Set build target as desired device.
4. **(Optional)** - Using dev tunnels OR Ngrok - If you need to connect to the Api locally
1. Under SSW.Rewards | **Constants.cs**
2. Update the `Constants.cs` `ApiBaseUrl` in The **#if DEBUG** region to use the custom ngrok **https** address (See Image below)
![ngrok Https Address](imgs/ngrok-https-example.png)
**Figure: ngrok https address**
5. Run / press f5

### Mobile App iOS (Mac Only, iOS Emulator)
1. Get the source code
1. `git clone https://github.com/SSWConsulting/SSW.Rewards.Mobile.git`
2. Set build target (either connected iOS device or emulator)
3. Run / Press F5
docker compose --profile admin up -d
```

## Mobile UI

Microsoft Learn has a great step-by-step process to get your first .NET MAUI project up and running, this will should allow you to run the Mobile UI with out much issue! https://learn.microsoft.com/en-us/dotnet/maui/get-started/first-app?view=net-maui-8.0&tabs=vsmac&pivots=devices-android

### To work on the Mobile UI (Android SDK)
1. Run the Docker containers (Only WebApi required)
2. Start a Dev Tunnel for the API
```bash
devtunnel host -p 5001
```
3. Update the `Constants.cs` `ApiBaseUrl` in the **#if DEBUG** block to use your DevTunnel address
4. Run the MobileUI, targeting your Android Emulator

### To work on the Mobile UI (iOS, MacOS Only)
2. Complete steps 1-3 above
3. Run the MobileUI, targeting your Android Emulator

**NOTE: if you cannot build and see an error relating to the provisioning profile/ app signing identity**

1. Open up the iOS project settings by right clicking on SSW.Consulting.iOS and selecting Options.
1. go to 'iOS Bundle Signing' and select your signing identity and provisioning profile.

- these should be automatic by default but if you get an error you can manually set them.
- if you don't have these, talk to another Team Member or Sys Admin and get them to add your appleID to the Superior Software for Windows Pty Ltd
Apple Developer Program Team)
- These should be automatic by default but if you get an error you can manually set them.
- If you don't have these, talk to another Team Member or Sys Admin and get them to add your AppleID to the Superior Software for Windows Pty Ltd
Apple Developer Program Team
### Setting up for Apple Development (on your own phone)
### Setting up for Apple Development (on your own iPhone)
If you want to set up to deploy to your own iPhone, talk to an App Manager (it's hard :))!

### Admin Portal
1. Get the source code
1. `git clone https://github.com/SSWConsulting/SSW.Rewards.Mobile.git`

[Now you are setup, lets get started on a PBI](Definition-of-Ready.md)

Be sure to read the [Definition of done](Definition-of-Done.md) and the [Definition of ready](Definition-of-Ready.md)
54 changes: 54 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: '3'

services:
# SQL Server
azuresqledge:
image: mcr.microsoft.com/azure-sql-edge:latest
environment:
- MSSQL_SA_PASSWORD=Rewards.Docker1!
- ACCEPT_EULA=1
ports:
- 1433:1433

# Azurite
azurite:
image: mcr.microsoft.com/azure-storage/azurite
ports:
- 10000:10000
- 10001:10001
- 10002:10002

# API
webapi:
depends_on:
- azuresqledge
build:
dockerfile: src/WebAPI/Dockerfile
ports:
- 5001:5001
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:5001
- ASPNETCORE_Kestrel__Certificates__Default__Password=ThisPassword
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/WebAPI.pfx
volumes:
- ~/.aspnet/https:/https:ro
profiles: ['all', 'webapi']


# Admin UI
adminui:
depends_on:
- azuresqledge
build:
dockerfile: src/AdminUI/Dockerfile
ports:
- 7137:7137
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:7137
- ASPNETCORE_Kestrel__Certificates__Default__Password=ThisPassword
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/WebAPI.pfx
volumes:
- ~/.aspnet/https:/https:ro
profiles: ['all', 'admin']
4 changes: 4 additions & 0 deletions src/AdminUI/AdminUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<IsPackable>false</IsPackable>
<TreatWarningsAsErrors Condition="'$(Configuration)' != 'Debug'">False</TreatWarningsAsErrors>
<RunCodeAnalysis Condition="'$(BuildingForLiveUnitTesting)' == 'true'">False</RunCodeAnalysis>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

<ItemGroup>
Expand All @@ -36,6 +37,9 @@
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\..\.dockerignore">
<Link>.dockerignore</Link>
</Content>
<Content Include=".codeanalysis\codeanalysis.ruleset" />
<Content Include=".codeanalysis\stylecop.json" />
<None Include="Components\Dialogs\Quizzes\QuizQuestionDialog.razor" />
Expand Down
39 changes: 39 additions & 0 deletions src/AdminUI/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["src/WebAPI/WebAPI.csproj", "src/WebAPI/"]
COPY ["src/Application/SSW.Rewards.Application.csproj", "src/Application/"]
COPY ["src/Domain/SSW.Rewards.Domain.csproj", "src/Domain/"]
COPY ["src/SSW.Rewards.Enums/SSW.Rewards.Enums.csproj", "src/SSW.Rewards.Enums/"]
COPY ["src/Common/Shared.csproj", "src/Common/"]
COPY ["src/Infrastructure/SSW.Rewards.Infrastructure.csproj", "src/Infrastructure/"]
RUN dotnet restore "src/AdminUI/AdminUI.csproj"

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS development
COPY . /src
WORKDIR /src/src/AdminUI
RUN dotnet dev-certs https
RUN dotnet dev-certs https --trust
CMD dotnet run --no-launch-profile

# FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
# ARG BUILD_CONFIGURATION=Release

# WORKDIR /app
# COPY [".", "./"]

# RUN dotnet publish "src/AdminUI/AdminUI.csproj" -c $BUILD_CONFIGURATION -o output

# # Prepare an Alpine-based image with OpenSSL.
# FROM alpine:latest as alpine
# RUN apk add --no-cache openssl
# RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt -subj "/C=GB/CN=localhost"

# FROM nginx
# # Copy the certificate files from the Alpine image.
# COPY --from=alpine localhost.key /etc/nginx/ssl/localhost.key
# COPY --from=alpine localhost.crt /etc/nginx/ssl/localhost.crt
# # COPY --from=build /app/src/Presentation/UI/AdminUI/nginx/nginx-ssl.conf /etc/nginx/conf.d/default.conf

# # Copy Blazor App
# WORKDIR /usr/share/nginx/html
# COPY --from=build /app/output/wwwroot .
2 changes: 1 addition & 1 deletion src/AdminUI/wwwroot/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Local": {
"Authority": /*"https://app-ssw-ident-staging-api.azurewebsites.net/",*/"https://localhost:5003/",
"Authority": "https://app-ssw-ident-staging-api.azurewebsites.net/",
"ClientId": "ssw-rewards-admin-portal"
},
"RewardsApiUrl": "https://localhost:5001/"
Expand Down
26 changes: 26 additions & 0 deletions src/WebAPI/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Learn about building .NET container images:
# https://github.com/dotnet/dotnet-docker/blob/main/samples/README.md
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["src/WebAPI/WebAPI.csproj", "src/WebAPI/"]
COPY ["src/Application/SSW.Rewards.Application.csproj", "src/Application/"]
COPY ["src/Domain/SSW.Rewards.Domain.csproj", "src/Domain/"]
COPY ["src/SSW.Rewards.Enums/SSW.Rewards.Enums.csproj", "src/SSW.Rewards.Enums/"]
COPY ["src/Common/Shared.csproj", "src/Common/"]
COPY ["src/Infrastructure/SSW.Rewards.Infrastructure.csproj", "src/Infrastructure/"]
RUN dotnet restore "src/WebAPI/WebAPI.csproj"

COPY . .
WORKDIR "/src/src/WebAPI"

# copy and publish app and libraries
RUN dotnet publish "WebAPI.csproj" --no-restore -o /app /p:UseAppHost=false


# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
EXPOSE 5001
WORKDIR /app
COPY --from=build /app .
USER $APP_UID
ENTRYPOINT ["dotnet", "SSW.Rewards.WebAPI.dll"]
7 changes: 7 additions & 0 deletions src/WebAPI/WebAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<IsPackable>true</IsPackable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>aspnet-SSW.Consulting-116EE6F2-C844-46F8-A58B-6C88A6F3588C</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

<ItemGroup>
Expand All @@ -32,6 +33,12 @@
<InternalsVisibleTo Include="SSW.Rewards.WebAPI.AcceptanceTests" />
</ItemGroup>

<ItemGroup>
<Content Include="..\..\.dockerignore">
<Link>.dockerignore</Link>
</Content>
</ItemGroup>

<PropertyGroup>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
</PropertyGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/WebAPI/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ConnectionStrings": {
"DefaultConnection": "<check in secrets.json>"
"DefaultConnection": "TrustServerCertificate=True; Server=azuresqledge; User Id=SA; Password=Rewards.Docker1!; Database=ssw.rewards"
},
"Logging": {
"LogLevel": {
Expand Down Expand Up @@ -29,7 +29,7 @@
"SendGridAPIKey": "<check in secrets.json>",

//"SigningAuthority": "https://ids.goforgoldman.com",
//"SigningAuthority": "https://app-ssw-ident-staging-api.azurewebsites.net/"
"SigningAuthority": "https://app-ssw-ident-staging-api.azurewebsites.net"
//"SigningAuthority": "https://identity.ssw.com.au"
"SigningAuthority": "https://localhost:5003"
//"SigningAuthority": "https://localhost:5003"
}

0 comments on commit f392929

Please sign in to comment.