Skip to content

Instantly share code, notes, and snippets.

@yeungon
Last active November 25, 2018 14:04
Show Gist options
  • Save yeungon/740e1b11acb1ac470ddef08af6cedbb0 to your computer and use it in GitHub Desktop.
Save yeungon/740e1b11acb1ac470ddef08af6cedbb0 to your computer and use it in GitHub Desktop.
Ubuntu from the scratch (for Vietnamese)
@yeungon
Copy link
Author

yeungon commented Nov 12, 2018

Cài đặt và phân vùng

Ubuntu có thể boot thông qua USB hoặc CD, DVD. Tạo một đĩa bootable bằng USB.

Phân vùng:

Ubuntu cũng xử lý phân vùng tương tự Windows gồm phân vùng chứa hệ điều hành và phân vùng chứa dữ liệu nhưng tên gọi khác. Ổ cứng gốc là dev/sda. Các phân vùng là dev/sda 1, dev/sda 2 vv...

Ta tạo một sda x (x là số) cho thư mục root chứa hệ điều hành và mount vào / khi phân vùng. Nên tầm 20GB.

Ta tạo một sda y cho thư mục home (giống phân vùng D trên Windows) và chứa dữ liệu, mount vào thư mục /home khi phân vùng. Thư mục này sẽ không bị ghi đè khi cài lại.

Ta tạo một phân vùng sda z và mount vào swap, nên gấp 1.5 lần dung lượng RAM thực.

Cài đặt

Có thể cài chạy song song với Windows, hoặc chỉ Ubuntu.

Tìm hiểu thêm tại https://askubuntu.com/questions/343268/how-to-use-manual-partitioning-during-installation

Chú ý, nếu trên máy đã có Windows, khi phân vùng, hệ thống trên Linux sẽ coi ổ C hoặc D cũ là một phân vùng có dạng sd x và sd y như thường, với định đạng type là ntfs hoặc fat32.

Trên Linux ta dùng etx 4 cho thân thuộc.

@yeungon
Copy link
Author

yeungon commented Nov 12, 2018

@yeungon
Copy link
Author

yeungon commented Nov 13, 2018

Bộ gõ tiếng Việt rất tốt:

https://github.com/teni-ime/ibus-teni

Cài đặt (Ubuntu)
sudo add-apt-repository ppa:teni-ime/ibus-teni
sudo apt-get update
sudo apt-get install ibus-teni
ibus restart
Lệnh bên dưới cho phép đọc event chuột, không bắt buộc nhưng cần để ibus-teni hoạt động tốt

sudo usermod -a -G input $USER

@yeungon
Copy link
Author

yeungon commented Nov 14, 2018

Cài đặt Ms font cho Ubuntu

sudo apt install ttf-mscorefonts-installer

@yeungon
Copy link
Author

yeungon commented Nov 16, 2018

30 việc cần làm sau khi cài Ubuntu https://www.youtube.com/watch?v=BLVtxpm5c2A

@yeungon
Copy link
Author

yeungon commented Nov 18, 2018

Gỡ cài đặt nginx trên Ubuntu


sudo apt-get remove nginx nginx-common # Removes all but config files.

sudo apt-get purge nginx nginx-common # Removes everything.

sudo apt-get autoremove # After using any of the above commands, use this in order to remove dependencies used by nginx which are no longer required.

@yeungon
Copy link
Author

yeungon commented Nov 18, 2018

@yeungon
Copy link
Author

yeungon commented Nov 19, 2018

@yeungon
Copy link
Author

yeungon commented Nov 19, 2018

Docker sử dụng kiến trúc client-server. Docker client sẽ liên lạc với các Docker daemon, các Docker daemon sẽ thực hiện các tác vụ build, run và distribuing các Docker container. Cả Docker client và Docker daemon có thể chạy trên cùng 1 máy, hoặc có thể kết nối theo kiểu Docker client điều khiển các docker daemon như hình trên. Docker client và daemon giao tiếp với nhau thông qua socket hoặc RESTful API

Docker daemon chạy trên các máy host. Người dùng sẽ không tương tác trực tiếp với các daemon, mà thông qua Docker Client.
Thực hành

Lý thuyết là thế vậy thực tế sẽ như thế nào? Sau đây mình có một ví dụ nho nhỏ với Docker
Cài đặt Docker

Sau đây, mình sẽ hướng dẫn các bạn cài đặt trên ubuntu

Cài đặt Docker sử dụng repository Thiết lập repository

Update ubuntu

$ sudo apt-get update

Cài đặt các gói để cho phép apt sử dụng repository qua HTTPS:

$ sudo apt-get install
apt-transport-https
ca-certificates
curl
software-properties-common

Thêm key chính thức của Docker:

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Thêm Repositories stable:

$ sudo add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/ubuntu
$(lsb_release -cs)
stable"

Sau khi thực hiện các bước trên tiến hành cài đặt Docker nào. Ở đây, mình cài đặt Docker CE

Update lần nưã 

$ sudo apt-get update

Cài đặt Docker CE phiên bản mới nhất:

$ sudo apt-get install docker-ce

Để test thử thành công hay khồng chúng ta mở terminal thử chạy một image kinh điển : hello-world

docker run hello-world

Sau khi chạy lệnh này terminal sẽ như sau:

terminal của bạn hiển thị như thế này là thành công rồi master docker đến nơi rồi

Lệnh docker run là để chạy một image và sẽ tạo ra một container chính là instance của image hello-world, nếu image đó chưa được pull về thì lệnh docker run sẽ tìm và tự động pull về image có phiên bản mới nhất. Để tìm kiếm một image chúng ta có thể dùng lệnh:

sudo docker search {image_name}

ví dụ: mình tìm kiếm image có tên nginx:

terminal sẽ hiển thị các images liên quan đến nginx, bạn thấy ưng cái bụng với image nào thì pull về dùng thôi Câu lệnh pull một image về:

sudo docker pull {image_name}

sau đây mình pull image có tên nginx, kết quả như sau:

Để xem danh sách các images đã có chúng ta có câu lệnh:

sudo docker images

terminal sẽ hiển thị tất cả các images:
Ví dụ chia sẻ tài nguyên với Docker sử dụng image nginx

Đầu tiên, Chúng ta cần một file HTML để hiển thị khi chúng ta kết nối với server. và mình đã tạo một file index.html ở trong thư mục docker-nginx mình tự tạo và thư mục này trong thư mục document với nội dung là:

Hello, world

Tiếp theo, chúng ta sử dụng image nginx mà chúng ta đã pull về ở phía trên:

sudo docker run -v /home/lyhuynh/Documents/docker-nginx:/usr/share/nginx/html:ro -p 8080:80 -d nginx

Docker sẽ chạy image nginx và tạo ra một instance của image nginx chính là container. Và ở câu lệnh phía trên docker run chắc các bạn đã biết nó làm gì rồi nhỉ vậy các thành phần phía sau nó là gì?

/home/lyhuynh/Documents/docker-nginx: chính là đường dẫn tới thư mục chưa file index.html của mình để hiển thị Hello, world đấy :v
-v /home/lyhuynh/Documents/docker-nginx:/usr/share/nginx/html:ro chính là ánh xạ web page tới địa chỉ được yêu cầu bởi image. 'ro' ở đây là dẫn Docker đến chế độ chỉ đọc (read-only)
-p 8080:80 map dịch vụ mạng port 80 trong container đến port 8080 của máy chủ hệ thống
-d : tách container khỏi phiên dòng lệnh của chúng ta
nginx: tên của image Sau khi thực hiện dòng lệnh trên mở trình duyệt lên và truy cập vào http://127.0.0.1:8080/ và xem kết quả nào: Khi chạy image nginx, chúng ta cần phải cho nó biết nơi để lấy các tập tin trên web. Ở đây mình đã làm điều này bằng cách gắn một thư mục trên hệ thống máy chủ của mình vào một thư mục bên trong container, ghi đè các tệp đã có trong image. Docker cũng hỗ trợ volume, cái có thể chứa các tập tin hệ thống và được chia sẻ giữa các container. Chúng ta cũng cần ánh xạ port 80 trong container của chúng ta đến cổng của hệ thống máy chủ để máy chủ web giao tiếp với thế giới bên ngoài.

Để xem các container nào đang chạy, câu lệnh:

sudo docker ps

để xem tất cả các container, câu lệnh:

sudo docker ps -a

Tổng kết

Ở trong bài viết này mình đã cùng với các bạn tìm hiểu về Docker ,các thành phần của nó và cách sử dụng cơ bản Docker. Docker thật tuyệt vời để tách biệt các môi trường lập trình và deploy môi trường cũng thật dễ dàng. Hãy thử tưởng tượng khi bạn tham gia vào 1 dự án, đáng ra bạn sẽ phải cài rất nhiều thứ để có thể chạy được môi trường lập trình trên máy mình thì bạn chỉ cần đơn giản là pull docker image của môi trường lập trình ấy về và start nó lên là xong

Trong bài viết tiếp theo mình sẽ cùng các bạn tìm hiểu các lệnh trong Docker. Nếu thấy bài viết có ích hãy upvote cho mình nhé

@yeungon
Copy link
Author

yeungon commented Nov 19, 2018

Lợi ích của Docker

Lợi ích dễ thấy nhất của Docker chính là khả năng ảo hóa của nó, Nó cho phép tách ứng dụng của bạn ra khỏi host mà thay vào đó, chạy nó trên một môi trường ảo hóa. Chính điểm này mang lại tính bảo mật rất cao khi bạn không biết ứng dụng kia có ảnh hưởng như thế nào đến máy tính của mình. Hay khi bạn phải duy trì 7 phiên bản của ruby để chạy 7 Ruby on Rails khác nhau, thay vào đó, hãy build 7 cái image cho ứng dụng của bạn. Bạn sẽ không còn phải đau đầu khi 7 phiên bản kia update lên bản mới và break cái gì đó trong app của bạn.

Dưới đây là một số lợi ích của Docker cho các lập trình viên cũng như các system admin:

Tạo ra một môi trường phát triển nhất quán, Docker sẽ chạy giống hệt nhau trên tất cả các host mà không phải dựa trên môi trường hay hệ điều hành trên máy host, tất cả các thư viện, biến môi trường đều được lưu trữ trên docker image. Sẽ không còn cảnh "Nhưng nó chạy trên máy của em mà!!!"
Nếu bạn gặp khó khăn khi build hoặc compile một ứng dụng nào đó, hãy thử build chúng bên trong docker. Vì môi trường bên trong docker là một môi trường sạch, sẽ có rất ít thay đổi hay cấu hình bên trong làm conflict với build của bạn
Khi bạn phải lập trình với nhiều ngôn ngữ như python, ruby, hay như nodejs, bạn sẽ thường gặp phải vấn đề versioning của các chương trình trên không phù hợp với ứng dụng của bạn. Hãy để chúng vào bên trong docker, cùng với các phiên bản mà ứng dụng của bạn yêu cầu.
Dễ dàng deploy ứng dụng. Nếu ứng dụng của bạn chạy trong một container trên máy dev của bạn, chúng cũng sẽ chạy trong một container trên server của bạn. Bây giờ, deploy chỉ đơn giản là build một docker image mới với những phiên bản code mới của bạn và run những image đó trên production server.
Cộng đồng hỗ trợ to lớn, có rất nhiều ứng dụng đã được xây dựng trên DockerHub, bạn chỉ cần pull các image đó và run chúng trên máy tính của mình. Sẽ không còn cảnh phải configure dependancies rồi configure config để một ứng dụng nào đó chạy để rồi break một ứng dụng khác.

Docker Image && Docker Container

Đây là hai khái niệm cơ bản nhất của Docker.

Docker Image là một executable package có chứa tất cả những gì cần tiết để có thể chạy một ứng dụng, từ core application cho đến các thư viện runtime và các các biến môi trường cùng với các file configuration của chúng.

Docker Container là một instance của một image. Điều này có nghĩa là image đó được nạp vào bộ nhớ và có thể được thực thi.

Bạn có thể hiểu một docker image là một image chứa toàn bộ trạng thái của một máy tính trong khi nó đang bị tắt, còn một container là trạng thái mà khi cái máy tính đó đang được bật lên, và cái máy tính đó sẵn sàng thực thi ứng dụng của bạn.
Làm sao để có thể chạy một docker container?

Để có thể khởi động một docker container, trước tiên bạn cần phải có một docker image. May mắn là Docker Hub có chứa rất nhiều các docker image cho bạn lựa chọn để có thể chạy trực tiếp các image đó hay để tùy biến những image đó theo yêu cầu của cá nhân.

Ví dụ điển hình nhất là image hello-world. Nhiệm vụ của image này rất đơn giản, nó chỉ in ra màn hình của bạn một vài dòng chữ giới thiệu về docker và sau đó sẽ tự tắt.

Hay một ví dụ hay ho hơn đó là nginx:

docker pull nginx
docker run nginx

Ở ví dụ này, câu lệnh đầu tiên có nghĩa là chúng ta sẽ kéo image nginx từ DockerHub về máy tính của bạn. Câu lệnh thứ hai có nghĩa là chạy nginx nó trên terminal của bạn. Log của nginx cũng được hiển thị ở đây. Bạn có thể nhấn Ctrl+C để thoát chương trình này.

Note: Nếu trên máy tính của bạn chưa có image nginx và bạn thực hiện docker run nginx thì docker sẽ tự động kéo image nginx về máy tính của bạn.
Xây dựng một docker image mới

Như đã nói ở trên, ta cần phải có một docker image để có thể chạy một ứng dụng docker.

Để xây dựng một image khá là đơn giản, Docker sẽ tự động dọc file Dockerfile trong thư mục hiện tại để xây dựng image. Dưới đây là một ví dụ về việc xây dựng một docker image

FROM ruby:2.5
WORKDIR /app
RUN apt-get update;
apt-get upgrade -y;
apt-get install -y build-essential libssl-dev libreadline-dev libyaml-dev
default-libmysqlclient-dev gnupg2 nodejs
RUN gem install rails --no-ri --no-rdoc; rails new .
ENV RAILS_ENV="development"
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server"]

Trong ví dụ này, ta sẽ xây dựng một image dựa trên base image là ruby:2.5 (image có tên là ruby với phiên bản của image này là 2.5, bạn có thể tìm hiểu thêm về image này tại đây)

Dòng 2: dòng này dùng để xác định thư mục trên image mà bạn muốn làm việc. Trong trường họp này là /app. Tất cả các lệnh được thực thi dưới dòng 2 này đều được thực hiện trong thư mục /app này.
Dòng 3: tại dòng này, lệnh RUN có thể hiểu là những gì bạn làm việc trên shell của cái máy tính có trạng thái giống với trạng thái của image ruby:2.5. Có nghĩa là bạn sẽ gõ các lệnh đứng sau RUN vào terminal của mình để máy tính xử lý. Như trong ví dụ này, nó sẽ update hệ thống, cài đặt các package cần thiết cho ứng dụng Rails.
Dòng 4: Dòng này cũng là một câu lệnh RUN, như bạn cũng có thể đoán được. Ở đây docker sẽ cài đặt một ứng dụng Rails mới trong thư mục /app
Dòng 5: Với câu lệnh ENV, bạn có thể thiết lập một environment variable trong image này. Trong ví dụ này, ta sẽ set biến môi trường RAILS_ENV thành development
Dòng 6: Lệnh EXPOSE là một câu lệnh đặc biệt trong docker, dùng để thông báo với docker rằng image này có thể nghe ở một cổng xác định (cổng 3000 trong trường hợp này). Lưu ý: lệnh EXPOSED này không có nghĩa là làm cho cổng này tiếp cận được trên máy host
Dòng 7: Lệnh CMD cũng là một lệnh đặc biệt của docker. Nó dùng để khai báo image sẽ làm gì sau khi nó được khởi chạy bằng lệnh docker run. Như trong ví dụ này, image sẽ tự động khởi động ứng dụng Rails bên trong container và cho nó lắng nghe ở cổng 3000 mặc định.

Build image mới này bằng cách chạy lệnh docker build -t [image_name] .. Vì bạn chạy lệnh docker build bên trong thư mục có chứa Dockerfile nên không cần phải khai báo Dockerfile vào lệnh docker build. Dấu chấm ở cuối cùng là không thể thiếu. Nó định nghĩa thư mục mà lệnh docker build sẽ chạy. Bạn có thể truyền vào đây một thự mục bất kì mong muốn.
Chạy một docker image

Như đã nói ở trên, bạn có thể chạy một docker image bằng cách sử dụng lệnh docker run. Ví dụ, ta lấy Dockerfile như ở ví dụ trước và build nó với tên là test-docker chẳng hạn, bạn sẽ có thể chạy nó bằng cách gọi docker run test-docker. Khi đó, docker sẽ tự động khởi động ứng dụng rails đã được cài đặt sẵn trong image test-docker mà bạn vừa build ra.

Tuy nhiên, khi bạn mở trang localhost:3000 thì vẫn chả thấy gì.

docker run

Lý do cho điều này khá là đơn giản, như tôi đã nói ở trong dòng 6 của Dockerfile ở trên, "Lệnh EXPOSE là một câu lệnh đặc biệt trong docker, dùng để thông báo với docker rằng image này có thể nghe ở một cổng xác định". Điều này hoàn toàn không đồng nghĩa với việc ta có thể truy cập đến cổng 3000 trong container này.

Để có thể truy cập vào cổng 3000 của container, ta cần phải map cổng 3000 của container vào một cổng nào đó trên máy host bằng cách sử dụng cờ -p của docker run.

docker run -p 3000:3000 test-docker

Violà, thế là bạn có thể truy cập vào cổng 3000 của container này. Ứng dụng rails trong container có thể truy cập và Rails logs sẽ hiện trên terminal của bạn!!!
Lời kết

Trong bài viết này, bạn đã được giới thiệu cơ bản về Docker, nó là gì, nó có tác dụng như thế nào, và làm thế nào để có thể sử dụng docker một cách cơ bản nhất.

Trong bài viết tới, tôi sẽ gửi đến các bạn những thủ thuật sử dụng docker cao cấp hơn và phù hợp với thực tế hơn. Cũng như một ví dụ nho nhỏ về build một docker image phù hợp để có thể deploy chúng trên staging hay production server.

@yeungon
Copy link
Author

yeungon commented Nov 19, 2018

Xin chào tất cả mọi người, vậy là chúng ta đã có thể gặp lại nhau sau phần trước của Docker for Beginner. Phần trước của Docker for Beginner chúng ta đã bàn luận về Docker là gì, Docker mang lại lợi ích gì cho dân dev hay cả như dân system administrator, cùng với đó, ta cũng đã tìm hiểu về một số tính năng cơ bản của Docker như Docker Image và Docker Container và cách để có thể chạy một ứng dụng Rails trong Docker.

Cho những bạn nào chưa đọc phần một của Docker for Beginner, hãy nhấn vào link này nhé
Docker Volumes

Docker cho phép bạn COPY dữ liệu vào trong image khi bạn build image đó, nhưng trong trường hợp bạn cần một dữ liệu động (có thể thay đổi sau khi build) thì sao? Hay khi bạn muốn dữ liệu trong container của bạn không bị mất khi bạn xóa container đó đi hoặc tắt nó.

Đó là lý do vì sao Docker tạo ra Docker Volume! Nó cho phép bạn mount dữ liệu từ host vào trong container một cách dễ dàng.

Các đơn giản nhất để sử dụng volume trong Docker đó là dùng cờ -v khi chạy một image. Ví dụ:

docker run -it --rm --name my-postgres -v /data/postgres:/var/lib/postgresql/data postgres

Trong câu lệnh trên, ta đã mount thư mục /data/postgres vào trong thư mục /var/lib/postgresql/data bên trong của container. Vậy nên mỗi khi bạn khởi động container my-postgres, các dữ liệu bên trong của database sẽ vẫn còn nguyên vẹn. Và bạn có thể xem các dữ liệu đó trong thư mục /data/postgres trên máy tính của mình.

Docker cũng cung cấp một CLI để quản lý volume này tại docker volume (bạn có thể chạy docker volume -h để xem help của CLI này)

Công cụ này dùng để quản lý các mount point trên host (tức là máy tính của bạn). Ví dụ:

docker volume create test-volume
docker volume inspect test-volume

Với câu lệnh đầu tiên, ta đã tạo một volume cho Docker, Docker sẽ lưu volume này đến khi bạn khai báo xóa nó

Với câu lệnh thứ hai, ta sử dụng lệnh inspect để xem thông tin của test-volume, output của lệnh này thường sẽ là như sau:

[
{
"CreatedAt": "2018-10-31T18:00:00+07:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]

Mountpoint mặc định của Docker nằm ở thư mục /var/lib/docker/volumes/{volume name}/_data.

Ngoài ra còn một số thông tin khác trong lệnh inspect này mà chúng ta không đề cập tại đây.
Docker Networks

Một trong số những lý do làm Docker trở nên mạnh mẽ chính là khả năng mà các container có thế liên kết với nhau hoặc có thể liên kết với các ứng dụng không sử dụng docker.

Trong mục này ta sẽ nói về cách mà các container có thể liên kết với nhau hoặc các ứng dụng khác nằm ngoài docker.
Các drive mạng trong Docker

bridge: Là driver mặc đinh được dùng trong Docker, nếu bạn không chỉ định một container chạy trên drive mạng nào thì driver này sẽ được sử dụng. Driver này cho phép container có thể nói chuyện với mạng hoặc máy tính host bằng cách sử dụng host làm cầu nối đến container.
host: Được sử dụng cho một container tách biệt, driver này cho phép container kết nối trực tiếp với hệ thống mạng mà host đang sử dụng. Điều này có nghĩa là nó không dùng host để làm cầu nối nữa mà sẽ là một node mạng ngang hàng với máy host.
overlay: Driver mạng overlay cho phép kết nối nhiều dịch vụ Docker với nhau và cho phép Docker Swarm liên lạc với nhau. Bạn cũng có thể sử dụng driver này để thiết lập liên kết giữa Swarm và một container tách biệt.
macvlan: Driver macvlan cho phép bạn gán địa của MAC cho một container, làm cho nó trở thành một thiết bị vật lý trong hệ thống mạng. Dịch vụ Docker sẽ điều hướng gói tin đến container bằng địa chỉ MAC của chính. Driver này thích hợp để làm việc với những ứng dụng cũ yêu cài kết nối trực tiếp đến máy thật thay vì điều hướng thông qua Docker trên máy host.
none: Cái tên nói lên tất cả, driver này chỉ định rằng container sẽ không có kết nối mạng. Thường được sử dụng chung với một driver mạng tùy chỉnh.

Cách các container nói chuyện với nhau

Cũng gần tương tự với một switch, Docker cho phép các container chạy trên cùng một mạng nói chuyện với nhau. Và tất nhiên, nó cũng cho phép các container nói chuyện trực tiếp với máy host.

Docker networks có thể được quản lý bởi CLI docker network. Khi khởi động Docker, nó sẽ tạo ra 3 driver mặc định là bridge, host và none.

Bạn cũng có thể tạo thêm driver bằng lệnh docker network create test-network. Như vậy ta đã có một network mới có tên test-network sử dụng driver là bridge (mặc định).

$ docker network inspect test-network
[
{
"Name": "test-network",
"Id": "60eef62b6048d9db84f43a24a0dfdcaddc65d71aca0f0f9ff8029312087f0f1c",
"Created": "2018-10-31T18:00:00.0000000+07:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]

Docker Compose

Docker Compose là một công cụ cho phép ta cấu hình và chạy một ứng dụng sử dụng nhiều container, điển hình như một ứng dụng chạy Rails và một database Postgres.

Với Docker Compose, ta sử dụng file định dạng YAML để cấu hình các dịch vụ mà bạn muốn Docker khởi tạo.

Việc sử dụng Docker Compose khá đơn giản, chỉ bằng 3 bước sau:

Định nghĩa môi trường của ứng dụng bằng Dockerfile để có thể build image mà bạn cần sử dụng
Định nghĩa các dịch vụ cần thiết trong docker-compose.yml để các dịch vụ này có thể khởi động trong một môi trường biệt lập và có thể liên kết với nhau.
Chạy lệnh docker-compose up để Docker Compose khởi động và chạy các dịch vụ mà bạn đã định nghĩa trong docker-compose.yml

Một docker-compose.yml có dạng như sau:

version: '3'
services:
rails_application:
build: .
image: rails_application
ports:
- "3000:3000"
links:
- redis
- postgres
redis:
image: redis
postgres:
image: postgres

Trong ví dụ trên, ta đã khai báo 3 ứng dụng chạy trong Docker đó là rails_application, redis và postgres. Khi đó, ta có thể chạy lệnh docker-compose up, Docker sẽ thực hiện các bước sau:

B1: Tạo một network có tên trùng với tên của ứng dụng (thường là tên của thư mục với postfix là _default)
B2: Tìm kiếm các ứng dụng được liệt kê dưới mục services
B3: Nếu không tìm thấy image được liệt kê đó trên máy local, nó sẽ tìm trên register của docker (mặc định là https://hub.docker.com)
B4: Nếu servier có lệnh build, Docker Compose của service theo như định nghĩa tại mục build của service
B5: Nếu vẫn không tìm thấy image thì Docker thông báo lỗi và ngừng khởi động các service tiếp theo
B6: Sau đó, Docker sẽ tiến hành chạy image đó và tạo thành một container.
B7: Lặp lại bước 2 đối với các service tiếp theo

Bạn cũng có thể sử dụng Docker Volume và Docker Network được nói bên trên để áp dụng cho Docker Compose:

version: '3'
services:
rails_application:
build: .
image: rails_application
ports:
- "3000:3000"
networks:
- redis
- database

redis:
image: redis
volumes:
- /data/redis:/data
networks:
- redis

postgres:
image: postgres
volumes:
- /data/postgres:/var/lib/postgresql/data
networks:
- database

networks:
redis:
name: redis-network
driver: bridge
database
name: database-network
driver: host

Và đến đây là bạn có thể tự mình viết ra một Dockerfile và docker-compose.yml đơn giản cho dự án của mình cùng với vô vàn lợi ích mà Docker đem lại khi phát triên dự án.

Happy Coding!

https://viblo.asia/p/docker-for-beginner-part-ii-3P0lPAqv5ox

@yeungon
Copy link
Author

yeungon commented Nov 19, 2018

  1. Vì sao nên sử dụng

Vào một ngày đẹp trời "trăng thanh gió mát", bạn được phân bổ vào dự án mới, và tất nhiên là hào khí ngút trời, thế như chẻ tre nhảy vào happy coding:

Bạn hứng khởi vào đọc README.md một hồi, thấy project này sao mà cài cắm nhiều thứ thế, nào là ruby, rồi rails, redis, mysql, nginx, ... mỗi thứ lại phải kèm theo version bao nhiêu, một tá thư viện, vân vân và mây mây với với hàng tá thứ khác. (Định kể thêm tý nữa cho nó nguy hiểm nhưng mà thôi các bạn cứ hiểu là nhiều nhé )

Lẩm bẩm một hồi, giờ ngồi search google, cài cắm, setup một tá thứ này thì hết bao lâu ta ?

Sếp ơi, em cần 1 buổi sáng để setup ạ.

Cài chưa xong đã conflic tùm lum, cái nọ xung đột cái kia chẳng hạn, lại còn ảnh hưởng tới những chương trình cũ đã cài đặt trong máy nữa chứ, thôi cài lại luôn cả hệ điều hành cho máy.

Sếp ơi, em cần thêm 1 buổi nữa để setup ạ -_- Hic

Thôi xong, mất thời gian, mệt mỏi với nhưng thao tác phụ mà chưa tập trung được vào việc chính.

Đó chính là lúc bạn nên nghĩ tới Docker, mọi thứ sẽ đơn giản hơn nhiều.

Chỉ vài dòng lệnh thôi, cạch cạch cạch, bạn sẽ có thể nhanh chóng tạo được môi trường ảo hóa chứa đầy đủ những cài đặt cần thiết cho project rồi.

Một ví dụ đơn giản vậy thôi, không dừng lại ở đó, công dụng của Docker còn khá nhiều, chúng ta cùng tìm hiểu dần nhé !
2. Quá trình hình thành

Cùng đọc lịch sử một chút đã:
2.1 Containerlization là gì ?

Ngày lâu lâu rồi, mô hình máy chủ thường là máy chủ vật lý + hệ điều hành(OS) + application.

Vấn đề gặp phải ở đây là lãng phí tài nguyên, một máy chủ chỉ cài được một OS, cho dù có ổ cứng khủng, ram khủng thì cũng không tận dụng hết lợi thế.

Sau đó ra đời công nghệ ảo hóa vitualization.

Bạn có thể đã nghe tới cái tên Vitualbox hay VMware rồi đúng không, đó đó chính nó đó. Với công nghệ này, trên một máy chủ vật lý mình có thể tạo được nhiều OS, tận dụng tài nguyên đã tốt hơn nhưng lại nảy sinh vấn đề tiếp.

Về tài nguyên: Khi bạn chạy máy ảo, bạn phải cung cấp "cứng" dung lượng ổ cứng cũng như ram cho máy ảo đó, bật máy ảo lên để đó không làm gì thì máy thật cũng phải phân phát tài nguyên.

Ví dụ khi tạo một máy ảo ram 2GB trên máy thật ram 4GB, lúc này máy thật sẽ mất 2GB ram cho máy ảo, kể cả khi máy ảo không dùng hết 2GB ram, đó là một sự lãng phí.

Về thời gian: Việc khởi động, shutdown khá lâu, có thể lên tới hàng phút.

Ở bước tiến hóa tiếp theo, người ta sinh ra công nghệ containerlization

Với công nghệ này, trên một máy chủ vật lý, ta sẽ sinh ra được nhiều máy con (giống với công nghệ ảo hóa vitualization), nhưng tốt hơn ở chỗ là các máy con này (Guess OS) đều dùng chung phần nhân của máy mẹ (Host OS) và chia sẻ với nhau tài nguyên máy mẹ.

Có thể nói là khi nào cần tài nguyên thì được cấp, cần bao nhiêu thì cấp bấy nhiêu, như vậy việc tận dụng tài nguyên đã tối ưu hơn. Điểm nổi bật nhất của containerlization là nó sử dụng các container, và một kĩ sư của Google đã phát biểu rằng:

Một công ty hàng đầu về công nghệ đã áp dụng nó, chứng tỏ lợi ích, độ tin cậy của công nghệ này rồi nhé ! Chúng ta cùng áp dụng nó thôi.

2.2 Container là gì ?

Các phần mềm, chương trình sẽ được Container Engine ( là một công cụ ảo hóa tinh gọn được cài đặt trên host OS) đóng gói thành các container.

Thế Container là gì, nó là một giải pháp để chuyển giao phần mềm một cách đáng tin cậy giữa các môi trường máy tính khác nhau bằng cách:

Tạo ra một môi trường chứa mọi thứ mà phần mềm cần để có thể chạy được.
Không bị các yếu tố liên quan đến môi trường hệ thống làm ảnh hưởng tới.
Cũng như không làm ảnh hưởng tới các phần còn lại của hệ thống.

Bạn có thể hiểu là ruby, rails, mysql ... kia được bỏ gọn vào một hoặc nhiều cái thùng (container), ứng dụng của bạn chạy trong những chiếc thùng đó, đã có sẵn mọi thứ cần thiết để hoạt động, không bị ảnh hưởng từ bên ngoài và cũng không gây ảnh hưởng ra ngoài.

Các tiến trình (process) trong một container bị cô lập với các tiến trình của các container khác trong cùng hệ thống tuy nhiên tất cả các container này đều chia sẻ kernel của host OS (dùng chung host OS).

Đây một nền tảng mở dành cho các lập trình viên, quản trị hệ thống dùng để xây dựng, chuyển giao và chạy các ứng dụng dễ dàng hơn. Ví dụ, bạn có một app java, bạn sẽ không cần cài đặt JDK vào máy thật để chạy app đó, chỉ cần kiếm container đã được setting tương ứng cho app về, bật nó lên, cho app chạy bên trong môi trường container đó, vậy là ok. Khi không sài nữa thì tắt hoặc xóa bỏ container đó đi, không ảnh hưởng gì tới máy thật của bạn.

Ưu điểm:

Linh động: Triển khai ở bất kỳ nơi đâu do sự phụ thuộc của ứng dụng vào tầng OS cũng như cơ sở hạ tầng được loại bỏ.
Nhanh: Do chia sẻ host OS nên container có thể được tạo gần như một cách tức thì. Điều này khác với vagrant - tạo môi trường ảo ở level phần cứng, nên khi khởi động mất nhiều thời gian hơn.
Nhẹ: Container cũng sử dụng chung các images nên cũng không tốn nhiều disks.
Đồng nhất :Khi nhiều người cùng phát triển trong cùng một dự án sẽ không bị sự sai khác về mặt môi trường.
Đóng gói: Có thể ẩn môi trường bao gồm cả app vào trong một gói được gọi là container. Có thể test được các container. Việc bỏ hay tạo lại container rất dễ dàng.

Nhược điểm:

Xét về tính an toàn:

Do dùng chung OS nên nếu có lỗ hổng nào đấy ở kernel của host OS thì nó sẽ ảnh hưởng tới toàn bộ container có trong host OS đấy.
Ngoài ra hãy thử tưởng tượng với host OS là Linux, nếu trong trường hợp ai đấy hoặc một ứng dụng nào đấy có trong container chiếm được quyền superuser, điều gì sẽ xảy ra? Về lý thuyết thì tầng OS sẽ bị crack và ảnh hưởng trực tiếp tới máy host bị hack cũng như các container khác trong máy đó (hacker sử dụng quyền chiếm được để lấy dữ liệu từ máy host cũng như từ các container khác trong cùng máy host bị hack chẳng hạn).

2.3 Docker ra đời

Công nghệ ảo hóa (vitualization) thì ta có thể dùng công cụ Vitualbox hay VMware thế còn đối với containerlization thì dùng gì đây ? Google họ dùng gì ?

Oh mình không biết được, mỗi một ông lớn có một cách để áp dụng công nghệ này và họ private source code.

Gần đây, mà cũng lâu rồi Có một công ty tiến hành public source code của họ về công nghệ này, họ tung ra sản phẩm mang tên là Docker và nhận được nhiều sự chú ý.

Sau đó công ty cũng đổi tên thành Docker luôn. Công ty này cung cấp công cụ Docker free nhưng họ kiếm được rất nhiều tiền từ những dịch vụ khác đi kèm với nó.

Với sự bùng nổ của việc sử dụng container cùng với những lợi ích lớn mà nó mang lại, gã khổng lồ phần mềm Microsoft không muốn bỏ qua cơ hội màu mỡ này với việc cho ra mắt tính năng mới có tên Windows Container.

Các bạn có thể tham khảo, áp dụng công cụ Windows Container của công ty Microsoft cho Windows tại đây.
Còn phạm vi bài viết này xin giới hạn lại áp dụng sản phẩm Docker của công ty Docker cho Linux.

Đó, dân ta phải biết sử Tây là thế đó, chứ cứ lao vào học Docker luôn rồi cũng chẳng biết nó sinh đẻ thế nào, từ đâu mà ra, có anh em họ hàng gì không ?
  1. Cài đặt ra sao ?

    Docker hỗ trợ nhiều nền tảng hệ điều hành khác nhau bao gồm Linux, Windows và cả Mac. Ngoài ra, Docker còn hỗ trợ nhiều dịch vụ điện toán đám mây nổi tiếng như Microsoft Azure hay Amazon Web Services.

    Lưu ý là ban đầu nó được xây dựng trên nền tảng Linux. Vì Docker cần can thiệp vào phần lõi, nhân Kernel trong khí đó Linux là mã nguồn mở, gọi là cần gì có nấy.

    Đến khi thấy Docker hay quá, bác Windows ngỏ lời, thế là công ty Docker và công ty Microsoft hợp tác với nhau nhưng nghe chừng chưa khả quan lắm bởi vì nhân Windows có nhưng thứ không public được ( bản quyền mà ).

    Cho tới hiện tại khi cài Docker trên Windows hay Mac thì Docker sẽ cài một máy ảo Linux trên máy thật và Docker hoạt động dựa trên máy ảo Linux đó. Còn tương lai về sau thì ai biết được.

    Docker có 2 phiên bản, CE( dành cho nhà phát triển, nhóm nhỏ, coder như chúng ta) và EE (dành cho doanh nghiệp).

    Dưới đây mình sẽ giới thiệu cài đặt đối với bản CE trên Ubuntu thông qua repository như sau:

I. Chuẩn bị một chút:

Update the apt package index:

$ sudo apt-get update

Install packages to allow apt to use a repository over HTTPS:

$ sudo apt-get install
apt-transport-https
ca-certificates
curl
software-properties-common

Add Docker’s official GPG key:

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Verify that you now have the key with the fingerprint 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88, by searching for the last 8 characters of the fingerprint.

$ sudo apt-key fingerprint 0EBFCD88

pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) [email protected]
sub 4096R/F273FCD8 2017-02-22

Use the following command to set up the stable repository

$ sudo add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/ubuntu
$(lsb_release -cs)
stable"

II. Cài đặt docker CE:

Update the apt package index:

$ sudo apt-get update

Install the latest version of Docker CE, or go to the next step to install a specific version. Any existing installation of Docker is replaced.

$ sudo apt-get install docker-ce

Verify that Docker CE is installed correctly by running the hello-world image.

$ sudo docker run hello-world

Nếu câu lệnh cuối cùng của bạn ra kết quả như sau thì bạn đã cài đặt Docker thành công:

Ngoài ra bạn có thể tham khảo cài đặt tại trang chủ.
4. Hoạt động như thế nào ?

Docker image là nền tảng của container, có thể hiểu Docker image như khung xương giúp định hình cho container, nó sẽ tạo ra container khi thực hiện câu lệnh chạy image đó. Nếu nói với phong cách lập trình hướng đối tượng, Docker image là class, còn container là thực thể (instance, thể hiện) của class đó.

Docker có hai khái niệm chính cần hiểu, đó là image và container:

Container: Tương tự như một máy ảo, xuất hiện khi mình khởi chạy image.

Tốc độ khởi chạy container nhanh hơn tốc độ khởi chạy máy ảo rất nhiều và bạn có thể thoải mái chạy 4,5 container mà không sợ treo máy.

Các files và settings được sử dụng trong container được lưu, sử dụng lại, gọi chung là images của docker.

Image: Tương tự như file .gho để ghost win mà mấy ông cài win dạo hay dùng.

Image này không phải là một file vật lý mà nó chỉ được chứa trong Docker.

Một image bao gồm hệ điều hành (Windows, CentOS, Ubuntu, …) và các môi trường lập trình được cài sẵn (httpd, mysqld, nginx, python, git, …).

Docker hub là nơi lưu giữ và chia sẻ các file images này (hiện có khoảng 300.000 images)

Bạn có thể tìm tải các image mọi người chia sẻ sẵn trên mạng hoặc có thể tự tạo cho mình một cái image như ý.
  1. Các câu lệnh trong Docker

    Chuẩn chỉnh & đầy đủ nhất thì bạn cứ tham khảo trên trang chủ của docker docs. Còn ở bài viết này sẽ trích dẫn những câu lệnh cơ bản nhất giúp các bạn nhanh chóng nắm bắt:

    Pull một image từ Docker Hub

         sudo docker pull image_name
    

    Tạo mới container bằng cách chạy image, kèm theo các tùy chọn:

         sudo docker run -v <forder_in_computer>:<forder_in_container> -p <port_in_computer>:<port_in_container> -it <image_name> /bin/bash
    

Ví dụ:

sudo docker pull ubuntu:16.04

sudo docker run -it ubuntu:16.04 /bin/bash

Bây giờ bạn đã dựng thành công một môi trường ubuntu ảo rồi đó.

Câu lệnh

uname -a

sẽ hiển thị thông tin của Kernel ubuntu, cùng so sánh nhé:

Kết quả của dòng uname-a thứ nhất là thông tin Kernel của máy ảo (tức là của container)

Linux 5ed7d9f282fe 4.15.0-36-generic #39~16.04.1-Ubuntu SMP Tue Sep 25 08:59:23 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Kết quả của dòng uname-a thứ hai là thông tin Kernel của máy "thật" (Linux) bạn đang dùng.

Linux hoanki-Nitro-AN515-51 4.15.0-36-generic #39~16.04.1-Ubuntu SMP Tue Sep 25 08:59:23 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

-> Thông tin nhân Kernel như nhau nhé ! Do container sử dụng chung tài nguyên với host OS mà.

Một vài câu lệnh khác:

docker images: Liệt kê các images hiện có

docker rmi {image_id/name}: Xóa một image

docker ps: Liệt kê các container đang chạy

docker ps -a: Liệt kê các container đã tắt

docker rm -f {container_id/name}: Xóa một container

docker start {new_container_name}: Khởi động một container

docker exec -it {new_container_name} /bin/bash: Truy cập vào container đang chạy
  1. Updating ...

Phần 1 này chủ yếu giới thiệu về lý thuyết, để mình cùng nhau hiểu Docker là gì và bản chất của Docker đã. Trong quá trình viết bài mình cần tìm hiểu thêm nhiều và cũng nhận ra nhiều điều mới. Nếu có ý kiến đóng góp gì, bạn vui lòng comment bên dưới nhé !

Trong phần 2 mình sẽ:

Giải thích chi tiết hơn các câu lệnh (-it nghĩa là gì, /bin/bash nghĩa là gì,..)
Cách tạo Dockerfile
Cách tạo Docker Conpose, cấu hình,... Mời các bạn đón đọc.

###############################################

###############################################

@yeungon
Copy link
Author

yeungon commented Nov 19, 2018

  1. Mở đầu

Xin chào các bạn, sau khi viết xong Docker: Chưa biết gì đến biết dùng (Phần 1), mình đã giới thiệu với các bạn các công nghệ ảo hóa containerlization với công cụ docker của công ty Docker trên hệ điều hành Ubuntu, nhưng mới chỉ dừng lại ở tìm hiểu lịch sử && cơ chế hoạt động của Docker.

Đây là một công cụ khá tuyệt vời, rất hữu ích, khuyên các bạn nên tìm hiểu và sử dụng. Trước khi đọc phần 2 này, hãy đọc phần 1 - chủ yếu về lý thuyết, để mình hiểu bản chất của Docker đã.

Hôm nay chúng ta sẽ đi chi tiết hơn, xem thực tế chúng ta sử dụng Docker như thế nào, đầu tiên sẽ là Dockerfile nhé ! Let go
2. Dockerfile
2.1 Dockerfile là gì ?

Thì đơn giản, Dockerfile là một file

dạng text, không có đuôi, giúp thiết lập cấu trúc cho docker image nhờ chứa một tập hợp các câu lệnh.

Từ những câu lệnh đó, Docker có thể thực hiện đóng gói một docker images theo yêu cầu tùy biến của riêng bạn.

=> Như vậy Dockerfile sẽ quy định Docker image được khởi tạo từ đâu, gồm những gì trong đó.
2.2 Cách viết Dockerfile

Demo như sau:

Đầu tiên chúng ta sẽ viết Dockerfile để tạo nên image rồi tạo nên container, sau khi tạo được container rồi thì đồng nghĩa là đã tạo ra được máy ảo để bạn có thể khởi chạy ứng dụng của bạn trên máy ảo đó.

Thư mục webroot chứa mã nguồn chương trình, có thể là một c++ app, java app hoặc web app được viết bằng php hoặc ruby,.... (Ở đây, để cho đơn giản, chúng ta chỉ đặt file hello.html, chạy trên trình duyệt sẽ hiển thị dòng Hello Word)

Sau này, bạn dùng editor để lập trình trên máy thật, chỉnh sửa mã nguồn trong thư mục này, mọi sự thay đổi được cập nhật ngay lập tức trên máy ảo.

File start.sh chứa những câu lệnh được chạy khi bật container (có thể dùng để start mysql, nginx, redis ...)

Nào, bắt đầu viết Dockerfile nhé:
2.2.1 Thiết lập image gốc

Đầu tiên, ta cần khai báo thằng cha của image này là thằng nào, tức là nó khởi nguồn từ đâu, sử dụng:

FROM

Image gốc có thể là centos:7, ubuntu:16.04, vân vân và mây mây.

Vi dụ:

FROM ubuntu:16.04

Có thể bạn sắp biết, Docker hub - nơi lưu trữ và chia sẻ các image sẽ chứa những image gốc mà từ đó, bạn có thể phát triển, cài cắm, thay tháo, chỉnh sửa, thêm bớt để tạo ra những images tùy biến cho riêng bạn.

Khi Docker đọc tới câu lệnh này, nó sẽ tự động tìm xem image ubuntu:16.04 này đã tồn tại trong máy chưa, nếu chưa thì Docker sẽ tự động pull image này về. Trong đó ubuntu là tên của image, 16:04 là tag, bạn cũng có thể hiểu nó nôm na như là branch trong git.

MAINTAINER : Một optional dùng để đặt tên cho tác giả của Dockerfile mà bạn đang viết. Ví dụ:

MAINTAINER HoanKi[email protected]

2.2.2 Cài đặt ứng dụng

Bây giờ, chúng ta sẽ cài thêm các ứng dụng, thiết lập môi trường cần thiết trên ubuntu:16.04 này

Bạn có thể cài nginx, php, python, ruby, java ... phụ thuộc vào nhu cầu của bạn, sử dụng:

RUN : Để thực thi một câu lệnh nào đó trong quá trình build images.

CMD : Để thực thi một câu lệnh trong quá trình bật container.

Mỗi Dockerfile chỉ có một câu lệnh CMD, nếu như có nhiều hơn một câu lệnh CMD thì chỉ có câu lệnh CMD cuối cùng được sử dụng.

Một câu hỏi đặt ra là nếu tôi muốn khởi động nhiều ứng dụng khi start container thì sao, lúc đó hay nghĩ tới ENTRYPOINT

ENTRYPOINT: Để thực thi một số câu lệnh trong quá trình start container, những câu lệnh này sẽ được viết trong file .sh.

Ví dụ:

Update ubuntu

RUN apt-get update

Install nginx

RUN apt-get install -y nginx

Install mysql server

RUN echo "mysql-server mysql-server/root_password password root" | debconf-set-selections
&& echo "mysql-server mysql-server/root_password_again password root" | debconf-set-selections
&& apt-get install -y mysql-server

Trong khi cài nginx, sẽ có câu hỏi xuất hiện và bạn cần trả lời yes/no, khi đó tùy chọn -y trong RUN apt-get install -y nginx sẽ thể hiện cho sự lựa chọn yes của bạn.
2.2.3 Cấu hình

EXPOSE: Container sẽ lắng nghe trên các cổng mạng được chỉ định khi chạy

ADD : Copy file, thư mục, remote file thêm chúng vào filesystem của image.

COPY : Copy file, thư mục từ host machine vào image. Có thể sử dụng url cho tập tin cần copy.

WORKDIR : Định nghĩa directory cho CMD

VOLUME : Mount thư mục từ máy host vào container.

Tạo file .sh

Như ở phần entrypoint đã nói, cho dù chỉ cần một câu lệnh mình vẫn dùng ENTRYPOINT, để sau này dễ dàng tùy biến, phát triển.

Tạo file start.sh như sau

#!/bin/bash
service nginx start
exec $@

Ta có ví dụ ở phần này như sau:

ADD start.sh /venv

WORKDIR /venv

RUN chmod a+x /venv/*

ENTRYPOINT ["/venv/start.sh"]

EXPOSE 80

Tổng hợp lại, ta có một ví dụ cho Dockerfile như sau :

FROM ubuntu:16.04

MAINTAINER HoanKi[email protected]

RUN DEBIAN_FRONTEND=noninteractive

RUN apt-get update

RUN apt-get install -y nginx

RUN echo "mysql-server mysql-server/root_password password root" | debconf-set-selections
&& echo "mysql-server mysql-server/root_password_again password root" | debconf-set-selections
&& apt-get install -y mysql-server

WORKDIR /venv

COPY start.sh /venv

RUN chmod a+x /venv/*

ENTRYPOINT ["/venv/start.sh"]

EXPOSE 80

Tạo file hello.html trong thư mục webroot:

Hello word

Mình có push code mẫu lên GitHub: HoanKi/docker_tutorial

2.3 Cách sử dụng Dockerfile
2.3.1 Build docker image từ Dockerfile

Ta sử dụng câu lệnh sau:

    sudo docker build -t <image_name> .

Ví dụ:

sudo docker build -t ubuntu-nginx .

Bạn có thể dùng lệnh

docker images

để xem thành quả nhé !

2.3.2 Tạo container từ image.

Gõ lệnh theo syntax:

    sudo docker run -v <forder_in_computer>:<forder_in_container> -p <port_in_computer>:<port_in_container> -it <image_name> /bin/bash

Trong đó:

-v : Thể hiện việc mount volume, dữ liệu từ thư mục từ máy thật có thể được truy cập từ thư mục của máy ảo.

-p: Cổng mạng từ máy thật để dẫn tới cổng mạng của máy ảo đang chạy.

-t: Chạy container và mở terminal bằng /bin/bash

Ví dụ vào localhost mặc định của nginx:

sudo docker run -p 9000:80 -it ubuntu-nginx /bin/bash

Kiểm tra log trên Terminal:

Trên trình duyệt:

Ví dụ vào thư mục dự án ở máy thật:

sudo docker run -v /media/hoanki/PROJECT4/GitRepo/docker_tutorial/webroot:/var/www/html -p 9000:80 -it ubuntu-nginx /bin/bash

Thay thế /media/hoanki/PROJECT4/GitRepo/docker_tutorial/webroot cho đúng với trên máy bạn nhé !

Kết quả:

  1. Docker Hub

Docker-hub: Nơi lưu trữ và chia sẻ các image của Docker, nhưng không chỉ có vậy.

Nãy giờ bạn và tôi đang build image hoàn toàn dưới local, nhưng Docker Hub còn hỗ trợ chúng ta làm việc này trên server nữa.

Mình tạo mới repo docker-basic trên Github, như này:

Sau đó mình tạo mới một repo trên Dockerhub.

Vào Create chọn Create Automated Build, chọn Github rồi trỏ tới docker-basic bạn vừa tạo ở GitHub.

Và ta có docker_basic, trông như sau:

Dockerhub sẽ hỗ trợ bạn build docker image online, sau đó bạn có thể pull nó về để sử dụng.

Vào tab Build Settings,

Từ giờ trở đi, mỗi khi bạn push code lên branch nào trên github branch đó bạn đã setting trên DockerHub thì images sẽ tự động được build.

Việc build này sẽ tự động thực hiên trên server Docker Hub nhé, ví dụ mình push code lên branch init_dockerfile thì Dockerhub tự động build image, kết quả có ở trong tab Build Detail.

Mình tạo pull request, sau khi mình merge nó thì DockerHub cũng sẽ build image tiếp trên branch master.

Thử đi nhé, đôi khi buid ở local thì pass mà build trên server thì lỗi, cảm giác fix mãi nó mới hiện dòng chữ "Success" nó mới awesome làm sao.
  1. Docker compose

###############################################

@yeungon
Copy link
Author

yeungon commented Nov 19, 2018

Chú ý lỗi

Problem:
You are trying to run a docker container or do the docker tutorial, but you only get an error message like this:

docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.26/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.
Solution:
The error message tells you that your current user can’t access the docker engine, because you’re lacking permissions to access the unix socket to communicate with the engine.

As a temporary solution, you can use sudo to run the failed command as root.
However it is recommended to fix the issue by adding the current user to the docker group:

Run this command in your favourite shell and then completely log out of your account and log back in (if in doubt, reboot!):

sudo usermod -a -G docker $USER
After doing that, you should be able to run the command without any issues. Run docker run hello-world as a normal user in order to check if it works. Reboot if the issue still persists.

Logging out and logging back in is required because the group change will not have an effect unless your session is closed

@yeungon
Copy link
Author

yeungon commented Nov 20, 2018

@yeungon
Copy link
Author

yeungon commented Nov 21, 2018

@yeungon
Copy link
Author

yeungon commented Nov 21, 2018

Cách đơn giản để chạy LAMP với docker

https://phptherightway.com/#docker

@yeungon
Copy link
Author

yeungon commented Nov 21, 2018

@yeungon
Copy link
Author

yeungon commented Nov 21, 2018

@yeungon
Copy link
Author

yeungon commented Nov 21, 2018

@yeungon
Copy link
Author

yeungon commented Nov 21, 2018

@yeungon
Copy link
Author

yeungon commented Nov 22, 2018

Delete all docker containers
docker rm $(docker ps -a -q)
Delete all docker images
docker rmi $(docker images -q)

@yeungon
Copy link
Author

yeungon commented Nov 23, 2018

How docker ps helped me: docker rm -f $(docker ps -aq) is a short command which I use to remove all containers.

@yeungon
Copy link
Author

yeungon commented Nov 25, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment