From 8ac62b48a6c6bd79dd38f37f81aa4477261d6568 Mon Sep 17 00:00:00 2001 From: Lalit Sudhir Date: Wed, 22 Oct 2025 19:10:33 -0700 Subject: [PATCH] feat: implement non-root user security for Docker container --- Dockerfile | 13 +++++ README.md | 21 ++++++++ SECURITY.md | 108 +++++++++++++++++++++++++++++++++++++++++ docker-compose.dev.yml | 4 ++ nginx.conf | 2 + 5 files changed, 148 insertions(+) create mode 100644 SECURITY.md diff --git a/Dockerfile b/Dockerfile index a89dd67..84d70a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,9 +17,22 @@ RUN npm run build -- --mode production # Production stage FROM nginx:alpine +ARG APP_USER_ID=1001 +ARG APP_GROUP_ID=1001 + +RUN addgroup -g $APP_GROUP_ID bentopdf && \ + adduser -u $APP_USER_ID -G bentopdf -D -s /bin/sh bentopdf + COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/nginx.conf +RUN mkdir -p /var/cache/nginx /var/log/nginx /var/run/nginx && \ + chown -R bentopdf:bentopdf /usr/share/nginx/html /var/cache/nginx /var/log/nginx /var/run/nginx + +RUN sed -i 's/user nginx;/user bentopdf;/' /etc/nginx/nginx.conf + EXPOSE 80 +USER bentopdf + CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/README.md b/README.md index 52fe5c6..bec307c 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,27 @@ For organizations that want a clean, distraction-free interface focused solely o For more details, see [SIMPLE_MODE.md](SIMPLE_MODE.md). +### 🔒 Security Features + +BentoPDF runs as a non-root user for enhanced security: + +- **Non-Root Execution**: Container runs with minimal privileges +- **Configurable UID/GID**: Customize user/group IDs for your environment +- **Security Best Practices**: Follows Principle of Least Privilege + +#### Custom User Configuration + +```bash +docker build \ + --build-arg APP_USER_ID=2000 \ + --build-arg APP_GROUP_ID=2000 \ + -t bentopdf . + +docker run -p 8080:80 bentopdf +``` + +For detailed security configuration, see [SECURITY.md](SECURITY.md). + ### 📦 Version Management BentoPDF supports semantic versioning with multiple Docker tags: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..c067111 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,108 @@ +# Security Configuration + +## Non-Root User Support + +BentoPDF now supports running as a non-root user for enhanced security. This follows the Principle of Least Privilege and is essential for production environments. + +### Security Benefits + +- **Reduced Attack Surface**: If compromised, attackers won't have root privileges +- **Compliance**: Meets security standards like SOC 2, PCI DSS +- **Kubernetes/OpenShift Compatibility**: Works with security policies that require non-root execution +- **System Protection**: Prevents system-wide damage if the application is compromised + +### Usage + +#### Default Configuration (UID/GID 1001) +```bash +docker build -t bentopdf . +docker run -p 8080:80 bentopdf +``` + +#### Custom UID/GID +```bash +# Build with custom user/group IDs +docker build \ + --build-arg APP_USER_ID=2000 \ + --build-arg APP_GROUP_ID=2000 \ + -t bentopdf . + +# Run the container +docker run -p 8080:80 bentopdf +``` + +#### Kubernetes Example +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bentopdf +spec: + template: + spec: + securityContext: + runAsNonRoot: true + runAsUser: 2000 + runAsGroup: 2000 + containers: + - name: bentopdf + image: bentopdf:latest + ports: + - containerPort: 80 +``` + +#### Docker Compose Example +```yaml +version: '3.8' +services: + bentopdf: + build: + context: . + dockerfile: Dockerfile + args: + APP_USER_ID: 2000 + APP_GROUP_ID: 2000 + ports: + - "8080:80" + security_opt: + - no-new-privileges:true +``` + +### Verification + +To verify the container is running as non-root: + +```bash +# Check the user inside the container +docker exec whoami +# Should output: bentopdf + +# Check the user ID +docker exec id +# Should show UID/GID matching your configuration +``` + +### Security Best Practices + +1. **Use specific UID/GID**: Don't use 0 (root) or common system UIDs +2. **Regular Updates**: Keep the base image updated +3. **Minimal Permissions**: Only grant necessary file permissions +4. **Security Scanning**: Regularly scan images for vulnerabilities +5. **Network Policies**: Implement network segmentation + +### Troubleshooting + +If you encounter permission issues: + +1. **Check file ownership**: Ensure all application files are owned by the bentopdf user +2. **Verify UID/GID**: Make sure the configured IDs don't conflict with host system +3. **Directory permissions**: Ensure nginx can write to log and cache directories + +### Migration from Root + +If migrating from a root-based setup: + +1. Update your Dockerfile to use the new non-root configuration +2. Rebuild your images with the new security settings +3. Update your deployment configurations (Kubernetes, Docker Compose, etc.) +4. Test thoroughly in a staging environment diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 59e2974..600eaa7 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -3,6 +3,10 @@ services: build: context: . dockerfile: Dockerfile + args: + APP_USER_ID: 1001 // default value is 1001 can be customized to any other value + APP_GROUP_ID: 1001 // default value is 1001 can be customized to any other value + SIMPLE_MODE: false // false for default mode, true for simple mode container_name: bentopdf ports: - '3000:80' diff --git a/nginx.conf b/nginx.conf index abcd35d..27d2496 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,3 +1,5 @@ +pid /var/run/nginx/nginx.pid; + events { worker_connections 1024; }