From Local Builds to Cloud Deployment

  • Home
  • Blog
  • From Local Builds to Cloud Deployment
Learning By Kartikeya rajulapati 07 Jun 2026 06:47 PM
From Local Builds to Cloud Deployment
Learn how Docker containers can streamline your development workflow, eliminate “it works on my machine” problems, and make deploying applications faster and more consistent.

New to Docker? This guide breaks down images, containers, and Dockerfiles with hands-on examples, plus tips for using Docker in production and CI/CD pipelines.

Introduction

If you’ve ever spent hours debugging an issue that only appears on your colleague’s laptop or on a production server, you know how frustrating environment inconsistencies can be. Docker solves this by packaging applications and their dependencies into lightweight, portable containers.

In this article, we’ll explore Docker’s core concepts, build a real container step by step, and look at best practices for using Docker in real-world projects.

What Is Docker?

Docker is an open-source platform that automates the deployment of applications inside software containers. Unlike traditional virtual machines, containers share the host system’s OS kernel, making them faster to start and more resource efficient.

Images – Read-only templates with instructions for creating a container (e.g., ubuntu:22.04, node:20).

Containers – The running instances of an image – isolated, but lightweight.

Dockerfile – A script that defines how to build an image.

Registry – A place to store and share images (Docker Hub is the default).

Why Use Docker?

Consistency – Works the same on a developer’s laptop, a test server, and the cloud.

Isolation – No dependency conflicts between different projects.

Reproducibility – Entire environments described in version‑controlled Dockerfiles.

Efficiency – Lower overhead than VMs, faster startup times.

Your First Dockerized Application

Let’s containerize a simple Node.js app. Create a project folder with two files.

1. app.js

 
const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.send('Hello from Docker! 🐳');
});

app.listen(PORT, () => {
  console.log(`App running on port ${PORT}`);
});
<svg class="_9bc997d _33882ae" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg><svg class="_9bc997d _28d7e84" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg>

2. Dockerfile

 
# Base image with Node.js
FROM node:18-alpine

# Set working directory
WORKDIR /usr/src/app

# Copy package files (if any) and install deps
COPY package*.json ./
RUN npm install express

# Copy app source
COPY . .

# Expose the app port
EXPOSE 3000

# Start the app
CMD ["node", "app.js"]
<svg class="_9bc997d _33882ae" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg><svg class="_9bc997d _28d7e84" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg>

3. Build and Run

 
docker build -t my-node-app .
docker run -p 3000:3000 my-node-app
<svg class="_9bc997d _33882ae" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg><svg class="_9bc997d _28d7e84" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg>

Open http://localhost:3000 – you should see the welcome message.

Useful Docker Commands

 
 
CommandDescription
docker psList running containers
docker ps -aList all containers (including stopped)
docker imagesShow local images
docker stopStop a running container
docker rmRemove a stopped container
docker rmi <>< >></></><><><>><></></><>< class>View container logs
docker exec -it shOpen a shell inside a running container

Docker in Real Projects

Using Docker Compose for multi‑service apps

A docker-compose.yml example for a Node.js app with Redis:

 
version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - redis
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"
<svg class="_9bc997d _33882ae" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg><svg class="_9bc997d _28d7e84" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg>

Start everything with docker compose up.

Best practices

Use small base images (Alpine variants).

Combine RUN commands to reduce layers.

Don’t run containers as root – create a non‑privileged user.

Use .dockerignore to exclude unnecessary files.

Tag images meaningfully (e.g., myapp:1.2.3).

Docker and CI/CD

Docker fits naturally into CI/CD pipelines. A typical flow:

Run tests inside a container.

Build a production image.

Push the image to a registry (Docker Hub, GitHub Container Registry, Amazon ECR).

Deploy by pulling the image on your server (or Kubernetes cluster).

Example GitHub Actions snippet:

 
- name: Build Docker image
  run: docker build -t myapp:${{ github.sha }} .

- name: Push to registry
  run: |
    docker tag myapp:${{ github.sha }} myrepo/myapp:latest
    docker push myrepo/myapp:latest
<svg class="_9bc997d _33882ae" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg><svg class="_9bc997d _28d7e84" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"></svg>

Common Pitfalls and How to Avoid Them

 
 
ProblemSolution
Huge image sizeUse multi‑stage builds or Alpine images
Secrets hard‑coded in imagesUse environment variables or Docker secrets
Containers losing dataUse volumes (docker run -v /host/path:/container/path)
Slow buildsOrder Dockerfile layers from least to most frequently changing

Interested in our training?

To stay updated with regular alerts via email, subscribing is quick and hassle-free. Please fill out the subscription form below to receive timely updates. By providing your information, you will be added to our mailing list, keeping you informed about the latest news and announcements