{"id":3240,"date":"2025-12-22T15:04:44","date_gmt":"2025-12-22T06:04:44","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=3240"},"modified":"2025-12-24T18:45:58","modified_gmt":"2025-12-24T09:45:58","slug":"linux-docker-mysql-express","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2025\/12\/22\/linux-docker-mysql-express\/","title":{"rendered":"[OCI,Linux]\ub3c4\ucee4 + mysql + express \/ Docker + mysql + express(2)"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb \ub514\ub809\ud1a0\ub9ac \uad6c\uc870 \/ directory structure<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.js (or server.js)\n \u251c\u2500 db.js\n \u251c\u2500 routes\/\n \u2502   \u2514\u2500 index.js\n \u2502   \u2514\u2500 health.js\n<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb app.js<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require(\"express\");\nconst app = express();\nconst port = 3000;\n\n\/\/ \ubbf8\ub4e4\uc6e8\uc5b4 \/ middleware\napp.use(express.json());\n\n\/\/ \ub77c\uc6b0\ud130 \/ router\nconst indexRouter = require(\".\/routes\/index\");\napp.use(\"\/\", indexRouter);\n\napp.use(\"\/health\", require(\".\/routes\/health\"));\n\napp.listen(port, () =&gt; {\n  console.log(`Express server running on port ${port}`);\n});\n~                 <\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb db.js<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ db.js\nconst mysql = require(\"mysql2\");\n\nconst db = mysql.createPool({\nhost: \"host.docker.internal\",\n\/\/  host:\"localhost\",\n  user: \"myapp\",\n  password: \"Myapp@1234\",\n  database: \"myapp\",\n  port: 3306,\n  waitForConnections: true,\n  connectionLimit: 10,\n  connectTimeout: 10000,\n});\n\nmodule.exports = db;<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb routes\/index.js<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ routes\/index.js\nconst express = require(\"express\");\nconst router = express.Router();\nconst db = require(\"..\/db\");\n\nrouter.get(\"\/\", (req, res) =&gt; {\n  db.query(\"SELECT NOW() AS now\", (err, results) =&gt; {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({\n        success: false,\n        error: \"Database connection failed\",\n      });\n    }\n\n    res.json({\n      success: true,\n      message: \"Connected to external MySQL!\",\n      serverTime: results&#91;0].now,\n    });\n  });\n});\n\nmodule.exports = router;\n<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb routes\/health.js<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require(\"express\");\nconst router = express.Router();\nconst db = require(\"..\/db\");\n\nrouter.get(\"\/\", (req, res) =&gt; {\n  db.query(\"SELECT 1\", (err) =&gt; {\n    if (err) {\n      return res.status(500).json({ status: \"DOWN\" });\n    }\n    res.json({ status: \"UP\" });\n\n  });\n});\n\nmodule.exports = router;<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffbDockerfile<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM node:24\nWORKDIR \/app\nCOPY package*.json .\/\nRUN npm install\nCOPY . .\nEXPOSE 3000\nCMD &#91;\"node\",\"app.js\"]<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc774\ubbf8\uc9c0 \ube4c\ub4dc \/ image build<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo docker build -t myexpressapp .<\/code><\/pre>\n\n\n\n<p>\u2b50\ufe0f\uc774\ubbf8\uc9c0 \ubc0f \ucee8\ud14c\uc774\ub108 \ud655\uc778 \uba85\ub839\uc5b4 \/ Image and container verification commands<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \uc2e4\ud589\uc911\uc778 \ucee8\ud14c\uc774\ub108 \ud655\uc778 \/ Check running containers\nsudo docker ps\n\n# \ubaa8\ub4e0 \ucee8\ud14c\uc774\ub108 \ud655\uc778 \/ Check all containers\nsudo docker ps -a\n\n# \ubaa8\ub4e0 \uc774\ubbf8\uc9c0 \ud655\uc778 \/ Check all images\nsudo docker images\n\n# \ucee8\ud14c\uc774\ub108 \uc0ad\uc81c \/ Delete container\nsudo docker rm container name\n\n# \uc774\ubbf8\uc9c0 \uc0ad\uc81c \/ delete image\nsudo docker rmi image name<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ucee8\ud14c\uc774\ub108 \uc2e4\ud589 \/ Container run<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo docker run --name yourexpressapp -d -p 8000:3000 --add-host=host.docker.internal:host-gateway myexpressapp<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb\ube0c\ub77c\uc6b0\uc800 \uc811\uc18d\ud14c\uc2a4\ud2b8 \/ Browser connection test<br>\u2714\ufe0f http:\/\/ipaddress:8000\uc811\uc18d\uc2dc \uc544\ub798\uc758 \uba54\uc138\uc9c0\uac00 \ucd9c\ub825\ub418\uba74 \uc815\uc0c1<br>If the message below is displayed when accessing http:\/\/ipaddress:8000, it is normal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\"success\":true,\"message\":\"Connected to external MySQL!\",\"serverTime\":\"2025-12-22T15:25:30.000Z\"}<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f http:\/\/ipaddress:8000\/health\uc811\uc18d\uc2dc \uc544\ub798\uc758 \uba54\uc138\uc9c0\uac00 \ucd9c\ub825\ub418\uba74 \uc815\uc0c1<br>If the message below is displayed when accessing http:\/\/ipaddress:8000\/health, it is normal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\"status\":\"UP\"}<\/code><\/pre>\n\n\n\n<p>\u2b50\ufe0f \ub3c4\ucee4\uc5d0 \uc62c\ub9ac\uae30 \uc804\uc5d0 \ud14c\uc2a4\ud2b8 \ud558\ub824\uba74 db\uc5d0\uc11c host \uc218\uc815\ud558\uace0 npm install\ub85c mysql2\uc640 express \ubaa8\ub4c8 \uc124\uce58 \ud560\uac83<br>To test before uploading to Docker, modify host in db and install mysql2 and express modules with npm install.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb \ub514\ub809\ud1a0\ub9ac \uad6c\uc870 \/ directory structure \ud83d\udc49\ud83c\udffb app.js \ud83d\udc49\ud83c\udffb db.js \ud83d\udc49\ud83c\udffb routes\/index.js \ud83d\udc49\ud83c\udffb routes\/health.js \ud83d\udc49\ud83c\udffbDockerfile \ud83d\udc49\ud83c\udffb \uc774\ubbf8\uc9c0 \ube4c\ub4dc \/ image build \u2b50\ufe0f\uc774\ubbf8\uc9c0 \ubc0f \ucee8\ud14c\uc774\ub108 \ud655\uc778 \uba85\ub839\uc5b4 \/ Image and container verification commands \ud83d\udc49\ud83c\udffb \ucee8\ud14c\uc774\ub108 \uc2e4\ud589 \/ Container run \ud83d\udc49\ud83c\udffb\ube0c\ub77c\uc6b0\uc800 \uc811\uc18d\ud14c\uc2a4\ud2b8 \/ Browser connection test\u2714\ufe0f http:\/\/ipaddress:8000\uc811\uc18d\uc2dc \uc544\ub798\uc758 \uba54\uc138\uc9c0\uac00 \ucd9c\ub825\ub418\uba74 \uc815\uc0c1If the message below is displayed when [&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,20,1],"tags":[],"class_list":["post-3240","post","type-post","status-publish","format-standard","hentry","category-linux","category-oci","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3240","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=3240"}],"version-history":[{"count":21,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3240\/revisions"}],"predecessor-version":[{"id":3422,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3240\/revisions\/3422"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=3240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=3240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=3240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}