Thứ ba, 09/06/2020 | 00:00 GMT+7

Cách cài đặt và sử dụng Docker trên Ubuntu 20.04

Docker là một ứng dụng giúp đơn giản hóa quá trình quản lý các tiến trình ứng dụng trong vùng chứa . Vùng chứa cho phép bạn chạy các ứng dụng của bạn trong các quy trình cách ly tài nguyên. Chúng tương tự như máy ảo, nhưng các container di động hơn, thân thiện với tài nguyên hơn và phụ thuộc nhiều hơn vào hệ điều hành server .

Để có giới thiệu chi tiết về các thành phần khác nhau của containers Docker, hãy xem Hệ sinh thái Docker: Giới thiệu về các thành phần chung .

Trong hướng dẫn này, bạn sẽ cài đặt và sử dụng Docker Community Edition (CE) trên Ubuntu 20.04. Bạn sẽ tự cài đặt Docker, làm việc với các containers và hình ảnh cũng như đẩy hình ảnh vào Kho lưu trữ Docker.

Yêu cầu

Để làm theo hướng dẫn này, bạn cần những thứ sau:

Bước 1 - Cài đặt Docker

Gói cài đặt Docker có sẵn trong repository lưu trữ Ubuntu chính thức có thể không phải là version mới nhất. Để đảm bảo ta nhận được version mới nhất, ta sẽ cài đặt Docker từ repository Docker chính thức. Để làm điều đó, ta sẽ thêm một nguồn gói mới, thêm khóa GPG từ Docker đảm bảo download hợp lệ, sau đó cài đặt gói.

Trước tiên, hãy cập nhật danh sách gói hiện có của bạn:

  • sudo apt update

Tiếp theo, cài đặt một vài gói yêu cầu cho phép apt sử dụng các gói qua HTTPS:

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

Sau đó, thêm khóa GPG cho repository 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 repository Docker vào các nguồn APT:

  • sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

Tiếp theo, cập nhật database gói với các gói Docker từ repo mới được thêm vào:

  • sudo apt update

Đảm bảo rằng bạn sắp cài đặt từ kho Docker thay vì kho mặc định của Ubuntu:

  • apt-cache policy docker-ce

Bạn sẽ thấy kết quả như thế này, mặc dù số version cho Docker có thể khác:

Đầu ra của docker-ce policy apt-cache
docker-ce:   Installed: (none)   Candidate: 5:19.03.9~3-0~ubuntu-focal   Version table:      5:19.03.9~3-0~ubuntu-focal 500         500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages 

Lưu ý docker-ce chưa được cài đặt, nhưng thành phần để cài đặt là từ repository Docker cho Ubuntu 20.04 ( focal ).

Cuối cùng, cài đặt Docker:

  • sudo apt install docker-ce

Docker bây giờ sẽ được cài đặt, service được chạy và quá trình được kích hoạt để bắt đầu khi server khởi động . Kiểm tra xem nó đang chạy:

  • sudo systemctl status docker

Đầu ra phải giống như sau , cho thấy rằng dịch vụ đang đang chạy :

Output
● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-05-19 17:00:41 UTC; 17s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 24321 (dockerd) Tasks: 8 Memory: 46.4M CGroup: /system.slice/docker.service └─24321 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Việc cài đặt Docker giờ đây không chỉ cung cấp cho bạn dịch vụ Docker (daemon) mà còn cả tiện ích dòng lệnh docker hoặc ứng dụng client Docker. Ta sẽ khám phá cách sử dụng lệnh docker ở phần sau trong hướng dẫn này.

Bước 2 - Thực thi lệnh Docker mà không cần Sudo (Tùy chọn)

Theo mặc định, lệnh docker chỉ có thể được chạy bởi user root hoặc bởi user trong group docker , lệnh này được tạo tự động trong quá trình cài đặt của Docker. Nếu bạn cố gắng chạy docker lệnh mà không đặt trước từ đó sudo hoặc không là ở group Docker, bạn sẽ nhận được một kết quả như thế này:

Output
docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?. See 'docker run --help'.

Nếu bạn muốn tránh nhập sudo khi nào bạn chạy lệnh docker , hãy thêm tên user của bạn vào group docker :

  • sudo usermod -aG docker ${USER}

Để áp dụng tư cách thành viên group mới, hãy đăng xuất khỏi server và đăng nhập lại hoặc chạy lệnh sau :

  • su - ${USER}

Bạn sẽ được yêu cầu nhập password của user để tiếp tục.

Xác nhận user của bạn hiện đã được thêm vào group docker bằng lệnh :

  • id -nG
Output
sammy sudo docker

Nếu bạn cần thêm user vào group docker mà bạn chưa đăng nhập, hãy khai báo tên user đó một cách rõ ràng bằng cách sử dụng:

  • sudo usermod -aG docker username

Phần còn lại của bài viết này giả sử bạn đang chạy lệnh docker với quyền là user trong group docker . Nếu bạn chọn không, vui lòng thêm các lệnh với sudo .

Tiếp theo ta hãy khám phá lệnh docker .

Bước 3 - Sử dụng lệnh Docker

Sử dụng docker bao gồm việc chuyển cho nó một chuỗi các tùy chọn và lệnh theo sau là các đối số. Cú pháp có dạng sau:

  • docker [option] [command] [arguments]

Để xem tất cả các lệnh con có sẵn, hãy nhập:

  • docker

Kể từ Docker 19, danh sách đầy đủ các lệnh con có sẵn 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 tùy chọn có sẵn cho một lệnh cụ thể, hãy nhập:

  • docker docker-subcommand --help

Để xem thông tin toàn hệ thống về Docker, hãy sử dụng:

  • docker info

Hãy cùng khám phá một số lệnh này. Ta sẽ bắt đầu bằng cách làm việc với hình ảnh.

Bước 4 - Làm việc với Docker Images

Docker container được xây dựng từ Docker image . Theo mặc định, Docker kéo những hình ảnh này từ Docker Hub , một nơi đăng ký Docker được quản lý bởi Docker, công ty đứng sau dự án Docker. Bất kỳ ai cũng có thể lưu trữ Docker image của họ trên Docker Hub, vì vậy hầu hết các ứng dụng và bản phân phối Linux mà bạn cần sẽ có hình ảnh được lưu trữ ở đó.

Để kiểm tra xem bạn có thể truy cập và download hình ảnh từ Docker Hub hay không, hãy nhập:

  • docker run hello-world

Kết quả kết quả sẽ cho biết Docker hoạt động chính xác:

Output
Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 0e03bdcc26d7: Pull complete Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1 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 thể tìm thấy hình ảnh hello-world local , vì vậy nó đã download hình ảnh từ Docker Hub, đây là repository mặc định . Sau khi hình ảnh được download , Docker đã tạo một containers từ hình ảnh và ứng dụng trong containers được thực thi, hiển thị thông báo.

Bạn có thể tìm kiếm hình ảnh có sẵn trên Docker Hub bằng cách sử dụng lệnh docker với lệnh con search . Ví dụ, để tìm kiếm hình ảnh Ubuntu, hãy nhập:

  • docker search ubuntu

Tập lệnh sẽ thu thập dữ liệu Docker Hub và trả về danh sách tất cả các hình ảnh có tên trùng với chuỗi tìm kiếm. Trong trường hợp này, kết quả sẽ tương tự như sau:

Output
NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Ubuntu is a Debian-based Linux operating sys… 10908 [OK] dorowu/ubuntu-desktop-lxde-vnc Docker image to provide HTML5 VNC interface … 428 [OK] rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 244 [OK] consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… 218 [OK] ubuntu-upstart Upstart is an event-based replacement for th… 108 [OK] ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ...

Trong cột CHÍNH THỨC , OK cho biết hình ảnh được xây dựng và hỗ trợ bởi tổ chức đứng sau dự án. Khi bạn đã xác định được hình ảnh mà bạn muốn sử dụng, bạn có thể tải nó xuống máy tính của bạn bằng cách sử dụng lệnh con pull .

Thực thi lệnh sau để tải hình ảnh ubuntu chính thức xuống máy tính của bạn:

  • docker pull ubuntu

Bạn sẽ thấy kết quả sau:

Output
Using default tag: latest latest: Pulling from library/ubuntu d51af753c3d3: Pull complete fc878cd0a91c: Pull complete 6154df8ff988: Pull complete fee5db0ff82f: Pull complete Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7 Status: Downloaded newer image for ubuntu:latest docker.io/library/ubuntu:latest

Sau khi một hình ảnh đã được download , bạn có thể chạy containers bằng cách sử dụng hình ảnh đã download với lệnh con run . Như bạn đã thấy với ví dụ hello-world , nếu một hình ảnh chưa được download khi docker được thực thi với lệnh con run , thì ứng dụng client Docker trước tiên sẽ download hình ảnh, sau đó chạy một containers bằng cách sử dụng nó.

Để xem các hình ảnh đã được download máy tính của bạn, hãy nhập:

  • docker images

Đầu ra sẽ tương tự như sau:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 1d622ef86b13 3 weeks ago 73.9MB hello-world latest bf756fb1ae65 4 months ago 13.3kB

Như bạn sẽ thấy ở phần sau của hướng dẫn này, hình ảnh mà bạn sử dụng để chạy containers có thể được sửa đổi và sử dụng để tạo hình ảnh mới, sau đó có thể được tải lên (được đẩy là thuật ngữ kỹ thuật) lên Docker Hub hoặc các tổ chức đăng ký Docker khác.

Hãy xem cách chạy các containers chi tiết hơn.

Bước 5 - Chạy Docker Container

Vùng chứa hello-world mà bạn đã chạy ở bước trước là một ví dụ về containers chạy và thoát sau khi gửi thông báo thử nghiệm. Các containers có thể hữu ích hơn thế nhiều và chúng có thể tương tác. Xét cho cùng, chúng tương tự như máy ảo, chỉ thân thiện hơn với tài nguyên.

Ví dụ, hãy chạy một containers bằng hình ảnh mới nhất của Ubuntu. Sự kết hợp của các lựa chọn -i-t cho phép bạn truy cập shell tương tác vào containers :

  • docker run -it ubuntu

Dấu nhắc lệnh của bạn sẽ thay đổi để cho biết là bạn hiện đang làm việc bên trong containers và sẽ có dạng sau:

Output
root@d9b100f2f636:/#

Lưu ý id containers trong dấu nhắc lệnh. Trong ví dụ này, nó là d9b100f2f636 . Sau này, bạn cần ID containers đó để xác định containers khi bạn muốn xóa nó.

Đến đây bạn có thể chạy bất kỳ lệnh nào bên trong containers . Ví dụ: hãy cập nhật database gói bên trong containers . Bạn không cần đặt trước bất kỳ lệnh nào với sudo , vì bạn đang hoạt động bên trong containers với quyền là user root :

  • apt update

Sau đó cài đặt bất kỳ ứng dụng nào trong đó. Hãy cài đặt Node.js:

  • apt install nodejs

Điều này sẽ cài đặt Node.js trong containers từ repository chính thức của Ubuntu. Khi quá trình cài đặt kết thúc, hãy xác minh Node.js đã được cài đặt:

  • node -v

Bạn sẽ thấy số version được hiển thị trong terminal của bạn :

Output
v10.19.0

Mọi thay đổi bạn thực hiện bên trong containers chỉ áp dụng cho containers đó.

Để thoát khỏi containers , hãy nhập exit tại dấu nhắc .

Tiếp theo hãy xem cách quản lý các containers trên hệ thống của ta .

Bước 6 - Quản lý containers Docker

Sau khi sử dụng Docker một thời gian, bạn sẽ có nhiều containers hoạt động (đang chạy) và không hoạt động trên máy tính của bạn . Để xem những cái đang hoạt động , hãy sử dụng:

  • docker ps

Bạn sẽ thấy kết quả tương tự như sau:

Output
CONTAINER ID IMAGE COMMAND CREATED

Trong hướng dẫn này, bạn đã bắt đầu hai containers ; một từ hình ảnh hello-world và một từ hình ảnh ubuntu . Cả hai containers không còn chạy nữa, nhưng chúng vẫn tồn tại trên hệ thống.

Để xem tất cả các containers - đang hoạt động và không hoạt động, hãy chạy docker ps bằng lựa chọn -a :

  • docker ps -a

Bạn sẽ thấy kết quả tương tự như sau:

1c08a7a0d0e4        ubuntu              "/bin/bash"         2 minutes ago       Exited (0) 8 seconds ago                       quizzical_mcnulty a707221a5f6c        hello-world         "/hello"            6 minutes ago       Exited (0) 6 minutes ago                       youthful_curie  

Để xem containers mới nhất bạn đã tạo, hãy chuyển nó qua lựa chọn -l :

  • docker ps -l
  • CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  • 1c08a7a0d0e4 ubuntu "/bin/bash" 2 minutes ago Exited (0) 40 seconds ago quizzical_mcnulty

Để bắt đầu một containers đã dừng, hãy sử dụng docker start , theo sau là ID containers hoặc tên của containers . Hãy bắt đầu containers dựa trên Ubuntu với ID là 1c08a7a0d0e4 :

  • docker start 1c08a7a0d0e4

Vùng chứa sẽ bắt đầu và bạn có thể sử dụng docker ps để xem trạng thái của nó:

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1c08a7a0d0e4 ubuntu "/bin/bash" 3 minutes ago Up 5 seconds quizzical_mcnulty

Để dừng một containers đang chạy, hãy sử dụng docker stop , theo sau là ID hoặc tên containers . Lần này, ta sẽ sử dụng tên mà Docker đã gán cho containers , đó là quizzical_mcnulty :

  • docker stop quizzical_mcnulty

Sau khi bạn quyết định không cần containers nữa, hãy xóa nó bằng lệnh docker rm , sử dụng ID containers hoặc tên. Sử dụng lệnh docker ps -a để tìm ID containers hoặc tên cho containers được liên kết với hình ảnh hello-world và xóa nó.

  • docker rm youthful_curie

Bạn có thể bắt đầu một containers mới và đặt tên cho nó bằng cách sử dụng lựa chọn --name . Bạn cũng có thể sử dụng lựa chọn --rm để tạo một containers tự loại bỏ khi nó dừng lại. Xem lệnh docker run help để biết thêm thông tin về các tùy chọn này và các tùy chọn khác.

Các containers có thể được chuyển thành hình ảnh mà bạn có thể sử dụng để xây dựng các containers mới. Hãy xem nó hoạt động như thế nào.

Bước 7 - Commit các thay đổi trong containers thành Docker image

Khi bạn khởi động Docker image , bạn có thể tạo, sửa đổi và xóa các file giống như bạn có thể làm với máy ảo. Những thay đổi bạn thực hiện sẽ chỉ áp dụng cho containers đó. Bạn có thể bắt đầu và dừng nó, nhưng một khi bạn xóa nó bằng lệnh docker rm , các thay đổi sẽ bị mất.

Phần này hướng dẫn bạn cách lưu trạng thái của containers dưới dạng Docker image mới.

Sau khi cài đặt Node.js bên trong containers Ubuntu, bây giờ bạn có một containers đang chạy trên một hình ảnh, nhưng containers khác với hình ảnh bạn đã sử dụng để tạo nó. Nhưng bạn có thể cần sử dụng lại containers Node.js này làm cơ sở cho các hình ảnh mới sau này.

Sau đó, commit các thay đổi đối với version Docker image mới bằng lệnh sau.

  • docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name

Lựa chọn -m dành cho thông báo commit giúp bạn và những người khác biết bạn đã thực hiện những thay đổi nào, trong khi -a được sử dụng để chỉ định tác giả. container_id là cái bạn đã lưu ý trước đó trong hướng dẫn khi bạn bắt đầu phiên Docker tương tác. Trừ khi bạn tạo thêm repository trên Docker Hub, repository thường là tên user Docker Hub của bạn.

Ví dụ: đối với sammy user , với ID containers là d9b100f2f636 , lệnh sẽ là:

  • docker commit -m "added Node.js" -a "sammy" d9b100f2f636 sammy/ubuntu-nodejs

Khi bạn commit một hình ảnh, hình ảnh mới sẽ được lưu local trên máy tính của bạn. Phần sau của hướng dẫn này, bạn sẽ học cách đẩy hình ảnh vào register Docker như Docker Hub để những người khác có thể truy cập vào nó.

Liệt kê các Docker image sẽ hiển thị hình ảnh mới, cũng như hình ảnh cũ mà nó được kế thừa từ :

  • docker images

Bạn sẽ thấy kết quả như thế này:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE sammy/ubuntu-nodejs latest 7c1f35226ca6 7 seconds ago 179MB ...

Trong ví dụ này, ubuntu-nodejs là hình ảnh mới, được lấy từ hình ảnh ubuntu hiện có từ Docker Hub. Sự khác biệt về kích thước phản ánh những thay đổi đã được thực hiện. Và trong ví dụ này, thay đổi là NodeJS đã được cài đặt. Vì vậy, lần tới khi bạn cần chạy containers bằng Ubuntu với NodeJS được cài đặt sẵn, bạn chỉ có thể sử dụng hình ảnh mới.

Bạn cũng có thể tạo Hình ảnh từ Dockerfile , cho phép bạn tự động cài đặt phần mềm trong một hình ảnh mới. Tuy nhiên, điều đó nằm ngoài phạm vi của hướng dẫn này.

Bây giờ hãy chia sẻ hình ảnh mới với những người khác để họ có thể tạo containers từ nó.

Bước 8 - Đẩy Docker image vào Kho lưu trữ Docker

Bước hợp lý tiếp theo sau khi tạo một hình ảnh mới từ một hình ảnh hiện có là chia sẻ nó với một vài người bạn được chọn của bạn, cả thế giới trên Docker Hub hoặc register Docker khác mà bạn có quyền truy cập. Để đẩy một hình ảnh lên Docker Hub hoặc tổ chức đăng ký Docker nào khác, bạn phải có account ở đó.

Phần này hướng dẫn bạn cách đẩy một Docker image vào Docker Hub. Để tìm hiểu cách tạo register Docker riêng của bạn, hãy xem Cách cài đặt register Docker riêng trên Ubuntu 14.04 .

Để đẩy hình ảnh của bạn, trước tiên hãy đă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 password Docker Hub của bạn . Nếu bạn chỉ định password chính xác, xác thực sẽ thành công.

Lưu ý: Nếu tên user đăng ký Docker của bạn khác với tên user local bạn đã sử dụng để tạo hình ảnh, bạn sẽ phải gắn thẻ hình ảnh của bạn bằng tên user đăng ký. Đối với ví dụ được đưa ra trong bước cuối cùng, bạn sẽ nhập:

  • docker tag sammy/ubuntu-nodejs docker-registry-username/ubuntu-nodejs

Sau đó, bạn có thể đẩy hình ảnh của riêng mình bằng cách sử dụng:

  • docker push docker-registry-username/docker-image-name

Để đẩy hình ảnh ubuntu-nodejs vào repository sammy , lệnh sẽ là:

  • docker push sammy/ubuntu-nodejs

Quá trình này có thể mất một chút thời gian để hoàn thành vì quá trình tải hình ảnh lên, nhưng khi hoàn tất, kết quả 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 hình ảnh vào register , hình ảnh đó sẽ được liệt kê trên trang tổng quan của account của bạn, giống như hiển thị trong hình ảnh bên dưới.

Danh sách  Docker image  mới trên Docker Hub

Nếu một việc push dẫn đến lỗi thuộc loại này, thì có thể bạn đã không đă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

Đăng nhập bằng docker login và lặp lại việc push . Sau đó, xác minh nó tồn tại trên trang repository Docker Hub của bạn.

Đến đây bạn có thể sử dụng docker pull sammy / ubuntu-nodejs để kéo hình ảnh sang một máy mới và sử dụng nó để chạy một containers mới.

Kết luận

Trong hướng dẫn này, bạn đã cài đặt Docker, làm việc với hình ảnh và containers cũng như đẩy hình ảnh đã sửa đổi vào Docker Hub. Đến đây bạn đã biết những điều cơ bản, hãy khám phá các hướng dẫn Docker khác trong Cộng đồng DigitalOcean.


Tags:

Các tin liên quan

Cách cài đặt và thiết lập Laravel với Docker Compose trên Ubuntu 20.04
2020-06-09
Cách cài đặt và sử dụng Docker Compose trên Ubuntu 20.04
2020-06-05
Cách chia sẻ dữ liệu giữa các container Docker
2020-05-21
Cách sử dụng Traefik 1.7.21 làm Reverse Proxy cho Docker Containers trên CentOS 7
2020-05-12
Cách cài đặt Drupal với Docker Compose
2020-04-25
Cách xây dựng và triển khai ứng dụng Flask bằng Docker trên Ubuntu 18.04
2020-04-05
Como Conteinerizar um aplicativo Laravel para desenvolvimento com o Docker Compose em Ubuntu 18.04
2020-02-20
Cách tạo ứng dụng Node.js với Docker [Quickstart]
2020-02-06
Cách cài đặt Docker Compose trên Debian 10
2020-01-30
Cách chứa một ứng dụng Laravel để phát triển với Docker Compose trên Ubuntu 18.04
2020-01-23