# Interview questions docker and docker-compose

docker build -t(tag) &lt;image name&gt; .(current file) - this command will build image from default dockerfile

docker build -t(tag) &lt;image name&gt; -f(file) &lt;specific docker file name&gt; .(current file) - will create image out of specific docker file which will be written after -f

docker run -it --name &lt;container name&gt; &lt;image name&gt;

### `docker run`

* **What it does:** Starts a new container based on a specified image.
    
* `-it`
    

* **What it means:**
    
    * `-i` (interactive): Keeps STDIN open even if you're not attached to the container.
        
    * `-t` (tty): Allocates a pseudo-TTY, making the container's output behave like a terminal.
        
* **Key purpose:** Ensures you can interact with the container's terminal during execution.
    

**What is the difference between** `CMD` **and** `ENTRYPOINT` **in a Dockerfile?**

The `CMD` and `ENTRYPOINT` instructions in a Dockerfile define the default behavior of a container when it is run, but they are used in slightly different ways and have different levels of flexibility.

---

### **1\. CMD (Command):**

* **Purpose:** Specifies the default command to be executed when a container is run.
    
* **Behavior:**
    
    * It can be overridden when the container is started using arguments passed to `docker run`.
        
    * Typically used for providing default arguments to an `ENTRYPOINT` or as a standalone command.
        
* **Syntax:**
    
    * Shell form: `CMD command`
        
    * Exec form: `CMD ["executable", "arg1", "arg2"]`
        
* **Example:**
    
    ```dockerfile
    CMD ["nginx", "-g", "daemon off;"]
    ```
    
    If you run:
    
    ```bash
    docker run myimage
    ```
    
    The above `CMD` will execute. However, if you provide a command during `docker run`, it replaces the `CMD`:
    
    ```bash
    docker run myimage echo "Hello"
    ```
    

---

### **2\. ENTRYPOINT:**

* **Purpose:** Specifies the main executable or script for the container. The container always executes this as the entry point.
    
* **Behavior:**
    
    * It cannot be overridden unless `--entrypoint` is explicitly specified during `docker run`.
        
    * Any additional arguments provided during `docker run` are passed as arguments to the `ENTRYPOINT`.
        
* **Syntax:**
    
    * Shell form: `ENTRYPOINT command`
        
    * Exec form: `ENTRYPOINT ["executable", "arg1", "arg2"]`
        
* **Example:**
    
    ```dockerfile
    ENTRYPOINT ["nginx"]
    ```
    
    If you run:
    
    ```bash
    docker run myimage -g "daemon off;"
    ```
    
    The container will execute:
    
    ```bash
    nginx -g "daemon off;"
    ```
    

---

### **Key Differences:**

| Feature | CMD | ENTRYPOINT |
| --- | --- | --- |
| **Primary Purpose** | Default command, modifiable at runtime. | Main executable, intended as mandatory. |
| **Overridable** | Yes, by arguments to `docker run`. | No, unless `--entrypoint` is used. |
| **Use Case** | Flexible defaults, fallback commands. | Enforcing a specific application or script. |

---

### **Combining CMD and ENTRYPOINT:**

* You can use both in a Dockerfile. In this case:
    
    * `ENTRYPOINT` defines the main application.
        
    * `CMD` provides default arguments for the `ENTRYPOINT`, which can be overridden.
        

**Example:**

```dockerfile
ENTRYPOINT ["python", "app.py"]
CMD ["--help"]
```

**compare CMD and ANTRYPOINT**

$ vim Dockerfile8

FROM ubuntu

ENTRYPOINT \["echo", "Hello"\]

CMD \["echo", "Dan"\]

$ sudo docker build -t testimage2 -f Dockerfile8 .

$ sudo docker run -it testimage2

output: Hello echo Dan

$ sudo docker run -it testimage2 AJ

output: Hello AJ

**How do you scale services in Docker Compose? Provide an example**

### **Steps to Scale Services in Docker Compose**

1. **Define the Service in** `docker-compose.yml`:
    
    * Specify the service and its configurations. Ensure the service can handle multiple instances (e.g., no conflicts on ports).
        
    
    Example `docker-compose1.yml`:
    
    ```yaml
    version: '3.8'
    services:
      web:
        image: nginx:latest
        ports:
          - "8080:80"
    ```
    
2. **Scale the Service Using** `docker-compose up`:
    
    * Use the `--scale` flag to specify the number of instances to run for the service.
        
    
    Example:
    
    ```bash
    docker-compose up --scale web=3
    ```
    
    This command starts 3 instances of the `web` service.
    
3. **Result:**
    
    * Docker Compose will create multiple containers for the `web` service (e.g., `web_1`, `web_2`, `web_3`).
        
    * These containers will share the same configuration but will run independently.
        

---

### **Example in Action**

1. `docker-compose.yml`:
    
    ```yaml
    version: '3.8'
    services:
      app:
        image: httpd:latest
        ports:
          - "8080:80"
    ```
    
2. **Run the Command to Scale:**
    
    ```bash
    docker-compose up --scale app=3
    ```
    
3. **Output:** The following containers will be created:
    
    * `myproject_app_1`
        
    * `myproject_app_2`
        
    * `myproject_app_3`
        
4. **Verification:** Use the `docker ps` command to verify the running containers:
    
    ```bash
    docker ps
    ```
    
    Example output:
    
    ```plaintext
    CONTAINER ID   IMAGE          COMMAND                  PORTS                   NAMES
    abc123456789   httpd:latest   "httpd-foreground"       0.0.0.0:8080->80/tcp    myproject_app_1
    def987654321   httpd:latest   "httpd-foreground"       0.0.0.0:8081->80/tcp    myproject_app_2
    ghi135792468   httpd:latest   "httpd-foreground"       0.0.0.0:8082->80/tcp    myproject_app_3
    ```
    

---

### **Important Notes:**

* **Port Conflicts:** If each instance needs to expose a port, you'll need to configure `ports` dynamically or use a reverse proxy (e.g., Nginx or Traefik).
    
* **Load Balancing:** Docker Compose itself does not provide load balancing. To distribute traffic, use a load balancer like Nginx, Traefik, or Kubernetes.
    

### **. Create yml file**

compose1.yml:

```bash
version: '3.9'

services:

  backend:

    image: python:3.9

    command: python -m http.server 8000

    depends_on:

      - db

  db:

    image: postgres:13

    environment:

      POSTGRES_USER: user

      POSTGRES_PASSWORD: password

```

### **1\. Verify the Current Setup**

Run the following to check your services:

```bash
docker-compose -f compose1.yml ps
```

This will show all running containers for `backend` and `db`.

---

### **2\. Upscaling Services**

To scale up the number of `backend` instances, use the `--scale` flag:

```bash
docker-compose -f compose1.yml up -d --scale backend=3
```

* This command starts 3 instances of the `backend` service.
    
* Containers will be named `compose1_backend_1`, `compose1_backend_2`, and `compose1_backend_3`.
    

---

### **3\. Verify Upscaling**

Check the running containers:

```bash
docker ps
```

You should see multiple `backend` containers running alongside the single `db` container.

---

### **4\. Downscaling Services**

To scale down the `backend` service, specify a lower number:

```bash
docker-compose -f compose1.yml up -d --scale backend=1
```

* This stops and removes extra `backend` containers, leaving only one running instance.
    

---

### **5\. Clean Up Unused Containers**

After scaling down, remove stopped containers to free resources:

```bash
docker container prune -f
```

---

### **6\. Notes on Dependencies**

* The `db` service will remain unaffected during scaling, as it is not being scaled.
    
* Since `backend` depends on `db` (via `depends_on`), Docker ensures the database is available before starting `backend`containers.
    

---

### **7\. Verify Container Logs**

Ensure all containers are running correctly by checking the logs:

```bash
docker-compose -f compose1.yml logs -f
```
