{"id":2477,"date":"2024-06-02T17:32:44","date_gmt":"2024-06-02T14:32:44","guid":{"rendered":"https:\/\/www.fibacloud.com\/community\/tutorials\/?p=2477"},"modified":"2026-10-04T22:57:46","modified_gmt":"2026-10-04T19:57:46","slug":"how-to-set-up-native-orchestration-with-docker-and-kubernetes","status":"publish","type":"post","link":"https:\/\/www.fibacloud.com\/community\/tutorials\/en\/how-to-set-up-native-orchestration-with-docker-and-kubernetes\/","title":{"rendered":"Set Up Local Kubernetes with Docker and Minikube"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"2477\" class=\"elementor elementor-2477\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5b239ca e-con-full e-flex e-con e-parent\" data-id=\"5b239ca\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-dfd5144 elementor-widget elementor-widget-text-editor\" data-id=\"dfd5144\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.21.0 - 08-05-2024 *\/\n.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:#69727d;color:#fff}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap{color:#69727d;border:3px solid;background-color:transparent}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap{margin-top:8px}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap-letter{width:1em;height:1em}.elementor-widget-text-editor .elementor-drop-cap{float:left;text-align:center;line-height:1;font-size:50px}.elementor-widget-text-editor .elementor-drop-cap-letter{display:inline-block}<\/style>\t\t\t\t<p>Minikube creates a Kubernetes cluster on one machine for learning and testing application definitions. Its Docker driver runs the Minikube node inside Docker; it does not mean Kubernetes directly manages application containers through Docker Engine. The cluster uses a CRI-compatible container runtime.<\/p>\n<p>This guide uses <strong>Ubuntu 24.04 LTS, x86-64, Docker Engine and Minikube v1.39.0<\/strong> for a separate local lab. It does not replace a production design for high availability, backups or security.<\/p>\n<figure class=\"fc-editorial-figure\" data-fc-visual=\"20260920\" aria-labelledby=\"fc-editorial-caption-2477\"><a href=\"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-content\/uploads\/community-editorial-20260920\/fc-kubernetes-en-inline-20260920.webp\" target=\"_blank\" rel=\"noopener\" aria-label=\"Open full-size illustration\"><picture><source media=\"(max-width: 600px)\" srcset=\"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-content\/uploads\/community-editorial-20260920\/fc-kubernetes-en-mobile-20260920.webp\" width=\"720\" height=\"1140\"><img loading=\"lazy\" src=\"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-content\/uploads\/community-editorial-20260920\/fc-kubernetes-en-inline-20260920.webp\" srcset=\"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-content\/uploads\/community-editorial-20260920\/fc-kubernetes-en-inline-20260920.webp 1440w, https:\/\/www.fibacloud.com\/community\/tutorials\/wp-content\/uploads\/community-editorial-20260920\/fc-kubernetes-en-inline-20260920-300x242.webp 300w, https:\/\/www.fibacloud.com\/community\/tutorials\/wp-content\/uploads\/community-editorial-20260920\/fc-kubernetes-en-inline-20260920-1024x825.webp 1024w, https:\/\/www.fibacloud.com\/community\/tutorials\/wp-content\/uploads\/community-editorial-20260920\/fc-kubernetes-en-inline-20260920-768x619.webp 768w\" sizes=\"auto, (max-width: 900px) 100vw, 820px\" width=\"1440\" height=\"1160\" alt=\"How the reconciliation loop works\" class=\"wp-image-2596\"  decoding=\"async\"><\/picture><\/a><figcaption id=\"fc-editorial-caption-2477\"><strong>How the reconciliation loop works<\/strong> A Deployment declares the desired replica count. Controllers observe current state and work to close the gap. A Service provides a stable endpoint for eligible Pods.<details><summary>Step-by-step explanation<\/summary><ol><li>Declare: Describe desired state in a Deployment.<\/li><li>Observe: Watch the state of running Pods.<\/li><li>Reconcile: Controllers work to close the gap.<\/li><li>Reach: Use a Service to access ready Pods.<\/li><\/ol><\/details><\/figcaption><\/figure>\n<h2>1. Check resources and Docker access<\/h2>\n<p>Minikube&#8217;s starting requirements are two CPUs, 2 GB of free memory and 20 GB of free disk. This example allocates 4 GB of memory; leave additional resources for the host. Internet access is required to download images.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-82aa804 elementor-widget elementor-widget-text-editor\" data-id=\"82aa804\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<pre><code class=\"language-bash\">uname -m\nfree -h\ndf -h\ndocker version\ndocker info --format '{{.OSType}}'<\/code><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-29bbb28 elementor-widget elementor-widget-text-editor\" data-id=\"29bbb28\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>The Docker commands must succeed <strong>without sudo, as the same user who will run Minikube<\/strong>, and report <code>linux<\/code>. Working <code>sudo docker<\/code> access does not prove that user&#8217;s driver access. Docker socket access is highly privileged; do not add accounts to the <code>docker<\/code> group indiscriminately. Prepare the permission model using Docker&#8217;s official guidance. For rootless Docker, follow Minikube&#8217;s separate rootless section instead of mixing the two modes.<\/p>\n<h2>2. Verify and install a versioned Minikube binary<\/h2>\n<p>These downloads are for x86-64; select the corresponding architecture on ARM systems. In a new directory:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8cf3ef6 elementor-widget elementor-widget-text-editor\" data-id=\"8cf3ef6\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<pre><code class=\"language-bash\">mkdir -p fc-minikube-download\ncd fc-minikube-download\nFC_MINIKUBE_VERSION=v1.39.0\ncurl --fail --location --proto '=https' \"https:\/\/github.com\/kubernetes\/minikube\/releases\/download\/${FC_MINIKUBE_VERSION}\/minikube-linux-amd64\" -o minikube-linux-amd64\ncurl --fail --location --proto '=https' \"https:\/\/github.com\/kubernetes\/minikube\/releases\/download\/${FC_MINIKUBE_VERSION}\/minikube-linux-amd64.sha256\" -o minikube-linux-amd64.sha256\nprintf '%s  %s\\n' \"$(cat minikube-linux-amd64.sha256)\" minikube-linux-amd64 | sha256sum --check<\/code><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-06f1e8d elementor-widget elementor-widget-text-editor\" data-id=\"06f1e8d\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>Stop if the checksum fails. After a successful check:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-835218d elementor-widget elementor-widget-text-editor\" data-id=\"835218d\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<pre><code class=\"language-bash\">sudo install -m 0755 minikube-linux-amd64 \/usr\/local\/bin\/minikube\nminikube version<\/code><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-731665d elementor-widget elementor-widget-text-editor\" data-id=\"731665d\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>Downloading a checksum and binary from the same official release checks transfer consistency; it is not an independent signature-verification claim. Review release notes and compatibility before changing versions.<\/p>\n<h2>3. Start a separate local profile<\/h2>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7e2c2ab elementor-widget elementor-widget-text-editor\" data-id=\"7e2c2ab\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<pre><code class=\"language-bash\">minikube profile list\nminikube start -p fc-lab --driver=docker --container-runtime=containerd --cpus=2 --memory=4096\nminikube status -p fc-lab\nminikube -p fc-lab kubectl -- --context=fc-lab get nodes -o wide\nminikube -p fc-lab kubectl -- --context=fc-lab version<\/code><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1565156 elementor-widget elementor-widget-text-editor\" data-id=\"1565156\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>If <code>fc-lab<\/code> already exists, check its owner and workloads or choose another profile name. The node should become <code>Ready<\/code>. Record the Kubernetes server and client versions. The <code>kubectl --<\/code> wrapper obtains a matching client, so this guide does not invoke an uninstalled standalone command. Explicit context arguments also reduce the risk of operating on another cluster accidentally.<\/p>\n<h2>4. Define a bounded application<\/h2>\n<p>Create <code>fc-demo.yaml<\/code>:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d324ffe elementor-widget elementor-widget-text-editor\" data-id=\"d324ffe\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<pre><code class=\"language-yaml\">apiVersion: v1\nkind: Namespace\nmetadata:\n  name: fc-demo\n---\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: web\n  namespace: fc-demo\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: web\n  template:\n    metadata:\n      labels:\n        app: web\n    spec:\n      automountServiceAccountToken: false\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 101\n        runAsGroup: 101\n        fsGroup: 101\n        seccompProfile:\n          type: RuntimeDefault\n      containers:\n        - name: web\n          image: nginxinc\/nginx-unprivileged:stable-alpine\n          ports:\n            - containerPort: 8080\n          securityContext:\n            allowPrivilegeEscalation: false\n            readOnlyRootFilesystem: true\n            capabilities:\n              drop: [ALL]\n          resources:\n            requests:\n              cpu: 50m\n              memory: 32Mi\n            limits:\n              cpu: 250m\n              memory: 256Mi\n          readinessProbe:\n            httpGet:\n              path: \/\n              port: 8080\n            initialDelaySeconds: 3\n            periodSeconds: 5\n          livenessProbe:\n            httpGet:\n              path: \/\n              port: 8080\n            initialDelaySeconds: 15\n            periodSeconds: 10\n          volumeMounts:\n            - name: temporary\n              mountPath: \/tmp\n      volumes:\n        - name: temporary\n          emptyDir:\n            sizeLimit: 64Mi\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: web\n  namespace: fc-demo\nspec:\n  selector:\n    app: web\n  ports:\n    - port: 80\n      targetPort: 8080\n  type: ClusterIP<\/code><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-15f3771 elementor-widget elementor-widget-text-editor\" data-id=\"15f3771\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>The unprivileged Nginx image uses port 8080, a non-root account, a read-only root filesystem and limited temporary storage. <code>stable-alpine<\/code> can change: record and pin the tested image digest for a real deployment. Do not put secret values in this file. <code>emptyDir<\/code> is not persistent application storage.<\/p>\n<h2>5. Apply and verify<\/h2>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0fadfe9 elementor-widget elementor-widget-text-editor\" data-id=\"0fadfe9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<pre><code class=\"language-bash\">minikube -p fc-lab kubectl -- --context=fc-lab apply --dry-run=client -f fc-demo.yaml\nminikube -p fc-lab kubectl -- --context=fc-lab apply -f fc-demo.yaml\nminikube -p fc-lab kubectl -- --context=fc-lab -n fc-demo rollout status deployment\/web --timeout=120s\nminikube -p fc-lab kubectl -- --context=fc-lab -n fc-demo get pods,service\nminikube -p fc-lab kubectl -- --context=fc-lab -n fc-demo port-forward --address=127.0.0.1 service\/web 8080:80<\/code><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7e6e6c3 elementor-widget elementor-widget-text-editor\" data-id=\"7e6e6c3\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>Leave port-forward running and execute <code>curl --fail http:\/\/127.0.0.1:8080\/<\/code> in another terminal. The Service remains ClusterIP: this workflow does not expose an internet-facing LoadBalancer or NodePort. Using <code>--address=0.0.0.0<\/code> would change that access boundary.<\/p>\n<p>Readiness determines whether a Pod can receive traffic; liveness can trigger a restart. Paths and delays must match the application. A successful <code>apply<\/code> alone does not prove that the application works.<\/p>\n<h2>Troubleshooting, rollback and cleanup<\/h2>\n<p><strong>Pending:<\/strong> inspect resources and events. <strong>ImagePullBackOff:<\/strong> check the image name, architecture and registry access. <strong>CrashLoopBackOff:<\/strong> inspect logs, exit reasons, memory limits and required writable paths. <strong>Port-forward fails:<\/strong> confirm the local port is free and the Pod is ready.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4dd4956 elementor-widget elementor-widget-text-editor\" data-id=\"4dd4956\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<pre><code class=\"language-bash\">minikube -p fc-lab kubectl -- --context=fc-lab -n fc-demo describe deployment web\nminikube -p fc-lab kubectl -- --context=fc-lab -n fc-demo logs deployment\/web --tail=50\nminikube logs -p fc-lab --problems<\/code><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-69bdc33 elementor-widget elementor-widget-text-editor\" data-id=\"69bdc33\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>After an application update, inspect Deployment rollout history before using <code>rollout undo deployment\/web -n fc-demo<\/code> with the same explicit-context wrapper. This does not restore an external database.<\/p>\n<p>Stop port-forward with Ctrl+C. Preserve the lab using <code>minikube stop -p fc-lab<\/code>. Use <code>minikube delete -p fc-lab<\/code> only when deliberately removing this lab; its workloads and data can be lost. Complete Docker\/Minikube networking and runtime acceptance on your separate machine. YAML validation alone does not establish those results.<\/p>\n<h2>Official references<\/h2>\n<ul>\n<li><a href=\"https:\/\/minikube.sigs.k8s.io\/docs\/start\/\" rel=\"nofollow noopener\" target=\"_blank\">Minikube startup and resource requirements<\/a><\/li>\n<li><a href=\"https:\/\/minikube.sigs.k8s.io\/docs\/drivers\/docker\/\" rel=\"nofollow noopener\" target=\"_blank\">Docker driver and rootless differences<\/a><\/li>\n<li><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-kubectl-linux\/\" rel=\"nofollow noopener\" target=\"_blank\">kubectl installation and version compatibility<\/a><\/li>\n<li><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-liveness-readiness-startup-probes\/\" rel=\"nofollow noopener\" target=\"_blank\">Kubernetes readiness and liveness probes<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/nginx\/docker-nginx-unprivileged\" rel=\"nofollow noopener\" target=\"_blank\">NGINX unprivileged container image<\/a><\/li>\n<\/ul>\n<p class=\"fc-article-review-date\">Technical content and sources reviewed on October 4, 2026. Recheck the relevant official documentation when a version or provider changes.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Build a local Kubernetes lab with Docker and Minikube, verify versions, deploy a bounded application and check readiness and access.<\/p>\n","protected":false},"author":1,"featured_media":2595,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[261,276,278],"class_list":["post-2477","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials-en","tag-docker","tag-kubernetes","tag-minikube"],"lang":"en","translations":{"en":2477,"tr":2102},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/posts\/2477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/comments?post=2477"}],"version-history":[{"count":5,"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/posts\/2477\/revisions"}],"predecessor-version":[{"id":2483,"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/posts\/2477\/revisions\/2483"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/media\/2595"}],"wp:attachment":[{"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/media?parent=2477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/categories?post=2477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fibacloud.com\/community\/tutorials\/wp-json\/wp\/v2\/tags?post=2477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}