$ services: k0s-controller: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-controller hostname: k0s-controller privileged: true # Required for kubelet to manage pods -weight: 500;">restart: unless-stopped volumes: - k0s-data:/var/lib/k0s # Cluster state and etcd data - pods-log:/var/log/pods # Pod logs tmpfs: - /run # Runtime data ports: - "6443:6443" # Kubernetes API server command: ["k0s", "controller", "--single"] # Single-node mode (controller + worker) volumes: k0s-data: pods-log:
services: k0s-controller: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-controller hostname: k0s-controller privileged: true # Required for kubelet to manage pods -weight: 500;">restart: unless-stopped volumes: - k0s-data:/var/lib/k0s # Cluster state and etcd data - pods-log:/var/log/pods # Pod logs tmpfs: - /run # Runtime data ports: - "6443:6443" # Kubernetes API server command: ["k0s", "controller", "--single"] # Single-node mode (controller + worker) volumes: k0s-data: pods-log:
services: k0s-controller: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-controller hostname: k0s-controller privileged: true # Required for kubelet to manage pods -weight: 500;">restart: unless-stopped volumes: - k0s-data:/var/lib/k0s # Cluster state and etcd data - pods-log:/var/log/pods # Pod logs tmpfs: - /run # Runtime data ports: - "6443:6443" # Kubernetes API server command: ["k0s", "controller", "--single"] # Single-node mode (controller + worker) volumes: k0s-data: pods-log:
-weight: 500;">docker compose up -d
-weight: 500;">docker compose up -d
-weight: 500;">docker compose up -d
# Extract kubeconfig from the running container
-weight: 500;">docker exec k0s-controller k0s kubeconfig admin > ~/.kube/config # Verify the cluster is running
-weight: 500;">kubectl get nodes
# Extract kubeconfig from the running container
-weight: 500;">docker exec k0s-controller k0s kubeconfig admin > ~/.kube/config # Verify the cluster is running
-weight: 500;">kubectl get nodes
# Extract kubeconfig from the running container
-weight: 500;">docker exec k0s-controller k0s kubeconfig admin > ~/.kube/config # Verify the cluster is running
-weight: 500;">kubectl get nodes
-weight: 500;">kubectl get pods -A
-weight: 500;">kubectl get pods -A
-weight: 500;">kubectl get pods -A
# Generate default config
-weight: 500;">docker exec k0s-controller k0s config create > k0s.yaml # Edit the config, then mount it
# Add to -weight: 500;">docker-compose.yml volumes:
# - ./k0s.yaml:/etc/k0s/k0s.yaml:ro
# Generate default config
-weight: 500;">docker exec k0s-controller k0s config create > k0s.yaml # Edit the config, then mount it
# Add to -weight: 500;">docker-compose.yml volumes:
# - ./k0s.yaml:/etc/k0s/k0s.yaml:ro
# Generate default config
-weight: 500;">docker exec k0s-controller k0s config create > k0s.yaml # Edit the config, then mount it
# Add to -weight: 500;">docker-compose.yml volumes:
# - ./k0s.yaml:/etc/k0s/k0s.yaml:ro
services: k0s-controller: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-controller hostname: k0s-controller privileged: true -weight: 500;">restart: unless-stopped volumes: - k0s-controller-data:/var/lib/k0s tmpfs: - /run ports: - "6443:6443" # Kubernetes API - "9443:9443" # k0s join API - "8132:8132" # Konnectivity (controller-worker tunnel) command: ["k0s", "controller"] k0s-worker: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-worker hostname: k0s-worker privileged: true -weight: 500;">restart: unless-stopped volumes: - k0s-worker-data:/var/lib/k0s - pods-log:/var/log/pods tmpfs: - /run depends_on: - k0s-controller volumes: k0s-controller-data: k0s-worker-data: pods-log:
services: k0s-controller: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-controller hostname: k0s-controller privileged: true -weight: 500;">restart: unless-stopped volumes: - k0s-controller-data:/var/lib/k0s tmpfs: - /run ports: - "6443:6443" # Kubernetes API - "9443:9443" # k0s join API - "8132:8132" # Konnectivity (controller-worker tunnel) command: ["k0s", "controller"] k0s-worker: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-worker hostname: k0s-worker privileged: true -weight: 500;">restart: unless-stopped volumes: - k0s-worker-data:/var/lib/k0s - pods-log:/var/log/pods tmpfs: - /run depends_on: - k0s-controller volumes: k0s-controller-data: k0s-worker-data: pods-log:
services: k0s-controller: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-controller hostname: k0s-controller privileged: true -weight: 500;">restart: unless-stopped volumes: - k0s-controller-data:/var/lib/k0s tmpfs: - /run ports: - "6443:6443" # Kubernetes API - "9443:9443" # k0s join API - "8132:8132" # Konnectivity (controller-worker tunnel) command: ["k0s", "controller"] k0s-worker: image: -weight: 500;">docker.io/k0sproject/k0s:v1.35.1-k0s.1 container_name: k0s-worker hostname: k0s-worker privileged: true -weight: 500;">restart: unless-stopped volumes: - k0s-worker-data:/var/lib/k0s - pods-log:/var/log/pods tmpfs: - /run depends_on: - k0s-controller volumes: k0s-controller-data: k0s-worker-data: pods-log:
# Generate worker join token
TOKEN=$(-weight: 500;">docker exec k0s-controller k0s token create --role=worker) # Join the worker to the cluster
-weight: 500;">docker exec k0s-worker k0s worker $TOKEN
# Generate worker join token
TOKEN=$(-weight: 500;">docker exec k0s-controller k0s token create --role=worker) # Join the worker to the cluster
-weight: 500;">docker exec k0s-worker k0s worker $TOKEN
# Generate worker join token
TOKEN=$(-weight: 500;">docker exec k0s-controller k0s token create --role=worker) # Join the worker to the cluster
-weight: 500;">docker exec k0s-worker k0s worker $TOKEN
# Download and -weight: 500;">install
-weight: 500;">curl -sSLf https://get.k0s.sh | -weight: 600;">sudo sh # Install as single-node (controller + worker)
-weight: 600;">sudo k0s -weight: 500;">install controller --single # Start the -weight: 500;">service
-weight: 600;">sudo k0s -weight: 500;">start # Check -weight: 500;">status
-weight: 600;">sudo k0s -weight: 500;">status # Get kubeconfig
-weight: 600;">sudo k0s kubeconfig admin > ~/.kube/config
# Download and -weight: 500;">install
-weight: 500;">curl -sSLf https://get.k0s.sh | -weight: 600;">sudo sh # Install as single-node (controller + worker)
-weight: 600;">sudo k0s -weight: 500;">install controller --single # Start the -weight: 500;">service
-weight: 600;">sudo k0s -weight: 500;">start # Check -weight: 500;">status
-weight: 600;">sudo k0s -weight: 500;">status # Get kubeconfig
-weight: 600;">sudo k0s kubeconfig admin > ~/.kube/config
# Download and -weight: 500;">install
-weight: 500;">curl -sSLf https://get.k0s.sh | -weight: 600;">sudo sh # Install as single-node (controller + worker)
-weight: 600;">sudo k0s -weight: 500;">install controller --single # Start the -weight: 500;">service
-weight: 600;">sudo k0s -weight: 500;">start # Check -weight: 500;">status
-weight: 600;">sudo k0s -weight: 500;">status # Get kubeconfig
-weight: 600;">sudo k0s kubeconfig admin > ~/.kube/config
# Nginx stream block (not http block)
stream { server { listen 6443; proxy_pass k0s-controller:6443; }
}
# Nginx stream block (not http block)
stream { server { listen 6443; proxy_pass k0s-controller:6443; }
}
# Nginx stream block (not http block)
stream { server { listen 6443; proxy_pass k0s-controller:6443; }
}
# Stop the cluster (if possible) for consistent backup
-weight: 500;">docker compose -weight: 500;">stop k0s-controller # Back up the named volume
-weight: 500;">docker run --rm -v k0s-data:/source -v $(pwd):/backup alpine \ tar czf /backup/k0s-backup-$(date +%Y%m%d).tar.gz -C /source . # Restart
-weight: 500;">docker compose -weight: 500;">start k0s-controller
# Stop the cluster (if possible) for consistent backup
-weight: 500;">docker compose -weight: 500;">stop k0s-controller # Back up the named volume
-weight: 500;">docker run --rm -v k0s-data:/source -v $(pwd):/backup alpine \ tar czf /backup/k0s-backup-$(date +%Y%m%d).tar.gz -C /source . # Restart
-weight: 500;">docker compose -weight: 500;">start k0s-controller
# Stop the cluster (if possible) for consistent backup
-weight: 500;">docker compose -weight: 500;">stop k0s-controller # Back up the named volume
-weight: 500;">docker run --rm -v k0s-data:/source -v $(pwd):/backup alpine \ tar czf /backup/k0s-backup-$(date +%Y%m%d).tar.gz -C /source . # Restart
-weight: 500;">docker compose -weight: 500;">start k0s-controller - A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 1 GB of free RAM minimum (2 GB+ recommended for controller + worker)
- 2 GB of free disk space
- Root/-weight: 600;">sudo access (privileged mode required for nested containers) - Controller only: 1 vCPU, 1 GB RAM, 500 MB disk
- Controller + worker (single-node): 2 vCPU, 2 GB RAM, 2 GB disk
- Per additional worker: 0.5 vCPU, 512 MB RAM baseline (plus workload resources)
- Storage: SSD recommended for etcd performance - k3s vs k0s: Which Lightweight Kubernetes?
- Best Self-Hosted Container Orchestration
- How to Self-Host k3s
- k3s vs Kubernetes
- Docker Swarm vs Kubernetes
- How to Self-Host MicroK8s
- How to Self-Host Rancher
- Docker Compose Basics
- Replace Managed Kubernetes