[{"data":1,"prerenderedAt":699},["ShallowReactive",2],{"news-item-\u002Fvi\u002Fnews\u002Flaunch-with-docker":3},{"id":4,"title":5,"body":6,"category":686,"created by":687,"date":688,"description":689,"extension":690,"meta":691,"navigation":692,"path":693,"sections":694,"seo":695,"stem":696,"thumbnail":697,"__hash__":698},"content_vi\u002Fvi\u002Fnews\u002Flaunch-with-docker.md","Giới thiệu về Docker",{"type":7,"value":8,"toc":671},"minimark",[9,17,21,27,30,33,36,39,42,48,57,63,66,72,75,81,90,171,177,180,183,223,226,236,242,248,254,260,266,272,278,284,290,296,302,308,311,317,320,326,329,335,338,344,347,353,356,362,365,371,374,380,383,389,396,402,405,413,418,423,428,433,437,440,443,449,452,458,461,467,470,476,479,482,488,491,497,506,510,513,519,522,528,531,537,540,543,546,549,555,558,561,564,567,573,576,581,587,592,598,601,607,610,616,619,624,628,633,638,641,645,649,654,659,665],[10,11,13],"h2",{"id":12},"i-docker-là-gì",[14,15,16],"strong",{},"I. DOCKER LÀ GÌ?",[18,19,20],"p",{},"Docker là một nền tảng mở dành cho phát triển, triển khai, vận chuyển và chạy các ứng dụng. Docker cho phép bạn tách các ứng dụng khỏi cơ sở hạ tầng để bạn có thể phân phối phần mềm một cách nhanh chóng. Với Docker, bạn có thể quản lý cơ sở hạ tầng của mình giống như cách bạn quản lý các ứng dụng của mình. Bằng cách tận dụng các phương pháp luận của Docker để vận chuyển, kiểm thử và triển khai code một cách nhanh chóng, bạn có thể giảm đáng kể độ trễ giữa việc viết code và chạy code trong môi trường thật.",[10,22,24],{"id":23},"ii-lợi-ích-của-docker",[14,25,26],{},"II. LỢI ÍCH CỦA DOCKER",[18,28,29],{},"Không như máy ảo, Docker start và stop chỉ trong vài giây.",[18,31,32],{},"Bạn có thể khởi chạy container trên mỗi hệ thống mà bạn muốn.",[18,34,35],{},"Container có thể build và loại bỏ nhanh hơn máy ảo.",[18,37,38],{},"Dễ dàng thiết lập môi trường làm việc. Chỉ cần config 1 lần duy nhất và không bao giờ phải cài đặt lại các dependencies.",[18,40,41],{},"Nó giữ cho không gian làm việc của bạn sạch sẽ hơn khi bạn xóa môi trường mà ảnh hưởng đến các phần khác.",[10,43,45],{"id":44},"iii-cài-đặt",[14,46,47],{},"III. CÀI ĐẶT",[18,49,50,51],{},"Xem hướng dẫn theo link: ",[52,53,54],"a",{"href":54,"rel":55},"https:\u002F\u002Fdocs.docker.com\u002Fget-docker\u002F",[56],"nofollow",[10,58,60],{"id":59},"iv-image",[14,61,62],{},"IV. IMAGE",[18,64,65],{},"Một Docker Image là một read-only template dùng để tạo ra các containers. Image được cấu tạo theo dạng layer và tất cả các layer đều là read-only. Một image có thể được tạo ra dựa trên một image khác với một số tùy chỉnh bổ sung. Nói ngắn gọn, Docker Image là nơi lưu trữ các cài đặt môi trường như OS, package, phần mềm cần chạy, …",[10,67,69],{"id":68},"v-container",[14,70,71],{},"V. CONTAINER",[18,73,74],{},"Docker Container được tạo ra từ Docker Image, là nơi chứa mọi thứ cần thiết để có thể chạy ứng dụng. Là ảo hóa nhưng Container lại rất nhẹ, có thể coi như là một quy trình của hệ thống. Chỉ mất vài giây để start, stop hoặc restart một Container. Với một máy chủ vật lý, thay vì chạy được vài cái máy ảo truyền thống thì ta có thể chạy vài chục, thậm chí vài trăm cái Docker Container.",[10,76,78],{"id":77},"vi-so-sánh-container-và-máy-ảo",[14,79,80],{},"VI. SO SÁNH CONTAINER VÀ MÁY ẢO",[82,83],"img",{"className":84,"alt":87,"src":88,"style":89},[85,86],"block","mx-auto","","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28100010\u002Fcompare.jpg","width: 100%;",[91,92,93,112],"table",{},[94,95,96],"thead",{},[97,98,99,102,107],"tr",{},[100,101],"th",{},[100,103,104],{},[14,105,106],{},"CONTAINER",[100,108,109],{},[14,110,111],{},"MÁY ẢO",[113,114,115,127,138,149,160],"tbody",{},[97,116,117,121,124],{},[118,119,120],"td",{},"Tài nguyên",[118,122,123],{},"Quy trình trong container sử dụng trực tiếp tài nguyên thật, nhưng HĐH có thể quy định mỗi process một mức giới hạn tài nguyên khác nhau (hoặc không giới hạn).",[118,125,126],{},"Mọi thứ đều bị giới hạn bởi phần cứng ảo.",[97,128,129,132,135],{},[118,130,131],{},"Thực thi",[118,133,134],{},"HĐH thật chạy phần mềm.",[118,136,137],{},"HĐH thật → HĐH ảo → HĐH ảo chạy phần mềm. (Đối với VPS, Hypervisor type 1 thay thế cho HĐH thật)",[97,139,140,143,146],{},[118,141,142],{},"Sự tối ưu",[118,144,145],{},"Phần mềm thật chạy trên phần cứng thật. Tốc độ khởi động gần như một phần mềm bình thường.",[118,147,148],{},"Phần cứng thật phải gánh cả một HĐH ảo. Từ khi máy tính khởi động lên, cho tới khi sử dụng được phần mềm rất mất thời gian.",[97,150,151,154,157],{},[118,152,153],{},"Tính bảo mật",[118,155,156],{},"Process trong cùng container vẫn có thể ảnh hưởng tới nhau. Nhưng thông thường mỗi container chỉ nên chạy một process. Process khác container không thể gây ảnh hưởng cho nhau.",[118,158,159],{},"Phần mềm có mã độc có thể ảnh hưởng tới tài nguyên của process khác trong cùng VM.",[97,161,162,165,168],{},[118,163,164],{},"Phần mềm hỗ trợ",[118,166,167],{},"Docker Engine, LXC Linux Container, Apache Mesos, CRI-O (Kubernetes)…",[118,169,170],{},"VirtualBox, VMWare, Microsoft Hyper-V, Parallels, Linux KVM, Docker Machine…",[10,172,174],{"id":173},"vii-dockerfile",[14,175,176],{},"VII. DOCKERFILE",[18,178,179],{},"Dockerfile là file config cho Docker để build ra image. Nó dùng một image cơ bản để xây dựng class image khởi tạo. Một số image cơ bản: python, ubuntu and alpine. Sau đó nếu có các layer bổ sung thì nó được xếp chồng lên layer cơ bản.",[18,181,182],{},"Các config :",[184,185,186,190,193,196,199,202,205,208,211,214,217,220],"ul",{},[187,188,189],"li",{},"FROM — Chỉ định image gốc: python, ubuntu, alpine…",[187,191,192],{},"LABEL — Cung cấp metadata cho image. Có thể sử dụng để thêm thông tin bảo trì. Để xem các label của images, dùng lệnh docker inspect.",[187,194,195],{},"ENV — Thiết lập một biến môi trường.",[187,197,198],{},"RUN — Có thể tạo một lệnh khi build image. Được sử dụng để cài đặt các package vào container.",[187,200,201],{},"COPY — Sao chép các file và thư mục vào container.",[187,203,204],{},"ADD — Sao chép các file và thư mục vào container.",[187,206,207],{},"CMD — Cung cấp một lệnh và đối số cho container thực thi. Các tham số có thể được ghi đè và chỉ có một CMD.",[187,209,210],{},"WORKDIR — Thiết lập thư mục đang làm việc cho các chỉ thị khác như: RUN, CMD, ENTRYPOINT, COPY, ADD,…",[187,212,213],{},"ARG — Định nghĩa giá trị biến được dùng trong lúc build image.",[187,215,216],{},"ENTRYPOINT — Cung cấp lệnh và đối số cho một container thực thi.",[187,218,219],{},"EXPOSE — Khai báo port của image.",[187,221,222],{},"VOLUME — Tạo một điểm gắn thư mục để truy cập và lưu trữ data.",[18,224,225],{},"Ví dụ",[227,228,233],"pre",{"className":229,"code":231,"language":232},[230],"language-text","FROM node:12-alpine\nRUN apk add git\nRUN mkdir -p \u002Fhome\u002Fnode\u002Fapp\nWORKDIR \u002Fhome\u002Fnode\u002Fapp\nCOPY package*.json .\u002F\nRUN npm install\nCOPY . .\nENV HOST=0.0.0.0 PORT=3334\nEXPOSE $PORT\nCMD [ \"node\", \".\" ]\n","text",[234,235,231],"code",{"__ignoreMap":87},[10,237,239],{"id":238},"viii-một-số-khái-niệm-khác",[14,240,241],{},"VIII. MỘT SỐ KHÁI NIỆM KHÁC",[18,243,244,247],{},[14,245,246],{},"Docker Client",": tương tác với docker thông qua command trong terminal. Docker Client sẽ sử dụng API gửi lệnh tới Docker Daemon.",[18,249,250,253],{},[14,251,252],{},"Docker Daemon",": là server Docker cho các request từ Docker API. Nó quản lý images, containers, networks và volume.",[18,255,256,259],{},[14,257,258],{},"Docker Volumes",": là nơi lưu trữ dữ liệu liên tục cho việc sử dụng và tạo apps.",[18,261,262,265],{},[14,263,264],{},"Docker Registry",": là nơi lưu trữ riêng của Docker Images. Images được push vào registry và client sẽ pull images từ registry. Có thể sử dụng registry của riêng bạn hoặc registry của các nhà cung cấp như : AWS, Google Cloud, Microsoft Azure.",[18,267,268,271],{},[14,269,270],{},"Docker Hub",": là Registry lớn nhất của Docker Images ( mặc định). Có thể tìm thấy images và lưu trữ images của riêng bạn trên Docker Hub ( miễn phí).",[18,273,274,277],{},[14,275,276],{},"Docker Repository",": là tập hợp các Docker Images cùng tên nhưng khác tags. Ví dụ: node:12-alpine.",[18,279,280,283],{},[14,281,282],{},"Docker Networking",": cho phép kết nối các container lại với nhau. Kết nối này có thể trên 1 host hoặc nhiều host.",[18,285,286,289],{},[14,287,288],{},"Docker Compose",": là công cụ cho phép run app với nhiều Docker containers 1 cách dễ dàng hơn. Docker Compose cho phép bạn config các command trong file docker-compose.yml để sử dụng lại. Có sẵn khi cài Docker.",[18,291,292,295],{},[14,293,294],{},"Docker Swarm",": để phối hợp triển khai container.",[18,297,298,301],{},[14,299,300],{},"Docker Services",": là các containers trong môi trường thật. 1 service chỉ run 1 image nhưng nó mã hoá cách thức để run image — sử dụng port nào, bao nhiêu bản sao container run để service có hiệu năng cần thiết và ngay lập tức.",[10,303,305],{"id":304},"ix-các-lệnh-cơ-bản-trong-docker",[14,306,307],{},"IX. CÁC LỆNH CƠ BẢN TRONG DOCKER",[18,309,310],{},"Hiển thị image\u002Fcontainer:",[227,312,315],{"className":313,"code":314,"language":232},[230],"docker image\u002Fcontainer ls\n",[234,316,314],{"__ignoreMap":87},[18,318,319],{},"Hiển thị toàn bộ container hiện có:",[227,321,324],{"className":322,"code":323,"language":232},[230],"docker ps –a\n",[234,325,323],{"__ignoreMap":87},[18,327,328],{},"Dừng một container cụ thể:",[227,330,333],{"className":331,"code":332,"language":232},[230],"$docker stop \u003Ctên container>\n",[234,334,332],{"__ignoreMap":87},[18,336,337],{},"Chạy container từ image và thay đổi tên container:",[227,339,342],{"className":340,"code":341,"language":232},[230],"docker run –name \u003Ctên container> \u003Ctên image>\n",[234,343,341],{"__ignoreMap":87},[18,345,346],{},"Dừng toàn bộ container:",[227,348,351],{"className":349,"code":350,"language":232},[230],"docker stop $(docker ps –a –q)\n",[234,352,350],{"__ignoreMap":87},[18,354,355],{},"Hiển thị log của một container:",[227,357,360],{"className":358,"code":359,"language":232},[230],"docker logs \u003Ctên container>\n",[234,361,359],{"__ignoreMap":87},[18,363,364],{},"Build một image từ container:",[227,366,369],{"className":367,"code":368,"language":232},[230],"docker build -t \u003Ctên container> .\n",[234,370,368],{"__ignoreMap":87},[18,372,373],{},"Tạo một container chạy ngầm:",[227,375,378],{"className":376,"code":377,"language":232},[230],"docker run -d \u003Ctên image>\n",[234,379,377],{"__ignoreMap":87},[18,381,382],{},"Khởi động một container:",[227,384,387],{"className":385,"code":386,"language":232},[230],"docker start \u003Ctên container>\n\n",[234,388,386],{"__ignoreMap":87},[18,390,391,392],{},"Xem thêm: ",[52,393,394],{"href":394,"rel":395},"https:\u002F\u002Fdocs.docker.com\u002Freference\u002F",[56],[10,397,399],{"id":398},"x-cài-đặt-ban-đầu",[14,400,401],{},"X.  CÀI ĐẶT BAN ĐẦU",[18,403,404],{},"Bước 1: Truy cập vào EC2 của AWS.",[184,406,407,410],{},[187,408,409],{},"Mở  ứng dụng Tera Term để truy cập.",[187,411,412],{},"Nhập host server vào ô Host.",[82,414],{"className":415,"alt":87,"src":416,"style":417},[85,86],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163035\u002Fhost-teraterm.png","width: 80%;",[184,419,420],{},[187,421,422],{},"Nhập username và key, sau đó nhấn OK.",[82,424],{"className":425,"alt":87,"src":426,"style":427},[85,86],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163312\u002Fkey-teraterm.png","width: 60%;",[184,429,430],{},[187,431,432],{},"Màn hình sau khi truy cập vào.",[82,434],{"className":435,"alt":87,"src":436,"style":417},[85,86],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163531\u002FTerminal.png",[18,438,439],{},"Bước 2: Cài đặt docker",[18,441,442],{},"1. Cập nhật các package trên instance của bạn",[227,444,447],{"className":445,"code":446,"language":232},[230],"sudo yum update -y\n",[234,448,446],{"__ignoreMap":87},[18,450,451],{},"2. Cài đặt Docker",[227,453,456],{"className":454,"code":455,"language":232},[230],"sudo yum install docker -y\n",[234,457,455],{"__ignoreMap":87},[18,459,460],{},"3. Start service của docker",[227,462,465],{"className":463,"code":464,"language":232},[230],"sudo service docker start\n",[234,466,464],{"__ignoreMap":87},[18,468,469],{},"4. Thêm ec2-user vào group docker để bạn có thể thực hiện các lệnh Docker mà không cần sử dụng sudo.",[227,471,474],{"className":472,"code":473,"language":232},[230],"sudo usermod -a -G docker ec2-user\n",[234,475,473],{"__ignoreMap":87},[18,477,478],{},"Bước 3: Cài đặt git và clone\u002Fpull source code.",[18,480,481],{},"1.  Cài đặt git.",[227,483,486],{"className":484,"code":485,"language":232},[230],"sudo yum install git \n",[234,487,485],{"__ignoreMap":87},[18,489,490],{},"2. Clone\u002Fpull source code.",[227,492,495],{"className":493,"code":494,"language":232},[230],"git clone https:\u002F\u002FusernameToken:passwordToken@gitlab.com\u002F\u003Cproject name>\u002F\u003Cgit name>.git\nhoặc\ngit pull origin develop\n",[234,496,494],{"__ignoreMap":87},[18,498,499,500,505],{},"**  Với usernameToken là tên deploy token và passwordToken là một chuỗi ký tự random.(Xem thêm ",[52,501,504],{"href":502,"rel":503},"https:\u002F\u002Fdocs.gitlab.com\u002Fee\u002Fuser\u002Fproject\u002Fdeploy_tokens\u002F",[56],"tại đây",").",[10,507,509],{"id":508},"xi-deploy","XI. DEPLOY",[18,511,512],{},"Bước 1: Đi đến thư mục chứa source code",[227,514,517],{"className":515,"code":516,"language":232},[230],"cd \u003Cproject folder>\n",[234,518,516],{"__ignoreMap":87},[18,520,521],{},"file Dockerfile-dev trong source được cấu hình như sau",[227,523,526],{"className":524,"code":525,"language":232},[230],"# Check out https:\u002F\u002Fhub.docker.com\u002F_\u002Fnode to select a new base image\nFROM node:12-alpine\n# RUN apk update\nRUN apk add git\n# Set to a non-root built-in user `node`\nUSER node\n# Create app directory (with user `node`)\nRUN mkdir -p \u002Fhome\u002Fnode\u002Fapp\nWORKDIR \u002Fhome\u002Fnode\u002Fapp\n\nENV NODE_ENV=\"\u003CTên môi trường>\"\nENV PORT=\"3334\"\nENV DEBUG=\"front:*\"\nENV SESSION_SECRET=\"session-secret\"\n\n# Install app dependencies\n# A wildcard is used to ensure both package.json AND package-lock.json are copied\n# where available (npm@5+)\n\nCOPY package*.json .\u002F\nRUN npm install\n\n# Bundle app source code\nCOPY . .\n\n# Bind to all network interfaces so that it can be mapped to the host OS\nENV HOST=0.0.0.0 PORT=3334\n\nEXPOSE $PORT\n\nCMD [ \"node\", \".\" ]\n",[234,527,525],{"__ignoreMap":87},[18,529,530],{},"Bước 2: Build images của source",[227,532,535],{"className":533,"code":534,"language":232},[230],"docker build --no-cache -t \u003CTên image> -f Dockerfile.dev . (Đối với development)\n",[234,536,534],{"__ignoreMap":87},[18,538,539],{},"* -t: option tags của image.",[18,541,542],{},"* . : thư mục source.",[18,544,545],{},"* --no-cache: không lưu cache.",[18,547,548],{},"Bước 3: Chạy container từ image source",[227,550,553],{"className":551,"code":552,"language":232},[230],"docker run -dp \u003Chost port>:\u003Ccontainer port> --name \u003CTên container> \u003CTên image>\n",[234,554,552],{"__ignoreMap":87},[18,556,557],{},"* --name: đặt tên cho container ở đây là  evaluate-system. Name này là duy nhất, nếu không đặt thì docker tự generate.",[18,559,560],{},"* -p mở port container.",[18,562,563],{},"* -d bật chế độ chạy background.",[18,565,566],{},"Bước 4: Đi đến thư mục nginx trong source",[227,568,571],{"className":569,"code":570,"language":232},[230],"cd nginx\n",[234,572,570],{"__ignoreMap":87},[18,574,575],{},"Trong thư mục nginx gồm 2 file là default.conf và Dockerfile",[184,577,578],{},[187,579,580],{},"File default.conf",[227,582,585],{"className":583,"code":584,"language":232},[230],"server {\n    location \u002F {\n          proxy_set_header Host $host;\n          proxy_set_header X-Real-IP $remote_addr;\n          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n          proxy_set_header X-Forwarded-Proto $scheme;\n          proxy_pass http:\u002F\u002Fapp:3334;\n    }\n}\n",[234,586,584],{"__ignoreMap":87},[184,588,589],{},[187,590,591],{},"File Dockerfile",[227,593,596],{"className":594,"code":595,"language":232},[230],"FROM nginx\nRUN rm \u002Fetc\u002Fnginx\u002Fconf.d\u002F*\nCOPY default.conf \u002Fetc\u002Fnginx\u002Fconf.d\u002F\n",[234,597,595],{"__ignoreMap":87},[18,599,600],{},"Build image nginx cho source",[227,602,605],{"className":603,"code":604,"language":232},[230],"docker build -t es\u002Fnginx .\n",[234,606,604],{"__ignoreMap":87},[18,608,609],{},"Chạy container es\u002Fnginx",[227,611,614],{"className":612,"code":613,"language":232},[230],"docker run -dp 80:80 --link \u003CTên Container>:app --name nginx-proxy es\u002Fnginx\n",[234,615,613],{"__ignoreMap":87},[18,617,618],{},"Bước 5: Hiển thị các image và container.",[184,620,621],{},[187,622,623],{},"Danh sách image.",[82,625],{"className":626,"alt":87,"src":627,"style":89},[85,86],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28122425\u002Fimages-ec2.png",[184,629,630],{},[187,631,632],{}," Danh sách container.",[18,634,635],{},[82,636],{"alt":87,"src":637},"images\u002Fcontainer-ec2.png",[18,639,640],{},"Bước 6: Truy cập vào web",[82,642],{"className":643,"alt":87,"src":644,"style":89},[85,86],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28122802\u002Flogin-ec2-1024x490.jpg",[10,646,648],{"id":647},"xii-tài-liệu-tham-khảo","XII. TÀI LIỆU THAM KHẢO",[18,650,651],{},[52,652,54],{"href":54,"rel":653},[56],[18,655,656],{},[52,657,394],{"href":394,"rel":658},[56],[18,660,661],{},[52,662,663],{"href":663,"rel":664},"https:\u002F\u002Fdocs.docker.com\u002F",[56],[18,666,667],{},[52,668,669],{"href":669,"rel":670},"https:\u002F\u002Fegghead.io\u002Flessons\u002Fnode-js-setup-an-nginx-proxy-for-a-node-js-app-with-docker",[56],{"title":87,"searchDepth":672,"depth":672,"links":673},2,[674,675,676,677,678,679,680,681,682,683,684,685],{"id":12,"depth":672,"text":16},{"id":23,"depth":672,"text":26},{"id":44,"depth":672,"text":47},{"id":59,"depth":672,"text":62},{"id":68,"depth":672,"text":71},{"id":77,"depth":672,"text":80},{"id":173,"depth":672,"text":176},{"id":238,"depth":672,"text":241},{"id":304,"depth":672,"text":307},{"id":398,"depth":672,"text":401},{"id":508,"depth":672,"text":509},{"id":647,"depth":672,"text":648},"tech talk","Briswell Vietnam Co Ltd","2021-03-18","I. DOCKER LÀ GÌ? Docker là một nền tảng mở dành cho phát triển, triển khai, vận chuyển và chạy các ứng dụng. Docker cho phép bạn tách các ứng dụng khỏi cơ sở hạ tầng để bạn có thể phân phối phần mềm một cách nhanh chóng. Với Docker, bạn có thể quản lý cơ sở hạ tầng của mình giống như cách bạn quản lý các ứng dụng của mình.","md",{},true,"\u002Fvi\u002Fnews\u002Flaunch-with-docker",null,{"title":5,"description":689},"vi\u002Fnews\u002Flaunch-with-docker","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05103100\u002Flogo-docker.png","mUtEWC4ee2IxobYexvrNRL8LggjsYQ8zksICujez7C0",1782205037628]