-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile.original
More file actions
380 lines (360 loc) · 13.5 KB
/
Copy pathDockerfile.original
File metadata and controls
380 lines (360 loc) · 13.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# ===========================================================================================
# DOCKERFILE - BlueTreadApp (Blazor .NET 8 Application)
# ===========================================================================================
# Multi-stage build for optimal image size and security
# Stage 1: Build - Full SDK image with build tools
# Stage 2: Runtime - Minimal runtime image with only necessary dependencies
#
# Benefits of multi-stage builds:
# - Smaller final image (runtime-only, no build tools)
# - Better security (fewer components = smaller attack surface)
# - Faster deployments (smaller images transfer faster)
# - Layer caching (faster rebuilds)
# ===========================================================================================
# ===========================================================================================
# STAGE 1: BUILD
# ===========================================================================================
# Use official .NET 8 SDK image for building the application
# This image includes:
# - .NET 8 SDK (compiler, build tools)
# - NuGet package manager
# - MSBuild
# - All build-time dependencies
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
# Set working directory for build
# All subsequent commands run in this directory
WORKDIR /src
# ===== CONFIGURE NUGET FOR BETTER RELIABILITY =====
# Add explicit NuGet source with increased timeout and retry settings
# This resolves most "Unable to load service index" errors
RUN dotnet nuget list source || true \
&& dotnet nuget add source https://api.nuget.org/v3/index.json \
--name nuget.org \
--configfile /root/.nuget/NuGet/NuGet.Config \
|| echo "NuGet source already exists" \
&& echo "Configured NuGet sources:" \
&& dotnet nuget list source
# ===== COPY PROJECT FILE FIRST (LAYER CACHING OPTIMIZATION) =====
# Copy only .csproj first to leverage Docker layer caching
# If project file hasn't changed, Docker reuses cached NuGet restore layer
# This significantly speeds up rebuilds when only source code changes
COPY ["BlueTreadApp.csproj", "./"]
# ===== RESTORE NUGET PACKAGES =====
# Restore NuGet packages separately for better caching
# Docker caches this layer and only re-runs if .csproj changes
# Uses NuGet package cache to speed up restoration
# Added flags for better reliability:
# --disable-parallel: Prevent parallel restore issues that can cause network errors
# --verbosity normal: Provide useful output without being too verbose
# --force-evaluate: Re-evaluate all dependencies
RUN echo "Starting NuGet restore..." \
&& dotnet restore "BlueTreadApp.csproj" \
--disable-parallel \
--verbosity normal \
--runtime linux-x64 \
&& echo "NuGet restore completed successfully"
# ===== COPY SOURCE CODE =====
# Copy all application source files
# Done after restore to maximize cache hits
# If only code changes (not dependencies), restore layer is cached
COPY . .
# ===== BUILD APPLICATION =====
# Build the application in Release configuration
# Release mode optimizations:
# - Code optimization enabled
# - Debug symbols removed
# - Smaller output size
# - Better runtime performance
RUN echo "Starting build..." \
&& dotnet build "BlueTreadApp.csproj" \
--configuration Release \
--no-restore \
--output /app/build \
&& echo "Build completed successfully"
# ===========================================================================================
# STAGE 2: PUBLISH
# ===========================================================================================
# Publish application for deployment
# Creates optimized, self-contained deployment package
FROM build AS publish
# ===== PUBLISH APPLICATION =====
# Publish creates deployment-ready output
# Options:
# --configuration Release: Production optimizations
# --no-build: Reuse build from previous stage
# --output: Destination directory for published files
#
# Published output includes:
# - Compiled assemblies (.dll)
# - Configuration files (appsettings.json)
# - Static files (wwwroot)
# - Runtime dependencies
RUN echo "Starting publish..." \
&& dotnet publish "BlueTreadApp.csproj" \
--configuration Release \
--no-build \
--output /app/publish \
/p:UseAppHost=false \
&& echo "Publish completed successfully"
# ===========================================================================================
# STAGE 3: RUNTIME (FINAL IMAGE)
# ===========================================================================================
# Use minimal ASP.NET Core runtime image
# This image includes ONLY:
# - ASP.NET Core runtime (no SDK)
# - Kestrel web server
# - Minimal OS dependencies
#
# Size comparison:
# - SDK image: ~700 MB
# - Runtime image: ~200 MB
# - Final image: ~220 MB (with your app)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
# ===== CREATE NON-ROOT USER (SECURITY BEST PRACTICE) =====
# Running as non-root reduces security risks
# If container is compromised, attacker has limited privileges
RUN addgroup --system --gid 1000 appuser && \
adduser --system --uid 1000 --ingroup appuser --shell /bin/sh appuser
# ===== SET WORKING DIRECTORY =====
WORKDIR /app
# ===== EXPOSE PORTS =====
# Document which ports the application listens on
# Note: EXPOSE is documentation only, doesn't actually publish ports
# Use -p flag when running container: docker run -p 8080:8080
#
# Port 8080: Standard HTTP port for containerized apps
# Port 8081: Alternative HTTPS port (if configured)
EXPOSE 8080
EXPOSE 8081
# ===== COPY PUBLISHED APPLICATION =====
# Copy published output from publish stage
# --chown: Set ownership to non-root user
# --from=publish: Copy from previous build stage
COPY --chown=appuser:appuser --from=publish /app/publish .
# ===== SWITCH TO NON-ROOT USER =====
# All subsequent commands and container runtime use this user
# Security: Container doesn't run as root
USER appuser
# ===== CONFIGURE ENVIRONMENT =====
# Set ASP.NET Core to listen on all network interfaces
# Required for container networking (localhost won't work)
# 0.0.0.0 means "listen on all available network interfaces"
ENV ASPNETCORE_URLS=http://+:8080
# Optional: Set environment to Production
# Can be overridden with docker run -e ASPNETCORE_ENVIRONMENT=Development
# ENV ASPNETCORE_ENVIRONMENT=Production
# ===== HEALTH CHECK =====
# Built-in health check without requiring curl
# Uses dotnet's built-in HTTP client
# Note: This requires .NET 8 which has built-in health check support
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD dotnet /app/BlueTreadApp.dll --urls "http://localhost:8080" --check || exit 1
# ===== DEFINE ENTRY POINT =====
# Command to run when container starts
# Starts the Kestrel web server with your application
# DLL name must match your project name
ENTRYPOINT ["dotnet", "BlueTreadApp.dll"]
# ===========================================================================================
# BUILD & RUN INSTRUCTIONS
# ===========================================================================================
#
# BUILD IMAGE:
# docker build -t bluetreadapp:latest .
# docker build -t yourdockerhubusername/bluetreadapp:latest .
# docker build -t yourdockerhubusername/bluetreadapp:v1.0.0 .
#
# BUILD WITH NETWORK MODE (if DNS issues persist):
# docker build --network=host -t bluetreadapp:latest .
#
# BUILD WITH BUILDKIT (RECOMMENDED):
# DOCKER_BUILDKIT=1 docker build -t bluetreadapp:latest .
#
# RUN CONTAINER (Basic):
# docker run -d -p 8080:8080 --name bluetreadapp bluetreadapp:latest
#
# RUN CONTAINER (with environment variables):
# docker run -d \
# -p 8080:8080 \
# --name bluetreadapp \
# -e ASPNETCORE_ENVIRONMENT=Production \
# -e JwtSettings__SecretKey="YourProductionSecretKey" \
# -e ThirdPartyApi__ApiKey="YourActualApiKey" \
# -e Azure__KeyVaultUri="https://your-vault.vault.azure.net/" \
# bluetreadapp:latest
#
# RUN CONTAINER (with Azure Key Vault):
# docker run -d \
# -p 8080:8080 \
# --name bluetreadapp \
# -e ASPNETCORE_ENVIRONMENT=Production \
# -e Azure__KeyVaultUri="https://your-vault.vault.azure.net/" \
# -e AZURE_CLIENT_ID="your-managed-identity-client-id" \
# -e AZURE_CLIENT_SECRET="your-service-principal-secret" \
# -e AZURE_TENANT_ID="your-tenant-id" \
# bluetreadapp:latest
#
# PUSH TO DOCKER HUB:
# docker login
# docker push yourdockerhubusername/bluetreadapp:latest
# docker push yourdockerhubusername/bluetreadapp:v1.0.0
#
# PULL FROM DOCKER HUB:
# docker pull yourdockerhubusername/bluetreadapp:latest
#
# VIEW RUNNING CONTAINERS:
# docker ps
#
# VIEW LOGS:
# docker logs bluetreadapp
# docker logs -f bluetreadapp (follow logs in real-time)
#
# STOP CONTAINER:
# docker stop bluetreadapp
#
# REMOVE CONTAINER:
# docker rm bluetreadapp
#
# REMOVE IMAGE:
# docker rmi bluetreadapp:latest
#
# ===========================================================================================
# TROUBLESHOOTING CONNECTIVITY ISSUES
# ===========================================================================================
#
# If you see apt-get or NuGet connectivity errors (exit code: 100):
#
# 1. CHECK DOCKER DNS:
# - Docker Desktop -> Settings -> Docker Engine
# - Add DNS configuration:
# {
# "dns": ["8.8.8.8", "8.8.4.4"]
# }
# - Click "Apply & Restart"
#
# 2. BUILD WITH HOST NETWORK:
# docker build --network=host -t bluetreadapp:latest .
# docker-compose build (already configured with host network)
#
# 3. USE BUILDKIT:
# DOCKER_BUILDKIT=1 docker build --network=host -t bluetreadapp:latest .
#
# 4. CLEAR BUILD CACHE:
# docker builder prune -a
# docker build --no-cache -t bluetreadapp:latest .
#
# 5. RESTART DOCKER DESKTOP:
# - Quit Docker Desktop completely
# - Wait 10 seconds
# - Start Docker Desktop
# - Wait for green icon in system tray
# - Retry build
#
# 6. DISABLE VPN/PROXY TEMPORARILY:
# - Disconnect from VPN
# - Retry build
# - If successful, configure VPN to allow Docker
#
# 7. CHECK INTERNET CONNECTION:
# - Ensure stable internet connection
# - Test: curl https://api.nuget.org/v3/index.json
# - Test: curl http://deb.debian.org
#
# ===========================================================================================
# DOCKER COMPOSE EXAMPLE
# ===========================================================================================
# Create docker-compose.yml for easier management:
#
# services:
# bluetreadapp:
# build:
# context: .
# dockerfile: Dockerfile
# network: host
# image: bluetreadapp:latest
# container_name: bluetreadapp
# ports:
# - "8080:8080"
# dns:
# - 8.8.8.8
# - 8.8.4.4
# environment:
# - ASPNETCORE_ENVIRONMENT=Production
# - JwtSettings__SecretKey=${JWT_SECRET_KEY}
# - ThirdPartyApi__ApiKey=${THIRDPARTY_API_KEY}
# restart: unless-stopped
#
# Run with docker-compose:
# docker-compose up -d --build
# docker-compose down
# docker-compose logs -f
#
# ===========================================================================================
# PRODUCTION DEPLOYMENT NOTES
# ===========================================================================================
#
# AZURE CONTAINER INSTANCES (ACI):
# az container create \
# --resource-group myResourceGroup \
# --name bluetreadapp \
# --image yourdockerhubusername/bluetreadapp:latest \
# --dns-name-label bluetreadapp \
# --ports 8080 \
# --environment-variables \
# ASPNETCORE_ENVIRONMENT=Production \
# Azure__KeyVaultUri=https://your-vault.vault.azure.net/
#
# AZURE CONTAINER APPS:
# az containerapp create \
# --name bluetreadapp \
# --resource-group myResourceGroup \
# --environment myEnvironment \
# --image yourdockerhubusername/bluetreadapp:latest \
# --target-port 8080 \
# --ingress external \
# --env-vars \
# ASPNETCORE_ENVIRONMENT=Production \
# Azure__KeyVaultUri=https://your-vault.vault.azure.net/
#
# AZURE KUBERNETES SERVICE (AKS):
# kubectl create deployment bluetreadapp --image=yourdockerhubusername/bluetreadapp:latest
# kubectl expose deployment bluetreadapp --type=LoadBalancer --port=80 --target-port=8080
#
# AWS ECS/Fargate:
# Use AWS Console or CLI to create ECS service with this image
#
# GOOGLE CLOUD RUN:
# gcloud run deploy bluetreadapp \
# --image yourdockerhubusername/bluetreadapp:latest \
# --platform managed \
# --region us-central1 \
# --allow-unauthenticated
#
# ===========================================================================================
# SECURITY RECOMMENDATIONS
# ===========================================================================================
#
# 1. SECRETS MANAGEMENT:
# - Never hardcode secrets in Dockerfile
# - Use environment variables or Azure Key Vault
# - Rotate secrets regularly
# - Use Docker secrets or Kubernetes secrets in orchestrated environments
#
# 2. IMAGE SECURITY:
# - Scan images for vulnerabilities: docker scan bluetreadapp:latest
# - Use minimal base images (aspnet runtime, not SDK)
# - Run as non-root user (already configured)
# - Keep base images updated regularly
#
# 3. NETWORK SECURITY:
# - Use HTTPS in production (configure reverse proxy)
# - Implement rate limiting (already configured in app)
# - Use firewall rules to restrict access
# - Consider using Azure Front Door or Application Gateway
#
# 4. MONITORING:
# - Implement health checks
# - Set up logging (Azure Application Insights, ELK, etc.)
# - Monitor resource usage (CPU, memory, network)
# - Set up alerts for errors and performance issues
#
# ===========================================================================================