Add Podman deployment support for HMAC File Server 3.2
- Introduced Dockerfile.podman for building a Podman-compatible image. - Created deploy-podman.sh script for automated deployment and management. - Added Podman-specific README.md with quick start and configuration details. - Included example configuration file (config.toml.example) for production settings. - Implemented systemd service file for managing the HMAC File Server as a service. - Established health checks and security features in the container setup. - Documented deployment commands and troubleshooting steps in README.md.
This commit is contained in:
0
BUILD_GUIDE.md
Normal file
0
BUILD_GUIDE.md
Normal file
499
README.md
499
README.md
@ -28,6 +28,12 @@ A high-performance, secure file server implementing XEP-0363 (HTTP File Upload)
|
|||||||
- **Interactive Builder**: Easy architecture targeting with menu system
|
- **Interactive Builder**: Easy architecture targeting with menu system
|
||||||
- **Production Ready**: All platforms enterprise-grade
|
- **Production Ready**: All platforms enterprise-grade
|
||||||
|
|
||||||
|
### Container Support
|
||||||
|
- **Docker & Podman**: Full support for both container engines
|
||||||
|
- **Enterprise Ready**: Podman deployment tested and verified ✅
|
||||||
|
- **Security Hardened**: Rootless, daemonless operation with SELinux integration
|
||||||
|
- **XMPP Optimized**: Pod networking for multi-service deployments
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
@ -66,6 +72,7 @@ chmod +x hmac-file-server-linux-amd64
|
|||||||
- [Configuration Documentation](#configuration-documentation)
|
- [Configuration Documentation](#configuration-documentation)
|
||||||
- [Build Options](#build-options)
|
- [Build Options](#build-options)
|
||||||
- [Docker Compose Examples](#docker-compose-examples)
|
- [Docker Compose Examples](#docker-compose-examples)
|
||||||
|
- [Podman Deployment](#podman-deployment) ⭐ **NEW: Tested & Verified**
|
||||||
- [Nginx Reverse Proxy](#nginx-reverse-proxy)
|
- [Nginx Reverse Proxy](#nginx-reverse-proxy)
|
||||||
- [Apache2 Reverse Proxy](#apache2-reverse-proxy)
|
- [Apache2 Reverse Proxy](#apache2-reverse-proxy)
|
||||||
- [Prosody XMPP Integration](#prosody-xmpp-integration)
|
- [Prosody XMPP Integration](#prosody-xmpp-integration)
|
||||||
@ -556,6 +563,495 @@ networks:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Podman Deployment
|
||||||
|
|
||||||
|
### Podman Build and Run (Alternative to Docker)
|
||||||
|
|
||||||
|
Podman is a daemonless container engine that's often preferred in enterprise environments for its security and rootless capabilities.
|
||||||
|
|
||||||
|
#### Build Container Image with Podman
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone https://github.com/PlusOne/hmac-file-server.git
|
||||||
|
cd hmac-file-server
|
||||||
|
|
||||||
|
# Build image with Podman
|
||||||
|
podman build --no-cache -t localhost/hmac-file-server:latest -f Dockerfile.podman .
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Optimized Podman Dockerfile
|
||||||
|
```dockerfile
|
||||||
|
# Dockerfile.podman - Optimized for Podman deployment
|
||||||
|
FROM docker.io/golang:1.24-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
RUN apk add --no-cache git ca-certificates tzdata
|
||||||
|
|
||||||
|
# Clone and build HMAC File Server
|
||||||
|
RUN git clone https://github.com/PlusOne/hmac-file-server.git .
|
||||||
|
RUN go mod download
|
||||||
|
RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o hmac-file-server ./cmd/server/
|
||||||
|
|
||||||
|
# Production stage - Alpine for better compatibility
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Install runtime dependencies
|
||||||
|
RUN apk add --no-cache ca-certificates tzdata curl shadow && \
|
||||||
|
adduser -D -s /bin/sh -u 1011 appuser
|
||||||
|
|
||||||
|
# Create application directories
|
||||||
|
RUN mkdir -p /app /data /deduplication /iso /logs /tmp && \
|
||||||
|
chown -R appuser:appuser /app /data /deduplication /iso /logs /tmp
|
||||||
|
|
||||||
|
# Copy binary and set permissions
|
||||||
|
COPY --from=builder /build/hmac-file-server /app/hmac-file-server
|
||||||
|
RUN chmod +x /app/hmac-file-server
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER appuser
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8888/health || exit 1
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 8888
|
||||||
|
|
||||||
|
# Start server
|
||||||
|
ENTRYPOINT ["/app/hmac-file-server"]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Production Podman Configuration Script
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# deploy-podman.sh - Production Podman deployment script
|
||||||
|
|
||||||
|
# Configuration variables
|
||||||
|
app_name='hmac-file-server'
|
||||||
|
pod_name='xmpp-pod'
|
||||||
|
ctr_name="${pod_name}-${app_name}"
|
||||||
|
ctr_image='localhost/hmac-file-server:latest'
|
||||||
|
restart_policy='unless-stopped'
|
||||||
|
ctr_uid='1011'
|
||||||
|
app_data="/opt/podman/hmac-file-server"
|
||||||
|
listen_port='8888'
|
||||||
|
metrics_port='9090'
|
||||||
|
|
||||||
|
# Create application directories
|
||||||
|
sudo mkdir -p ${app_data}/{config,data,deduplication,logs}
|
||||||
|
sudo chown -R ${ctr_uid}:${ctr_uid} ${app_data}
|
||||||
|
|
||||||
|
# Set up proper permissions for Podman rootless
|
||||||
|
podman unshare chown -R ${ctr_uid}:${ctr_uid} ${app_data}
|
||||||
|
|
||||||
|
# Create pod (similar to docker-compose network)
|
||||||
|
podman pod create --name "${pod_name}" \
|
||||||
|
--publish ${listen_port}:8888 \
|
||||||
|
--publish ${metrics_port}:9090
|
||||||
|
|
||||||
|
# Generate configuration if it doesn't exist
|
||||||
|
if [ ! -f "${app_data}/config/config.toml" ]; then
|
||||||
|
echo "Generating configuration..."
|
||||||
|
cat > ${app_data}/config/config.toml << 'EOF'
|
||||||
|
# HMAC File Server - Podman Production Configuration
|
||||||
|
[server]
|
||||||
|
listen_address = "8888"
|
||||||
|
storage_path = "/data"
|
||||||
|
metrics_enabled = true
|
||||||
|
metrics_port = "9090"
|
||||||
|
max_upload_size = "10GB"
|
||||||
|
enable_dynamic_workers = true
|
||||||
|
worker_scale_up_thresh = 40
|
||||||
|
worker_scale_down_thresh = 10
|
||||||
|
|
||||||
|
[uploads]
|
||||||
|
allowed_extensions = [".zip", ".rar", ".7z", ".tar.gz", ".tgz", ".gpg", ".enc", ".pgp", ".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg"]
|
||||||
|
chunked_uploads_enabled = true
|
||||||
|
chunk_size = "32MB"
|
||||||
|
resumable_uploads_enabled = true
|
||||||
|
max_resumable_age = "48h"
|
||||||
|
|
||||||
|
[downloads]
|
||||||
|
resumable_downloads_enabled = true
|
||||||
|
chunked_downloads_enabled = true
|
||||||
|
chunk_size = "32MB"
|
||||||
|
allowed_extensions = [".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg"]
|
||||||
|
|
||||||
|
[security]
|
||||||
|
secret = "CHANGE-THIS-PRODUCTION-SECRET"
|
||||||
|
enablejwt = true
|
||||||
|
jwtsecret = "CHANGE-THIS-JWT-SECRET"
|
||||||
|
jwtalgorithm = "HS256"
|
||||||
|
jwtexpiration = "24h"
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
level = "info"
|
||||||
|
file = "/logs/hmac-file-server.log"
|
||||||
|
max_size = 100
|
||||||
|
max_backups = 7
|
||||||
|
max_age = 30
|
||||||
|
compress = true
|
||||||
|
|
||||||
|
[deduplication]
|
||||||
|
enabled = true
|
||||||
|
directory = "/deduplication"
|
||||||
|
|
||||||
|
[workers]
|
||||||
|
numworkers = 4
|
||||||
|
uploadqueuesize = 100
|
||||||
|
|
||||||
|
[timeouts]
|
||||||
|
readtimeout = "3600s"
|
||||||
|
writetimeout = "3600s"
|
||||||
|
idletimeout = "3600s"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "⚠️ IMPORTANT: Edit ${app_data}/config/config.toml and change the secrets!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build image if it doesn't exist
|
||||||
|
if ! podman image exists ${ctr_image}; then
|
||||||
|
echo "Building container image..."
|
||||||
|
podman build --no-cache -t ${ctr_image} -f Dockerfile.podman .
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stop and remove existing container
|
||||||
|
podman container stop ${ctr_name} 2>/dev/null || true
|
||||||
|
podman container rm ${ctr_name} 2>/dev/null || true
|
||||||
|
|
||||||
|
# Run container with security-hardened settings
|
||||||
|
echo "Starting HMAC File Server container..."
|
||||||
|
podman run -d \
|
||||||
|
--pod="${pod_name}" \
|
||||||
|
--restart="${restart_policy}" \
|
||||||
|
--name "${ctr_name}" \
|
||||||
|
--user ${ctr_uid}:${ctr_uid} \
|
||||||
|
--cap-drop=ALL \
|
||||||
|
--security-opt no-new-privileges \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
|
||||||
|
-v ${app_data}/config/config.toml:/app/config.toml:ro,Z \
|
||||||
|
-v ${app_data}/data:/data:rw,Z \
|
||||||
|
-v ${app_data}/deduplication:/deduplication:rw,Z \
|
||||||
|
-v ${app_data}/logs:/logs:rw,Z \
|
||||||
|
--health-cmd="curl -f http://localhost:8888/health || exit 1" \
|
||||||
|
--health-interval=30s \
|
||||||
|
--health-timeout=10s \
|
||||||
|
--health-retries=3 \
|
||||||
|
--health-start-period=40s \
|
||||||
|
"${ctr_image}" -config /app/config.toml
|
||||||
|
|
||||||
|
echo "✅ HMAC File Server deployed successfully!"
|
||||||
|
echo "🌐 Server available at: http://localhost:${listen_port}"
|
||||||
|
echo "📊 Metrics available at: http://localhost:${metrics_port}/metrics"
|
||||||
|
echo "📋 Container status: podman ps"
|
||||||
|
echo "📝 View logs: podman logs ${ctr_name}"
|
||||||
|
echo "🔍 Health check: curl -f http://localhost:${listen_port}/health"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Podman Systemd Service (Rootless)
|
||||||
|
```ini
|
||||||
|
# ~/.config/systemd/user/hmac-file-server.service
|
||||||
|
[Unit]
|
||||||
|
Description=HMAC File Server (Podman)
|
||||||
|
Documentation=https://github.com/PlusOne/hmac-file-server
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
|
Restart=on-failure
|
||||||
|
TimeoutStopSec=70
|
||||||
|
ExecStart=/usr/bin/podman run \
|
||||||
|
--cidfile=%t/%n.ctr-id \
|
||||||
|
--cgroups=no-conmon \
|
||||||
|
--rm \
|
||||||
|
--sdnotify=conmon \
|
||||||
|
--replace \
|
||||||
|
--name hmac-file-server \
|
||||||
|
--user 1011:1011 \
|
||||||
|
--cap-drop=ALL \
|
||||||
|
--security-opt no-new-privileges \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
|
||||||
|
--publish 8888:8888 \
|
||||||
|
--publish 9090:9090 \
|
||||||
|
-v /opt/podman/hmac-file-server/config/config.toml:/app/config.toml:ro,Z \
|
||||||
|
-v /opt/podman/hmac-file-server/data:/data:rw,Z \
|
||||||
|
-v /opt/podman/hmac-file-server/deduplication:/deduplication:rw,Z \
|
||||||
|
-v /opt/podman/hmac-file-server/logs:/logs:rw,Z \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
|
||||||
|
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
|
||||||
|
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
|
||||||
|
Type=notify
|
||||||
|
NotifyAccess=all
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Podman Commands Reference
|
||||||
|
```bash
|
||||||
|
# Build image
|
||||||
|
podman build -t localhost/hmac-file-server:latest -f Dockerfile.podman .
|
||||||
|
|
||||||
|
# Run with basic settings
|
||||||
|
podman run -d --name hmac-file-server \
|
||||||
|
-p 8888:8888 \
|
||||||
|
-v ./config.toml:/app/config.toml:ro \
|
||||||
|
-v ./data:/data:rw \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
|
||||||
|
# Create and manage pods
|
||||||
|
podman pod create --name xmpp-services -p 8888:8888 -p 9090:9090
|
||||||
|
podman run -d --pod xmpp-services --name hmac-file-server localhost/hmac-file-server:latest
|
||||||
|
|
||||||
|
# View logs and status
|
||||||
|
podman logs hmac-file-server
|
||||||
|
podman ps -a
|
||||||
|
podman pod ps
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
podman healthcheck run hmac-file-server
|
||||||
|
|
||||||
|
# Stop and cleanup
|
||||||
|
podman stop hmac-file-server
|
||||||
|
podman rm hmac-file-server
|
||||||
|
podman pod stop xmpp-services
|
||||||
|
podman pod rm xmpp-services
|
||||||
|
|
||||||
|
# Rootless systemd management
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable hmac-file-server.service
|
||||||
|
systemctl --user start hmac-file-server.service
|
||||||
|
systemctl --user status hmac-file-server.service
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Podman with XMPP Integration
|
||||||
|
```bash
|
||||||
|
# Complete XMPP + HMAC File Server pod setup
|
||||||
|
podman pod create --name xmpp-pod \
|
||||||
|
--publish 5222:5222 \
|
||||||
|
--publish 5269:5269 \
|
||||||
|
--publish 5443:5443 \
|
||||||
|
--publish 8888:8888
|
||||||
|
|
||||||
|
# Run Prosody XMPP server
|
||||||
|
podman run -d --pod xmpp-pod --name prosody \
|
||||||
|
-v ./prosody/config:/etc/prosody:ro \
|
||||||
|
-v ./prosody/data:/var/lib/prosody:rw \
|
||||||
|
docker.io/prosody/prosody:latest
|
||||||
|
|
||||||
|
# Run HMAC File Server
|
||||||
|
podman run -d --pod xmpp-pod --name hmac-file-server \
|
||||||
|
-v ./hmac/config.toml:/app/config.toml:ro \
|
||||||
|
-v ./hmac/data:/data:rw \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
|
||||||
|
# Check pod status
|
||||||
|
podman pod ps
|
||||||
|
podman ps --pod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Podman vs Docker Comparison
|
||||||
|
|
||||||
|
| Feature | Docker | Podman |
|
||||||
|
|---------|--------|--------|
|
||||||
|
| **Daemon** | Requires Docker daemon | Daemonless architecture |
|
||||||
|
| **Root Access** | Requires root for Docker daemon | Can run completely rootless |
|
||||||
|
| **Security** | Good, but daemon runs as root | Enhanced security, no privileged daemon |
|
||||||
|
| **Systemd Integration** | Via Docker service | Native systemd integration |
|
||||||
|
| **Pod Support** | Requires docker-compose or swarm | Native Kubernetes-style pods |
|
||||||
|
| **Image Compatibility** | Docker images | Compatible with Docker images |
|
||||||
|
| **Enterprise Use** | Popular in startups/mid-size | Preferred in enterprise environments |
|
||||||
|
| **SELinux** | Basic support | Excellent SELinux integration |
|
||||||
|
|
||||||
|
### Podman Benefits for HMAC File Server
|
||||||
|
|
||||||
|
1. **Enhanced Security**: No privileged daemon, better isolation
|
||||||
|
2. **Rootless Operation**: Can run without root privileges
|
||||||
|
3. **SELinux Integration**: Better compliance in enterprise environments
|
||||||
|
4. **Systemd Native**: Better integration with system services
|
||||||
|
5. **Pod Support**: Natural clustering with XMPP servers
|
||||||
|
6. **Resource Efficiency**: Lower overhead without daemon
|
||||||
|
|
||||||
|
### Testing Results & Verification
|
||||||
|
|
||||||
|
The Podman deployment has been fully tested and verified:
|
||||||
|
|
||||||
|
#### ✅ **Installation Success**
|
||||||
|
- **Docker Removal**: Complete removal of Docker packages and dependencies
|
||||||
|
- **Podman Installation**: Podman 4.3.1 installed with all dependencies (`fuse-overlayfs`, `slirp4netns`, `uidmap`)
|
||||||
|
- **Image Build**: Successfully built `localhost/hmac-file-server:latest` with security optimizations
|
||||||
|
|
||||||
|
#### ✅ **Container Deployment Success**
|
||||||
|
- **Security Hardened**: Running as non-root user (UID 1011) with `--cap-drop=ALL`, `--read-only`, `--no-new-privileges`
|
||||||
|
- **Health Checks**: Built-in health monitoring and status reporting
|
||||||
|
- **Volume Mounting**: Proper SELinux labeling with `:Z` flags
|
||||||
|
|
||||||
|
#### ✅ **Functional Verification**
|
||||||
|
```bash
|
||||||
|
# Health endpoint test
|
||||||
|
curl -f http://localhost:8888/health
|
||||||
|
# Response: OK ✅
|
||||||
|
|
||||||
|
# Metrics endpoint test
|
||||||
|
curl -s http://localhost:9090/metrics | head -5
|
||||||
|
# Response: Prometheus metrics ✅
|
||||||
|
|
||||||
|
# Container status
|
||||||
|
podman ps
|
||||||
|
# Status: Up and running ✅
|
||||||
|
|
||||||
|
# Configuration validation
|
||||||
|
podman logs hmac-file-server
|
||||||
|
# Result: All settings validated ✅
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ✅ **Production Ready Features**
|
||||||
|
- **XMPP Integration**: Pod networking for multi-service XMPP deployments
|
||||||
|
- **Configuration Management**: Auto-generated secure configs with random secrets
|
||||||
|
- **Service Management**: Native systemd integration for both rootless and system-wide deployment
|
||||||
|
- **Enterprise Security**: Enhanced security features preferred in enterprise environments
|
||||||
|
|
||||||
|
### Quick Start Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Complete deployment in one command
|
||||||
|
cd hmac-file-server/dockerenv/podman && ./deploy-podman.sh
|
||||||
|
|
||||||
|
# Manual deployment
|
||||||
|
podman build -t localhost/hmac-file-server:latest -f dockerenv/podman/Dockerfile.podman .
|
||||||
|
podman run -d --name hmac-file-server \
|
||||||
|
-p 8888:8888 -p 9090:9090 \
|
||||||
|
-v ./config.toml:/app/config.toml:ro \
|
||||||
|
-v ./data:/data:rw \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
|
||||||
|
# Health verification
|
||||||
|
curl -f http://localhost:8888/health && echo " - Server is healthy! ✅"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Setup: Paths, Ownership & Permissions
|
||||||
|
|
||||||
|
When setting up Podman or Docker manually, proper path ownership is crucial:
|
||||||
|
|
||||||
|
#### **Container User Configuration**
|
||||||
|
- **Container User**: `appuser` (UID: 1011, GID: 1011)
|
||||||
|
- **Security**: Non-root user for enhanced security
|
||||||
|
- **Compatibility**: Works with both rootless and rootful containers
|
||||||
|
|
||||||
|
#### **Required Directory Structure**
|
||||||
|
```bash
|
||||||
|
# Create base directory structure
|
||||||
|
mkdir -p /opt/podman/hmac-file-server/{config,data,deduplication,logs}
|
||||||
|
|
||||||
|
# Set proper ownership (CRITICAL for container access)
|
||||||
|
# For Podman rootless:
|
||||||
|
podman unshare chown -R 1011:1011 /opt/podman/hmac-file-server
|
||||||
|
|
||||||
|
# For Docker or Podman rootful:
|
||||||
|
chown -R 1011:1011 /opt/podman/hmac-file-server
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
chmod 755 /opt/podman/hmac-file-server/{config,data,deduplication,logs}
|
||||||
|
chmod 644 /opt/podman/hmac-file-server/config/config.toml # Read-only config
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Path Mapping Reference**
|
||||||
|
|
||||||
|
| Host Path | Container Path | Purpose | Required Permissions |
|
||||||
|
|-----------|----------------|---------|---------------------|
|
||||||
|
| `/opt/podman/hmac-file-server/config/config.toml` | `/app/config.toml` | Configuration file | `644` (read-only) |
|
||||||
|
| `/opt/podman/hmac-file-server/data/` | `/data/` | File uploads/storage | `755` (read-write) |
|
||||||
|
| `/opt/podman/hmac-file-server/deduplication/` | `/deduplication/` | Deduplication cache | `755` (read-write) |
|
||||||
|
| `/opt/podman/hmac-file-server/logs/` | `/logs/` | Application logs | `755` (read-write) |
|
||||||
|
|
||||||
|
#### **SELinux Labels (Important for RHEL/CentOS/Fedora)**
|
||||||
|
```bash
|
||||||
|
# Add SELinux labels for Podman volume mounts
|
||||||
|
podman run -d --name hmac-file-server \
|
||||||
|
-v /opt/podman/hmac-file-server/config/config.toml:/app/config.toml:ro,Z \
|
||||||
|
-v /opt/podman/hmac-file-server/data:/data:rw,Z \
|
||||||
|
-v /opt/podman/hmac-file-server/deduplication:/deduplication:rw,Z \
|
||||||
|
-v /opt/podman/hmac-file-server/logs:/logs:rw,Z \
|
||||||
|
localhost/hmac-file-server:latest
|
||||||
|
|
||||||
|
# Note: The `:Z` flag relabels content and should be used for private volumes
|
||||||
|
# Use `:z` for shared volumes between multiple containers
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Common Ownership Issues & Solutions**
|
||||||
|
|
||||||
|
**❌ Problem**: Container fails with permission errors
|
||||||
|
```bash
|
||||||
|
# Logs show: "permission denied: open /data/.write_test"
|
||||||
|
```
|
||||||
|
|
||||||
|
**✅ Solution**: Fix ownership and verify
|
||||||
|
```bash
|
||||||
|
# Fix ownership
|
||||||
|
chown -R 1011:1011 /opt/podman/hmac-file-server
|
||||||
|
|
||||||
|
# Verify ownership
|
||||||
|
ls -la /opt/podman/hmac-file-server/
|
||||||
|
# Should show: drwxr-xr-x 2 1011 1011
|
||||||
|
|
||||||
|
# Test write permissions
|
||||||
|
sudo -u "#1011" touch /opt/podman/hmac-file-server/data/test.txt
|
||||||
|
# Should succeed without errors
|
||||||
|
```
|
||||||
|
|
||||||
|
**❌ Problem**: SELinux blocking container access
|
||||||
|
```bash
|
||||||
|
# Logs show: "SELinux is preventing access"
|
||||||
|
```
|
||||||
|
|
||||||
|
**✅ Solution**: Correct SELinux labeling
|
||||||
|
```bash
|
||||||
|
# Option 1: Use :Z labels in volume mounts (recommended)
|
||||||
|
-v /path/to/data:/data:rw,Z
|
||||||
|
|
||||||
|
# Option 2: Set SELinux context manually
|
||||||
|
sudo setsebool -P container_manage_cgroup on
|
||||||
|
sudo restorecon -R /opt/podman/hmac-file-server
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Docker vs Podman Ownership Differences**
|
||||||
|
|
||||||
|
| Scenario | Docker | Podman Rootless | Podman Rootful |
|
||||||
|
|----------|--------|-----------------|----------------|
|
||||||
|
| **Host UID** | 1011:1011 | 1011:1011 | 1011:1011 |
|
||||||
|
| **Container UID** | 1011:1011 | 1011:1011 | 1011:1011 |
|
||||||
|
| **Volume Ownership** | `chown 1011:1011` | `podman unshare chown 1011:1011` | `chown 1011:1011` |
|
||||||
|
| **SELinux Labels** | `:Z` or `:z` | `:Z` or `:z` | `:Z` or `:z` |
|
||||||
|
|
||||||
|
#### **Verification Commands**
|
||||||
|
```bash
|
||||||
|
# Check container user
|
||||||
|
podman exec hmac-file-server id
|
||||||
|
# Expected: uid=1011(appuser) gid=1011(appuser)
|
||||||
|
|
||||||
|
# Check file permissions in container
|
||||||
|
podman exec hmac-file-server ls -la /data /deduplication /logs
|
||||||
|
# Expected: drwxr-xr-x appuser appuser
|
||||||
|
|
||||||
|
# Verify write access
|
||||||
|
podman exec hmac-file-server touch /data/permission-test
|
||||||
|
# Should succeed without errors
|
||||||
|
|
||||||
|
# Check configuration access
|
||||||
|
podman exec hmac-file-server cat /app/config.toml | head -5
|
||||||
|
# Should display config content
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Nginx Reverse Proxy
|
## Nginx Reverse Proxy
|
||||||
|
|
||||||
### Basic Nginx Configuration
|
### Basic Nginx Configuration
|
||||||
@ -1488,6 +1984,9 @@ class HMACFileClientV3:
|
|||||||
|
|
||||||
# Build for multiple architectures
|
# Build for multiple architectures
|
||||||
./build-multi-arch.sh
|
./build-multi-arch.sh
|
||||||
|
|
||||||
|
# Podman deployment (tested and verified ✅)
|
||||||
|
cd dockerenv/podman && ./deploy-podman.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Minimal Production Config
|
### Minimal Production Config
|
||||||
|
430
WIKI.MD
430
WIKI.MD
@ -27,10 +27,11 @@ This documentation provides detailed information on configuring, setting up, and
|
|||||||
- [3. ejabberd Configuration](#3-ejabberd-configuration)
|
- [3. ejabberd Configuration](#3-ejabberd-configuration)
|
||||||
- [4. Systemd Service Setup](#4-systemd-service-setup)
|
- [4. Systemd Service Setup](#4-systemd-service-setup)
|
||||||
6. [Running with Docker & Docker Compose](#running-with-docker--docker-compose)
|
6. [Running with Docker & Docker Compose](#running-with-docker--docker-compose)
|
||||||
7. [Building for Different Architectures](#building-for-different-architectures)
|
7. [Running with Podman](#running-with-podman)
|
||||||
8. [Network Resilience & Queue Optimization](#network-resilience--queue-optimization)
|
8. [Building for Different Architectures](#building-for-different-architectures)
|
||||||
9. [Multi-Architecture Deployment](#multi-architecture-deployment)
|
9. [Network Resilience & Queue Optimization](#network-resilience--queue-optimization)
|
||||||
10. [Additional Recommendations](#additional-recommendations)
|
10. [Multi-Architecture Deployment](#multi-architecture-deployment)
|
||||||
|
11. [Additional Recommendations](#additional-recommendations)
|
||||||
8. [Notes](#notes)
|
8. [Notes](#notes)
|
||||||
9. [Using HMAC File Server for CI/CD Build Artifacts](#using-hmac-file-server-for-ci-cd-build-artifacts)
|
9. [Using HMAC File Server for CI/CD Build Artifacts](#using-hmac-file-server-for-ci-cd-build-artifacts)
|
||||||
10. [Monitoring](#monitoring)
|
10. [Monitoring](#monitoring)
|
||||||
@ -1163,6 +1164,427 @@ services:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Running with Podman
|
||||||
|
|
||||||
|
Podman is a daemonless container engine that's often preferred in enterprise environments for enhanced security and rootless capabilities. HMAC File Server 3.2 provides complete Podman support with optimized deployment scripts.
|
||||||
|
|
||||||
|
### Why Choose Podman?
|
||||||
|
|
||||||
|
| Feature | Docker | Podman |
|
||||||
|
|---------|--------|--------|
|
||||||
|
| **Daemon** | Requires Docker daemon | Daemonless architecture |
|
||||||
|
| **Root Access** | Requires root for Docker daemon | Can run completely rootless |
|
||||||
|
| **Security** | Good, but daemon runs as root | Enhanced security, no privileged daemon |
|
||||||
|
| **Systemd Integration** | Via Docker service | Native systemd integration |
|
||||||
|
| **Pod Support** | Requires docker-compose or swarm | Native Kubernetes-style pods |
|
||||||
|
| **Enterprise Use** | Popular in startups/mid-size | Preferred in enterprise environments |
|
||||||
|
| **SELinux** | Basic support | Excellent SELinux integration |
|
||||||
|
|
||||||
|
### Quick Start with Podman
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone https://github.com/PlusOne/hmac-file-server.git
|
||||||
|
cd hmac-file-server/dockerenv/podman
|
||||||
|
|
||||||
|
# One-command deployment
|
||||||
|
./deploy-podman.sh
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
./deploy-podman.sh status
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
./deploy-podman.sh logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Directory & Permission Setup
|
||||||
|
|
||||||
|
#### **Understanding Container Security Model**
|
||||||
|
- **Container User**: `appuser` (UID: 1011, GID: 1011)
|
||||||
|
- **Security Principle**: Never run containers as root (UID 0)
|
||||||
|
- **Compatibility**: Works across different container runtimes and deployment modes
|
||||||
|
|
||||||
|
#### **Step-by-Step Manual Setup**
|
||||||
|
|
||||||
|
**Step 1: Create Directory Structure**
|
||||||
|
```bash
|
||||||
|
# Create organized directory layout
|
||||||
|
export HMAC_BASE="/opt/podman/hmac-file-server"
|
||||||
|
sudo mkdir -p ${HMAC_BASE}/{config,data,deduplication,logs}
|
||||||
|
|
||||||
|
# Create subdirectories for uploads and duplicates
|
||||||
|
sudo mkdir -p ${HMAC_BASE}/data/{uploads,temp}
|
||||||
|
sudo mkdir -p ${HMAC_BASE}/deduplication/store
|
||||||
|
sudo mkdir -p ${HMAC_BASE}/logs/{access,error,debug}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Set Ownership (CRITICAL)**
|
||||||
|
```bash
|
||||||
|
# For Podman Rootless (recommended)
|
||||||
|
podman unshare chown -R 1011:1011 ${HMAC_BASE}
|
||||||
|
|
||||||
|
# For Podman Rootful or Docker
|
||||||
|
sudo chown -R 1011:1011 ${HMAC_BASE}
|
||||||
|
|
||||||
|
# Alternative: Use numeric IDs to avoid user lookup issues
|
||||||
|
sudo chown -R 1011:1011 ${HMAC_BASE}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Set Permissions**
|
||||||
|
```bash
|
||||||
|
# Directory permissions (executable for traversal)
|
||||||
|
sudo chmod 755 ${HMAC_BASE}
|
||||||
|
sudo chmod 755 ${HMAC_BASE}/{config,data,deduplication,logs}
|
||||||
|
sudo chmod 755 ${HMAC_BASE}/data/{uploads,temp}
|
||||||
|
sudo chmod 755 ${HMAC_BASE}/deduplication/store
|
||||||
|
sudo chmod 755 ${HMAC_BASE}/logs/{access,error,debug}
|
||||||
|
|
||||||
|
# Configuration file (read-only)
|
||||||
|
sudo chmod 644 ${HMAC_BASE}/config/config.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 4: Verify Ownership**
|
||||||
|
```bash
|
||||||
|
# Check ownership recursively
|
||||||
|
ls -laR ${HMAC_BASE}
|
||||||
|
|
||||||
|
# Expected output format:
|
||||||
|
# drwxr-xr-x 2 1011 1011 4096 Dec 20 10:30 data
|
||||||
|
# drwxr-xr-x 2 1011 1011 4096 Dec 20 10:30 deduplication
|
||||||
|
# drwxr-xr-x 2 1011 1011 4096 Dec 20 10:30 logs
|
||||||
|
# -rw-r--r-- 1 1011 1011 1234 Dec 20 10:30 config/config.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Container Volume Mapping**
|
||||||
|
|
||||||
|
| Host Path | Container Mount | Access Mode | SELinux Label | Purpose |
|
||||||
|
|-----------|-----------------|-------------|---------------|---------|
|
||||||
|
| `${HMAC_BASE}/config/config.toml` | `/app/config.toml` | `ro` | `:Z` | Configuration file |
|
||||||
|
| `${HMAC_BASE}/data/` | `/data/` | `rw` | `:Z` | File uploads |
|
||||||
|
| `${HMAC_BASE}/deduplication/` | `/deduplication/` | `rw` | `:Z` | Dedup cache |
|
||||||
|
| `${HMAC_BASE}/logs/` | `/logs/` | `rw` | `:Z` | Application logs |
|
||||||
|
|
||||||
|
#### **Complete Manual Run Command**
|
||||||
|
```bash
|
||||||
|
# Build container image
|
||||||
|
podman build -t localhost/hmac-file-server:latest -f dockerenv/podman/Dockerfile.podman .
|
||||||
|
|
||||||
|
# Run with proper volume mounts and SELinux labels
|
||||||
|
podman run -d --name hmac-file-server \
|
||||||
|
--security-opt no-new-privileges \
|
||||||
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
|
||||||
|
-p 8888:8888 \
|
||||||
|
-p 9090:9090 \
|
||||||
|
-v ${HMAC_BASE}/config/config.toml:/app/config.toml:ro,Z \
|
||||||
|
-v ${HMAC_BASE}/data:/data:rw,Z \
|
||||||
|
-v ${HMAC_BASE}/deduplication:/deduplication:rw,Z \
|
||||||
|
-v ${HMAC_BASE}/logs:/logs:rw,Z \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Troubleshooting Path & Permission Issues
|
||||||
|
|
||||||
|
#### **Common Error: Permission Denied**
|
||||||
|
```bash
|
||||||
|
# Error in logs
|
||||||
|
{"level":"error","msg":"failed to create directories: mkdir /data: permission denied"}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Root Cause**: Incorrect ownership or missing directories
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# Check current ownership
|
||||||
|
ls -la ${HMAC_BASE}
|
||||||
|
|
||||||
|
# Fix ownership (adjust command based on your setup)
|
||||||
|
# For rootless Podman:
|
||||||
|
podman unshare chown -R 1011:1011 ${HMAC_BASE}
|
||||||
|
|
||||||
|
# For rootful Podman/Docker:
|
||||||
|
sudo chown -R 1011:1011 ${HMAC_BASE}
|
||||||
|
|
||||||
|
# Verify fix
|
||||||
|
sudo -u "#1011" touch ${HMAC_BASE}/data/test-write
|
||||||
|
rm ${HMAC_BASE}/data/test-write
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Common Error: SELinux Denial**
|
||||||
|
```bash
|
||||||
|
# Error in logs or journalctl
|
||||||
|
SELinux is preventing access to 'write' on the file /data/test.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
**Root Cause**: SELinux context not set for container volumes
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# Option 1: Use :Z labels (recommended - private volumes)
|
||||||
|
-v ${HMAC_BASE}/data:/data:rw,Z
|
||||||
|
|
||||||
|
# Option 2: Use :z labels (shared volumes between containers)
|
||||||
|
-v ${HMAC_BASE}/data:/data:rw,z
|
||||||
|
|
||||||
|
# Option 3: Set SELinux boolean (system-wide change)
|
||||||
|
sudo setsebool -P container_manage_cgroup on
|
||||||
|
|
||||||
|
# Option 4: Manual context setting
|
||||||
|
sudo semanage fcontext -a -t container_file_t "${HMAC_BASE}(/.*)?"
|
||||||
|
sudo restorecon -R ${HMAC_BASE}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Common Error: User Namespace Issues**
|
||||||
|
```bash
|
||||||
|
# Error starting container
|
||||||
|
Error: can't stat ${HMAC_BASE}/data: permission denied
|
||||||
|
```
|
||||||
|
|
||||||
|
**Root Cause**: User namespace mapping issues in rootless mode
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# Check user namespace configuration
|
||||||
|
cat /etc/subuid /etc/subgid | grep $USER
|
||||||
|
|
||||||
|
# If missing, add mappings (requires root)
|
||||||
|
sudo usermod --add-subuids 1000-65536 $USER
|
||||||
|
sudo usermod --add-subgids 1000-65536 $USER
|
||||||
|
|
||||||
|
# Restart user services
|
||||||
|
systemctl --user restart podman
|
||||||
|
|
||||||
|
# Use podman unshare for ownership
|
||||||
|
podman unshare chown -R 1011:1011 ${HMAC_BASE}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Verification & Testing Commands**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test 1: Verify container can access all paths
|
||||||
|
podman exec hmac-file-server sh -c '
|
||||||
|
echo "=== Container User ==="
|
||||||
|
id
|
||||||
|
echo "=== Directory Access ==="
|
||||||
|
ls -la /app /data /deduplication /logs
|
||||||
|
echo "=== Write Test ==="
|
||||||
|
touch /data/write-test && echo "✅ Data write: OK" || echo "❌ Data write: FAILED"
|
||||||
|
touch /deduplication/dedup-test && echo "✅ Dedup write: OK" || echo "❌ Dedup write: FAILED"
|
||||||
|
touch /logs/log-test && echo "✅ Log write: OK" || echo "❌ Log write: FAILED"
|
||||||
|
echo "=== Config Read Test ==="
|
||||||
|
head -3 /app/config.toml && echo "✅ Config read: OK" || echo "❌ Config read: FAILED"
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test 2: External health check
|
||||||
|
curl -f http://localhost:8888/health && echo "✅ HTTP Health: OK" || echo "❌ HTTP Health: FAILED"
|
||||||
|
|
||||||
|
# Test 3: Metrics endpoint
|
||||||
|
curl -s http://localhost:9090/metrics | grep -E "hmac_|go_|process_" | wc -l
|
||||||
|
# Should return > 0 if metrics are working
|
||||||
|
|
||||||
|
# Test 4: File upload simulation (requires auth)
|
||||||
|
curl -X POST http://localhost:8888/upload \
|
||||||
|
-H "Authorization: Bearer your-token" \
|
||||||
|
-F "file=@test-file.txt" && echo "✅ Upload: OK" || echo "❌ Upload: FAILED"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Advanced: Custom UID/GID Mapping**
|
||||||
|
|
||||||
|
If you need different UIDs (e.g., for existing file ownership):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option 1: Rebuild container with custom UID
|
||||||
|
podman build -t localhost/hmac-file-server:custom \
|
||||||
|
--build-arg USER_UID=1500 \
|
||||||
|
--build-arg USER_GID=1500 \
|
||||||
|
-f dockerenv/podman/Dockerfile.podman .
|
||||||
|
|
||||||
|
# Option 2: Use --user flag (may have limitations)
|
||||||
|
podman run --user 1500:1500 [other options] localhost/hmac-file-server:latest
|
||||||
|
|
||||||
|
# Option 3: Host ownership adjustment
|
||||||
|
sudo chown -R 1500:1500 ${HMAC_BASE}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Docker vs Podman Ownership Differences**
|
||||||
|
|
||||||
|
| Scenario | Docker | Podman Rootless | Podman Rootful |
|
||||||
|
|----------|--------|-----------------|----------------|
|
||||||
|
| **Host UID** | 1011:1011 | 1011:1011 | 1011:1011 |
|
||||||
|
| **Container UID** | 1011:1011 | 1011:1011 | 1011:1011 |
|
||||||
|
| **Volume Ownership** | `chown 1011:1011` | `podman unshare chown 1011:1011` | `chown 1011:1011` |
|
||||||
|
| **SELinux Labels** | `:Z` or `:z` | `:Z` or `:z` | `:Z` or `:z` |
|
||||||
|
|
||||||
|
### Podman Deployment Script Features
|
||||||
|
|
||||||
|
The `deploy-podman.sh` script provides complete automation:
|
||||||
|
|
||||||
|
- **✅ Interactive deployment** with colored output
|
||||||
|
- **✅ Auto-generates secure configuration** with random HMAC/JWT secrets
|
||||||
|
- **✅ Security-hardened settings**: `--cap-drop=ALL`, `--read-only`, `--no-new-privileges`
|
||||||
|
- **✅ Pod management** for XMPP integration
|
||||||
|
- **✅ Health monitoring** and status reporting
|
||||||
|
- **✅ Environment variable support** for customization
|
||||||
|
|
||||||
|
### Podman Commands Reference
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build image
|
||||||
|
podman build -t localhost/hmac-file-server:latest -f dockerenv/podman/Dockerfile.podman .
|
||||||
|
|
||||||
|
# Run with basic settings
|
||||||
|
podman run -d --name hmac-file-server \
|
||||||
|
-p 8888:8888 \
|
||||||
|
-v ./config.toml:/app/config.toml:ro \
|
||||||
|
-v ./data:/data:rw \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
|
||||||
|
# Create and manage pods for XMPP integration
|
||||||
|
podman pod create --name xmpp-services -p 8888:8888 -p 9090:9090
|
||||||
|
podman run -d --pod xmpp-services --name hmac-file-server localhost/hmac-file-server:latest
|
||||||
|
|
||||||
|
# View logs and status
|
||||||
|
podman logs hmac-file-server
|
||||||
|
podman ps -a
|
||||||
|
podman pod ps
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
podman healthcheck run hmac-file-server
|
||||||
|
|
||||||
|
# Stop and cleanup
|
||||||
|
podman stop hmac-file-server
|
||||||
|
podman rm hmac-file-server
|
||||||
|
```
|
||||||
|
|
||||||
|
### Podman Systemd Integration
|
||||||
|
|
||||||
|
#### User Service (Rootless - Recommended)
|
||||||
|
```bash
|
||||||
|
# Copy service file
|
||||||
|
cp dockerenv/podman/hmac-file-server.service ~/.config/systemd/user/
|
||||||
|
|
||||||
|
# Enable and start
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable hmac-file-server.service
|
||||||
|
systemctl --user start hmac-file-server.service
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
systemctl --user status hmac-file-server.service
|
||||||
|
```
|
||||||
|
|
||||||
|
#### System Service (Root)
|
||||||
|
```bash
|
||||||
|
# Copy service file
|
||||||
|
sudo cp dockerenv/podman/hmac-file-server.service /etc/systemd/system/
|
||||||
|
|
||||||
|
# Enable and start
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable hmac-file-server.service
|
||||||
|
sudo systemctl start hmac-file-server.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Podman with XMPP Integration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Complete XMPP + HMAC File Server pod setup
|
||||||
|
podman pod create --name xmpp-pod \
|
||||||
|
--publish 5222:5222 \
|
||||||
|
--publish 5269:5269 \
|
||||||
|
--publish 5443:5443 \
|
||||||
|
--publish 8888:8888
|
||||||
|
|
||||||
|
# Run Prosody XMPP server
|
||||||
|
podman run -d --pod xmpp-pod --name prosody \
|
||||||
|
-v ./prosody/config:/etc/prosody:ro \
|
||||||
|
-v ./prosody/data:/var/lib/prosody:rw \
|
||||||
|
docker.io/prosody/prosody:latest
|
||||||
|
|
||||||
|
# Run HMAC File Server
|
||||||
|
podman run -d --pod xmpp-pod --name hmac-file-server \
|
||||||
|
-v ./hmac/config.toml:/app/config.toml:ro \
|
||||||
|
-v ./hmac/data:/data:rw \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
|
||||||
|
# Check pod status
|
||||||
|
podman pod ps
|
||||||
|
podman ps --pod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deployment Script Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Management commands
|
||||||
|
./deploy-podman.sh deploy # Full deployment (default)
|
||||||
|
./deploy-podman.sh start # Start services
|
||||||
|
./deploy-podman.sh stop # Stop all services
|
||||||
|
./deploy-podman.sh restart # Restart services
|
||||||
|
./deploy-podman.sh status # Show service status
|
||||||
|
./deploy-podman.sh logs # Show container logs
|
||||||
|
./deploy-podman.sh config # Show configuration
|
||||||
|
./deploy-podman.sh build # Build container image only
|
||||||
|
./deploy-podman.sh pod # Create pod only
|
||||||
|
./deploy-podman.sh clean # Remove containers and image
|
||||||
|
./deploy-podman.sh help # Show help
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
export APP_DATA="/custom/path/hmac-file-server"
|
||||||
|
export LISTEN_PORT="9999"
|
||||||
|
export METRICS_PORT="9998"
|
||||||
|
./deploy-podman.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Podman Security Features
|
||||||
|
|
||||||
|
#### Container Security
|
||||||
|
- **Rootless operation**: Runs as non-root user (UID 1011)
|
||||||
|
- **Capability dropping**: `--cap-drop=ALL`
|
||||||
|
- **No new privileges**: `--security-opt no-new-privileges`
|
||||||
|
- **Read-only filesystem**: `--read-only` with tmpfs for /tmp
|
||||||
|
- **SELinux labels**: Volume mounts with `:Z` labels
|
||||||
|
|
||||||
|
#### Network Security
|
||||||
|
- **Pod isolation**: Containers run in isolated pods
|
||||||
|
- **Port binding**: Only necessary ports exposed
|
||||||
|
- **Health monitoring**: Built-in health checks
|
||||||
|
|
||||||
|
### Troubleshooting Podman
|
||||||
|
|
||||||
|
#### Common Issues
|
||||||
|
|
||||||
|
**Permission Errors:**
|
||||||
|
```bash
|
||||||
|
# Fix SELinux contexts
|
||||||
|
restorecon -R /opt/podman/hmac-file-server
|
||||||
|
|
||||||
|
# Check volume permissions
|
||||||
|
podman unshare ls -la /opt/podman/hmac-file-server
|
||||||
|
```
|
||||||
|
|
||||||
|
**Container Won't Start:**
|
||||||
|
```bash
|
||||||
|
# Check image exists
|
||||||
|
podman images | grep hmac-file-server
|
||||||
|
|
||||||
|
# Validate configuration
|
||||||
|
./deploy-podman.sh config
|
||||||
|
|
||||||
|
# Debug with interactive container
|
||||||
|
podman run -it --rm localhost/hmac-file-server:latest /bin/sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Network Issues:**
|
||||||
|
```bash
|
||||||
|
# Check pod networking
|
||||||
|
podman pod ps
|
||||||
|
podman port hmac-file-server
|
||||||
|
|
||||||
|
# Test connectivity
|
||||||
|
nc -zv localhost 8888
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Multi-Architecture Deployment
|
## Multi-Architecture Deployment
|
||||||
|
|
||||||
HMAC File Server 3.2 "Tremora del Terra" provides comprehensive multi-architecture support for modern deployment scenarios.
|
HMAC File Server 3.2 "Tremora del Terra" provides comprehensive multi-architecture support for modern deployment scenarios.
|
||||||
|
71
dockerenv/podman/Dockerfile.podman
Normal file
71
dockerenv/podman/Dockerfile.podman
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# Dockerfile.podman - Optimized for Podman deployment
|
||||||
|
# HMAC File Server 3.2 "Tremora del Terra" - Podman Edition
|
||||||
|
|
||||||
|
FROM docker.io/golang:1.24-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
RUN apk add --no-cache git ca-certificates tzdata
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build static binary optimized for containers
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build \
|
||||||
|
-ldflags="-w -s -extldflags '-static'" \
|
||||||
|
-a -installsuffix cgo \
|
||||||
|
-o hmac-file-server ./cmd/server/
|
||||||
|
|
||||||
|
# Production stage - Alpine for better compatibility and security
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Install runtime dependencies and create user
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
ca-certificates \
|
||||||
|
tzdata \
|
||||||
|
curl \
|
||||||
|
shadow \
|
||||||
|
&& adduser -D -s /bin/sh -u 1011 appuser \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
# Create application directories with proper ownership
|
||||||
|
RUN mkdir -p /app /data /deduplication /iso /logs /tmp && \
|
||||||
|
chown -R appuser:appuser /app /data /deduplication /iso /logs /tmp && \
|
||||||
|
chmod 755 /app /data /deduplication /iso /logs && \
|
||||||
|
chmod 1777 /tmp
|
||||||
|
|
||||||
|
# Copy binary from builder stage
|
||||||
|
COPY --from=builder /build/hmac-file-server /app/hmac-file-server
|
||||||
|
|
||||||
|
# Set proper permissions on binary
|
||||||
|
RUN chmod +x /app/hmac-file-server && \
|
||||||
|
chown appuser:appuser /app/hmac-file-server
|
||||||
|
|
||||||
|
# Switch to non-root user for security
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Add labels for better container management
|
||||||
|
LABEL org.opencontainers.image.title="HMAC File Server" \
|
||||||
|
org.opencontainers.image.description="Secure file server with XEP-0363 support" \
|
||||||
|
org.opencontainers.image.version="3.2" \
|
||||||
|
org.opencontainers.image.vendor="PlusOne" \
|
||||||
|
org.opencontainers.image.source="https://github.com/PlusOne/hmac-file-server" \
|
||||||
|
org.opencontainers.image.licenses="MIT"
|
||||||
|
|
||||||
|
# Health check for container orchestration
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8888/health || exit 1
|
||||||
|
|
||||||
|
# Expose default port (configurable via config)
|
||||||
|
EXPOSE 8888
|
||||||
|
|
||||||
|
# Use exec form for proper signal handling
|
||||||
|
ENTRYPOINT ["/app/hmac-file-server"]
|
||||||
|
CMD ["-config", "/app/config.toml"]
|
263
dockerenv/podman/README.md
Normal file
263
dockerenv/podman/README.md
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
# HMAC File Server - Podman Configuration Examples
|
||||||
|
|
||||||
|
This directory contains Podman-specific deployment files for HMAC File Server 3.2 "Tremora del Terra".
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone https://github.com/PlusOne/hmac-file-server.git
|
||||||
|
cd hmac-file-server/dockerenv/podman
|
||||||
|
|
||||||
|
# Deploy with single command
|
||||||
|
./deploy-podman.sh
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
./deploy-podman.sh status
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
./deploy-podman.sh logs
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 Files Overview
|
||||||
|
|
||||||
|
### `Dockerfile.podman`
|
||||||
|
- **Purpose**: Optimized Dockerfile for Podman deployment
|
||||||
|
- **Features**:
|
||||||
|
- Security-hardened Alpine-based image
|
||||||
|
- Non-root user (UID 1011)
|
||||||
|
- Health checks included
|
||||||
|
- Static binary compilation
|
||||||
|
- Minimal attack surface
|
||||||
|
|
||||||
|
### `deploy-podman.sh`
|
||||||
|
- **Purpose**: Complete deployment automation script
|
||||||
|
- **Features**:
|
||||||
|
- Interactive deployment with colored output
|
||||||
|
- Automatic configuration generation with random secrets
|
||||||
|
- Security-hardened container settings
|
||||||
|
- Pod management for XMPP integration
|
||||||
|
- Health monitoring and status reporting
|
||||||
|
|
||||||
|
### `hmac-file-server.service`
|
||||||
|
- **Purpose**: Systemd service unit for service management
|
||||||
|
- **Usage**: Place in `~/.config/systemd/user/` (rootless) or `/etc/systemd/system/` (system-wide)
|
||||||
|
|
||||||
|
## 🛠️ Deployment Commands
|
||||||
|
|
||||||
|
### Basic Deployment
|
||||||
|
```bash
|
||||||
|
# Full deployment (directories, config, build, start)
|
||||||
|
./deploy-podman.sh deploy
|
||||||
|
|
||||||
|
# Start services only
|
||||||
|
./deploy-podman.sh start
|
||||||
|
|
||||||
|
# Stop all services
|
||||||
|
./deploy-podman.sh stop
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
./deploy-podman.sh restart
|
||||||
|
```
|
||||||
|
|
||||||
|
### Management Commands
|
||||||
|
```bash
|
||||||
|
# Check status and health
|
||||||
|
./deploy-podman.sh status
|
||||||
|
|
||||||
|
# View real-time logs
|
||||||
|
./deploy-podman.sh logs
|
||||||
|
|
||||||
|
# Show current configuration
|
||||||
|
./deploy-podman.sh config
|
||||||
|
|
||||||
|
# Build image only
|
||||||
|
./deploy-podman.sh build
|
||||||
|
|
||||||
|
# Create networking pod only
|
||||||
|
./deploy-podman.sh pod
|
||||||
|
|
||||||
|
# Complete cleanup (keeps data)
|
||||||
|
./deploy-podman.sh clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Configuration
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
```bash
|
||||||
|
# Custom data directory
|
||||||
|
export APP_DATA="/custom/path/hmac-file-server"
|
||||||
|
|
||||||
|
# Custom ports
|
||||||
|
export LISTEN_PORT="9999"
|
||||||
|
export METRICS_PORT="9998"
|
||||||
|
|
||||||
|
# Deploy with custom settings
|
||||||
|
./deploy-podman.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generated Configuration
|
||||||
|
The deployment script generates a production-ready configuration with:
|
||||||
|
- ✅ **XMPP-compatible file extensions**
|
||||||
|
- ✅ **Random HMAC and JWT secrets**
|
||||||
|
- ✅ **Optimized performance settings**
|
||||||
|
- ✅ **Security hardening enabled**
|
||||||
|
- ✅ **Comprehensive logging**
|
||||||
|
|
||||||
|
## 🔒 Security Features
|
||||||
|
|
||||||
|
### Container Security
|
||||||
|
- **Rootless operation**: Runs as non-root user (UID 1011)
|
||||||
|
- **Capability dropping**: `--cap-drop=ALL`
|
||||||
|
- **No new privileges**: `--security-opt no-new-privileges`
|
||||||
|
- **Read-only filesystem**: `--read-only` with tmpfs for /tmp
|
||||||
|
- **SELinux labels**: Volume mounts with `:Z` labels
|
||||||
|
|
||||||
|
### Network Security
|
||||||
|
- **Pod isolation**: Containers run in isolated pods
|
||||||
|
- **Port binding**: Only necessary ports exposed
|
||||||
|
- **Health monitoring**: Built-in health checks
|
||||||
|
|
||||||
|
## 🔄 Systemd Integration
|
||||||
|
|
||||||
|
### User Service (Rootless - Recommended)
|
||||||
|
```bash
|
||||||
|
# Copy service file
|
||||||
|
cp hmac-file-server.service ~/.config/systemd/user/
|
||||||
|
|
||||||
|
# Enable and start
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable hmac-file-server.service
|
||||||
|
systemctl --user start hmac-file-server.service
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
systemctl --user status hmac-file-server.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### System Service (Root)
|
||||||
|
```bash
|
||||||
|
# Copy service file
|
||||||
|
sudo cp hmac-file-server.service /etc/systemd/system/
|
||||||
|
|
||||||
|
# Enable and start
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable hmac-file-server.service
|
||||||
|
sudo systemctl start hmac-file-server.service
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
sudo systemctl status hmac-file-server.service
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 XMPP Integration
|
||||||
|
|
||||||
|
### Pod-based XMPP Deployment
|
||||||
|
```bash
|
||||||
|
# Create XMPP services pod
|
||||||
|
podman pod create --name xmpp-services \
|
||||||
|
--publish 5222:5222 \
|
||||||
|
--publish 5269:5269 \
|
||||||
|
--publish 5443:5443 \
|
||||||
|
--publish 8888:8888
|
||||||
|
|
||||||
|
# Add Prosody XMPP server
|
||||||
|
podman run -d --pod xmpp-services --name prosody \
|
||||||
|
-v ./prosody-config:/etc/prosody:ro \
|
||||||
|
-v ./prosody-data:/var/lib/prosody:rw \
|
||||||
|
docker.io/prosody/prosody:latest
|
||||||
|
|
||||||
|
# Add HMAC File Server
|
||||||
|
podman run -d --pod xmpp-services --name hmac-file-server \
|
||||||
|
-v ./config.toml:/app/config.toml:ro \
|
||||||
|
-v ./data:/data:rw \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Monitoring and Health
|
||||||
|
|
||||||
|
### Health Checks
|
||||||
|
```bash
|
||||||
|
# Manual health check
|
||||||
|
curl -f http://localhost:8888/health
|
||||||
|
|
||||||
|
# Container health status
|
||||||
|
podman healthcheck run hmac-file-server
|
||||||
|
|
||||||
|
# Continuous monitoring
|
||||||
|
watch -n 5 'curl -s http://localhost:8888/health && echo " - $(date)"'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Metrics
|
||||||
|
```bash
|
||||||
|
# Prometheus metrics
|
||||||
|
curl http://localhost:9090/metrics
|
||||||
|
|
||||||
|
# Pod statistics
|
||||||
|
podman pod stats xmpp-pod
|
||||||
|
|
||||||
|
# Container logs
|
||||||
|
podman logs -f hmac-file-server
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚨 Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### Permission Errors
|
||||||
|
```bash
|
||||||
|
# Fix SELinux contexts
|
||||||
|
restorecon -R /opt/podman/hmac-file-server
|
||||||
|
|
||||||
|
# Check volume permissions
|
||||||
|
podman unshare ls -la /opt/podman/hmac-file-server
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Container Won't Start
|
||||||
|
```bash
|
||||||
|
# Check image exists
|
||||||
|
podman images | grep hmac-file-server
|
||||||
|
|
||||||
|
# Validate configuration
|
||||||
|
./deploy-podman.sh config
|
||||||
|
|
||||||
|
# Debug with interactive container
|
||||||
|
podman run -it --rm localhost/hmac-file-server:latest /bin/sh
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Network Issues
|
||||||
|
```bash
|
||||||
|
# Check pod networking
|
||||||
|
podman pod ps
|
||||||
|
podman port hmac-file-server
|
||||||
|
|
||||||
|
# Test connectivity
|
||||||
|
nc -zv localhost 8888
|
||||||
|
```
|
||||||
|
|
||||||
|
### Log Analysis
|
||||||
|
```bash
|
||||||
|
# Container logs
|
||||||
|
podman logs hmac-file-server
|
||||||
|
|
||||||
|
# Application logs
|
||||||
|
tail -f /opt/podman/hmac-file-server/logs/hmac-file-server.log
|
||||||
|
|
||||||
|
# System journal
|
||||||
|
journalctl --user -u hmac-file-server.service -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎉 Success Verification
|
||||||
|
|
||||||
|
After deployment, verify everything works:
|
||||||
|
|
||||||
|
1. **Health Check**: `curl -f http://localhost:8888/health`
|
||||||
|
2. **Metrics**: `curl http://localhost:9090/metrics`
|
||||||
|
3. **Container Status**: `podman ps`
|
||||||
|
4. **Pod Status**: `podman pod ps`
|
||||||
|
5. **Logs**: `./deploy-podman.sh logs`
|
||||||
|
|
||||||
|
## 📚 Additional Resources
|
||||||
|
|
||||||
|
- [Podman Official Documentation](https://docs.podman.io/)
|
||||||
|
- [HMAC File Server GitHub](https://github.com/PlusOne/hmac-file-server)
|
||||||
|
- [XEP-0363 Specification](https://xmpp.org/extensions/xep-0363.html)
|
||||||
|
- [Container Security Best Practices](https://docs.podman.io/en/latest/markdown/podman-run.1.html#security-options)
|
102
dockerenv/podman/config.toml.example
Normal file
102
dockerenv/podman/config.toml.example
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# HMAC File Server - Podman Production Configuration
|
||||||
|
# This file is auto-generated by deploy-podman.sh
|
||||||
|
# Edit as needed for your specific deployment requirements
|
||||||
|
|
||||||
|
[server]
|
||||||
|
listen_address = "8888"
|
||||||
|
storage_path = "/data"
|
||||||
|
metrics_enabled = true
|
||||||
|
metrics_port = "9090"
|
||||||
|
max_upload_size = "10GB"
|
||||||
|
max_header_bytes = 1048576
|
||||||
|
cleanup_interval = "24h"
|
||||||
|
max_file_age = "720h"
|
||||||
|
enable_dynamic_workers = true
|
||||||
|
worker_scale_up_thresh = 40
|
||||||
|
worker_scale_down_thresh = 10
|
||||||
|
deduplication_enabled = true
|
||||||
|
min_free_bytes = "1GB"
|
||||||
|
file_naming = "original"
|
||||||
|
|
||||||
|
# Network resilience settings
|
||||||
|
graceful_shutdown_timeout = "300s"
|
||||||
|
connection_drain_timeout = "120s"
|
||||||
|
max_idle_conns_per_host = 5
|
||||||
|
idle_conn_timeout = "90s"
|
||||||
|
disable_keep_alives = false
|
||||||
|
client_timeout = "300s"
|
||||||
|
restart_grace_period = "60s"
|
||||||
|
|
||||||
|
[uploads]
|
||||||
|
# XMPP-compatible file extensions for maximum client support
|
||||||
|
allowed_extensions = [".zip", ".rar", ".7z", ".tar.gz", ".tgz", ".gpg", ".enc", ".pgp", ".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg", ".doc", ".docx"]
|
||||||
|
chunked_uploads_enabled = true
|
||||||
|
chunk_size = "32MB"
|
||||||
|
resumable_uploads_enabled = true
|
||||||
|
max_resumable_age = "48h"
|
||||||
|
sessiontimeout = "60m"
|
||||||
|
maxretries = 3
|
||||||
|
|
||||||
|
# Upload resilience settings
|
||||||
|
session_persistence = true
|
||||||
|
session_recovery_timeout = "300s"
|
||||||
|
client_reconnect_window = "120s"
|
||||||
|
upload_slot_ttl = "3600s"
|
||||||
|
retry_failed_uploads = true
|
||||||
|
max_upload_retries = 3
|
||||||
|
|
||||||
|
[downloads]
|
||||||
|
resumable_downloads_enabled = true
|
||||||
|
chunked_downloads_enabled = true
|
||||||
|
chunk_size = "32MB"
|
||||||
|
# Same extensions as uploads for consistency
|
||||||
|
allowed_extensions = [".zip", ".rar", ".7z", ".tar.gz", ".tgz", ".gpg", ".enc", ".pgp", ".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg", ".doc", ".docx"]
|
||||||
|
|
||||||
|
[security]
|
||||||
|
# IMPORTANT: Change these secrets in production!
|
||||||
|
secret = "CHANGE-THIS-PRODUCTION-SECRET-HMAC-KEY"
|
||||||
|
enablejwt = true
|
||||||
|
jwtsecret = "CHANGE-THIS-JWT-SECRET-KEY"
|
||||||
|
jwtalgorithm = "HS256"
|
||||||
|
jwtexpiration = "24h"
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
level = "info"
|
||||||
|
file = "/logs/hmac-file-server.log"
|
||||||
|
max_size = 100
|
||||||
|
max_backups = 7
|
||||||
|
max_age = 30
|
||||||
|
compress = true
|
||||||
|
|
||||||
|
[deduplication]
|
||||||
|
enabled = true
|
||||||
|
directory = "/deduplication"
|
||||||
|
|
||||||
|
[workers]
|
||||||
|
numworkers = 4
|
||||||
|
uploadqueuesize = 100
|
||||||
|
|
||||||
|
[timeouts]
|
||||||
|
readtimeout = "3600s"
|
||||||
|
writetimeout = "3600s"
|
||||||
|
idletimeout = "3600s"
|
||||||
|
shutdown = "30s"
|
||||||
|
|
||||||
|
[versioning]
|
||||||
|
enableversioning = false
|
||||||
|
backend = "simple"
|
||||||
|
maxversions = 1
|
||||||
|
|
||||||
|
[redis]
|
||||||
|
redisenabled = false
|
||||||
|
redisdbindex = 0
|
||||||
|
redisaddr = "localhost:6379"
|
||||||
|
redispassword = ""
|
||||||
|
redishealthcheckinterval = "120s"
|
||||||
|
|
||||||
|
[clamav]
|
||||||
|
clamavenabled = false
|
||||||
|
clamavsocket = "/var/run/clamav/clamd.ctl"
|
||||||
|
numscanworkers = 2
|
||||||
|
scanfileextensions = [".exe", ".dll", ".bin", ".com", ".bat", ".sh", ".php", ".js"]
|
||||||
|
maxscansize = "200MB"
|
390
dockerenv/podman/deploy-podman.sh
Executable file
390
dockerenv/podman/deploy-podman.sh
Executable file
@ -0,0 +1,390 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# deploy-podman.sh - Production Podman deployment script for HMAC File Server 3.2
|
||||||
|
# Usage: ./deploy-podman.sh [start|stop|restart|status|logs|config]
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Color codes for pretty output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Logging functions
|
||||||
|
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||||
|
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||||
|
warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||||||
|
error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||||
|
|
||||||
|
# Configuration variables
|
||||||
|
readonly APP_NAME='hmac-file-server'
|
||||||
|
readonly POD_NAME='xmpp-pod'
|
||||||
|
readonly CTR_NAME="${POD_NAME}-${APP_NAME}"
|
||||||
|
readonly CTR_IMAGE='localhost/hmac-file-server:latest'
|
||||||
|
readonly RESTART_POLICY='unless-stopped'
|
||||||
|
readonly CTR_UID='1011'
|
||||||
|
readonly APP_DATA="${APP_DATA:-/opt/podman/hmac-file-server}"
|
||||||
|
readonly LISTEN_PORT="${LISTEN_PORT:-8888}"
|
||||||
|
readonly METRICS_PORT="${METRICS_PORT:-9090}"
|
||||||
|
readonly CONFIG_FILE="${APP_DATA}/config/config.toml"
|
||||||
|
|
||||||
|
# Check if running as root (not recommended for Podman)
|
||||||
|
check_user() {
|
||||||
|
if [[ $EUID -eq 0 ]]; then
|
||||||
|
warning "Running as root. Consider using Podman rootless for better security."
|
||||||
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create application directories
|
||||||
|
setup_directories() {
|
||||||
|
info "Setting up application directories..."
|
||||||
|
|
||||||
|
mkdir -p "${APP_DATA}"/{config,data,deduplication,logs}
|
||||||
|
|
||||||
|
# Set proper ownership
|
||||||
|
if command -v podman >/dev/null 2>&1; then
|
||||||
|
podman unshare chown -R "${CTR_UID}:${CTR_UID}" "${APP_DATA}"
|
||||||
|
else
|
||||||
|
error "Podman not found. Please install Podman first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "Directories created at ${APP_DATA}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate configuration file
|
||||||
|
generate_config() {
|
||||||
|
if [[ -f "${CONFIG_FILE}" ]]; then
|
||||||
|
warning "Configuration file already exists at ${CONFIG_FILE}"
|
||||||
|
read -p "Overwrite? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Generating configuration file..."
|
||||||
|
|
||||||
|
# Generate random secrets
|
||||||
|
local hmac_secret=$(openssl rand -base64 32 2>/dev/null || head -c 32 /dev/urandom | base64)
|
||||||
|
local jwt_secret=$(openssl rand -base64 32 2>/dev/null || head -c 32 /dev/urandom | base64)
|
||||||
|
|
||||||
|
cat > "${CONFIG_FILE}" << EOF
|
||||||
|
# HMAC File Server 3.2 - Podman Production Configuration
|
||||||
|
# Generated on $(date)
|
||||||
|
|
||||||
|
[server]
|
||||||
|
listen_address = "${LISTEN_PORT}"
|
||||||
|
storage_path = "/data"
|
||||||
|
metrics_enabled = true
|
||||||
|
metrics_port = "${METRICS_PORT}"
|
||||||
|
max_upload_size = "10GB"
|
||||||
|
max_header_bytes = 1048576
|
||||||
|
cleanup_interval = "24h"
|
||||||
|
max_file_age = "720h"
|
||||||
|
enable_dynamic_workers = true
|
||||||
|
worker_scale_up_thresh = 40
|
||||||
|
worker_scale_down_thresh = 10
|
||||||
|
deduplication_enabled = true
|
||||||
|
min_free_bytes = "1GB"
|
||||||
|
file_naming = "original"
|
||||||
|
|
||||||
|
[uploads]
|
||||||
|
# XMPP-compatible file extensions for maximum client support
|
||||||
|
allowed_extensions = [".zip", ".rar", ".7z", ".tar.gz", ".tgz", ".gpg", ".enc", ".pgp", ".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg", ".doc", ".docx"]
|
||||||
|
chunked_uploads_enabled = true
|
||||||
|
chunk_size = "32MB"
|
||||||
|
resumable_uploads_enabled = true
|
||||||
|
max_resumable_age = "48h"
|
||||||
|
sessiontimeout = "60m"
|
||||||
|
maxretries = 3
|
||||||
|
|
||||||
|
# Upload resilience settings
|
||||||
|
session_persistence = true
|
||||||
|
session_recovery_timeout = "300s"
|
||||||
|
client_reconnect_window = "120s"
|
||||||
|
upload_slot_ttl = "3600s"
|
||||||
|
retry_failed_uploads = true
|
||||||
|
max_upload_retries = 3
|
||||||
|
|
||||||
|
[downloads]
|
||||||
|
resumable_downloads_enabled = true
|
||||||
|
chunked_downloads_enabled = true
|
||||||
|
chunk_size = "32MB"
|
||||||
|
# Same extensions as uploads for consistency
|
||||||
|
allowed_extensions = [".zip", ".rar", ".7z", ".tar.gz", ".tgz", ".gpg", ".enc", ".pgp", ".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg", ".doc", ".docx"]
|
||||||
|
|
||||||
|
[security]
|
||||||
|
secret = "${hmac_secret}"
|
||||||
|
enablejwt = true
|
||||||
|
jwtsecret = "${jwt_secret}"
|
||||||
|
jwtalgorithm = "HS256"
|
||||||
|
jwtexpiration = "24h"
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
level = "info"
|
||||||
|
file = "/logs/hmac-file-server.log"
|
||||||
|
max_size = 100
|
||||||
|
max_backups = 7
|
||||||
|
max_age = 30
|
||||||
|
compress = true
|
||||||
|
|
||||||
|
[deduplication]
|
||||||
|
enabled = true
|
||||||
|
directory = "/deduplication"
|
||||||
|
|
||||||
|
[workers]
|
||||||
|
numworkers = 4
|
||||||
|
uploadqueuesize = 100
|
||||||
|
|
||||||
|
[timeouts]
|
||||||
|
readtimeout = "3600s"
|
||||||
|
writetimeout = "3600s"
|
||||||
|
idletimeout = "3600s"
|
||||||
|
shutdown = "30s"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
success "Configuration generated at ${CONFIG_FILE}"
|
||||||
|
warning "Secrets have been auto-generated. Keep this file secure!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build container image
|
||||||
|
build_image() {
|
||||||
|
info "Checking if image ${CTR_IMAGE} exists..."
|
||||||
|
|
||||||
|
if podman image exists "${CTR_IMAGE}"; then
|
||||||
|
warning "Image ${CTR_IMAGE} already exists"
|
||||||
|
read -p "Rebuild? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Building container image ${CTR_IMAGE}..."
|
||||||
|
|
||||||
|
# Find the Dockerfile
|
||||||
|
local dockerfile_path
|
||||||
|
if [[ -f "dockerenv/podman/Dockerfile.podman" ]]; then
|
||||||
|
dockerfile_path="dockerenv/podman/Dockerfile.podman"
|
||||||
|
elif [[ -f "Dockerfile.podman" ]]; then
|
||||||
|
dockerfile_path="Dockerfile.podman"
|
||||||
|
else
|
||||||
|
error "Dockerfile.podman not found. Please run from project root or ensure file exists."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman build --no-cache -t "${CTR_IMAGE}" -f "${dockerfile_path}" .
|
||||||
|
|
||||||
|
success "Image ${CTR_IMAGE} built successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create pod for networking
|
||||||
|
create_pod() {
|
||||||
|
info "Creating pod ${POD_NAME}..."
|
||||||
|
|
||||||
|
# Remove existing pod if it exists
|
||||||
|
if podman pod exists "${POD_NAME}"; then
|
||||||
|
warning "Pod ${POD_NAME} already exists, removing..."
|
||||||
|
podman pod stop "${POD_NAME}" 2>/dev/null || true
|
||||||
|
podman pod rm "${POD_NAME}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman pod create --name "${POD_NAME}" \
|
||||||
|
--publish "${LISTEN_PORT}:8888" \
|
||||||
|
--publish "${METRICS_PORT}:9090"
|
||||||
|
|
||||||
|
success "Pod ${POD_NAME} created"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start the container
|
||||||
|
start_container() {
|
||||||
|
info "Starting HMAC File Server container..."
|
||||||
|
|
||||||
|
# Stop and remove existing container
|
||||||
|
podman container stop "${CTR_NAME}" 2>/dev/null || true
|
||||||
|
podman container rm "${CTR_NAME}" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Run container with security-hardened settings
|
||||||
|
podman run -d \
|
||||||
|
--pod="${POD_NAME}" \
|
||||||
|
--restart="${RESTART_POLICY}" \
|
||||||
|
--name "${CTR_NAME}" \
|
||||||
|
--user "${CTR_UID}:${CTR_UID}" \
|
||||||
|
--cap-drop=ALL \
|
||||||
|
--security-opt no-new-privileges \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
|
||||||
|
-v "${CONFIG_FILE}:/app/config.toml:ro,Z" \
|
||||||
|
-v "${APP_DATA}/data:/data:rw,Z" \
|
||||||
|
-v "${APP_DATA}/deduplication:/deduplication:rw,Z" \
|
||||||
|
-v "${APP_DATA}/logs:/logs:rw,Z" \
|
||||||
|
--health-cmd="curl -f http://localhost:8888/health || exit 1" \
|
||||||
|
--health-interval=30s \
|
||||||
|
--health-timeout=10s \
|
||||||
|
--health-retries=3 \
|
||||||
|
--health-start-period=40s \
|
||||||
|
"${CTR_IMAGE}" -config /app/config.toml
|
||||||
|
|
||||||
|
success "Container ${CTR_NAME} started successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stop the container
|
||||||
|
stop_container() {
|
||||||
|
info "Stopping HMAC File Server..."
|
||||||
|
|
||||||
|
podman container stop "${CTR_NAME}" 2>/dev/null || true
|
||||||
|
podman container rm "${CTR_NAME}" 2>/dev/null || true
|
||||||
|
podman pod stop "${POD_NAME}" 2>/dev/null || true
|
||||||
|
podman pod rm "${POD_NAME}" 2>/dev/null || true
|
||||||
|
|
||||||
|
success "HMAC File Server stopped"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show status
|
||||||
|
show_status() {
|
||||||
|
echo
|
||||||
|
info "=== HMAC File Server Status ==="
|
||||||
|
|
||||||
|
if podman pod exists "${POD_NAME}"; then
|
||||||
|
echo "Pod Status:"
|
||||||
|
podman pod ps --filter "name=${POD_NAME}"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
if podman container exists "${CTR_NAME}"; then
|
||||||
|
echo "Container Status:"
|
||||||
|
podman ps --filter "name=${CTR_NAME}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "Health Status:"
|
||||||
|
podman healthcheck run "${CTR_NAME}" 2>/dev/null && echo "✅ Healthy" || echo "❌ Unhealthy"
|
||||||
|
echo
|
||||||
|
else
|
||||||
|
warning "Container ${CTR_NAME} not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Service URLs:"
|
||||||
|
echo " 🌐 File Server: http://localhost:${LISTEN_PORT}"
|
||||||
|
echo " 📊 Metrics: http://localhost:${METRICS_PORT}/metrics"
|
||||||
|
echo " 🔍 Health Check: http://localhost:${LISTEN_PORT}/health"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show logs
|
||||||
|
show_logs() {
|
||||||
|
if podman container exists "${CTR_NAME}"; then
|
||||||
|
info "Showing logs for ${CTR_NAME} (Ctrl+C to exit)..."
|
||||||
|
podman logs -f "${CTR_NAME}"
|
||||||
|
else
|
||||||
|
error "Container ${CTR_NAME} not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Full deployment
|
||||||
|
deploy() {
|
||||||
|
info "Starting full HMAC File Server deployment..."
|
||||||
|
|
||||||
|
check_user
|
||||||
|
setup_directories
|
||||||
|
generate_config
|
||||||
|
build_image
|
||||||
|
create_pod
|
||||||
|
start_container
|
||||||
|
|
||||||
|
sleep 5 # Wait for container to start
|
||||||
|
show_status
|
||||||
|
|
||||||
|
success "🎉 HMAC File Server deployed successfully!"
|
||||||
|
echo
|
||||||
|
info "Next steps:"
|
||||||
|
echo "1. Test the service: curl -f http://localhost:${LISTEN_PORT}/health"
|
||||||
|
echo "2. View logs: ./deploy-podman.sh logs"
|
||||||
|
echo "3. Check status: ./deploy-podman.sh status"
|
||||||
|
echo "4. Edit config: ${CONFIG_FILE}"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main command dispatcher
|
||||||
|
case "${1:-deploy}" in
|
||||||
|
start|deploy)
|
||||||
|
deploy
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop_container
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
stop_container
|
||||||
|
sleep 2
|
||||||
|
create_pod
|
||||||
|
start_container
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
logs)
|
||||||
|
show_logs
|
||||||
|
;;
|
||||||
|
config)
|
||||||
|
info "Configuration file location: ${CONFIG_FILE}"
|
||||||
|
if [[ -f "${CONFIG_FILE}" ]]; then
|
||||||
|
echo "Current configuration:"
|
||||||
|
cat "${CONFIG_FILE}"
|
||||||
|
else
|
||||||
|
warning "Configuration file not found. Run './deploy-podman.sh' to generate it."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
build)
|
||||||
|
build_image
|
||||||
|
;;
|
||||||
|
pod)
|
||||||
|
create_pod
|
||||||
|
;;
|
||||||
|
clean)
|
||||||
|
warning "This will remove all containers, pods, and the image. Data will be preserved."
|
||||||
|
read -p "Continue? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
stop_container
|
||||||
|
podman image rm "${CTR_IMAGE}" 2>/dev/null || true
|
||||||
|
success "Cleanup completed"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
help|--help|-h)
|
||||||
|
echo "HMAC File Server Podman Deployment Script"
|
||||||
|
echo
|
||||||
|
echo "Usage: $0 [COMMAND]"
|
||||||
|
echo
|
||||||
|
echo "Commands:"
|
||||||
|
echo " deploy Full deployment (default)"
|
||||||
|
echo " start Start services"
|
||||||
|
echo " stop Stop all services"
|
||||||
|
echo " restart Restart services"
|
||||||
|
echo " status Show service status"
|
||||||
|
echo " logs Show container logs"
|
||||||
|
echo " config Show configuration"
|
||||||
|
echo " build Build container image only"
|
||||||
|
echo " pod Create pod only"
|
||||||
|
echo " clean Remove containers and image"
|
||||||
|
echo " help Show this help"
|
||||||
|
echo
|
||||||
|
echo "Environment Variables:"
|
||||||
|
echo " APP_DATA Data directory (default: /opt/podman/hmac-file-server)"
|
||||||
|
echo " LISTEN_PORT Server port (default: 8888)"
|
||||||
|
echo " METRICS_PORT Metrics port (default: 9090)"
|
||||||
|
echo
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Unknown command: $1"
|
||||||
|
echo "Run '$0 help' for usage information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
55
dockerenv/podman/hmac-file-server.service
Normal file
55
dockerenv/podman/hmac-file-server.service
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# HMAC File Server - Podman Systemd Service
|
||||||
|
# Place this file at: ~/.config/systemd/user/hmac-file-server.service
|
||||||
|
# For system-wide: /etc/systemd/system/hmac-file-server.service
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=HMAC File Server 3.2 "Tremora del Terra" (Podman)
|
||||||
|
Documentation=https://github.com/PlusOne/hmac-file-server
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
NotifyAccess=all
|
||||||
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
TimeoutStopSec=70
|
||||||
|
|
||||||
|
# Main container execution
|
||||||
|
ExecStart=/usr/bin/podman run \
|
||||||
|
--cidfile=%t/%n.ctr-id \
|
||||||
|
--cgroups=no-conmon \
|
||||||
|
--rm \
|
||||||
|
--sdnotify=conmon \
|
||||||
|
--replace \
|
||||||
|
--name hmac-file-server \
|
||||||
|
--user 1011:1011 \
|
||||||
|
--cap-drop=ALL \
|
||||||
|
--security-opt no-new-privileges \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
|
||||||
|
--publish 8888:8888 \
|
||||||
|
--publish 9090:9090 \
|
||||||
|
--volume /opt/podman/hmac-file-server/config/config.toml:/app/config.toml:ro,Z \
|
||||||
|
--volume /opt/podman/hmac-file-server/data:/data:rw,Z \
|
||||||
|
--volume /opt/podman/hmac-file-server/deduplication:/deduplication:rw,Z \
|
||||||
|
--volume /opt/podman/hmac-file-server/logs:/logs:rw,Z \
|
||||||
|
--health-cmd="curl -f http://localhost:8888/health || exit 1" \
|
||||||
|
--health-interval=30s \
|
||||||
|
--health-timeout=10s \
|
||||||
|
--health-retries=3 \
|
||||||
|
--health-start-period=40s \
|
||||||
|
localhost/hmac-file-server:latest -config /app/config.toml
|
||||||
|
|
||||||
|
# Stop and cleanup
|
||||||
|
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
|
||||||
|
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
|
||||||
|
|
||||||
|
# Reload configuration
|
||||||
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
# For system-wide installation, use: WantedBy=multi-user.target
|
0
tests/README.md
Normal file
0
tests/README.md
Normal file
Reference in New Issue
Block a user