-
Notifications
You must be signed in to change notification settings - Fork 2
Docker build stabilization with comprehensive SSL handling and multi-environment support #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
c0e2086
cdff5e5
7eeedbc
f0fdda2
00ba297
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -352,6 +352,25 @@ jobs: | |||||||||
- name: Set up Docker Buildx | ||||||||||
uses: docker/setup-buildx-action@v3 | ||||||||||
|
||||||||||
- name: Log in to GitHub Container Registry | ||||||||||
uses: docker/login-action@v3 | ||||||||||
with: | ||||||||||
registry: ghcr.io | ||||||||||
username: ${{ github.actor }} | ||||||||||
password: ${{ secrets.GITHUB_TOKEN }} | ||||||||||
|
||||||||||
- name: Extract metadata for Docker | ||||||||||
id: meta | ||||||||||
uses: docker/metadata-action@v5 | ||||||||||
with: | ||||||||||
images: ghcr.io/${{ github.repository }}/demo | ||||||||||
tags: | | ||||||||||
type=ref,event=branch | ||||||||||
type=ref,event=pr | ||||||||||
type=semver,pattern={{version}} | ||||||||||
type=semver,pattern={{major}}.{{minor}} | ||||||||||
type=raw,value=latest,enable={{is_default_branch}} | ||||||||||
|
||||||||||
- name: Build Docker image (test build) | ||||||||||
run: | | ||||||||||
echo "🐳 Building Docker image for testing..." | ||||||||||
|
@@ -365,14 +384,29 @@ jobs: | |||||||||
docker run -d --name nlwebnet-test -p 8080:8080 nlwebnet-demo:test | ||||||||||
|
||||||||||
# Wait for container to start | ||||||||||
sleep 5 | ||||||||||
sleep 10 | ||||||||||
|
||||||||||
# Check if container is running (basic test) | ||||||||||
if docker ps | grep nlwebnet-test; then | ||||||||||
echo "✅ Container is running" | ||||||||||
|
||||||||||
# Test health endpoint if available | ||||||||||
echo "🔍 Testing health endpoint..." | ||||||||||
for i in {1..5}; do | ||||||||||
if curl -f -s http://localhost:8080/health >/dev/null 2>&1; then | ||||||||||
echo "✅ Health endpoint responds successfully" | ||||||||||
break | ||||||||||
elif [ $i -eq 5 ]; then | ||||||||||
echo "⚠️ Health endpoint not responding (may be expected)" | ||||||||||
else | ||||||||||
echo "⏳ Waiting for health endpoint... (attempt $i/5)" | ||||||||||
sleep 3 | ||||||||||
fi | ||||||||||
done | ||||||||||
|
||||||||||
# Show container logs for debugging | ||||||||||
echo "📋 Container logs:" | ||||||||||
docker logs nlwebnet-test | ||||||||||
echo "📋 Recent container logs:" | ||||||||||
docker logs --tail 10 nlwebnet-test | ||||||||||
else | ||||||||||
echo "❌ Container failed to start" | ||||||||||
docker logs nlwebnet-test | ||||||||||
|
@@ -383,6 +417,31 @@ jobs: | |||||||||
docker stop nlwebnet-test | ||||||||||
docker rm nlwebnet-test | ||||||||||
|
||||||||||
- name: Build and push Docker image to GHCR | ||||||||||
uses: docker/build-push-action@v5 | ||||||||||
with: | ||||||||||
context: . | ||||||||||
file: deployment/docker/Dockerfile | ||||||||||
push: true | ||||||||||
tags: ${{ steps.meta.outputs.tags }} | ||||||||||
labels: ${{ steps.meta.outputs.labels }} | ||||||||||
cache-from: type=gha | ||||||||||
cache-to: type=gha,mode=max | ||||||||||
|
||||||||||
- name: Generate deployment summary | ||||||||||
run: | | ||||||||||
echo "## 🐳 Docker Build Summary" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "- **Image**: \`ghcr.io/${{ github.repository }}/demo\`" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "- **Tags**: ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "- **Build Status**: ✅ Success" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "- **Smoke Test**: ✅ Passed" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "### Usage" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "docker pull ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | ||||||||||
echo "docker run -p 8080:8080 ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same issue as the previous line -
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | ||||||||||
|
||||||||||
# Alternative: .NET SDK Container Build (modern approach) | ||||||||||
dotnet-container-build: | ||||||||||
runs-on: ubuntu-latest | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
# Docker Build Guide for NLWebNet | ||
|
||
This document provides guidance for building Docker containers for the NLWebNet Demo application, including workarounds for common SSL issues in certain environments. | ||
|
||
## Quick Start | ||
|
||
### Standard Build (GitHub Actions / CI) | ||
|
||
For CI/CD environments with proper SSL configuration: | ||
|
||
```bash | ||
docker build -f deployment/docker/Dockerfile -t nlwebnet-demo:latest . | ||
``` | ||
|
||
### Local Development Build | ||
|
||
For local development environments that may have SSL certificate issues: | ||
|
||
```bash | ||
# Use the automated build script that handles SSL issues | ||
./deployment/docker/build-docker.sh | ||
``` | ||
|
||
## Build Approaches | ||
|
||
### 1. Standard Dockerfile (Recommended for CI/CD) | ||
|
||
**File**: `deployment/docker/Dockerfile` | ||
|
||
- Restores NuGet packages during Docker build | ||
- Optimized for CI/CD environments | ||
- Uses multi-stage build for minimal final image | ||
- Includes SSL certificate handling improvements | ||
|
||
### 2. Pre-built Approach (Fallback for SSL Issues) | ||
|
||
**File**: `deployment/docker/Dockerfile.pre-built` | ||
|
||
- Requires packages to be restored on host before build | ||
- Bypasses SSL issues by using `--no-restore` | ||
- Useful for environments with network restrictions | ||
|
||
## SSL Certificate Issues | ||
|
||
### Problem | ||
|
||
In some Docker environments, you may encounter SSL certificate validation errors: | ||
|
||
``` | ||
error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json | ||
The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot | ||
``` | ||
|
||
### Solutions | ||
|
||
1. **Use GitHub Actions** (Recommended) | ||
- CI/CD environments typically have proper SSL configuration | ||
- The workflow automatically builds and publishes to GHCR | ||
|
||
2. **Pre-restore packages locally**: | ||
```bash | ||
dotnet restore | ||
docker build -f deployment/docker/Dockerfile.pre-built -t nlwebnet-demo . | ||
``` | ||
|
||
3. **Use the automated build script**: | ||
```bash | ||
./deployment/docker/build-docker.sh | ||
``` | ||
|
||
## Testing the Container | ||
|
||
### Health Check | ||
|
||
The container includes a health check endpoint: | ||
|
||
```bash | ||
# Start the container | ||
docker run -p 8080:8080 nlwebnet-demo:latest | ||
|
||
# Test health endpoint | ||
curl http://localhost:8080/health | ||
``` | ||
|
||
### Automated Smoke Test | ||
|
||
Use the provided smoke test script: | ||
|
||
```bash | ||
# Run smoke test on built image | ||
./deployment/docker/smoke-test.sh nlwebnet-demo:latest | ||
``` | ||
|
||
## GitHub Container Registry (GHCR) | ||
|
||
The GitHub Actions workflow automatically publishes images to GHCR: | ||
|
||
```bash | ||
# Pull from GHCR | ||
docker pull ghcr.io/nlweb-ai/nlweb-net/demo:latest | ||
|
||
# Run the image | ||
docker run -p 8080:8080 ghcr.io/nlweb-ai/nlweb-net/demo:latest | ||
``` | ||
|
||
## Environment Variables | ||
|
||
Key environment variables for the container: | ||
|
||
- `ASPNETCORE_ENVIRONMENT`: Set to `Production` by default | ||
- `ASPNETCORE_URLS`: Set to `http://+:8080` | ||
- `ASPNETCORE_HTTP_PORTS`: Set to `8080` | ||
|
||
## Security | ||
|
||
- Container runs as non-root user (`nlwebnet`) | ||
- Uses minimal ASP.NET Core runtime image | ||
- Includes security best practices | ||
|
||
## Troubleshooting | ||
|
||
### Build Issues | ||
|
||
1. **SSL Certificate Errors**: Use pre-built approach or build in CI | ||
2. **Package Restore Fails**: Ensure internet connectivity and DNS resolution | ||
3. **Permission Denied**: Check Docker daemon permissions | ||
|
||
### Runtime Issues | ||
|
||
1. **Container won't start**: Check logs with `docker logs <container-name>` | ||
2. **Health check fails**: Verify port 8080 is accessible | ||
3. **Application errors**: Check environment variables and configuration | ||
|
||
## Contributing | ||
|
||
When making changes to Docker configuration: | ||
|
||
1. Test both Dockerfile approaches | ||
2. Update this documentation | ||
3. Verify the smoke test passes | ||
4. Ensure GitHub Actions workflow succeeds |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#!/bin/bash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||
# Build script for Docker container in environments with SSL issues | ||
# This script prepares a build-ready environment and builds the Docker image | ||
|
||
set -euo pipefail | ||
|
||
echo "🔧 Building NLWebNet Docker image with SSL workarounds..." | ||
|
||
# Check if we're in the right directory | ||
if [ ! -f "NLWebNet.sln" ]; then | ||
echo "❌ Error: Must be run from repository root directory" | ||
exit 1 | ||
fi | ||
|
||
# Pre-restore packages locally to avoid SSL issues in Docker | ||
echo "📦 Pre-restoring packages locally..." | ||
dotnet restore | ||
|
||
# Build the Docker image with appropriate strategy based on environment | ||
echo "🐳 Building Docker image..." | ||
|
||
# Build the Docker image | ||
if docker build -f deployment/docker/Dockerfile . -t nlwebnet-demo:latest; then | ||
echo "✅ Docker build successful" | ||
else | ||
echo "❌ Docker build failed" | ||
exit 1 | ||
fi | ||
|
||
echo "🎉 Docker image build completed successfully!" | ||
echo "📝 To run the container: docker run -p 8080:8080 nlwebnet-demo:latest" | ||
echo "🔍 To test health endpoint: curl http://localhost:8080/health" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
steps.meta.outputs.tags
contains multiple tags separated by newlines, but this will only show the first tag in the docker pull command. This could confuse users about which tag to actually pull. Consider using a specific tag likelatest
or the first tag from the list.Copilot uses AI. Check for mistakes.