Console Login

Stop Running Containers as Root: A Survival Guide for Norwegian DevOps (2022 Edition)

The "It Works on My Machine" Security Nightmare

Let’s be honest. Most Docker files in production today are garbage. They pull latest from Docker Hub, run as root, and expose ports that have no business talking to the internet. I've audited clusters where a single compromised Nginx container allowed an attacker to pivot straight into the host's /etc/shadow because the orchestration layer was treated like a magical security blanket. It isn't.

It is November 2022. The Log4j scars are still fresh. If you are still deploying containers without a rigid security context, you aren't a Systems Administrator; you're a gambler. And in the Norwegian market, where Datatilsynet (The Norwegian Data Protection Authority) is rightfully aggressive about GDPR and Schrems II compliance, gambling with customer data is a resume-generating event.

1. The Root Problem (Literally)

The default behavior of Docker is to run processes as root inside the container. Since the container shares the host kernel, a process escaping the container as root often grants root access to the host. This is not theoretical. CVE-2019-5736 (runc container breakout) proved how fragile this barrier can be.

The Fix: enforce non-root users.

Stop writing Dockerfiles that end after the COPY command. Create a specific user. Here is the bare minimum standard we expect in 2022:

# Don't use 'latest'. Pin the hash or version.
FROM alpine:3.16

# Create a group and user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Install dependencies
WORKDIR /app
COPY . .

# Switch ownership
RUN chown -R appuser:appgroup /app

# SWITCH TO USER
USER appuser

CMD ["./main"]
Pro Tip: If you are using Kubernetes 1.25 (released just a few months ago), PodSecurityPolicy (PSP) is removed. You must migrate to Pod Security Standards (PSS) or use an admission controller like OPA Gatekeeper or Kyverno to enforce runAsNonRoot: true.

2. Supply Chain: Trust Nothing

Pulling node:16 seems innocent until you realize the base image contains vulnerabilities. In 2022, supply chain attacks are the vector of choice. You are inheriting the technical debt of every maintainer upstream.

We integrate Trivy into our CI/CD pipelines. It’s faster than Clair and easier to set up. Don't push an image to your registry without scanning it first.

# Install Trivy (v0.34.0 is current stable)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.34.0

# Scan your image before deployment
trivy image --severity HIGH,CRITICAL coolvds-app:v1.2

If you see a "CRITICAL" vulnerability in glibc or openssl, the build fails. Period. We don't ship known holes.

3. The Performance vs. Security Trade-off

Here is where the hardware reality hits. Scanning containers at runtime (using tools like Falco) consumes CPU cycles. Encrypting traffic between pods (mTLS with Linkerd or Istio) consumes CPU cycles. If you are running on oversubscribed, cheap shared hosting, your security measures will kill your application's latency.

Feature Shared Hosting (Oversold) CoolVDS (Dedicated Resources)
Kernel Isolation Weak (Container isolation only) Strong (KVM Hardware Virtualization)
I/O Impact of Logging High Latency (Rotational/SATA) Zero Impact (NVMe Arrays)
Compliance Data often leaves Norway 100% Data Sovereignty (Oslo)

We use KVM at CoolVDS because container isolation isn't enough for multi-tenant environments. Even if an attacker breaks out of a container on your VPS, KVM ensures they are trapped inside your virtual machine, unable to touch the hypervisor or other clients. This "Defense in Depth" is non-negotiable for enterprise security.

4. Network Policies: The Firewall Inside

By default, in Kubernetes, every pod can talk to every other pod. This is convenient for developers and disastrous for security. If your frontend gets popped, the attacker can port scan your database directly.

Lock it down. Use a CNI that supports NetworkPolicies (like Calico or Cilium). Deny everything by default.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Then, explicitly allow traffic only where necessary.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 5432

5. The Norwegian Context: GDPR & Schrems II

Since the Schrems II ruling invalidated the Privacy Shield, sending personal data to US-owned cloud providers is a legal minefield. The US CLOUD Act allows American authorities to demand data from US companies, regardless of where the server is physically located.

This is why physical jurisdiction matters. CoolVDS is not just "servers in Norway." We are a Norwegian entity. Your data stays in Oslo. It traverses the NIX (Norwegian Internet Exchange) for low latency, sure, but more importantly, it stays under the protection of Norwegian/EEA law. When you configure your container storage, you need to know exactly where those bytes are written.

6. Runtime Hardening

Finally, utilize the kernel's capabilities to restrict what a container can do. Drop Linux capabilities you don't need. Does your web app need to change the system time? No? Then drop CAP_SYS_TIME.

Here is a hardened Kubernetes security context configuration:

securityContext:
  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000
  allowPrivilegeEscalation: false
  capabilities:
    drop:
      - ALL
  readOnlyRootFilesystem: true

Running with readOnlyRootFilesystem: true is painful at first—you have to mount strict volumes for logs and temp files—but it renders a massive class of exploits useless because the attacker cannot write their malware to disk.

Conclusion

Container security in 2022 is not about a single tool; it is about architecture. It's about minimal base images, non-root users, strict network policies, and underlying infrastructure that respects data sovereignty.

Don't build a fortress on a swamp. Ensure your underlying compute is as robust as your container config. For those needing guaranteed NVMe I/O performance and legal certainty in Norway, spin up a KVM instance on CoolVDS. It takes less than a minute to deploy, but the peace of mind lasts significantly longer.