{"id":4940,"date":"2026-03-02T20:58:55","date_gmt":"2026-03-02T11:58:55","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=4940"},"modified":"2026-03-03T17:18:35","modified_gmt":"2026-03-03T08:18:35","slug":"linuxmacos-kubernetes-3","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/03\/02\/linuxmacos-kubernetes-3\/","title":{"rendered":"[Linux,MacOS]\ucfe0\ubc84\ub124\ud2f0\uc2a4 + \ub9ac\uc561\ud2b8 \ub4dc\ub85c\uc5b4\uba54\ub274 \/ Kubernetes + React Drawer Menu -3"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb \ucfe0\ubc84\ub124\ud2f0\uc2a4\uc5d0\uc11c react Dreawer Menu\ub97c \uc801\uc6a9\ud55c \uc608\uc81c\uc785\ub2c8\ub2e4. <br>This is an example of applying React Dreawer Menu in Kubernetes.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb vite+react Install \/ \uc124\uce58<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm create vite@latest react-drawer\ncd react-drawer\nnpm install\nnpm run dev<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb\/Appk8s\/react-drawer\/src\/App.jsx<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { useState } from \"react\";\nimport \".\/App.css\";\n\nfunction App() {\n  const &#91;isOpen, setIsOpen] = useState(false);\n\n  return (\n    &lt;&gt;\n      &lt;header className=\"header\"&gt;\n        &lt;button className=\"menu-btn\" onClick={() =&gt; setIsOpen(true)}&gt;\n          \u2630\n        &lt;\/button&gt;\n        &lt;h2&gt;Vite Drawer App&lt;\/h2&gt;\n      &lt;\/header&gt;\n\n      {isOpen &amp;&amp; &lt;div className=\"overlay\" onClick={() =&gt; setIsOpen(false)} \/&gt;}\n\n      &lt;aside className={`drawer ${isOpen ? \"open\" : \"\"}`}&gt;\n        &lt;button className=\"close-btn\" onClick={() =&gt; setIsOpen(false)}&gt;\n          \u2715\n        &lt;\/button&gt;\n        &lt;ul&gt;\n          &lt;li&gt;Home&lt;\/li&gt;\n          &lt;li&gt;About&lt;\/li&gt;\n          &lt;li&gt;Services&lt;\/li&gt;\n          &lt;li&gt;Contact&lt;\/li&gt;\n        &lt;\/ul&gt;\n      &lt;\/aside&gt;\n\n      &lt;main className=\"content\"&gt;\n        &lt;p&gt;Vite \uae30\ubc18 Drawer \uba54\ub274 \uc608\uc81c\uc785\ub2c8\ub2e4.&lt;\/p&gt;\n      &lt;\/main&gt;\n    &lt;\/&gt;\n  );\n}\n\nexport default App;<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb<code>\/Appk8s\/react-drawer\/src\/App.css<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>body {\n  margin: 0;\n  font-family: sans-serif;\n}\n\n.header {\n  display: flex;\n  align-items: center;\n  padding: 15px 20px;\n  background: #1e293b;\n  color: white;\n}\n\n.menu-btn {\n  font-size: 24px;\n  margin-right: 15px;\n  background: none;\n  border: none;\n  color: white;\n  cursor: pointer;\n}\n\n.drawer {\n  position: fixed;\n  top: 0;\n  left: -260px;\n  width: 260px;\n  height: 100%;\n  background: white;\n  box-shadow: 2px 0 10px rgba(0,0,0,0.2);\n  transition: left 0.3s ease;\n  padding: 20px;\n  z-index: 1000;\n}\n\n.drawer.open {\n  left: 0;\n}\n\n.drawer ul {\n  list-style: none;\n  padding: 0;\n}\n\n.drawer li {\n  padding: 12px 0;\n  cursor: pointer;\n  border-bottom: 1px solid #eee;\n}\n\n.close-btn {\n  background: none;\n  border: none;\n  font-size: 18px;\n  float: right;\n  cursor: pointer;\n}\n\n.overlay {\n  position: fixed;\n  inset: 0;\n  background: rgba(0,0,0,0.4);\n  z-index: 999;\n}\n\n.content {\n  padding: 20px;\n}<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffbdist \ube4c\ub4dc \/ dist build<\/p>\n\n\n\n<p>\u2714\ufe0f \uc704\uce58 \/ location<\/p>\n\n\n\n<p>&#8212; \/Appk8s\/react-drawer<\/p>\n\n\n\n<p>\u2714\ufe0f \ube4c\ub4dc \ud6c4 dist\ub514\ub809\ud1a0\ub9ac\uac00 \uc0dd\uc131\ub418\uc5b4 \uc788\uc5b4\uc57c\ud558\uba70 \ub514\ub809\ud1a0\ub9ac \ub0b4\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub418\uc5b4 \uc788\uc5b4\uc57c\ud569\ub2c8\ub2e4.<br>After building, a dist directory should be created and files should be created inside the directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run build<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb Dockerfile<\/p>\n\n\n\n<p>\u2714\ufe0f \uc704\uce58 \/ location<\/p>\n\n\n\n<p>&#8212; \/Appk8s\/react-drawer<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># build node\nFROM node:18 AS build\nWORKDIR \/app\nCOPY package*.json .\/\nRUN npm install\nCOPY . .\nRUN npm run build\n\n# build nginx\nFROM nginx:alpine\nCOPY --from=build \/app\/dist \/usr\/share\/nginx\/html\nCOPY nginx.conf \/etc\/nginx\/conf.d\/default.conf<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffbnginx.conf<\/p>\n\n\n\n<p>\u2714\ufe0f \uc704\uce58 \/ location<\/p>\n\n\n\n<p>&#8212; \/Appk8s\/react-drawer<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n  listen 80;\n  server_name _;\n  \n  location \/ {\n    root \/usr\/share\/nginx\/html;\n    try_files $uri \/index.html;\n  }\n}<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc774\ubbf8\uc9c0\ub85c \ube4c\ub4dc(\ub3c4\ucee4\ub370\uc2a4\ud06c\ud0d1\uc774 \uc2e4\ud589\ub418\uc5b4 \uc788\uc5b4\uc57c \ud569\ub2c8\ub2e4.)<br>Build from image (Docker Desktop must be running)<\/p>\n\n\n\n<p>\u2714\ufe0f \uc704\uce58 \/ location<\/p>\n\n\n\n<p>&#8212; \/Appk8s\/react-drawer<\/p>\n\n\n\n<p>&#8212; -t \uc635\uc158\uc740 \ud0dc\uadf8\ub97c \uc758\ubbf8\ud558\uba70 \uc774\ubbf8\uc9c0\uc5d0 \uc774\ub984\uacfc \ubc84\uc804\uc744 \ubd99\uc774\uaca0\ub2e4\ub294 \uc758\ubbf8\uc785\ub2c8\ub2e4.<br>The -t option means tag, which means to give the image a name and version.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker build -t react-drawer-local:1.0 .<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud655\uc778 \/ Confirm creation of image<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>% <strong>docker images<\/strong>\n                                                           i Info \u2192   U  In Use\nIMAGE                           ID             DISK USAGE   CONTENT SIZE   EXTRA\ndocker\/desktop-kubernetes:kubernetes-v1.34.1-cni-v1.7.1-critools-v1.33.0-cri-dockerd-v0.3.20-1-debian\n                                12d6673564e0        552MB          169MB        \ndocker\/desktop-storage-provisioner:v3.0\n                                57d2b6ad1c6f       75.4MB         21.9MB    U   \ndocker\/desktop-vpnkit-controller:v4.0\n                                bdaff3408b1c         50MB         10.7MB    U   \nnginx:latest                    0236ee02dcbc        258MB         64.1MB        \nnode:20-alpine                  09e2b3d97260        193MB           49MB        \n<strong>react-drawer-local:1.0          f5186d602216         92MB         25.9MB    U <\/strong> <\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffbdeployment.yaml<\/p>\n\n\n\n<p>\u2714\ufe0f \uc704\uce58 \/ location<\/p>\n\n\n\n<p>&#8212; \/Appk8s\/react-drawer<\/p>\n\n\n\n<p>\u2714\ufe0f 1. \uae30\ubcf8 \uc815\ubcf4 \ubc0f \uad00\ub9ac \uaddc\uce59 \/ Basic Information and Management Rules<\/p>\n\n\n\n<p>&#8211;kind: Deployment -> \uc774 \ub9ac\uc18c\uc2a4\uac00 &#8216;Deployment&#8217;\uc784\uc744 \uba85\uc2dc\ud569\ub2c8\ub2e4.<br>Specifies that this resource is a &#8216;Deployment&#8217;.<\/p>\n\n\n\n<p>&#8211;metadata: name: react-drawer -> \ucfe0\ubc84\ub124\ud2f0\uc2a4 \ud074\ub7ec\uc2a4\ud130 \uc548\uc5d0\uc11c \uc774 \ubc30\ud3ec \uac1d\uccb4\uc758 \uc774\ub984\uc744 react-drawer\ub77c\uace0 \ubd80\ub974\uaca0\ub2e4\ub294 \ub73b\uc785\ub2c8\ub2e4.<br>This means that we will call this deployment object react-drawer within our Kubernetes cluster.<\/p>\n\n\n\n<p>&#8211;spec: replicas: 1: \uc774 \uc560\ud50c\ub9ac\ucf00\uc774\uc158(Pod)\uc744 \ud56d\uc0c1 1\uac1c \uc720\uc9c0\ud558\ub77c\ub294 \uba85\ub839\uc785\ub2c8\ub2e4. \ub9cc\uc57d \ucee8\ud14c\uc774\ub108\uac00 \uc8fd\uc73c\uba74 \ucfe0\ubc84\ub124\ud2f0\uc2a4\uac00 \uc790\ub3d9\uc73c\ub85c \ub2e4\uc2dc \uc0b4\ub824\ub0c5\ub2c8\ub2e4.<br>This command ensures that only one instance of this application (Pod) is always running. If the container dies, Kubernetes will automatically revive it.<\/p>\n\n\n\n<p>\u2714\ufe0f2. \uc140\ub809\ud130 \/ Selector<\/p>\n\n\n\n<p>&#8211;selector: matchLabels: app: react-drawer: <br>\uc774 Deployment\uac00 \uc5b4\ub5a4 Pod\ub4e4\uc744 \uad00\ub9ac\ud560\uc9c0 \uacb0\uc815\ud558\ub294 \uae30\uc900\uc785\ub2c8\ub2e4. \uc544\ub798 template\uc5d0 \uc815\uc758\ub41c \ub77c\ubca8\uacfc \uc77c\uce58\ud574\uc57c \ud569\ub2c8\ub2e4.<br>This is the criterion that determines which Pods this Deployment will manage. It must match the labels defined in the template below.<\/p>\n\n\n\n<p>\u2714\ufe0f 3. \ud3ec\ub4dc \ud15c\ud50c\ub9bf \/ Pod Template<\/p>\n\n\n\n<p>&#8211;image: react-drawer-local:1.0: <br>react-drawer-local:1.0 \uc774 \uc774\ubbf8\uc9c0\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<br>react-drawer-local:1.0 uses this image.<\/p>\n\n\n\n<p>&#8211;imagePullPolicy: Never: <br>\uac00\uc7a5 \uc911\uc694\ud55c \ubd80\ubd84\uc785\ub2c8\ub2e4.\uc774 \uc124\uc815\uc740 &#8220;\uc678\ubd80\uc5d0\uc11c \ucc3e\uc9c0 \ub9d0\uace0, \ud604\uc7ac \ub178\ub4dc\uc5d0 \uc774\ubbf8 \ube4c\ub4dc\ub418\uc5b4 \uc788\ub294 \ub85c\uceec \uc774\ubbf8\uc9c0\ub97c \uc0ac\uc6a9\ud574\ub77c&#8221;\ub77c\ub294 \uc758\ubbf8\uc785\ub2c8\ub2e4.<br>This is the most important part. This setting means &#8220;don&#8217;t look for it externally, use the local image that is already built on the current node.&#8221;<\/p>\n\n\n\n<p>&#8211;ports: containerPort: 80<\/p>\n\n\n\n<p>\u2b50\ufe0f \uccab\ubc88\uc9f8 spec\uc740 \uc804\uccb4 \uc2dc\uc2a4\ud15c(Deployment)\uc744 \uc5b4\ub5bb\uac8c \uc6b4\uc601\ud560\uc9c0\uc5d0 \ub300\ud55c \uba85\uc138<br>The first spec is a specification of how to operate the entire system (Deployment).<\/p>\n\n\n\n<p>\u2b50\ufe0f \ub450\ubc88\uc9f8 spec\uc740 \uc2e4\uc81c\ub85c \ub3cc\uc544\uac08 Pod\uc774 \uc5b4\ub5bb\uac8c \uc0dd\uacbc\ub294\uc9c0\uc5d0 \ub300\ud55c \uba85\uc138<br>The second spec is a specification of what the Pod that will actually return looks like.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: react-drawer\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: react-drawer\n  template:\n    metadata:\n      labels:\n        app: react-drawer\n    spec:\n      containers:\n        - name: react-drawer\n          image: react-drawer-local:1.0\n          imagePullPolicy: Never   #  \ub85c\uceec \uc774\ubbf8\uc9c0 \uc0ac\uc6a9\ud558\uae30 \/ Using local images\n          ports:\n            - containerPort: 80<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb service.yaml<\/p>\n\n\n\n<p>\u2714\ufe0f \uc704\uce58 \/ location<\/p>\n\n\n\n<p>&#8212; \/Appk8s\/react-drawer<\/p>\n\n\n\n<p>\u2714\ufe0f service.yaml\uc740 Deployment(\uc560\ud50c\ub9ac\ucf00\uc774\uc158)\ub97c \uc678\ubd80\uc5d0\uc11c \uc811\uc18d\ud560 \uc218 \uc788\ub3c4\ub85d \uae38\uc744 \uc5f4\uc5b4\uc8fc\ub294 Service \uc124\uc815\uc785\ub2c8\ub2e4.<br>service.yaml is a service setting that opens the way for Deployment (application) to be accessed externally.<\/p>\n\n\n\n<p>&#8212; kind: Service -> \uc774 \uc124\uc815\uc774 \ub124\ud2b8\uc6cc\ud06c \uc11c\ube44\uc2a4(L4 \ub85c\ub4dc\ubc38\ub7f0\uc11c \uc5ed\ud560)\uc784\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.<br>This setting means that this is a network service (L4 load balancer role).<\/p>\n\n\n\n<p>&#8212; type: NodePort -> \ud074\ub7ec\uc2a4\ud130 \uc678\ubd80\uc5d0\uc11c \uc811\uc18d\ud558\uae30 \uc704\ud574 \uac01 \ub178\ub4dc(\ucef4\ud4e8\ud130)\uc758 \ud2b9\uc815 \ud3ec\ud2b8\ub97c \uac1c\ubc29\ud558\ub294 \ubc29\uc2dd\uc785\ub2c8\ub2e4.<br>This method opens a specific port on each node (computer) to allow access from outside the cluster.<\/p>\n\n\n\n<p>&#8212; selector: app: react-drawer -> \uc774 \uc11c\ube44\uc2a4\uac00 *\uc5b4\ub5a4 \ubc30\ud3ec\ubb3c(Deployment)\uacfc \uc5f0\uacb0\ub420\uc9c0 \uacb0\uc815\ud569\ub2c8\ub2e4. \uc544\uae4c \ub9cc\ub4e0 Deployment\uc758 \ub77c\ubca8\uacfc \uc77c\uce58\ud574\uc57c \ud569\ub2c8\ub2e4.<br>Determines which deployment this service will be associated with. This must match the label of the deployment you created earlier.<\/p>\n\n\n\n<p>&#8212; nodePort: 30007: \uc678\ubd80\uc5d0\uc11c \uc811\uc18d\ud558\ub294 \ubc88\ud638\uc785\ub2c8\ub2e4. \ube0c\ub77c\uc6b0\uc800\uc5d0 http:\/\/&lt;\ub178\ub4dcIP>:30007\uc774\ub77c\uace0 \uce58\uba74 \uc811\uc18d\ub429\ub2c8\ub2e4. (\ubc94\uc704\ub294 \ubcf4\ud1b5 30000~32767 \uc0ac\uc774\ub85c \uc9c0\uc815\ud569\ub2c8\ub2e4.)<br>This is the number you access from outside. You can connect by entering http:\/\/:30007 in your browser. (The range is usually 30000 to 32767.)<\/p>\n\n\n\n<p>&#8212; port: 80: \uc11c\ube44\uc2a4 \uc790\uccb4\uc758 \ubc88\ud638\uc785\ub2c8\ub2e4. \ud074\ub7ec\uc2a4\ud130 \ub0b4\ubd80\uc758 \ub2e4\ub978 \uc571\ub4e4\uc774 \uc774 \uc11c\ube44\uc2a4\ub97c \ucc3e\uc744 \ub54c \uc0ac\uc6a9\ud558\ub294 \ud3ec\ud2b8\uc785\ub2c8\ub2e4.<br>This is the number of the service itself. This is the port that other apps within the cluster use to find this service.<\/p>\n\n\n\n<p>&#8212; targetPort: 80: \ucee8\ud14c\uc774\ub108 \ub0b4\ubd80\uc758 \ubc88\ud638\uc785\ub2c8\ub2e4. \uc2e4\uc81c React \uc571(Nginx \ub4f1)\uc774 \ucee8\ud14c\uc774\ub108 \uc548\uc5d0\uc11c \uae30\ub2e4\ub9ac\uace0 \uc788\ub294 \ud3ec\ud2b8\uc785\ub2c8\ub2e4.<br>This is the number inside the container. This is the port that the actual React app (Nginx, etc.) is listening on inside the container.<\/p>\n\n\n\n<p>\u2b50\ufe0f \ud3ec\ud2b8 \ud750\ub984 : nodePort(3007) -&gt; service port(80) -&gt; service targetport(80) -&gt; deployment containerport(80)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: v1\nkind: Service\nmetadata:\n  name: react-drawer-service\nspec:\n  type: NodePort\n  selector:\n    app: react-drawer\n  ports:\n    - port: 80\n      targetPort: 80\n      nodePort: 30007<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc801\uc6a9 \ubc0f \uc2e4\ud589  \/ Apply and Run<\/p>\n\n\n\n<p>\u2714\ufe0f \uc801\uc6a9 \/ apply<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f deployment.yaml\nkubectl apply -f service.yaml<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \uc2e4\ud589\ud655\uc778 \/ Check execution<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>% kubectl get pods\n% kubectl get svc<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>% kubectl get pods<\/strong>\nNAME                            READY   STATUS    RESTARTS   AGE\n<strong>react-drawer-76b9c89659-cf6q9   1\/1     Running   0          4m26s<\/strong>\n\n<strong>% kubectl get service<\/strong>\nNAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE\nkubernetes             ClusterIP   10.96.0.1        &lt;none&gt;        443\/TCP        73d\n<strong>react-drawer-service   NodePort    10.105.160.235   &lt;none&gt;        80:30007\/TCP   4m32s<\/strong>\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c \uc811\uc18d \/ Access from browser<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;localhost:30007<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc2a4\ud06c\ub9b0 \uc0f7 \/ ScreenShot<\/p>\n\n\n\n<p>\u2714\ufe0f \ube0c\ub77c\uc6b0\uc800 \/ Browser<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"1024\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu1-840x1024.png\" alt=\"\" class=\"wp-image-4988\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu1-840x1024.png 840w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu1-246x300.png 246w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu1-768x937.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu1-400x488.png 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu1-800x976.png 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu1.png 874w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"768\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu2.png\" alt=\"\" class=\"wp-image-4989\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu2.png 838w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu2-300x275.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu2-768x704.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu2-400x367.png 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/br-drawermenu2-800x733.png 800w\" sizes=\"auto, (max-width: 838px) 100vw, 838px\" \/><\/figure>\n\n\n\n<p>\u2714\ufe0f \ub3c4\ucee4 \ub370\uc2a4\ud06c\ud0d1 \/ Docker Desktop<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"857\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run-1024x857.png\" alt=\"\" class=\"wp-image-4991\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run-1024x857.png 1024w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run-300x251.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run-768x643.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run-1536x1285.png 1536w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run-400x335.png 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run-800x669.png 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/03\/docker-desktop-run.png 1690w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb \ucfe0\ubc84\ub124\ud2f0\uc2a4\uc5d0\uc11c react Dreawer Menu\ub97c \uc801\uc6a9\ud55c \uc608\uc81c\uc785\ub2c8\ub2e4. This is an example of applying React Dreawer Menu in Kubernetes. \ud83d\udc49\ud83c\udffb vite+react Install \/ \uc124\uce58 \ud83d\udc49\ud83c\udffb\/Appk8s\/react-drawer\/src\/App.jsx \ud83d\udc49\ud83c\udffb\/Appk8s\/react-drawer\/src\/App.css \ud83d\udc49\ud83c\udffbdist \ube4c\ub4dc \/ dist build \u2714\ufe0f \uc704\uce58 \/ location &#8212; \/Appk8s\/react-drawer \u2714\ufe0f \ube4c\ub4dc \ud6c4 dist\ub514\ub809\ud1a0\ub9ac\uac00 \uc0dd\uc131\ub418\uc5b4 \uc788\uc5b4\uc57c\ud558\uba70 \ub514\ub809\ud1a0\ub9ac \ub0b4\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub418\uc5b4 \uc788\uc5b4\uc57c\ud569\ub2c8\ub2e4.After building, a dist directory should be created and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,1],"tags":[],"class_list":["post-4940","post","type-post","status-publish","format-standard","hentry","category-linux","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4940","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=4940"}],"version-history":[{"count":70,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4940\/revisions"}],"predecessor-version":[{"id":5014,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4940\/revisions\/5014"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=4940"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=4940"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=4940"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}