db4f1ba6fc
Revised the section on building and running Docker images to include a recommended PowerShell script for publishing to a Docker registry. Added detailed options and examples for using the script, while maintaining the manual build instructions for flexibility. This update improves clarity and usability for developers deploying the application.
321 lines
7.3 KiB
Markdown
321 lines
7.3 KiB
Markdown
# Docker Deployment Guide
|
|
|
|
## Authentication Configuration for Production
|
|
|
|
The application supports two methods for configuring authentication credentials in Docker:
|
|
|
|
### Option 1: Volume-Mounted JSON File (Recommended)
|
|
|
|
This approach allows you to edit credentials without rebuilding the container.
|
|
|
|
**Steps:**
|
|
|
|
1. **Generate Password Hashes** (on your development machine):
|
|
|
|
```bash
|
|
# Run the app locally and navigate to:
|
|
https://localhost:<port>/dev/hash-password?password=YourPassword
|
|
```
|
|
2. **Create `auth-secrets.json`** on your Docker host:
|
|
|
|
```bash
|
|
cp auth-secrets.example.json auth-secrets.json
|
|
```
|
|
3. **Edit `auth-secrets.json`** and replace the placeholder hashes:
|
|
|
|
```json
|
|
{
|
|
"Authentication": {
|
|
"Users": [
|
|
{
|
|
"Email": "admin@example.com",
|
|
"PasswordHash": "$2a$11$actual.hash.here",
|
|
"Role": "Administrator",
|
|
"DisplayName": "Administrator"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
4. **Mount the file in Docker Compose**:
|
|
|
|
```yaml
|
|
volumes:
|
|
- ./auth-secrets.json:/app/secrets/auth-secrets.json:ro
|
|
```
|
|
5. **Update credentials**: Simply edit `auth-secrets.json` on the host and restart the container:
|
|
|
|
```bash
|
|
docker-compose restart webapp
|
|
```
|
|
|
|
**Security Note**: Set proper file permissions on the host:
|
|
|
|
```bash
|
|
chmod 600 auth-secrets.json
|
|
```
|
|
|
|
---
|
|
|
|
### Option 2: Environment Variables
|
|
|
|
This approach is useful for container orchestration platforms (Kubernetes, Docker Swarm, etc.).
|
|
|
|
**Docker Compose Example**:
|
|
|
|
```yaml
|
|
environment:
|
|
- TSA_Authentication__Users__0__Email=admin@example.com
|
|
- TSA_Authentication__Users__0__PasswordHash=$2a$11$hash...
|
|
- TSA_Authentication__Users__0__Role=Administrator
|
|
- TSA_Authentication__Users__0__DisplayName=Administrator
|
|
- TSA_Authentication__Users__1__Email=advisor@example.com
|
|
- TSA_Authentication__Users__1__PasswordHash=$2a$11$hash...
|
|
- TSA_Authentication__Users__1__Role=Advisor
|
|
- TSA_Authentication__Users__1__DisplayName=Chapter Advisor
|
|
```
|
|
|
|
**Docker Run Example**:
|
|
|
|
```bash
|
|
docker run -d \
|
|
-p 8080:8080 \
|
|
-e ASPNETCORE_ENVIRONMENT=Production \
|
|
-e TSA_Authentication__Users__0__Email=admin@example.com \
|
|
-e TSA_Authentication__Users__0__PasswordHash='$2a$11$hash...' \
|
|
-e TSA_Authentication__Users__0__Role=Administrator \
|
|
-e TSA_Authentication__Users__0__DisplayName=Administrator \
|
|
tsa-chapter-organizer:latest
|
|
```
|
|
|
|
**Kubernetes Secret Example**:
|
|
|
|
```yaml
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: tsa-auth-secrets
|
|
type: Opaque
|
|
stringData:
|
|
TSA_Authentication__Users__0__Email: "admin@example.com"
|
|
TSA_Authentication__Users__0__PasswordHash: "$2a$11$hash..."
|
|
TSA_Authentication__Users__0__Role: "Administrator"
|
|
TSA_Authentication__Users__0__DisplayName: "Administrator"
|
|
```
|
|
|
|
---
|
|
|
|
## Building and Running
|
|
|
|
### Publish to Docker Registry (Recommended)
|
|
|
|
Use the provided PowerShell script to build and publish the Docker image:
|
|
|
|
```powershell
|
|
.\publish-docker.ps1
|
|
```
|
|
|
|
**Options:**
|
|
- `-Tag "v1.0.0"` - Specify a custom tag (default: "latest")
|
|
- `-Registry "docker-registry.kolpacksoftware.com"` - Specify registry URL
|
|
- `-ImageName "tsa-chapter-organizer"` - Specify image name
|
|
- `-BuildConfiguration "Release"` - Specify build configuration
|
|
|
|
**Examples:**
|
|
```powershell
|
|
# Publish with default settings (latest tag)
|
|
.\publish-docker.ps1
|
|
|
|
# Publish with a version tag
|
|
.\publish-docker.ps1 -Tag "v1.0.0"
|
|
|
|
# Publish with custom registry
|
|
.\publish-docker.ps1 -Tag "latest" -Registry "my-registry.com"
|
|
```
|
|
|
|
### Build the Docker Image (Manual)
|
|
|
|
If you prefer to build manually:
|
|
|
|
```bash
|
|
cd WebApp
|
|
docker build -t tsa-chapter-organizer:latest .
|
|
```
|
|
|
|
Or from the root directory:
|
|
|
|
```bash
|
|
docker build -f WebApp/Dockerfile -t tsa-chapter-organizer:latest .
|
|
```
|
|
|
|
### Run with Docker Compose
|
|
|
|
```bash
|
|
# Copy and customize the example
|
|
cp docker-compose.example.yml docker-compose.yml
|
|
|
|
# Edit auth-secrets.json with your credentials
|
|
cp auth-secrets.example.json auth-secrets.json
|
|
# (Edit the file and replace hashes)
|
|
|
|
# Start the container
|
|
docker-compose up -d
|
|
|
|
# View logs
|
|
docker-compose logs -f webapp
|
|
```
|
|
|
|
### Access the Application
|
|
|
|
- HTTP: `http://localhost:8080`
|
|
- HTTPS: `https://localhost:8081` (if configured)
|
|
|
|
---
|
|
|
|
## Managing Users
|
|
|
|
### Adding a New User
|
|
|
|
**With Volume-Mounted File:**
|
|
|
|
1. Edit `auth-secrets.json` on the host
|
|
2. Add new user entry to the `Users` array
|
|
3. Restart the container: `docker-compose restart webapp`
|
|
|
|
**With Environment Variables:**
|
|
|
|
1. Add new environment variables (increment the index number)
|
|
2. Recreate the container: `docker-compose up -d`
|
|
|
|
### Changing a Password
|
|
|
|
1. Generate new hash using the dev endpoint (on local dev machine)
|
|
2. Update the `PasswordHash` value in your configuration
|
|
3. Restart/recreate the container
|
|
|
|
### Removing a User
|
|
|
|
1. Remove the user entry from your configuration
|
|
2. Restart/recreate the container
|
|
|
|
---
|
|
|
|
## Security Considerations
|
|
|
|
1. **File Permissions**:
|
|
|
|
```bash
|
|
chmod 600 auth-secrets.json
|
|
chown root:root auth-secrets.json
|
|
```
|
|
2. **Never Commit Secrets**: Add to `.gitignore`:
|
|
|
|
```
|
|
auth-secrets.json
|
|
docker-compose.yml
|
|
```
|
|
3. **Use HTTPS in Production**: Configure SSL/TLS certificates
|
|
4. **Backup Credentials**: Store encrypted backups of `auth-secrets.json`
|
|
5. **Password Rotation**: Periodically regenerate password hashes
|
|
6. **Monitor Access**: Review application logs for failed login attempts:
|
|
|
|
```bash
|
|
docker-compose logs webapp | grep "Failed login"
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Container Won't Start
|
|
|
|
Check logs:
|
|
|
|
```bash
|
|
docker-compose logs webapp
|
|
```
|
|
|
|
### Can't Login
|
|
|
|
1. Verify `auth-secrets.json` is properly mounted:
|
|
|
|
```bash
|
|
docker exec tsa-app ls -la /app/secrets/
|
|
```
|
|
2. Check if the file is being loaded:
|
|
|
|
```bash
|
|
docker-compose logs webapp | grep "secrets"
|
|
```
|
|
3. Verify JSON syntax:
|
|
|
|
```bash
|
|
cat auth-secrets.json | jq .
|
|
```
|
|
|
|
### Forgot Admin Password
|
|
|
|
1. Generate a new password hash locally
|
|
2. Update `auth-secrets.json` on the host
|
|
3. Restart the container
|
|
|
|
---
|
|
|
|
## Example: Complete Setup
|
|
|
|
```bash
|
|
# 1. Generate password hashes locally
|
|
# Navigate to: https://localhost:5001/dev/hash-password?password=MySecurePass123
|
|
|
|
# 2. Create secrets file
|
|
cat > auth-secrets.json <<EOF
|
|
{
|
|
"Authentication": {
|
|
"Users": [
|
|
{
|
|
"Email": "admin@myschool.edu",
|
|
"PasswordHash": "$2a$11$paste_hash_here",
|
|
"Role": "Administrator",
|
|
"DisplayName": "TSA Admin"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# 3. Set permissions
|
|
chmod 600 auth-secrets.json
|
|
|
|
# 4. Create docker-compose.yml
|
|
cp docker-compose.example.yml docker-compose.yml
|
|
|
|
# 5. Start the application
|
|
docker-compose up -d
|
|
|
|
# 6. Check it's running
|
|
docker-compose ps
|
|
curl http://localhost:8080
|
|
|
|
# 7. Login
|
|
# Navigate to http://localhost:8080/login
|
|
# Use: admin@myschool.edu / MySecurePass123
|
|
```
|
|
|
|
---
|
|
|
|
## Production Deployment Checklist
|
|
|
|
- [ ] Generated secure password hashes
|
|
- [ ] Created `auth-secrets.json` with production credentials
|
|
- [ ] Set file permissions to 600
|
|
- [ ] Configured HTTPS/SSL certificates
|
|
- [ ] Updated `ASPNETCORE_URLS` for production domain
|
|
- [ ] Configured volume for database persistence
|
|
- [ ] Removed development endpoints (already done in code)
|
|
- [ ] Set up log monitoring
|
|
- [ ] Configured automatic backups
|
|
- [ ] Tested login with all user roles
|
|
- [ ] Tested rate limiting (5 failed attempts)
|
|
- [ ] Documented admin password securely
|
|
- [ ] Added `auth-secrets.json` to `.gitignore`
|