diff --git a/content/en/docs/components/physical-envs/docker.md b/content/en/docs/components/physical-envs/docker.md index ee1b9fb..974fd82 100644 --- a/content/en/docs/components/physical-envs/docker.md +++ b/content/en/docs/components/physical-envs/docker.md @@ -6,123 +6,864 @@ description: > Container runtime for running containerized applications --- -{{% alert title="Draft" color="warning" %}} -**Editorial Status**: This page is currently being developed. - -* **Jira Ticket**: [TICKET-XXX](https://your-jira/browse/TICKET-XXX) -* **Assignee**: [Name or Team] -* **Status**: Draft -* **Last Updated**: YYYY-MM-DD -* **TODO**: - * [ ] Add detailed component description - * [ ] Include usage examples and code samples - * [ ] Add architecture diagrams - * [ ] Review and finalize content -{{% /alert %}} - ## Overview -[Detailed description of the component - what it is, what it does, and why it exists] +Docker is a container platform that packages applications and dependencies into standardized units called containers. In the Edge Developer Platform, Docker serves three primary functions: powering local development environments through Docker Desktop, building container images in CI/CD pipelines, and providing Docker-in-Docker (DinD) execution environments for Forgejo Actions runners. + +Docker provides a consistent runtime environment across development, testing, and production, ensuring applications behave identically regardless of the underlying infrastructure. ## Key Features -* [Feature 1] -* [Feature 2] -* [Feature 3] +* **Container Runtime**: Execute isolated application containers with process, network, and filesystem isolation +* **Image Building**: Create container images using Dockerfile specifications and layer caching +* **Docker-in-Docker**: Nested Docker execution for CI/CD runners and containerized build environments +* **Multi-stage Builds**: Optimize image size through efficient build processes +* **Volume Management**: Persistent data storage with bind mounts and named volumes +* **Network Isolation**: Software-defined networking with bridge, host, and overlay networks +* **Resource Control**: CPU, memory, and I/O limits through Linux cgroups ## Purpose in EDP -[Explain the role this component plays in the Edge Developer Platform and how it contributes to the overall platform capabilities] +Docker plays several critical roles in the Edge Developer Platform: + +**Local Development**: Docker Desktop provides developers with containerized development environments, enabling consistent tooling and dependencies across different machines. Developers can run entire application stacks locally using docker-compose configurations. + +**Image Building**: CI/CD pipelines use Docker to build container images from source code. The `docker build` command transforms Dockerfiles into layered images that can be deployed to Kubernetes or other container orchestration platforms. + +**CI/CD Execution**: Forgejo Actions runners use Docker-in-Docker to execute workflow steps in isolated containers. Each job runs in a fresh container environment, ensuring clean state and reproducible builds. ## Repository -**Code**: [Link to source code repository] +**Code**: Docker is an open-source project -**Documentation**: [Link to component-specific documentation] +**Documentation**: +* [Docker Official Documentation](https://docs.docker.com/) +* [Containerd Documentation](https://containerd.io/docs/) +* [OCI Runtime Specification](https://github.com/opencontainers/runtime-spec) +* [OverlayFS Documentation](https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html) ## Getting Started ### Prerequisites -* [Prerequisite 1] -* [Prerequisite 2] +* Linux kernel 3.10+ with namespace and cgroup support +* 64-bit processor architecture (x86_64, ARM64) +* At least 4GB RAM for Docker Desktop +* 20GB available disk space for images and containers ### Quick Start -[Step-by-step guide to get started with this component] +**Install Docker on Linux**: -1. [Step 1] -2. [Step 2] -3. [Step 3] +```bash +# Install Docker using official script +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh + +# Add user to docker group (optional, allows running docker without sudo) +sudo usermod -aG docker $USER + +# Start Docker daemon +sudo systemctl start docker +sudo systemctl enable docker +``` + +**Install Docker Desktop** (macOS/Windows): + +1. Download Docker Desktop from [docker.com](https://www.docker.com/products/docker-desktop) +2. Run the installer +3. Launch Docker Desktop from Applications +4. Verify installation in system tray/menu bar ### Verification -[How to verify the component is working correctly] +Verify Docker installation: + +```bash +# Check Docker version +docker --version + +# Verify daemon is running +docker info + +# Run test container +docker run hello-world + +# Check running containers +docker ps + +# View all containers (including stopped) +docker ps -a + +# List downloaded images +docker images +``` ## Usage Examples -### [Use Case 1] +### Running Containers -[Example with code/commands showing common use case] +**Basic Container Execution**: ```bash -# Example commands +# Run container in foreground +docker run ubuntu:22.04 echo "Hello from container" + +# Run container in background (detached) +docker run -d --name nginx-server nginx:latest + +# Run interactive container with shell +docker run -it ubuntu:22.04 /bin/bash + +# Run container with port mapping +docker run -d -p 8080:80 nginx:latest + +# Run container with volume mount +docker run -d -v /host/data:/container/data ubuntu:22.04 + +# Run container with environment variables +docker run -d -e POSTGRES_PASSWORD=secret postgres:15 + +# Run container with resource limits +docker run -d --memory=512m --cpus=1.5 nginx:latest ``` -### [Use Case 2] +**Container Management**: -[Another common scenario] +```bash +# Stop container +docker stop nginx-server -## Integration Points +# Start stopped container +docker start nginx-server -* **[Component A]**: [How it integrates] -* **[Component B]**: [How it integrates] -* **[Component C]**: [How it integrates] +# Restart container +docker restart nginx-server + +# View container logs +docker logs nginx-server +docker logs -f nginx-server # Follow logs + +# Execute command in running container +docker exec -it nginx-server /bin/bash + +# Copy files between host and container +docker cp myfile.txt nginx-server:/tmp/ +docker cp nginx-server:/tmp/myfile.txt ./ + +# Inspect container details +docker inspect nginx-server + +# View container resource usage +docker stats nginx-server + +# Remove container +docker rm nginx-server +docker rm -f nginx-server # Force remove running container +``` + +### Building Images + +**Simple Dockerfile**: + +```dockerfile +# Dockerfile +FROM ubuntu:22.04 + +# Install dependencies +RUN apt-get update && apt-get install -y \ + curl \ + vim \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /app + +# Copy application files +COPY . /app + +# Set environment variable +ENV APP_ENV=production + +# Expose port +EXPOSE 8080 + +# Define entrypoint +CMD ["./start.sh"] +``` + +**Build and Tag Image**: + +```bash +# Build image from Dockerfile +docker build -t myapp:1.0 . + +# Build with build arguments +docker build --build-arg VERSION=1.0 -t myapp:1.0 . + +# Build without cache +docker build --no-cache -t myapp:1.0 . + +# Tag image for registry +docker tag myapp:1.0 registry.example.com/myapp:1.0 + +# Push to registry +docker push registry.example.com/myapp:1.0 + +# Pull from registry +docker pull registry.example.com/myapp:1.0 +``` + +**Multi-stage Build**: + +```dockerfile +# Dockerfile with multi-stage build +FROM golang:1.21 AS builder + +WORKDIR /src +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +RUN CGO_ENABLED=0 go build -o /app/server + +# Final stage +FROM alpine:3.19 + +RUN apk --no-cache add ca-certificates +COPY --from=builder /app/server /usr/local/bin/server + +USER nobody +EXPOSE 8080 +CMD ["server"] +``` + +Multi-stage builds reduce final image size by excluding build tools and intermediate artifacts. + +### Docker-in-Docker for CI/CD + +**DinD Container for Building Images**: + +```bash +# Start DinD daemon +docker run -d \ + --name dind \ + --privileged \ + -e DOCKER_TLS_CERTDIR=/certs \ + -v docker-certs:/certs \ + docker:28.0.4-dind + +# Run build container connected to DinD +docker run --rm \ + -e DOCKER_HOST=tcp://dind:2376 \ + -e DOCKER_TLS_VERIFY=1 \ + -e DOCKER_CERT_PATH=/certs/client \ + -v docker-certs:/certs:ro \ + -v $(pwd):/workspace \ + -w /workspace \ + --link dind:dind \ + docker:28.0.4-cli \ + docker build -t myapp:latest . +``` + +**Kubernetes DinD Sidecar (Forgejo Runner Pattern)**: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: forgejo-runner +spec: + containers: + - name: runner + image: code.forgejo.org/forgejo/runner:6.4.0 + env: + - name: DOCKER_HOST + value: tcp://localhost:2376 + - name: DOCKER_TLS_VERIFY + value: "1" + - name: DOCKER_CERT_PATH + value: /certs/client + volumeMounts: + - name: docker-certs + mountPath: /certs + readOnly: true + - name: runner-data + mountPath: /data + + - name: dind + image: docker:28.0.4-dind + securityContext: + privileged: true + env: + - name: DOCKER_TLS_CERTDIR + value: /certs + volumeMounts: + - name: docker-certs + mountPath: /certs + - name: docker-storage + mountPath: /var/lib/docker + + volumes: + - name: docker-certs + emptyDir: {} + - name: runner-data + emptyDir: {} + - name: docker-storage + emptyDir: {} +``` + +This configuration runs a Forgejo Actions runner with a DinD sidecar, enabling containerized builds within Kubernetes pods. + +### Local Development with Docker Compose + +**Docker Compose Configuration**: + +```yaml +# docker-compose.yml +version: '3.8' + +services: + app: + build: . + ports: + - "8080:8080" + environment: + - DATABASE_URL=postgresql://user:pass@db:5432/appdb + depends_on: + - db + - redis + volumes: + - ./src:/app/src + + db: + image: postgres:15 + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=pass + - POSTGRES_DB=appdb + volumes: + - postgres-data:/var/lib/postgresql/data + + redis: + image: redis:7-alpine + ports: + - "6379:6379" + +volumes: + postgres-data: +``` + +**Compose Commands**: + +```bash +# Start all services +docker-compose up -d + +# View logs +docker-compose logs -f + +# Stop services +docker-compose down + +# Rebuild and restart +docker-compose up -d --build + +# Run command in service +docker-compose exec app /bin/bash + +# Scale service +docker-compose up -d --scale app=3 +``` + +### Image Management + +**Image Operations**: + +```bash +# List images +docker images + +# Remove image +docker rmi myapp:1.0 + +# Remove unused images +docker image prune + +# Remove all unused images +docker image prune -a + +# Inspect image layers +docker history myapp:1.0 +``` + +**Registry Operations**: + +```bash +# Login to registry +docker login registry.example.com + +# Login with credentials +echo $PASSWORD | docker login -u $USERNAME --password-stdin registry.example.com + +# Push image +docker push registry.example.com/myapp:1.0 + +# Pull image +docker pull registry.example.com/myapp:1.0 + +# Search registry +docker search nginx +``` ## Architecture -[Optional: Add architectural diagrams and descriptions] +### Docker Architecture Overview -### Component Architecture (C4) +Docker follows a client-server architecture with several key components: -[Add C4 Container or Component diagrams showing the internal structure] +**Docker Client**: Command-line tool (docker CLI) that sends API requests to the Docker daemon. Developers interact with Docker through client commands like `docker run`, `docker build`, and `docker ps`. -### Sequence Diagrams +**Docker Daemon (dockerd)**: Background service that manages containers, images, networks, and volumes. The daemon listens for Docker API requests and coordinates with lower-level runtime components. -[Add sequence diagrams showing key interaction flows with other components] +**Containerd**: High-level container runtime that manages container lifecycle operations. Containerd handles image transfer and storage, container execution supervision, and low-level storage and network attachments. -### Deployment Architecture +**runc**: Low-level OCI (Open Container Initiative) runtime that creates and runs containers. Runc interfaces directly with Linux kernel features to spawn and manage container processes. -[Add infrastructure and deployment diagrams showing how the component is deployed] +### Container Runtime Layers + +Docker's layered architecture separates concerns across multiple components: + +``` +┌─────────────────────────────────┐ +│ Docker Client (CLI) │ +│ docker run, build, push │ +└────────────┬────────────────────┘ + │ Docker API +┌────────────▼────────────────────┐ +│ Docker Daemon (dockerd) │ +│ API, Image management, Auth │ +└────────────┬────────────────────┘ + │ Container API +┌────────────▼────────────────────┐ +│ Containerd │ +│ Lifecycle, Image pull/push │ +└────────────┬────────────────────┘ + │ OCI Runtime API +┌────────────▼────────────────────┐ +│ runc │ +│ Namespace, cgroup creation │ +└────────────┬────────────────────┘ + │ System Calls +┌────────────▼────────────────────┐ +│ Linux Kernel │ +│ namespaces, cgroups, seccomp │ +└─────────────────────────────────┘ +``` + +**Docker Daemon Layer**: Handles high-level operations like image building, authentication, and API endpoint management. The daemon translates user commands into lower-level runtime operations. + +**Containerd Layer**: Manages container lifecycle independent of Docker-specific features. Containerd can be used directly by Kubernetes and other orchestrators, providing a standard container runtime interface. + +**runc Layer**: Implements the OCI runtime specification, creating container processes with Linux kernel isolation features. Runc configures namespaces, cgroups, and security policies before executing container entrypoints. + +### Linux Kernel Features + +Docker leverages several Linux kernel capabilities for container isolation: + +**Namespaces**: Provide process isolation by creating separate views of system resources: +- **PID namespace**: Isolates process IDs so containers see only their own processes +- **Network namespace**: Provides separate network stacks with unique IP addresses and routing tables +- **Mount namespace**: Isolates filesystem mount points so containers have independent filesystem views +- **UTS namespace**: Separates hostname and domain name +- **IPC namespace**: Isolates inter-process communication resources like shared memory +- **User namespace**: Maps container user IDs to different host user IDs for privilege separation + +**Control Groups (cgroups)**: Limit and account for resource usage: +- CPU allocation and throttling +- Memory limits and swap control +- Block I/O bandwidth limits +- Network bandwidth control (via tc integration) + +**Capabilities**: Fine-grained privilege control that breaks down root privileges into discrete capabilities. Containers run with reduced capability sets, dropping dangerous privileges like CAP_SYS_ADMIN. + +**Seccomp**: Filters system calls that containerized processes can make, reducing the kernel attack surface. Docker applies a default seccomp profile blocking ~44 dangerous syscalls. + +**AppArmor/SELinux**: Mandatory access control systems that enforce security policies on container processes, restricting file access and operations. + +### Image Storage and OverlayFS + +Docker uses storage drivers to manage image layers and container filesystems. The preferred storage driver is overlay2, which uses OverlayFS: + +**Image Layers**: Docker images consist of read-only layers stacked on top of each other. Each Dockerfile instruction creates a new layer. Layers are shared between images, reducing storage requirements. + +**Copy-on-Write (CoW)**: When a container modifies a file from an image layer, OverlayFS copies the file to the container's writable layer. The original image layer remains unchanged, enabling efficient image reuse. + +**OverlayFS Structure**: +``` +Container Writable Layer (upperdir) + │ + ├─ Modified files + │ +Image Layers (lowerdir) + │ + ├─ Layer 3 (READ-ONLY) + ├─ Layer 2 (READ-ONLY) + └─ Layer 1 (READ-ONLY) + │ + Merged View (merged) + │ + └─ Union of all layers +``` + +**LowerDir**: Read-only image layers containing base filesystem and application files + +**UpperDir**: Writable container layer where all changes are stored + +**MergedDir**: Union mount that presents a unified view of all layers to the container + +**WorkDir**: Internal working directory used by OverlayFS for atomic operations + +When a container reads a file, OverlayFS serves it from the topmost layer where it exists. Writes always go to the upperdir, leaving image layers immutable. + +### Networking Architecture + +Docker provides several networking modes: + +**Bridge Network**: Default network mode that creates a virtual bridge (docker0) on the host. Containers connect to the bridge and receive private IP addresses. Network Address Translation (NAT) enables outbound connectivity. + +**Host Network**: Container shares the host's network namespace, using the host's IP address directly. Offers maximum network performance but reduces isolation. + +**Overlay Network**: Multi-host networking for container communication across different Docker hosts. Used by Docker Swarm and can be integrated with Kubernetes. + +**None**: Disables networking for maximum isolation. + +### Docker-in-Docker (DinD) Architecture + +Docker-in-Docker runs a nested Docker daemon inside a container. This is used in CI/CD runners to provide isolated build environments: + +**Privileged Container**: DinD requires privileged mode to mount filesystems and create namespaces within the container. The `--privileged` flag grants extended capabilities. + +**Separate Daemon**: A complete Docker daemon runs inside the container, managing its own containers, images, and networks independently of the host daemon. + +**Certificate Management**: DinD uses mutual TLS authentication between the inner client and daemon. Certificates are shared through volumes mounted at `/certs`. + +**Storage Driver**: The inner Docker daemon typically uses vfs or overlay2 storage driver. VFS provides maximum compatibility but larger storage overhead. + +**Use in Forgejo Runners**: +```yaml +containers: + - name: runner + image: code.forgejo.org/forgejo/runner:6.4.0 + env: + - name: DOCKER_HOST + value: tcp://localhost:2376 + - name: DOCKER_TLS_VERIFY + value: "1" + + - name: dind + image: docker:28.0.4-dind + securityContext: + privileged: true + volumeMounts: + - name: docker-certs + mountPath: /certs +``` + +The runner container connects to the DinD container via TCP, allowing workflow steps to execute docker commands for building and testing. ## Configuration -[Key configuration options and how to set them] +### Docker Daemon Configuration + +The Docker daemon reads configuration from `/etc/docker/daemon.json`: + +```json +{ + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "3" + }, + "storage-driver": "overlay2", + "storage-opts": [ + "overlay2.override_kernel_check=true" + ], + "default-address-pools": [ + { + "base": "172.17.0.0/16", + "size": 24 + } + ], + "dns": ["8.8.8.8", "8.8.4.4"], + "insecure-registries": [], + "registry-mirrors": [], + "features": { + "buildkit": true + }, + "max-concurrent-downloads": 10, + "max-concurrent-uploads": 5 +} +``` + +**Key Configuration Options**: + +* `log-driver`: Logging mechanism (json-file, syslog, journald, etc.) +* `storage-driver`: Filesystem driver (overlay2, devicemapper, btrfs, zfs) +* `insecure-registries`: Registries that don't require HTTPS +* `registry-mirrors`: Mirror registries for faster pulls +* `buildkit`: Enable BuildKit for improved build performance + +**Apply Configuration Changes**: + +```bash +# Restart Docker daemon +sudo systemctl restart docker + +# Verify configuration +docker info +``` + +### Docker-in-Docker Configuration + +**Environment Variables**: + +* `DOCKER_TLS_CERTDIR`: Directory for TLS certificates (typically `/certs`) +* `DOCKER_HOST`: Docker daemon address (e.g., `tcp://localhost:2376`) +* `DOCKER_TLS_VERIFY`: Enable TLS verification (`1` or `0`) +* `DOCKER_CERT_PATH`: Path to client certificates + +**DinD Security Considerations**: + +DinD requires privileged mode, which grants extended capabilities. Use DinD only in trusted environments: +- CI/CD runners in isolated namespaces +- Development environments +- Build systems with network isolation + +Avoid using DinD for untrusted workloads or multi-tenant environments. + +## Integration Points + +* **Kubernetes**: Can use Docker (via dockershim, deprecated) or containerd directly as container runtime +* **Forgejo Actions**: Uses Docker-in-Docker for isolated build execution in CI/CD pipelines +* **Container Registries**: Pushes and pulls images to/from OCI-compliant registries +* **Development Environments**: Docker Desktop provides local container runtime for development +* **Image Scanning Tools**: Integrates with security scanners like Trivy and Clair +* **Monitoring Systems**: Exports metrics via Prometheus exporters and logging drivers ## Troubleshooting -### [Common Issue 1] +### Docker Daemon Won't Start -**Problem**: [Description] +**Problem**: Docker daemon fails to start or crashes immediately -**Solution**: [How to fix] +**Solution**: +1. Check daemon logs: + ```bash + sudo journalctl -u docker.service + sudo cat /var/log/docker.log + ``` -### [Common Issue 2] +2. Verify kernel support: + ```bash + docker info | grep -i kernel + grep CONFIG_NAMESPACES /boot/config-$(uname -r) + ``` -**Problem**: [Description] +3. Test daemon in debug mode: + ```bash + sudo dockerd --debug + ``` -**Solution**: [How to fix] +4. Check for port conflicts: + ```bash + sudo netstat -tulpn | grep docker + ``` -## Status +### Container Cannot Connect to Network -**Maturity**: [Production / Beta / Experimental] +**Problem**: Container has no network connectivity or DNS resolution fails + +**Solution**: +1. Check container network mode: + ```bash + docker inspect container-name | grep -i network + ``` + +2. Verify DNS configuration: + ```bash + docker exec container-name cat /etc/resolv.conf + docker exec container-name ping 8.8.8.8 + docker exec container-name ping google.com + ``` + +3. Check firewall rules: + ```bash + sudo iptables -L -n | grep DOCKER + ``` + +4. Restart Docker network: + ```bash + sudo systemctl restart docker + ``` + +5. Recreate default bridge: + ```bash + docker network rm bridge + sudo systemctl restart docker + ``` + +### Out of Disk Space + +**Problem**: Docker runs out of disk space for images or containers + +**Solution**: +1. Check disk usage: + ```bash + docker system df + docker system df -v # Verbose output + ``` + +2. Remove unused containers: + ```bash + docker container prune + ``` + +3. Remove unused images: + ```bash + docker image prune -a + ``` + +4. Remove unused volumes: + ```bash + docker volume prune + ``` + +5. Complete cleanup: + ```bash + docker system prune -a --volumes + ``` + +6. Configure log rotation in `/etc/docker/daemon.json`: + ```json + { + "log-opts": { + "max-size": "10m", + "max-file": "3" + } + } + ``` + +### Docker Build Fails + +**Problem**: Image build fails with errors or hangs + +**Solution**: +1. Build with verbose output: + ```bash + docker build --progress=plain --no-cache -t myapp . + ``` + +2. Check Dockerfile syntax: + ```bash + docker build --check -t myapp . + ``` + +3. Verify base image exists: + ```bash + docker pull ubuntu:22.04 + ``` + +4. Increase build memory (Docker Desktop): + - Open Docker Desktop settings + - Increase memory allocation to 4GB+ + +5. Check build context size: + ```bash + docker build --progress=plain -t myapp . 2>&1 | grep "transferring context" + ``` + +6. Use `.dockerignore` to exclude large files: + ``` + # .dockerignore + node_modules + .git + *.log + ``` + +### Docker-in-Docker Container Cannot Build Images + +**Problem**: DinD container fails to build images or start daemon + +**Solution**: +1. Verify privileged mode: + ```bash + docker inspect dind | grep -i privileged + ``` + +2. Check DinD daemon logs: + ```bash + docker logs dind + ``` + +3. Verify certificate volumes: + ```bash + docker exec dind ls -la /certs + ``` + +4. Test Docker client connection: + ```bash + docker run --rm \ + -e DOCKER_HOST=tcp://dind:2376 \ + -e DOCKER_TLS_VERIFY=1 \ + -e DOCKER_CERT_PATH=/certs/client \ + -v docker-certs:/certs:ro \ + --link dind:dind \ + docker:28.0.4-cli \ + docker info + ``` + +5. Check storage driver: + ```bash + docker exec dind docker info | grep "Storage Driver" + ``` + +### Permission Denied When Running Docker + +**Problem**: User cannot run Docker commands without sudo + +**Solution**: +1. Add user to docker group: + ```bash + sudo usermod -aG docker $USER + ``` + +2. Log out and back in to apply group changes + +3. Verify group membership: + ```bash + groups $USER + ``` + +4. Test Docker access: + ```bash + docker ps + ``` + +5. If issue persists, check socket permissions: + ```bash + sudo chmod 666 /var/run/docker.sock + ``` + +Note: Adding users to the docker group grants root-equivalent privileges. Only add trusted users. ## Additional Resources -* [Link to external documentation] -* [Link to community resources] -* [Link to related components] - -## Documentation Notes - -[Instructions for team members filling in this documentation - remove this section once complete] +* [Docker Documentation](https://docs.docker.com/) +* [Docker Hub](https://hub.docker.com/) +* [Dockerfile Best Practices](https://docs.docker.com/develop/dev-best-practices/) +* [Containerd Documentation](https://containerd.io/) +* [OCI Specifications](https://opencontainers.org/) +* [Docker Security Best Practices](https://docs.docker.com/engine/security/) +* [Kernel Namespace Documentation](https://man7.org/linux/man-pages/man7/namespaces.7.html) +* [Control Groups (cgroups) Documentation](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html)