{"id":833,"date":"2019-10-09T03:34:56","date_gmt":"2019-10-09T03:34:56","guid":{"rendered":"http:\/\/codeinsightacademy.com\/blog\/?page_id=833"},"modified":"2026-07-07T03:37:31","modified_gmt":"2026-07-07T03:37:31","slug":"docker","status":"publish","type":"page","link":"https:\/\/codeinsightacademy.com\/blog\/devops\/docker\/","title":{"rendered":"Docker"},"content":{"rendered":"\n<h1>Docker &amp; Node.js Development Guide<\/h1>\n\n\n\n<p>A comprehensive breakdown of volume mapping, auto-reloading, and core Docker concepts.<\/p>\n\n\n\n<h2>The Complete Command<\/h2>\n\n\n\n<p>This is the command we used to run your Express server with live-reloading enabled:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run --name express-app-3001 --rm -p 3001:3000 -v \/home\/shaileshsonare\/Desktop\/docker:\/app -w \/app node:latest node --watch app.js<\/code><\/pre>\n\n\n\n<h2>Docker Flags Explained<\/h2>\n\n\n\n<ul><li><strong><code>--name express-app-3001<\/code><\/strong>: Assigns a custom, memorable name to your container. Instead of Docker generating a random name, you can easily reference this container to stop it or view its logs (e.g., <code>docker stop express-app-3001<\/code>).<\/li><li><strong><code>--rm<\/code><\/strong>: Automatically removes the container from your system as soon as it stops running. This keeps your system clean from old, stopped containers piling up and consuming disk space.<\/li><li><strong><code>-p 3001:3000<\/code><\/strong>: Maps a port on your host machine to a port inside the container. Format: <code>HOST_PORT:CONTAINER_PORT<\/code>. We used <code>3001<\/code> on the host because <code>3000<\/code> was already in use. Your Node app inside the container listens on <code>3000<\/code>, but you access it via <code>http:\/\/localhost:3001<\/code>.<\/li><li><strong><code>-v \/path\/on\/host:\/app<\/code><\/strong>: Volume mounting. This mounts your local directory directly into the <code>\/app<\/code> directory inside the container. Any changes you make locally are instantly available inside the container.<\/li><li><strong><code>-w \/app<\/code><\/strong>: Sets the &#8220;Working Directory&#8221;. It tells Docker to run all subsequent commands (like <code>node app.js<\/code>) from inside the <code>\/app<\/code> directory.<\/li><\/ul>\n\n\n\n<h2>Node.js Flags Explained<\/h2>\n\n\n\n<ul><li><strong><code>--watch<\/code><\/strong>: A built-in Node.js feature (introduced in v18.11). It tells the Node engine to actively monitor the executed file and its dependencies for any changes. When you hit &#8220;Save&#8221; in your editor, Node.js automatically restarts the server to reflect those changes.<\/li><\/ul>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><strong>Why did the volume seem like it wasn&#8217;t working initially?<\/strong><br>The volume was always working perfectly\u2014the file updated inside the container instantly. However, without the <code>--watch<\/code> flag, Node.js loads your code into memory once and stays running indefinitely. It was blissfully unaware that the file on disk had changed. Adding <code>--watch<\/code> bridges that gap.<\/p><\/blockquote>\n\n\n\n<h2>Exploring Inside a Container (<code>-it bash<\/code>)<\/h2>\n\n\n\n<p>If you need to explore the files inside your container, install dependencies manually, or debug something, you can open an interactive terminal session inside the container.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -it -v \/home\/shaileshsonare\/Desktop\/docker:\/app -w \/app node:latest bash<\/code><\/pre>\n\n\n\n<ul><li><strong><code>-it<\/code><\/strong>: This is actually two flags combined: <code>-i<\/code> (interactive, keeps standard input open) and <code>-t<\/code> (allocates a pseudo-TTY). Together, they allow you to interact with the container just like a normal terminal.<\/li><li><strong><code>bash<\/code><\/strong>: Instead of running a Node command, this tells the container to start the Bash shell. You will immediately be dropped into a command prompt running <em>inside<\/em> the container.<\/li><\/ul>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><strong>Pro Tip:<\/strong> If your container is already running, you can jump into it without creating a new one by running: <code>docker exec -it express-app-3001 bash<\/code><\/p><\/blockquote>\n\n\n\n<h2>The Dockerfile<\/h2>\n\n\n\n<p>While running commands with flags is great for quick development, a <strong>Dockerfile<\/strong> acts as a blueprint. It allows you to write down exactly how to build a custom image containing your app, so you don&#8217;t have to map volumes or set working directories every time you deploy.<\/p>\n\n\n\n<p>A typical <code>Dockerfile<\/code> for this project would look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM node:latest\nWORKDIR \/app\nCOPY package*.json .\/\nRUN npm install\nCOPY . .\nEXPOSE 3000\nCMD &#91;\"node\", \"app.js\"]<\/code><\/pre>\n\n\n\n<p>With this file, you can bake your code into an image using <code>docker build -t my-node-app .<\/code> and then run it anywhere simply by using <code>docker run -p 3001:3000 my-node-app<\/code>.<\/p>\n\n\n\n<h2>Docker Compose<\/h2>\n\n\n\n<p>When your Docker run commands become extremely long (like ours did) or when you need to run multiple connected containers (like an Express app <em>and<\/em> a Database), you use <strong>Docker Compose<\/strong>.<\/p>\n\n\n\n<p>You create a file named <code>docker-compose.yml<\/code> which stores all your flags and configurations in a clean, readable format:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '3.8'\nservices:\n  web:\n    image: node:latest\n    container_name: express-app-3001\n    ports:\n      - \"3001:3000\"\n    volumes:\n      - .:\/app\n    working_dir: \/app\n    command: node --watch app.js<\/code><\/pre>\n\n\n\n<p>Instead of typing the huge <code>docker run ...<\/code> command in the terminal, you simply type <code>docker-compose up<\/code> and Docker handles creating the volumes, mapping the ports, and starting the server automatically!<\/p>\n\n\n\n<h2>Adding a Database (MariaDB\/MySQL)<\/h2>\n\n\n\n<p>Databases in Docker are ephemeral by default\u2014if the container stops or is removed, the data is lost. To persist data safely, we mount a volume from your local machine to the database&#8217;s internal data directory.<\/p>\n\n\n\n<p>Here is how you run a MariaDB container using your local directory <code>\/opt\/mysql\/mydata\/<\/code> for persistent storage:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d --name my-database -p 3306:3306 -e MYSQL_ROOT_PASSWORD=secret -v \/opt\/mysql\/mydata\/:\/var\/lib\/mysql mariadb:latest<\/code><\/pre>\n\n\n\n<ul><li><strong><code>-d<\/code><\/strong>: Runs the container in the background (detached mode) so it doesn&#8217;t block your terminal.<\/li><li><strong><code>-e MYSQL_ROOT_PASSWORD=...<\/code><\/strong>: Sets an environment variable required by the database image to set the root user password upon initialization.<\/li><li><strong><code>-v \/opt\/mysql\/mydata\/:\/var\/lib\/mysql<\/code><\/strong>: <strong>Crucial for persistence!<\/strong> This maps your local host folder to <code>\/var\/lib\/mysql<\/code>. Your data will safely survive even if the container is destroyed.<\/li><\/ul>\n\n\n\n<h3>Combining with Docker Compose<\/h3>\n\n\n\n<p>You can elegantly add the database to your <code>docker-compose.yml<\/code> file alongside your Node app:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '3.8'\nservices:\n  web:\n    image: node:latest\n    container_name: express-app-3001\n    ports:\n      - \"3001:3000\"\n    volumes:\n      - .:\/app\n    working_dir: \/app\n    command: node --watch app.js\n    depends_on:\n      - db\n\n  db:\n    image: mariadb:latest\n    container_name: my-database\n    restart: always\n    environment:\n      MYSQL_ROOT_PASSWORD: secret\n      MYSQL_DATABASE: myapp\n    ports:\n      - \"3306:3306\"\n    volumes:\n      - \/opt\/mysql\/mydata\/:\/var\/lib\/mysql<\/code><\/pre>\n\n\n\n<p>Now, running <code>docker-compose up -d<\/code> effortlessly spins up both your Express server and the MariaDB database at the same time!<\/p>\n\n\n\n<h3>Accessing the Database Console (<code>-it<\/code>)<\/h3>\n\n\n\n<p>Once your database container is running, you can log directly into the MySQL CLI prompt inside the container and run live SQL queries.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker exec -it my-database mysql -u root -p<\/code><\/pre>\n\n\n\n<p>It will prompt you for the password. Once logged in, you can execute standard SQL commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT NOW() FROM dual;<\/code><\/pre>\n\n\n\n<p>To exit, simply type <code>exit;<\/code> or press <strong>Ctrl + D<\/strong>.<\/p>\n\n\n\n<h2>Debugging with Docker Inspect<\/h2>\n\n\n\n<p>If you ever forget how a container was started, you can use the <code>docker inspect<\/code> command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker inspect my-database<\/code><\/pre>\n\n\n\n<p>This command outputs a massive JSON document containing <strong>everything<\/strong> Docker knows about that container.<\/p>\n\n\n\n<h3>Extracting Specific Information<\/h3>\n\n\n\n<p>Because the default JSON output is huge, you can use the <code>--format<\/code> flag to filter it down to exactly what you need. For example, to print out the environment variables (which is how we recovered your lost database password):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker inspect my-database --format '{{range .Config.Env}}{{println .}}{{end}}'<\/code><\/pre>\n\n\n\n<p>This prints out a clean list of variables like <code>MYSQL_ROOT_PASSWORD=root123<\/code>.<\/p>\n\n\n\n<h2>Restarting Containers<\/h2>\n\n\n\n<h3>1. Manual Restarts<\/h3>\n\n\n\n<p>To instantly stop and then start a container, use the <code>docker restart<\/code> command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker restart express-app-3001<\/code><\/pre>\n\n\n\n<p>If you are using Docker Compose, you can restart a specific service gracefully:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker-compose restart web<\/code><\/pre>\n\n\n\n<h3>2. Automatic Restart Policies<\/h3>\n\n\n\n<p>For production servers, you can configure Docker to restart containers automatically if they crash or the server reboots.<\/p>\n\n\n\n<ul><li><strong>Via Command Line<\/strong>: Add the <code>--restart=always<\/code> flag. (<code>docker run -d --restart=always ...<\/code>)<\/li><li><strong>Via Docker Compose<\/strong>: Simply add the property <code>restart: always<\/code> to your service block.<\/li><\/ul>\n\n\n\n<h2>Viewing Container Logs<\/h2>\n\n\n\n<h3>Basic Usage<\/h3>\n\n\n\n<p>To print out all the logs generated by a container since it started:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker logs express-app-3001<\/code><\/pre>\n\n\n\n<h3>Live Log Tailing (<code>-f<\/code>)<\/h3>\n\n\n\n<p>By adding the <code>-f<\/code> (follow) flag, Docker will stream new logs continuously to your terminal. Press <strong>Ctrl + C<\/strong> when you&#8217;re done watching.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker logs -f express-app-3001<\/code><\/pre>\n\n\n\n<h3>Viewing Recent Logs (<code>--tail<\/code>)<\/h3>\n\n\n\n<p>Use the <code>--tail<\/code> flag to only view the most recent output.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker logs --tail 50 mysql-db<\/code><\/pre>\n\n\n\n<h2>Bonus: Scaling (The &#8220;Wow&#8221; Factor)<\/h2>\n\n\n\n<p>Once your application gets popular, a single Node.js container might not be enough. With Docker Compose, scaling horizontally is incredibly simple:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker-compose up -d --scale web=3<\/code><\/pre>\n\n\n\n<p>This instantly spins up <strong>3 identical copies<\/strong> of your Node.js web server!<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><strong>Note for Freshers:<\/strong> Don&#8217;t worry about orchestrators or auto-scaling just yet! Master volumes, port mapping, debugging, and basic Docker Compose first.<\/p><\/blockquote>\n\n\n\n<h2>Intro to Docker Swarm<\/h2>\n\n\n\n<p>Docker Swarm is Docker&#8217;s native clustering and orchestration tool. It allows you to connect multiple machines (nodes) together into a single virtual cluster.<\/p>\n\n\n\n<h3>Starting a Swarm<\/h3>\n\n\n\n<p>To turn your single Docker machine into a Swarm Manager, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker swarm init<\/code><\/pre>\n\n\n\n<h3>Deploying a Stack with Scaling<\/h3>\n\n\n\n<p>To scale in Swarm mode, you add a <code>deploy<\/code> block directly into your <code>docker-compose.yml<\/code> file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '3.8'\nservices:\n  web:\n    image: node:latest\n    deploy:\n      replicas: 5  # Runs exactly 5 copies of your app\n      resources:\n        limits:\n          cpus: '0.50'\n          memory: 512M\n      update_config:\n        parallelism: 2  # Updates 2 containers at a time during rollouts<\/code><\/pre>\n\n\n\n<p>Once your file is updated, you deploy it as a <strong>Stack<\/strong> across the entire cluster:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker stack deploy -c docker-compose.yml my_app_stack<\/code><\/pre>\n\n\n\n<p>Swarm reads the <code>deploy<\/code> block, automatically spins up your containers, and handles the load balancing across them!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Docker &amp; Node.js Development Guide A comprehensive breakdown of volume mapping, auto-reloading, and core Docker concepts. The Complete Command This is the command we used to run your Express server with live-reloading enabled: Docker Flags Explained &#8211;name express-app-3001: Assigns a custom, memorable name to your container. Instead of Docker generating a random name, you can [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":483,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/pages\/833"}],"collection":[{"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/comments?post=833"}],"version-history":[{"count":11,"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/pages\/833\/revisions"}],"predecessor-version":[{"id":2984,"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/pages\/833\/revisions\/2984"}],"up":[{"embeddable":true,"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/pages\/483"}],"wp:attachment":[{"href":"https:\/\/codeinsightacademy.com\/blog\/wp-json\/wp\/v2\/media?parent=833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}