Docker single app - quan1997ap/Backend-app-note GitHub Wiki

Build + run docker: https://docs.docker.com/get-started/02_our_app/#build-the-apps-container-image

1. Chuan bi source code

    git clone https://github.com/docker/getting-started-app

2. Dockerfile

2.1 Create file trong thu muc root cua du an

   cd /path/to/app
   touch Dockerfile

Print Working Directory

   pwd

2.2 Edit file content

  • FROM : Sử dụng nodejs version 18 để build
  • WORKDIR : cd vào Trong thư mục app của container
  • COPY . . : COPY Copy từ ngoài vào trong container (VD COPY . /usr/src/app là copy từ thư mục hiện tại vào trong thư mục /usr/src/app của container )
  • RUN : Chạy lệnh. Nhập 1 mảng => cách nhau dấu cách ["node", "src/index.js"] => "node src/index.js"
  • EXPOSE : mở port 3000 của container thông với 3000 của máy hiện tại
   # syntax=docker/dockerfile:1  
   FROM node:18-alpine
   WORKDIR /app
   COPY . .
   RUN yarn install --production
   CMD ["node", "src/index.js"]
   EXPOSE 3000

3. Build new container image

Run trong thuc muc chua dockerfile "." la thu muc hien tai

 docker build -t getting-started .

The docker build command uses the Dockerfile to build a new container image. You might have noticed that Docker downloaded a lot of “layers”. This is because you instructed the builder that you wanted to start from the node:18-alpine image. But, since you didn’t have that on your machine, Docker needed to download the image.

After Docker downloaded the image, the instructions from the Dockerfile copied in your application and used yarn to install your application’s dependencies. The CMD directive specifies the default command to run when starting a container from this image.

Finally, the -t flag tags your image. Think of this simply as a human-readable name for the final image. Since you named the image getting-started, you can refer to that image when you run a container.

The . at the end of the docker build command tells Docker that it should look for the Dockerfile in the current directory.

4. Start an app container

docker run -p host_port:container_port images

    docker run -dp 127.0.0.1:3000:3000 getting-started

https://stackjava.com/docker/docker-expose-la-gi-huong-dan-exposing-port-docker-container.html#google_vignette

Docker expose là hành động chuyển hướng port của docker container sang port của host chứa container. Mỗi container khi được tạo ra đều chạy trên một ip riêng (nó tương tự như một máy ảo riêng biệt).

Ví dụ khi mình tạo một container từ image tomcat và kiểm tra thấy nó chạy trên ip 172.17.0.2 vậy muốn truy cập trang web của tomcat thì mình sẽ truy cập thông qua địa chỉ 172.17.0.2:8080 chứ không thể truy cập qua địa chỉ localhost:8080

Tuy nhiên, một host có thể chứa nhiều docker container. Khi truy cập người ta chỉ quan tâm nó ở trên host nào và truy cập thông qua ip của host đó. Do đó ta cần expose port của container sang port của host.

image

The -d flag (short for --detach) runs the container in the background. The -p flag (short for --publish) creates a port mapping between the host and the container. The -p flag take a string value in the format of HOST:CONTAINER, where HOST is the address on the host, and CONTAINER is the port on the container. The command shown here publishes the container’s port 3000 to 127.0.0.1:3000 (localhost:3000) on the host. Without the port mapping, you wouldn’t be able to access the application from the host.

5. Get containers

   docker ps

6. Stop and remove

Use Docker Desktop or docker ps to get the ID and then

   docker rm -f <id>

7. Dive into the volume

https://docs.docker.com/get-started/05_persisting_data/

7.1 Mount file

  • Give the volume a name, and mount it to /etc/todos in the container, which captures all files created at the path

  • Tao mout tu /etc/todos ( trong container ) ra /etc/todos ben ngoai

   docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started

7.2 Mount detail

  • Where is Docker storing my data when I use a volume?
   docker volume inspect todo-db

8. Access the container

   docker exec <container-id>
   docker run -it ubuntu

9. Look at the logs for the container

   docker logs -f <container-id>

10. Container networking

Muc dich

  • There’s a good chance you’d have to scale APIs and front-ends differently than databases.
  • Separate containers let you version and update versions in isolation.
  • While you may use a container for the database locally, you may want to use a managed service for the database in production. You don’t want to ship your database engine with your app then.
  • Running multiple processes will require a process manager (the container only starts one process), which adds complexity to container startup/shutdown.

There are two ways to put a container on a network:

  • Assign the network when starting the container.
  • Connect an already running container to a network.

10.1 Create the network + attach the MySQL container at startup

Step1: Create the network.

docker network create todo-app

Step 2: Start a MySQL container and attach it to the network + set Environment variables

docker run -d \
     --network todo-app --network-alias mysql \
     -v todo-mysql-data:/var/lib/mysql \
     -e MYSQL_ROOT_PASSWORD=secret \
     -e MYSQL_DATABASE=todos \
     mysql:8.0

Step 3: Check result Access docker and show list DB

   docker exec -it <mysql-container-id> mysql -u root -p
   SHOW DATABASES;

   exit
⚠️ **GitHub.com Fallback** ⚠️