{"id":104,"date":"2026-09-08T12:00:00","date_gmt":"2026-09-08T07:00:00","guid":{"rendered":"https:\/\/example.com\/?p=104"},"modified":"2026-09-08T12:00:00","modified_gmt":"2026-09-08T07:00:00","slug":"docker-for-beginners","status":"publish","type":"post","link":"https:\/\/www.nexooraclub.com\/?p=104","title":{"rendered":"Docker for Beginners: Containerize Your First App in 15 Minutes"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Every developer has heard it \u2014 or said it: <em>&#8220;But it works on my machine!&#8221;<\/em> Different operating systems, library versions and settings make software behave differently from one computer to the next.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Docker<\/strong> solves this by packaging your app together with everything it needs into a <strong>container<\/strong> that runs the same way everywhere: your laptop, a teammate&#8217;s PC or a cloud server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Containers vs virtual machines<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><\/th><th>Virtual machine<\/th><th>Container<\/th><\/tr><\/thead><tbody><tr><td>Includes<\/td><td>A full operating system<\/td><td>Just your app and its dependencies<\/td><\/tr><tr><td>Size<\/td><td>Gigabytes<\/td><td>Often tens of megabytes<\/td><\/tr><tr><td>Start-up time<\/td><td>Minutes<\/td><td>Seconds or less<\/td><\/tr><tr><td>Isolation<\/td><td>Very strong<\/td><td>Strong (shares the host kernel)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Containers are lightweight because they share the host&#8217;s operating system kernel instead of booting their own.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Key terms in 30 seconds<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Image<\/strong> \u2014 a read-only template (like a recipe) containing your app and its environment<\/li>\n\n\n<li><strong>Container<\/strong> \u2014 a running instance of an image (the meal cooked from the recipe)<\/li>\n\n\n<li><strong>Dockerfile<\/strong> \u2014 a text file with the instructions to build an image<\/li>\n\n\n<li><strong>Registry<\/strong> \u2014 a place to store and share images, such as Docker Hub<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Install Docker<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Download <strong>Docker Desktop<\/strong> for Windows or macOS from docker.com, or install Docker Engine on Linux. Then check it works:<\/p>\n\n\n\n<pre class=\"wp-block-code language-bash\"><code>docker --version\ndocker run hello-world<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you see a &#8220;Hello from Docker!&#8221; message, you&#8217;re ready.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: A tiny app to containerize<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a folder with a simple Node.js server, <code>server.js<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code language-js\"><code>const http = require(\"http\");\n\nhttp.createServer((req, res) =&gt; {\n  res.end(\"Hello from inside a container! &#x1f433;\");\n}).listen(3000, () =&gt; console.log(\"Listening on port 3000\"));<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And a minimal <code>package.json<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code language-json\"><code>{\n  \"name\": \"hello-docker\",\n  \"version\": \"1.0.0\",\n  \"main\": \"server.js\",\n  \"scripts\": { \"start\": \"node server.js\" }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Write the Dockerfile<\/h2>\n\n\n\n<pre class=\"wp-block-code language-dockerfile\"><code># Start from an official, small Node.js image\nFROM node:22-alpine\n\n# Work inside \/app in the container\nWORKDIR \/app\n\n# Copy dependency files first (better caching)\nCOPY package*.json .\/\nRUN npm install --omit=dev\n\n# Copy the rest of the code\nCOPY . .\n\nEXPOSE 3000\nCMD [\"npm\", \"start\"]<\/code><\/pre>\n\n\n\n<p class=\"tp-callout wp-block-paragraph\">Copying <code>package.json<\/code> before the rest of your code means Docker can reuse the cached <code>npm install<\/code> layer when only your code changes. Builds become dramatically faster.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Build and run<\/h2>\n\n\n\n<pre class=\"wp-block-code language-bash\"><code>docker build -t hello-docker .\ndocker run -p 3000:3000 hello-docker<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Open http:\/\/localhost:3000 and you&#8217;ll see your message. The <code>-p 3000:3000<\/code> flag maps port 3000 on your computer to port 3000 inside the container.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Useful commands to know:<\/p>\n\n\n\n<pre class=\"wp-block-code language-bash\"><code>docker ps                 # list running containers\ndocker stop &lt;id&gt;          # stop a container\ndocker images             # list images\ndocker logs &lt;id&gt;          # see a container's output<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Multi-container apps with Docker Compose<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Real apps need more than one service \u2014 say, a web app and a database. <strong>Docker Compose<\/strong> describes them all in one file, <code>compose.yaml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code language-yaml\"><code>services:\n  web:\n    build: .\n    ports:\n      - \"3000:3000\"\n    environment:\n      DATABASE_URL: postgres:\/\/app:secret@db:5432\/app\n    depends_on:\n      - db\n\n  db:\n    image: postgres:16\n    environment:\n      POSTGRES_USER: app\n      POSTGRES_PASSWORD: secret\n      POSTGRES_DB: app\n    volumes:\n      - db-data:\/var\/lib\/postgresql\/data\n\nvolumes:\n  db-data:<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Start everything with a single command:<\/p>\n\n\n\n<pre class=\"wp-block-code language-bash\"><code>docker compose up<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice the web app reaches the database at the hostname <code>db<\/code> \u2014 Compose creates a private network where services find each other by name. The <code>db-data<\/code> volume keeps your data safe when containers restart.<\/p>\n\n\n\n<p class=\"tp-callout tp-callout--warn wp-block-paragraph\">Never commit real passwords in <code>compose.yaml<\/code>. Use an <code>.env<\/code> file (added to <code>.gitignore<\/code>) or your platform&#8217;s secrets manager.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Where to go next<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add a <strong>.dockerignore<\/strong> file to keep <code>node_modules<\/code> and <code>.git<\/code> out of your image<\/li>\n\n\n<li>Learn <strong>multi-stage builds<\/strong> to make production images even smaller<\/li>\n\n\n<li>Push your image to a registry and deploy it to a cloud service<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Containers are now the standard way to ship software. Once you&#8217;ve containerized one app, you&#8217;ll want to containerize everything.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;It works on my machine&#8221; is no longer an excuse. Learn what containers are, write your first Dockerfile and run a full app with Docker Compose.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[10,17,18,34],"class_list":["post-104","post","type-post","status-publish","format-standard","hentry","category-cloud-devops","tag-beginners","tag-devops","tag-docker","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=\/wp\/v2\/posts\/104","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=104"}],"version-history":[{"count":0,"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=\/wp\/v2\/posts\/104\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=104"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=104"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nexooraclub.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=104"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}