# Build Docker image

* [Reference](https://nodejs.org/en/docs/guides/nodejs-docker-webapp/)

* Useful Command

  ```bash
  // run with interactive shell
  $ docker run -it <image> /bin/bash
  
  // list running process
  $ docker ps
  
  // list images
  $ docker images
  
  // 
  $ docker exec -it <container id> /bin/bash
  
  // print app output
  $ docker logs <container id>
  
  // build docker image. image name cannot use camel case
  $ docker build -t <target-image-name> .
  
  // store image in tar file
  $ docker save <generated-image-name> -o ./store/<generated-image-name>.tar
  
  // upload tar image to server
  $ rsync -rzvP ./store/<generated-image-name>.tar ubuntu@<serverip>:~/apps/<image-name>/
  
  $ ssh ubuntu@<serverip>
  $ cd ~/apps/<image-name>
  $ docker-compose stop
  $ docker load -i <image-name>.tar
  $ docker-compose up -d --build
  
  // skip docker entrypoint
  $ docker run -it --entrypoint=/bin/bash $IMAGE -i
  
  // delete all dangling images at once
  // -q return only the image unique id
  $ docker rmi $(docker images -q --filter "dangling=true")
  
  // remove build cache
  $ docker builder prune
  
  // pull latest
  $ docker-compose pull
  
  // restart image
  $ docker-compose restart
  
  // show container mem / io usage
  $ docker stats
  
  // show running process in container
  $ docker top <container>
  ```

  

* testing http

  ```bash
  $ curl -i localhost:5000
  
  HTTP/1.1 200 OK
  X-Powered-By: Express
  Content-Type: text/html; charset=utf-8
  Content-Length: 12
  ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0"
  Date: Mon, 13 Nov 2017 20:53:59 GMT
  Connection: keep-alive
  
  Hello world
  ```

  

* sample deploy script

  ```bash
  # docker way
  docker build -t razer-pay-direct-fast-middleware:latest .
  docker save razer-pay-direct-fast-middleware:latest -o ./docker-local/razer-pay-direct-fast-middleware.tar
  
  # upload docker image and compose file to the server
  rsync -rzvP ./docker-local/razer-pay-direct-fast-middleware.tar docker-compose.yml ubuntu@172.88.1.101:~/apps/razer-pay-direct-fast-middleware/
  
  ssh ubuntu@172.88.1.101 << EOF
      cd ~/apps/razer-pay-direct-fast-middleware
      pwd
  
      echo "Stopping Container..."
      docker-compose stop
  
      echo "Loading new Docker image..."
      docker load -i razer-pay-direct-fast-middleware.tar
  
      echo "Restarting Container..."
      docker-compose up -d --build
  
      echo "Container restarted."
  
  EOF
  
  echo "Deployed successfully."
  ```

  

* user permission

```shell
// create docker group
$ sudo groupadd docker

// add current user to group
$ sudo usermod -aG docker ${USER}

// reboot system for group privillege to take effect

// test run
$ docker run hello-world

```
* docker image versioning

  * Semantic Versioning ([Semver](https://medium.com/@mccode/using-semantic-versioning-for-docker-image-tags-dfde8be06699))
  * [blog](https://stevelasker.blog/2018/03/01/docker-tagging-best-practices-for-tagging-and-versioning-docker-images/)
  * Tag and push separately

  ```shell
  $ docker build -t registry:latest .
  $ docker push registry:latest
  
  $ docker tag registry:latest registry:2
  $ docker push registry:2
  
  $ docker tag registry:latest registry:2.6
  $ docker push registry:2.6
  
  $ docker tag registry:latest registry 2.6.3
  $ docker push registry:2.6.3
  ```

* ```shell
  // check image size
  $ docker run --entrypoint=/bin/sh $IMAGE:$VERSION -c 'du -s / 2 > /dev/null | cut -f1'
  ```

* [Best practice](https://cloud.google.com/architecture/best-practices-for-building-containers)

* Copy docker image to another machine

```shell
// build docker image on source machine
$ docker build -t razer-pay-direct-fast-middleware:latest .

// save Docker image as tar file on source machine
$ docker save -o <path for generated tar file> <image name>

// eg.
$ docker save -o c:/myfile.tar centos:16
$ docker save razer-pay-direct-fast-middleware:latest -o ./razer-pay-direct-fast-middleware.tar

// copy to target move via scp / rsync
// scp copy tar to aws ec2
$ scp -i ssh-identity.pem -o StrictHostKeyChecking=no ./razer-pay-direct-fast-middleware.tar $RPS_PRD_SSH_USER@$RPS_PRD_HOST:~/apps/razer-pay-direct-fast-middleware/

// Then, load the tar file into Docker
$ docker load -i <path to image tar file>

// using pipe to run all on the fly
// bzipping the on the fly
// pv - to show progress indicator
$ docker save <image> | bzip2 | pv | ssh user@host 'bunzip2 | docker load'


// run docker image
$ ssh ubuntu@172.88.1.101 

$ cd ~/apps/razer-pay-direct-fast-middleware
$ pwd

    echo "Stopping Container..."
$ docker-compose stop

$ echo "Loading new Docker image..."
$ docker load -i razer-pay-direct-fast-middleware.tar

$ echo "Restarting Container..."
// --build build image before starting container
$ docker-compose up -d --build

$ echo "Container restarted."

```



* persistent data setup

```yml
services:

  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
        - ./persistent_data:/var/lib/mysql
```



```shell

// stop container and remove volune
$ docker-compose down -v
```

## Host Networking [link](https://docs.docker.com/docker-for-windows/networking/)

* `host.docker.internal` or `gateway.docker.internal`

