Skip to content
Open

P04 #57

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
37 changes: 37 additions & 0 deletions Dockerfile.dotnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Stage 1: Build stage
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS builder

WORKDIR /src

# Copy project files
COPY dotnet/SimpleSocialMediaApplication/ .

# Restore and build
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish

# Stage 2: Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:10.0

WORKDIR /app

# Set environment variables
ENV ASPNETCORE_URLS=http://+:8000 \
DOTNET_URLS=http://+:8000

# Install curl for health checks
RUN apt-get update && apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*

# Copy published application from builder
COPY --from=builder /app/publish .

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000 || exit 1

# Run the application
CMD ["dotnet", "SimpleSocialMediaApplication.dll"]
41 changes: 41 additions & 0 deletions Dockerfile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Stage 1: Build stage
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu AS builder

WORKDIR /app

# Install Maven
RUN apt-get update && apt-get install -y maven && rm -rf /var/lib/apt/lists/*

# Copy Maven files
COPY java/socialapp/pom.xml .
COPY java/socialapp/src ./src

# Build the application
RUN mvn clean package -DskipTests

# Stage 2: Runtime stage
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu

WORKDIR /app

# Set environment variables
ENV PATH="/usr/local/openjdk-21/bin:${PATH}" \
JAVA_HOME="/usr/local/openjdk-21"

# Install SQLite and create database
RUN apt-get update && apt-get install -y sqlite3 curl && \
rm -rf /var/lib/apt/lists/* && \
sqlite3 /app/sns_api.db < /dev/null

# Copy the built JAR from builder stage
COPY --from=builder /app/target/socialapp-*.jar /app/socialapp.jar

# Expose port
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1

# Run the application
CMD ["java", "-jar", "/app/socialapp.jar"]
59 changes: 59 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
services:
contoso-backend:
build:
context: .
dockerfile: Dockerfile.java
image: contoso-backend:latest
container_name: contoso-backend
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- CODESPACE_NAME=${CODESPACE_NAME:-local}
- GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN=${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN:-localhost}
volumes:
- backend-data:/app/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
networks:
- contoso-network
restart: unless-stopped

contoso-frontend:
build:
context: .
dockerfile: Dockerfile.dotnet
image: contoso-frontend:latest
container_name: contoso-frontend
ports:
- "5000:8000"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:8000
- API_BASE_URL=http://contoso-backend:8080
- CODESPACE_NAME=${CODESPACE_NAME:-local}
- GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN=${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN:-localhost}
depends_on:
contoso-backend:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
networks:
- contoso-network
restart: unless-stopped

volumes:
backend-data:
driver: local

networks:
contoso-network:
driver: bridge
6 changes: 6 additions & 0 deletions dotnet/SimpleSocialMediaApplication/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Router AppAssembly="@typeof(App).Assembly" NotFoundPage="typeof(Pages.NotFound)">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
16 changes: 16 additions & 0 deletions dotnet/SimpleSocialMediaApplication/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>

<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>

<article class="content px-4">
@Body
</article>
</main>
</div>
77 changes: 77 additions & 0 deletions dotnet/SimpleSocialMediaApplication/Layout/MainLayout.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}

.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}

@media (min-width: 641px) {
.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
39 changes: 39 additions & 0 deletions dotnet/SimpleSocialMediaApplication/Layout/NavMenu.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">SimpleSocialMediaApplication</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>

<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
<nav class="nav flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
</NavLink>
</div>
</nav>
</div>

@code {
private bool collapseNavMenu = true;

private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
83 changes: 83 additions & 0 deletions dotnet/SimpleSocialMediaApplication/Layout/NavMenu.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}

.top-row {
min-height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}

.navbar-brand {
font-size: 1.1rem;
}

.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}

.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}

.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}

.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}

.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}

.nav-item:first-of-type {
padding-top: 1rem;
}

.nav-item:last-of-type {
padding-bottom: 1rem;
}

.nav-item ::deep a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}

.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}

.nav-item ::deep a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}

@media (min-width: 641px) {
.navbar-toggler {
display: none;
}

.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}

.nav-scrollable {
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}
Loading