Docker là một ứng dụng giúp đơn giản hóa quá trình quản lý các quy trình ứng dụng bên trong container. Container cho phép bạn chạy ứng dụng của mình dưới dạng các quy trình được cách ly tài nguyên. Chúng tương tự như máy ảo, nhưng container có tính di động cao hơn, tiết kiệm tài nguyên hơn và phụ thuộc nhiều hơn vào hệ điều hành của host.
Để tìm hiểu chi tiết về các thành phần khác nhau của một container Docker, hãy xem tài liệu Hệ Sinh Thái Docker: Giới Thiệu Các Thành Phần Phổ Biến
Trước khi khám phá cách cài đặt Docker trên Ubuntu 18.04, nếu bạn đang tìm kiếm giải pháp chạy ứng dụng trên Windows, hãy tham khảo dịch vụ VPS Windows tại DataOnline. Với hiệu suất cao và cấu hình linh hoạt, VPS Windows giúp bạn triển khai ứng dụng dễ dàng, tiết kiệm chi phí.
DataOnline sẽ hướng dẫn bạn cách cài đặt và sử dụng Docker Community Edition (CE) trên Ubuntu 18.04. Bạn sẽ cài đặt chính Docker, làm việc với các container và image, cũng như đẩy một image lên Docker Repository.
Yêu cầu
Để theo dõi bài hướng dẫn này, bạn cần có:
● Một server Ubuntu 18.04 được thiết lập theo hướng dẫn khởi tạo server Ubuntu 18.04, bao gồm một tài khoản người dùng không phải root có quyền sudo và một firewall.
● Một tài khoản trên Docker Hub nếu bạn muốn tạo image riêng và đẩy chúng lên Docker Hub, như được trình bày ở các Bước 7 và 8.
Bước 1 – Cài đặt Docker
Gói cài đặt Docker có sẵn trong kho chính thức của Ubuntu có thể không phải là phiên bản mới nhất. Để đảm bảo chúng ta nhận được phiên bản mới nhất, chúng ta sẽ cài đặt Docker từ kho chính thức của Docker. Để làm điều đó, ta sẽ:
- Thêm một nguồn gói mới.
- Thêm GPG key từ Docker để đảm bảo các gói tải xuống là hợp lệ.
- Sau đó cài đặt gói Docker.
Đầu tiên, cập nhật danh sách các gói hiện có:
sudo apt update
Tiếp theo, cài đặt một vài gói tiên quyết giúp apt
có thể sử dụng các gói qua HTTPS:
sudo apt install apt-transport-https ca-certificates curl software-properties-common
Sau đó, thêm GPG key cho kho Docker chính thức vào hệ thống của bạn:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Thêm kho Docker vào nguồn APT:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
Tiếp theo, cập nhật cơ sở dữ liệu gói với các gói Docker từ repo mới thêm vào:
sudo apt update
Kiểm tra xem bạn sẽ cài đặt từ kho của Docker thay vì kho mặc định của Ubuntu:
apt-cache policy docker-ce
Bạn sẽ thấy đầu ra tương tự như sau (số phiên bản có thể khác):
Output of apt-cache policy docker-ce docker-ce: Installed: (none) Candidate: 18.03.1~ce~3-0~ubuntu Version table: 18.03.1~ce~3-0~ubuntu 500 500 https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
Lưu ý rằng docker-ce
chưa được cài đặt, nhưng phiên bản ứng viên được cài đặt đến từ kho Docker cho Ubuntu 18.04 (bionic
).
Cuối cùng, cài đặt Docker:
sudo apt install docker-ce
Docker bây giờ đã được cài đặt, daemon đã được khởi động, và quá trình này được cấu hình để tự khởi động cùng hệ thống.
Kiểm tra Docker có đang chạy hay không:
sudo systemctl status docker
Đầu ra sẽ giống như sau, cho thấy dịch vụ đang hoạt động:
Output ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2021-08-09 19:42:32 UTC; 33s ago Docs: https://docs.docker.com Main PID: 5231 (dockerd) Tasks: 7 CGroup: /system.slice/docker.service └─5231 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Cài đặt Docker không chỉ cung cấp dịch vụ Docker (daemon) mà còn công cụ dòng lệnh docker
(Docker client). Chúng ta sẽ khám phá cách sử dụng lệnh docker
trong các bước tiếp theo.
Bước 2 – Thực thi lệnh Docker mà không cần Sudo
Theo mặc định, lệnh docker
chỉ có thể được chạy bởi người dùng root hoặc bởi người dùng thuộc nhóm docker – nhóm này được tự động tạo ra trong quá trình cài đặt Docker. Nếu bạn cố gắng chạy lệnh docker
mà không thêm sudo
hoặc không thuộc nhóm docker, bạn sẽ nhận được đầu ra như sau:
Output 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.24/containers/create": dial unix /var/run/docker.sock: connect: permission denied. See 'docker run --help'.
Nếu bạn muốn tránh phải gõ sudo
mỗi lần chạy lệnh docker
, hãy thêm tên người dùng của bạn vào nhóm docker
:
sudo usermod -aG docker ${USER}
Để áp dụng thành viên nhóm mới, đăng xuất khỏi server và đăng nhập lại, hoặc gõ:
su - ${USER}
Bạn sẽ được yêu cầu nhập mật khẩu người dùng của mình.
Xác nhận rằng người dùng của bạn đã được thêm vào nhóm docker:
id -nG
Đầu ra ví dụ:
Output sammy sudo docker
Nếu bạn cần thêm một người dùng khác vào nhóm docker mà bạn không đăng nhập, hãy chỉ định tên người dùng đó cụ thể:
sudo usermod -aG docker username
Phần còn lại của bài hướng dẫn này giả định rằng bạn đang chạy lệnh docker
với tư cách là người dùng thuộc nhóm docker. Nếu không, hãy nhớ thêm sudo
vào trước các lệnh.
Tiếp theo, hãy cùng khám phá lệnh docker.
Bước 3 – Sử dụng lệnh Docker
Sử dụng docker
bao gồm việc truyền cho nó một chuỗi các tham số và lệnh, theo sau là các đối số. Cú pháp có dạng:
docker [option] [command] [arguments]
Để xem tất cả các lệnh con có sẵn, hãy gõ:
docker
Tính đến Docker 20, danh sách đầy đủ các lệnh con bao gồm:
Output attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container's filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes
Để xem các tham số của một lệnh cụ thể, gõ:
docker docker-subcommand --help
Để xem thông tin toàn hệ thống về Docker, sử dụng:
docker info
Chúng ta sẽ khám phá một số lệnh này, bắt đầu với việc làm việc với các image Docker.
Bước 4 – Làm việc với docker Images
Các container Docker được xây dựng từ các image Docker. Theo mặc định, Docker kéo các image này từ Docker Hub – một Docker registry được quản lý bởi Docker, công ty đứng sau dự án Docker.
Ai cũng có thể lưu trữ image Docker của mình trên Docker Hub, vì vậy hầu hết các ứng dụng và bản phân phối Linux bạn cần đều có image được lưu trữ ở đó.
Để kiểm tra xem bạn có thể truy cập và tải xuống image từ Docker Hub hay không, gõ:
docker run hello-world
Đầu ra sẽ cho biết Docker hoạt động đúng cách:
Output Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world b8dfde127a29: Pull complete Digest: sha256:df5f5184104426b65967e016ff2ac0bfcd44ad7899ca3bbcf8e44e4461491a9e Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. . . .
Docker ban đầu không tìm thấy image hello-world cục bộ, vì vậy nó đã tải image từ Docker Hub – repository mặc định. Khi image được tải về, Docker tạo một container từ image đó và ứng dụng bên trong container thực thi, hiển thị thông điệp.
Bạn có thể tìm kiếm các image có sẵn trên Docker Hub bằng cách sử dụng lệnh docker search. Ví dụ, để tìm image Ubuntu, gõ:
docker search ubuntu
Script sẽ duyệt Docker Hub và trả về danh sách các image có tên khớp với chuỗi tìm kiếm. Ví dụ, đầu ra sẽ giống như sau:
Output NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Ubuntu is a Debian-based Linux operating sys… 7917 [OK] dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC 193 [OK] rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 156 [OK] ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 93 [OK] ubuntu-upstart Upstart is an event-based replacement for th… 87 [OK] neurodebian NeuroDebian provides neuroscience research s… 50 [OK] ubuntu-debootstrap debootstrap --variant=minbase --components=m… 38 [OK] 1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 36 [OK] nuagebec/ubuntu Simple always updated Ubuntu docker images w… 23 [OK] tutum/ubuntu Simple Ubuntu docker images with SSH access 18 i386/ubuntu Ubuntu is a Debian-based Linux operating sys… 13 ppc64le/ubuntu Ubuntu is a Debian-based Linux operating sys… 12 1and1internet/ubuntu-16-apache-php-7.0 ubuntu-16-apache-php-7.0 10 [OK] 1and1internet/ubuntu-16-nginx-php-phpmyadmin-mariadb-10 ubuntu-16-nginx-php-phpmyadmin-mariadb-10 6 [OK] eclipse/ubuntu_jdk8 Ubuntu, JDK8, Maven 3, git, curl, nmap, mc, … 6 [OK] codenvy/ubuntu_jdk8 Ubuntu, JDK8, Maven 3, git, curl, nmap, mc, … 4 [OK] darksheer/ubuntu Base Ubuntu Image -- Updated hourly 4 [OK] 1and1internet/ubuntu-16-apache ubuntu-16-apache 3 [OK] 1and1internet/ubuntu-16-nginx-php-5.6-wordpress-4 ubuntu-16-nginx-php-5.6-wordpress-4 3 [OK] 1and1internet/ubuntu-16-sshd ubuntu-16-sshd 1 [OK] pivotaldata/ubuntu A quick freshening-up of the base Ubuntu doc… 1 1and1internet/ubuntu-16-healthcheck ubuntu-16-healthcheck 0 [OK] pivotaldata/ubuntu-gpdb-dev Ubuntu images for GPDB development 0 smartentry/ubuntu ubuntu with smartentry 0 [OK] ossobv/ubuntu ...
Trong cột OFFICIAL, “OK” cho biết image được xây dựng và hỗ trợ bởi công ty đứng sau dự án.
Khi bạn đã xác định được image mong muốn, hãy tải nó về máy tính của bạn bằng lệnh docker pull:
docker pull ubuntu
Đầu ra sẽ như sau:
Output Using default tag: latest latest: Pulling from library/ubuntu 16ec32c2132b: Pull complete Digest: sha256:82becede498899ec668628e7cb0ad87b6e1c371cb8a1e597d83a47fac21d6af3 Status: Downloaded newer image for ubuntu:latest docker.io/library/ubuntu:latest
Sau khi image được tải về, bạn có thể chạy một container từ image đó bằng lệnh docker run. Như ví dụ với hello-world
, nếu image chưa được tải về khi sử dụng lệnh docker run, Docker sẽ tự động tải image trước, sau đó chạy container.
Để xem các image đã tải về trên máy tính của bạn, gõ:
docker images
Đầu ra sẽ giống như sau:
Output REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 1318b700e415 13 days ago 72.8MB hello-world latest d1165f221234 5 months ago 13.3kB
Như bạn sẽ thấy sau này, các image mà bạn sử dụng để chạy container có thể được sửa đổi và dùng để tạo ra image mới, sau đó có thể được tải (push) lên Docker Hub hoặc các Docker registry khác.
Chúng ta hãy xem cách chạy container chi tiết hơn.
Bước 5 – Chạy một Docker Container
Container hello-world
bạn chạy ở bước trước là ví dụ của một container chạy và thoát sau khi hiển thị thông điệp thử nghiệm. Container có thể hữu ích hơn thế và có thể hoạt động ở chế độ tương tác. Rốt cuộc, chúng tương tự như máy ảo, nhưng tiết kiệm tài nguyên hơn.
Ví dụ, hãy chạy một container sử dụng image Ubuntu mới nhất. Sự kết hợp của các tham số -i và -t sẽ cung cấp cho bạn quyền truy cập shell tương tác bên trong container:
docker run -it ubuntu
Prompt của bạn sẽ thay đổi, cho thấy rằng bạn đang làm việc bên trong container, ví dụ:
Output root@d9b100f2f636:/#
Lưu ý ID của container ở prompt (trong ví dụ này, ID là d9b100f2f636
). Bạn sẽ cần ID này sau này khi muốn xóa container.
Bây giờ, bạn có thể chạy bất kỳ lệnh nào bên trong container. Ví dụ, để cập nhật cơ sở dữ liệu gói bên trong container (không cần thêm sudo
vì bạn đang làm việc với tư cách root):
apt update
Sau đó, cài đặt một ứng dụng, ví dụ cài đặt Node.js:
apt install nodejs
Lệnh này cài đặt Node.js trong container từ kho chính thức của Ubuntu. Sau khi cài đặt hoàn tất, xác minh rằng Node.js đã được cài đặt bằng:
node -v
Bạn sẽ thấy số phiên bản được hiển thị, ví dụ:
Output v10.19.0
Bất kỳ thay đổi nào bạn thực hiện bên trong container chỉ áp dụng cho container đó.
Để thoát khỏi container, gõexit
Tiếp theo, hãy cùng tìm hiểu cách quản lý các container trên hệ thống của bạn.
Bước 6 – Quản lý Docker Containers
Sau một thời gian sử dụng Docker, bạn sẽ có nhiều container đang chạy (active) và không chạy (inactive) trên máy của bạn. Để xem các container đang chạy, sử dụng:
docker ps
Đầu ra sẽ giống như sau:
Output CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Trong bài hướng dẫn này, bạn đã khởi động hai container: một từ image hello-world và một từ image ubuntu. Cả hai container hiện không chạy nhưng vẫn tồn tại trên hệ thống.
Để xem tất cả các container – cả đang chạy và không chạy, sử dụng lệnh docker ps -a:
docker ps -a
Đầu ra sẽ giống như:
e4dcb273b696 ubuntu "bash" About a minute ago Exited (0) 30 seconds ago suspicious_hopper 79b892f318e9 hello-world "/hello" 3 minutes ago Exited (0) 3 minutes ago
Để xem container mới nhất bạn tạo, dùng tham số -l:
docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e4dcb273b696 ubuntu "bash" 2 minutes ago Exited (0) About a minute ago suspicious_hopper
Để khởi động lại một container đã dừng, sử dụng lệnh docker start
theo sau là ID hoặc tên container. Ví dụ, khởi động container Ubuntu với ID e4dcb273b696
:
docker start e4dcb273b696
Container sẽ khởi động và bạn có thể dùng lệnh docker ps
để kiểm tra trạng thái:
docker stop suspicious_hopper
Để dừng một container đang chạy, sử dụng lệnh docker stop
theo sau là ID hoặc tên container. Ví dụ, dừng container có tên sharp_volhard
::
docker stop suspicious_hopper
Khi bạn quyết định không cần container nữa, xóa nó bằng lệnh docker rm
, sử dụng ID hoặc tên container. Ví dụ, xóa container liên quan đến image hello-world
:
docker rm boring_jang
Bạn cũng có thể khởi tạo một container mới và đặt tên cho nó bằng cách sử dụng tham số --name
. Ngoài ra, bạn có thể sử dụng tham số --rm
để tạo container tự xóa khi nó dừng. Xem lệnh docker run --help
để biết thêm thông tin về các tùy chọn này.
Container có thể được chuyển thành image, từ đó bạn có thể xây dựng container mới. Hãy cùng xem cách thức thực hiện điều đó.
Bước 7 – Cam kết thay đổi trong Container thành Docker Image
Khi bạn khởi động một image Docker, bạn có thể tạo mới, chỉnh sửa và xóa các file giống như làm việc với máy ảo. Những thay đổi bạn thực hiện chỉ áp dụng cho container đó. Bạn có thể khởi động và dừng container, nhưng khi bạn xóa nó bằng lệnh docker rm
, các thay đổi sẽ bị mất vĩnh viễn.
Phần này hướng dẫn bạn cách lưu trạng thái của container thành một Docker image mới.
Sau khi cài đặt Node.js bên trong container Ubuntu, bạn có một container chạy từ một image, nhưng container đó đã khác so với image gốc. Bạn có thể muốn sử dụng container Node.js này làm cơ sở cho các image mới trong tương lai.
Sau đó, cam kết các thay đổi vào một Docker image mới bằng lệnh:
docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name
Tham số -m dùng để ghi chú cam kết (commit message) mô tả những thay đổi bạn đã thực hiện.Tham số -a dùng để chỉ định tác giả. container_id
là ID của container mà bạn đã lưu ý khi khởi động phiên làm việc Docker tương tác. Nếu bạn chưa tạo repository
riêng trên Docker Hub, repository thường là tên người dùng Docker Hub của bạn.
Ví dụ, với người dùng sammy và container ID d9b100f2f636
, lệnh sẽ là:
docker commit -m "added Node.js" -a "sammy" d9b100f2f636 sammy/ubuntu-nodejs
Khi bạn cam kết một image, image mới sẽ được lưu cục bộ trên máy tính của bạn. Sau này, bạn sẽ học cách đẩy (push) image lên Docker registry như Docker Hub để người khác có thể truy cập.
Chạy lại lệnh docker images để xem image mới cùng với image gốc:
docker images
Đầu ra sẽ giống như:
Output REPOSITORY TAG IMAGE ID CREATED SIZE sammy/ubuntu-nodejs latest 7c1f35226ca6 7 seconds ago 179MB ubuntu latest 113a43faa138 4 weeks ago 81.2MB hello-world
Trong ví dụ này, ubuntu-nodejs
là image mới được tạo ra từ image Ubuntu
có sẵn trên Docker Hub. Sự khác biệt về kích thước phản ánh các thay đổi đã được thực hiện (ở đây là việc cài đặt Node.js). Lần sau, nếu bạn cần chạy container với Ubuntu đã cài sẵn Node.js, bạn chỉ cần sử dụng image mới này.
Bạn cũng có thể tạo image từ Dockerfile
, cho phép tự động hóa quá trình cài đặt phần mềm trong image mới. Tuy nhiên, điều đó vượt quá phạm vi của bài hướng dẫn này.
Bây giờ, hãy chia sẻ image mới với người khác để họ có thể tạo container từ đó.
Bước 8 – Đẩy Docker Images lên Docker Repository
Bước tiếp theo sau khi tạo ra một image mới từ image cũ là chia sẻ nó với bạn bè, với cả thế giới trên Docker Hub hoặc trên một Docker registry khác mà bạn có quyền truy cập. Để đẩy một image lên Docker Hub hoặc bất kỳ registry nào khác, bạn cần có tài khoản tại đó.
Phần này hướng dẫn bạn cách đẩy Docker image lên Docker Hub. Để tìm hiểu cách tạo Docker registry riêng tư, hãy xem Cách Thiết Lập Docker Registry Riêng Tư Trên Ubuntu 14.04
Đầu tiên, để đẩy image, đăng nhập vào Docker Hub:
docker login -u docker-registry-username
Bạn sẽ được yêu cầu xác thực bằng mật khẩu Docker Hub của mình. Nếu mật khẩu đúng, quá trình xác thực sẽ thành công.
Lưu ý: Nếu tên người dùng Docker registry của bạn khác với tên người dùng cục bộ đã dùng để tạo image, bạn cần gán tag cho image với tên người dùng registry của bạn. Ví dụ, với ví dụ ở bước trước, gõ:
docker tag sammy/ubuntu-nodejs docker-registry-username/ubuntu-nodejs
Sau đó, bạn có thể đẩy image của mình lên bằng lệnh:
docker push docker-registry-username/docker-image-name
Để đẩy image ubuntu-nodejs
lên repository của sammy, lệnh sẽ là:
docker push sammy/ubuntu-nodejs
Quá trình đẩy image có thể mất một thời gian để hoàn thành khi image được tải lên, nhưng khi hoàn tất, đầu ra sẽ giống như sau:
Output The push refers to a repository [docker.io/sammy/ubuntu-nodejs] e3fbbfb44187: Pushed 5f70bf18a086: Pushed a3b5c80a4eba: Pushed 7f18b442972b: Pushed 3ce512daaf78: Pushed 7aae4540b42d: Pushed ...
Sau khi đẩy image lên registry, image đó sẽ xuất hiện trên dashboard của tài khoản Docker Hub của bạn.
Nếu lệnh đẩy gặp lỗi như sau, có khả năng bạn chưa đăng nhập:
Output The push refers to a repository [docker.io/sammy/ubuntu-nodejs] e3fbbfb44187: Preparing 5f70bf18a086: Preparing a3b5c80a4eba: Preparing 7f18b442972b: Preparing 3ce512daaf78: Preparing 7aae4540b42d: Waiting unauthorized: authentication required
Hãy đăng nhập lại bằng lệnh docker login
và thử đẩy lại, sau đó kiểm tra xem image đã có trên trang repository Docker Hub của bạn hay chưa.
Bây giờ, bạn có thể sử dụng lệnh docker pull sammy/ubuntu-nodejs
để kéo image về máy mới và sử dụng nó để chạy container.
Kết Luận
Trong bài hướng dẫn này, bạn đã hoàn thành việc cài đặt Docker, làm việc với các image và container, đồng thời đẩy một image đã được chỉnh sửa lên Docker Hub. Với những kiến thức cơ bản trong tay, bạn đã sẵn sàng để tiếp tục mở rộng khả năng sử dụng Docker. Hãy tiếp tục khám phá các bài hướng dẫn chuyên sâu khác về Docker trong cộng đồng DataOnline để nắm vững các kỹ thuật nâng cao, từ quản lý container hiệu quả đến tối ưu hóa quy trình phát triển phần mềm với Docker.
Sau khi thiết lập Docker, bạn có thể tối ưu hóa ứng dụng trên máy chủ. Nếu cần một môi trường mạnh mẽ, hãy cân nhắc thuê máy chủ VPS từ DataOnline. VPS cung cấp tài nguyên riêng biệt, đảm bảo hiệu suất ổn định và khả năng mở rộng linh hoạt cho mọi dự án.