CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Trang chủHướng dẫnCách cài đặt và thiết lập Laravel với Docker Compose trên Ubuntu 20.04

Cách cài đặt và thiết lập Laravel với Docker Compose trên Ubuntu 20.04

CyStack blog 16 phút để đọc
CyStack blog03/10/2025
Reading Time: 16 minutes

Container hóa một ứng dụng có nghĩa là quá trình điều chỉnh một ứng dụng và các thành phần của nó để có thể chạy trong những môi trường nhẹ gọi là container. Các môi trường này được cách ly và có thể loại bỏ dễ dàng, đồng thời có thể được tận dụng cho việc phát triển, kiểm thử và triển khai ứng dụng lên môi trường production.

Cài đặt Laravel trên Ubuntu 20.04

Trong hướng dẫn này, chúng ta sẽ sử dụng Docker Compose để container hóa một ứng dụng Laravel phục vụ cho việc phát triển. Sau khi hoàn thành, bạn sẽ có một ứng dụng Laravel demo chạy trên ba container dịch vụ riêng biệt:

  • Một app service chạy PHP 7.4-FPM;
  • Một db service chạy MySQL 5.7;
  • Một nginx service sử dụng app service để phân tích mã PHP trước khi phục vụ ứng dụng Laravel đến người dùng cuối.

Để quá trình phát triển diễn ra trơn tru và dễ dàng debug ứng dụng, chúng ta sẽ giữ cho các tệp của ứng dụng luôn đồng bộ bằng cách sử dụng shared volumes. Chúng ta cũng sẽ tìm hiểu cách sử dụng lệnh docker-compose exec để chạy Composer và Artisan trên container app.

Điều kiện tiên quyết

  • Cần có quyền truy cập vào máy cục bộ hoặc máy chủ phát triển chạy Ubuntu 20.04 với người dùng không phải root nhưng có quyền sudo. Nếu bạn sử dụng máy chủ từ xa, nên cài đặt tường lửa đang hoạt động. Để thiết lập các yêu cầu này, vui lòng tham khảo Hướng dẫn Cài đặt Máy chủ Ban đầu cho Ubuntu 20.04.
  • Docker phải được cài đặt trên máy chủ của bạn, theo Bước 1 và 2 của hướng dẫn Cách Cài đặt và Sử dụng Docker trên Ubuntu 20.04.
  • Docker Compose cũng phải được cài đặt trên máy chủ của bạn, theo Bước 1 của hướng dẫn Cách Cài đặt và Sử dụng Docker Compose trên Ubuntu 20.04.

Bước 1 – Lấy ứng dụng demo

Đầu tiên, chúng ta sẽ tải ứng dụng demo Laravel từ kho lưu trữ Github của nó. Chúng ta sẽ quan tâm đến nhánh tutorial-01, nhánh này chứa ứng dụng Laravel cơ bản mà chúng ta đã tạo trong hướng dẫn đầu tiên của loạt bài này.

Để có được mã ứng dụng tương thích với hướng dẫn này, hãy tải bản phát hành tutorial-1.0.1 về thư mục home của bạn bằng lệnh:

$ cd ~
$ curl -L <https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip> -o travellist.zip

Chúng ta sẽ cần lệnh unzip để giải nén mã nguồn của ứng dụng. Trong trường hợp bạn chưa cài đặt gói này trước đó, hãy thực hiện cài đặt ngay với lệnh:

$ sudo apt update
$ sudo apt install unzip

Bây giờ, hãy giải nén nội dung của ứng dụng và đổi tên thư mục vừa giải nén để dễ dàng truy cập hơn:

$ unzip travellist.zip
$ mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo

Di chuyển đến thư mục travellist-demo:

$ cd travellist-demo

Trong bước tiếp theo, chúng ta sẽ tạo một tệp cấu hình .env để thiết lập ứng dụng.

Bước 2 – Thiết lập tệp .env của ứng dụng

Các tệp cấu hình của Laravel nằm trong một thư mục có tên config, bên trong thư mục gốc của ứng dụng. Ngoài ra, một tệp .env được sử dụng để thiết lập các cấu hình phụ thuộc vào môi trường, chẳng hạn như thông tin đăng nhập và bất kỳ dữ liệu nào có thể thay đổi giữa các lần triển khai. Tệp này không được đưa vào hệ thống quản lý phiên bản.

⚠️ Cảnh báo: Tệp cấu hình môi trường chứa thông tin nhạy cảm về máy chủ của bạn, bao gồm thông tin đăng nhập cơ sở dữ liệu và các khóa bảo mật. Vì lý do đó, bạn không bao giờ nên chia sẻ công khai tệp này.

Các giá trị trong tệp .env sẽ có ưu tiên cao hơn so với các giá trị được thiết lập trong các tệp cấu hình thông thường nằm trong thư mục config. Mỗi lần cài đặt trên một môi trường mới sẽ yêu cầu một tệp môi trường được tùy chỉnh riêng để định nghĩa các thông số như cài đặt kết nối cơ sở dữ liệu, tùy chọn debug, URL của ứng dụng và nhiều mục khác có thể thay đổi tùy thuộc vào môi trường mà ứng dụng đang chạy.

Bây giờ, chúng ta sẽ tạo một tệp .env mới để tùy chỉnh các tùy chọn cấu hình cho môi trường phát triển mà chúng ta đang thiết lập. Laravel đi kèm với một tệp example.env, chúng ta có thể sao chép tệp này để tạo tệp ****.env của riêng mình:

$ cp .env.example .env

Mở tệp này bằng nano hoặc trình soạn thảo văn bản mà bạn chọn:

$ nano .env

Tệp .env hiện tại của ứng dụng demo travellist chứa các thiết lập để sử dụng cơ sở dữ liệu MySQL cục bộ, với 127.0.0.1 làm máy chủ cơ sở dữ liệu. Chúng ta cần cập nhật biến DB_HOST để nó trỏ đến dịch vụ cơ sở dữ liệu mà chúng ta sẽ tạo trong môi trường Docker. Trong hướng dẫn này, chúng ta sẽ gọi dịch vụ cơ sở dữ liệu là db. Hãy thay giá trị được liệt kê của DB_HOST bằng tên dịch vụ cơ sở dữ liệu.

.env
APP_NAME=Travellist
APP_ENV=dev
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=travellist
DB_USERNAME=travellist_user
DB_PASSWORD=password
...

Bạn cũng có thể thay đổi tên cơ sở dữ liệu, tên người dùng và mật khẩu nếu muốn. Những biến này sẽ được sử dụng ở bước sau, khi chúng ta thiết lập tệp docker-compose.yml để cấu hình các dịch vụ.

Hãy lưu tệp lại sau khi chỉnh sửa xong. Nếu bạn dùng nano, bạn có thể lưu bằng cách nhấn Ctrl+x, sau đó YEnter để xác nhận.

Bước 3 – Thiết lập Dockerfile cho ứng dụng

Mặc dù cả dịch vụ MySQL và Nginx của chúng ta sẽ dựa trên các image mặc định lấy từ Docker Hub, nhưng chúng ta vẫn cần xây dựng một image tùy chỉnh cho container của ứng dụng. Chúng ta sẽ tạo một Dockerfile mới cho việc này.

Image travellist của chúng ta sẽ dựa trên image chính thức php:7.4-fpm từ Docker Hub. Trên môi trường PHP-FPM cơ bản đó, chúng ta sẽ cài đặt thêm một vài module PHP và công cụ quản lý dependency Composer.

Chúng ta cũng sẽ tạo một người dùng hệ thống mới; điều này cần thiết để thực thi các lệnh artisancomposer trong quá trình phát triển ứng dụng. Thiết lập uid đảm bảo rằng người dùng bên trong container có cùng uid với người dùng hệ thống trên máy host, nơi bạn đang chạy Docker. Bằng cách này, bất kỳ tệp nào được tạo ra bởi các lệnh đó sẽ được phản chiếu trong host với quyền hạn chính xác. Điều này cũng có nghĩa là bạn có thể dùng trình soạn thảo mã ưa thích trên máy host để phát triển ứng dụng đang chạy bên trong container.

Tạo một Dockerfile mới với:

$ nano Dockerfile

Sao chép nội dung sau vào tệp Dockerfile của bạn:

Dockerfile
FROM php:7.4-fpm

# Arguments defined in docker-compose.yml
ARG user
ARG uid

# Install system dependencies
RUN apt-get update && apt-get install -y \\
    git \\
    curl \\
    libpng-dev \\
    libonig-dev \\
    libxml2-dev \\
    zip \\
    unzip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \\
    chown -R $user:$user /home/$user

# Set working directory
WORKDIR /var/www

USER $user

Đừng quên lưu tệp sau khi bạn hoàn tất.

Dockerfile của chúng ta bắt đầu bằng cách xác định image cơ sở mà chúng ta đang sử dụng: php:7.4-fpm.

Sau khi cài đặt các gói hệ thống và các extension PHP, chúng ta cài đặt Composer bằng cách sao chép file thực thi composer từ image chính thức mới nhất sang image ứng dụng của chúng ta.

Một người dùng hệ thống mới sau đó được tạo và thiết lập bằng cách sử dụng các tham số useruid đã được khai báo ở đầu Dockerfile. Những giá trị này sẽ được Docker Compose chèn vào trong quá trình build.

Cuối cùng, chúng ta đặt thư mục làm việc mặc định là /var/www và chuyển sang người dùng mới tạo. Điều này sẽ đảm bảo rằng bạn đang kết nối với tư cách là một người dùng bình thường, và bạn đang ở đúng thư mục khi chạy các lệnh composerartisan trong container của ứng dụng.

Bước 4 – Thiết lập cấu hình Nginx và các tệp Database Dump

Khi tạo môi trường phát triển với Docker Compose, thường cần phải chia sẻ các tệp cấu hình hoặc tệp khởi tạo với các service container, để thiết lập hoặc khởi động các dịch vụ đó. Thực hành này giúp dễ dàng thay đổi các tệp cấu hình nhằm tinh chỉnh môi trường trong khi bạn đang phát triển ứng dụng.

Bây giờ chúng ta sẽ thiết lập một thư mục chứa các tệp sẽ được dùng để cấu hình và khởi tạo các service container.

Để thiết lập Nginx, chúng ta sẽ chia sẻ một tệp travellist.conf dùng để cấu hình cách ứng dụng được phục vụ. Hãy tạo thư mục docker-compose/nginx bằng lệnh:

$ mkdir -p docker-compose/nginx

Mở một tệp mới có tên travellist.conf trong thư mục đó:

$ nano docker-compose/nginx/travellist.conf

Sao chép cấu hình Nginx sau vào tệp đó:

docker-compose/nginx/travellist.conf

server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;
    location ~ \\.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

Tệp này sẽ cấu hình Nginx lắng nghe trên cổng 80 và sử dụng index.php làm trang mặc định. Nó sẽ đặt thư mục gốc tài liệu thành /var/www/public, sau đó cấu hình Nginx để sử dụng dịch vụ app trên cổng 9000 để xử lý các tệp *.php.

Hãy lưu và đóng tệp sau khi bạn chỉnh sửa xong.

Để thiết lập cơ sở dữ liệu MySQL, chúng ta sẽ chia sẻ một bản dump của cơ sở dữ liệu, bản này sẽ được import khi container được khởi tạo. Đây là một tính năng do image MySQL 5.7 mà chúng ta sẽ sử dụng trong container đó cung cấp.

Tạo một thư mục mới cho các tệp khởi tạo MySQL của bạn bên trong thư mục docker-compose:

$ mkdir docker-compose/mysql

Mở một tệp .sql mới:

$ nano docker-compose/mysql/init_db.sql

Bản dump MySQL sau đây dựa trên cơ sở dữ liệu mà chúng ta đã thiết lập trong hướng dẫn Laravel trên LEMP. Nó sẽ tạo một bảng mới có tên places. Sau đó, bảng này sẽ được điền dữ liệu với một tập hợp các địa điểm mẫu.

Thêm đoạn mã sau vào tệp:

docker-compose/mysql/db_init.sql
DROP TABLE IF EXISTS `places`;

CREATE TABLE `places` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `visited` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);

Bảng places chứa ba trường: id, name, và visited. Trường visited là một cờ (flag) được dùng để xác định những địa điểm vẫn chưa đi. Bạn có thể thoải mái thay đổi các địa điểm mẫu hoặc thêm địa điểm mới. Hãy lưu và đóng tệp sau khi bạn chỉnh sửa xong.

Chúng ta đã hoàn tất việc thiết lập Dockerfile của ứng dụng và các tệp cấu hình dịch vụ. Tiếp theo, chúng ta sẽ thiết lập Docker Compose để sử dụng các tệp này khi tạo ra các dịch vụ.

Bước 5 – Tạo môi trường đa-container với Docker Compose

Docker Compose cho phép bạn tạo môi trường đa-container cho các ứng dụng chạy trên Docker. Nó sử dụng các định nghĩa dịch vụ để xây dựng môi trường tùy chỉnh hoàn chỉnh với nhiều container có thể chia sẻ mạng và các volume dữ liệu. Điều này cho phép tích hợp liền mạch giữa các thành phần của ứng dụng.

Để thiết lập các định nghĩa dịch vụ, chúng ta sẽ tạo một tệp mới có tên docker-compose.yml. Thông thường, tệp này được đặt ở thư mục gốc của ứng dụng, và nó định nghĩa môi trường container hóa của bạn, bao gồm các image cơ sở được dùng để xây dựng container, và cách các dịch vụ tương tác với nhau.

Chúng ta sẽ định nghĩa ba dịch vụ khác nhau trong tệp docker-compose.yml: app, db, và nginx.

Dịch vụ app sẽ build một image có tên travellist, dựa trên Dockerfile mà chúng ta đã tạo trước đó. Container được định nghĩa bởi dịch vụ này sẽ chạy một máy chủ php-fpm để phân tích mã PHP và gửi kết quả trở lại dịch vụ nginx, vốn sẽ chạy trong một container riêng biệt. Dịch vụ mysql sẽ định nghĩa một container chạy máy chủ MySQL 5.7. Các dịch vụ của chúng ta sẽ chia sẻ một mạng bridge có tên travellist.

Các tệp của ứng dụng sẽ được đồng bộ trên cả dịch vụ appnginx thông qua bind mounts. Bind mounts rất hữu ích trong môi trường phát triển vì chúng cho phép đồng bộ hai chiều hiệu quả giữa máy host và container.

Hãy tạo một tệp docker-compose.yml mới ở thư mục gốc của ứng dụng:

$ nano docker-compose.yml

Một tệp docker-compose.yml điển hình sẽ bắt đầu với phần khai báo phiên bản, tiếp theo là một node services, trong đó tất cả các dịch vụ được định nghĩa. Các mạng dùng chung thường được khai báo ở cuối tệp.

Để bắt đầu, hãy sao chép đoạn mã mẫu sau vào tệp docker-compose.yml của bạn:

docker-compose.yml
version: "3.7"
services:

networks:
  travellist:
    driver: bridge

Bây giờ chúng ta sẽ chỉnh sửa node services để bao gồm các dịch vụ app, dbnginx.

Dịch vụ app

Dịch vụ app sẽ thiết lập một container có tên travellist-app. Nó build một Docker image mới dựa trên Dockerfile nằm cùng đường dẫn với tệp docker-compose.yml. Image mới này sẽ được lưu cục bộ với tên travellist.

Mặc dù thư mục gốc của ứng dụng (document root) được phục vụ nằm trong container nginx, nhưng chúng ta vẫn cần có các tệp ứng dụng bên trong container app, để có thể thực thi các tác vụ dòng lệnh với công cụ Laravel Artisan.

Hãy sao chép định nghĩa dịch vụ sau vào dưới node services, bên trong tệp docker-compose.yml

docker-compose.yml
  app:
    build:
      args:
        user: sammy
        uid: 1000
      context: ./
      dockerfile: Dockerfile
    image: travellist
    container_name: travellist-app
    restart: unless-stopped
    working_dir: /var/www/
    volumes:
      - ./:/var/www
    networks:
      - travellist

Các thiết lập này thực hiện những việc sau:

  • build: Cấu hình này yêu cầu Docker Compose build một image cục bộ cho dịch vụ app, sử dụng đường dẫn (context) được chỉ định và Dockerfile làm hướng dẫn. Các tham số useruid được truyền vào Dockerfile để tùy chỉnh lệnh tạo user trong lúc build.
  • image: Tên sẽ được sử dụng cho image được build.
  • container_name: Đặt tên container cho dịch vụ này.
  • restart: Luôn khởi động lại, trừ khi dịch vụ bị dừng.
  • working_dir: Đặt thư mục mặc định cho dịch vụ này là /var/www.
  • volumes: Tạo một volume chia sẻ để đồng bộ nội dung từ thư mục hiện tại sang /var/www bên trong container. Lưu ý rằng đây không phải là document root của bạn, vì document root sẽ nằm trong container nginx.
  • networks: Thiết lập dịch vụ này sử dụng một mạng có tên travellist.

Dịch vụ db

Dịch vụ db sử dụng image MySQL 5.7 dựng sẵn từ Docker Hub. Vì Docker Compose tự động tải các tệp biến .env nằm cùng thư mục với tệp docker-compose.yml, chúng ta có thể lấy các thiết lập cơ sở dữ liệu từ tệp .env của Laravel đã tạo ở bước trước.

Thêm định nghĩa dịch vụ sau vào trong node services, ngay sau dịch vụ app:

docker-compose.yml
  db:
    image: mysql:5.7
    container_name: travellist-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./docker-compose/mysql:/docker-entrypoint-initdb.d
    networks:
      - travellist

Các thiết lập này thực hiện những việc sau:

  • image: Xác định Docker image sẽ được sử dụng cho container này. Trong trường hợp này, chúng ta dùng image MySQL 5.7 từ Docker Hub.
  • container_name: Thiết lập tên container cho dịch vụ này: travellist-db.
  • restart: Luôn khởi động lại dịch vụ này, trừ khi nó bị dừng thủ công.
  • environment: Định nghĩa các biến môi trường trong container mới. Chúng ta sử dụng các giá trị lấy từ tệp .env của Laravel để thiết lập dịch vụ MySQL, dịch vụ này sẽ tự động tạo một cơ sở dữ liệu và người dùng mới dựa trên các biến môi trường đã cung cấp.
  • volumes: Tạo một volume để chia sẻ file dump .sql, file này sẽ được dùng để khởi tạo cơ sở dữ liệu của ứng dụng. Image MySQL sẽ tự động import các file .sql được đặt trong thư mục /docker-entrypoint-initdb.d bên trong container.
  • networks: Thiết lập dịch vụ này để sử dụng một mạng có tên travellist.

Dịch vụ nginx

Dịch vụ nginx sử dụng image Nginx dựng sẵn trên nền Alpine, một bản phân phối Linux nhẹ. Nó tạo một container có tên travellist-nginx, và sử dụng phần khai báo ports để tạo chuyển hướng từ cổng 8000 trên máy host sang cổng 80 bên trong container.

Hãy thêm định nghĩa dịch vụ sau vào trong node services, ngay sau dịch vụ db:

docker-compose.yml
  nginx:
    image: nginx:1.17-alpine
    container_name: travellist-nginx
    restart: unless-stopped
    ports:
      - 8000:80
    volumes:
      - ./:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d
    networks:
      - travellist

Các thiết lập này thực hiện những việc sau:

  • image: Xác định Docker image sẽ được sử dụng cho container này. Trong trường hợp này, chúng ta sử dụng image Alpine Nginx 1.17.
  • container_name: Thiết lập tên container cho dịch vụ này: travellist-nginx.
  • restart: Luôn khởi động lại dịch vụ này, trừ khi nó bị dừng thủ công.
  • ports: Thiết lập chuyển hướng cổng cho phép truy cập từ bên ngoài qua cổng 8000 đến máy chủ web chạy trên cổng 80 bên trong container.
  • volumes: Tạo hai volume chia sẻ. Volume thứ nhất sẽ đồng bộ nội dung từ thư mục hiện tại sang /var/www bên trong container. Nhờ vậy, khi bạn thay đổi các tệp ứng dụng cục bộ, chúng sẽ được phản ánh nhanh chóng trong ứng dụng được Nginx phục vụ bên trong container. Volume thứ hai đảm bảo tệp cấu hình Nginx của chúng ta, nằm tại docker-compose/nginx/travellist.conf, được sao chép vào thư mục cấu hình Nginx trong container.
  • networks: Thiết lập dịch vụ này để sử dụng một mạng có tên travellist.

Tệp docker-compose.yml hoàn chỉnh

Đây là cách tệp docker-compose.yml hoàn chỉnh của chúng ta trông như sau:

docker-compose.yml
version: "3.7"
services:
  app:
    build:
      args:
        user: sammy
        uid: 1000
      context: ./
      dockerfile: Dockerfile
    image: travellist
    container_name: travellist-app
    restart: unless-stopped
    working_dir: /var/www/
    volumes:
      - ./:/var/www
    networks:
      - travellist

  db:
    image: mysql:5.7
    container_name: travellist-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./docker-compose/mysql:/docker-entrypoint-initdb.d
    networks:
      - travellist

  nginx:
    image: nginx:alpine
    container_name: travellist-nginx
    restart: unless-stopped
    ports:
      - 8000:80
    volumes:
      - ./:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d/
    networks:
      - travellist

networks:
  travellist:
    driver: bridge

Hãy đảm bảo rằng bạn lưu tệp sau khi hoàn tất.

Bước 6 – Chạy ứng dụng với Docker Compose

Bây giờ chúng ta sẽ sử dụng các lệnh docker-compose để build image của ứng dụng và chạy các dịch vụ mà chúng ta đã cấu hình.

Build image của app với lệnh sau:

$ docker-compose build app

Lệnh này có thể mất vài phút để hoàn tất. Bạn sẽ thấy phần output tương tự như sau:

Output
Building app
Step 1/11 : FROM php:7.4-fpm
 ---> fa37bd6db22a
Step 2/11 : ARG user
 ---> Running in f71eb33b7459
Removing intermediate container f71eb33b7459
 ---> 533c30216f34
Step 3/11 : ARG uid
 ---> Running in 60d2d2a84cda
Removing intermediate container 60d2d2a84cda
 ---> 497fbf904605
Step 4/11 : RUN apt-get update && apt-get install -y     git     curl     libpng-dev     libonig-dev     ...
Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
 ---> e499f74896e3
Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user
 ---> Running in 232ef9c7dbd1
Removing intermediate container 232ef9c7dbd1
 ---> 870fa3220ffa
Step 9/11 : RUN mkdir -p /home/$user/.composer &&     chown -R $user:$user /home/$user
 ---> Running in 7ca8c0cb7f09
Removing intermediate container 7ca8c0cb7f09
 ---> 3d2ef9519a8e
Step 10/11 : WORKDIR /var/www
 ---> Running in 4a964f91edfa
Removing intermediate container 4a964f91edfa
 ---> 00ada639da21
Step 11/11 : USER $user
 ---> Running in 9f8e874fede9
Removing intermediate container 9f8e874fede9
 ---> fe176ff4702b

Successfully built fe176ff4702b
Successfully tagged travellist:latest

Khi quá trình build hoàn tất, bạn có thể chạy môi trường ở chế độ nền với lệnh:

$ docker-compose up -d
Output
Creating travellist-db    ... done
Creating travellist-app   ... done
Creating travellist-nginx ... done

Lệnh này sẽ chạy các container của bạn ở chế độ nền. Để hiển thị thông tin về trạng thái của các dịch vụ đang hoạt động, hãy chạy lệnh:

$ docker-compose ps

Bạn sẽ thấy phần output giống như sau:

Output
      Name                    Command               State          Ports        
--------------------------------------------------------------------------------
travellist-app     docker-php-entrypoint php-fpm    Up      9000/tcp            
travellist-db      docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp 
travellist-nginx   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8000->80/tcp

Môi trường của bạn hiện đã được khởi động và chạy, nhưng chúng ta vẫn cần thực thi thêm một vài lệnh để hoàn tất việc thiết lập ứng dụng. Bạn có thể sử dụng lệnh docker-compose exec để chạy các lệnh bên trong các service container, ví dụ như ls -l để hiển thị thông tin chi tiết về các tệp trong thư mục của ứng dụng:

$ docker-compose exec app ls -l
Output
total 260
-rw-rw-r--  1 sammy sammy    737 Jun  9 11:19 Dockerfile
-rw-rw-r--  1 sammy sammy    101 Jan  7 08:05 README.md
drwxrwxr-x  6 sammy sammy   4096 Jan  7 08:05 app
-rwxr-xr-x  1 sammy sammy   1686 Jan  7 08:05 artisan
drwxrwxr-x  3 sammy sammy   4096 Jan  7 08:05 bootstrap
-rw-rw-r--  1 sammy sammy   1501 Jan  7 08:05 composer.json
-rw-rw-r--  1 sammy sammy 179071 Jan  7 08:05 composer.lock
drwxrwxr-x  2 sammy sammy   4096 Jan  7 08:05 config
drwxrwxr-x  5 sammy sammy   4096 Jan  7 08:05 database
drwxrwxr-x  4 sammy sammy   4096 Jun  9 11:19 docker-compose
-rw-rw-r--  1 sammy sammy    965 Jun  9 11:27 docker-compose.yml
-rw-rw-r--  1 sammy sammy   1013 Jan  7 08:05 package.json
-rw-rw-r--  1 sammy sammy   1405 Jan  7 08:05 phpunit.xml
drwxrwxr-x  2 sammy sammy   4096 Jan  7 08:05 public
-rw-rw-r--  1 sammy sammy    273 Jan  7 08:05 readme.md
drwxrwxr-x  6 sammy sammy   4096 Jan  7 08:05 resources
drwxrwxr-x  2 sammy sammy   4096 Jan  7 08:05 routes
-rw-rw-r--  1 sammy sammy    563 Jan  7 08:05 server.php
drwxrwxr-x  5 sammy sammy   4096 Jan  7 08:05 storage
drwxrwxr-x  4 sammy sammy   4096 Jan  7 08:05 tests
drwxrwxr-x 41 sammy sammy   4096 Jun  9 11:32 vendor
-rw-rw-r--  1 sammy sammy    538 Jan  7 08:05 webpack.mix.js

Bây giờ chúng ta sẽ chạy composer install để cài đặt các dependency của ứng dụng:

$ docker-compose exec app composer install

Bạn sẽ thấy phần output giống như sau:

Output
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 85 installs, 0 updates, 0 removals
  - Installing doctrine/inflector (1.3.1): Downloading (100%)         
  - Installing doctrine/lexer (1.2.0): Downloading (100%)         
  - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%)         
  - Installing erusev/parsedown (1.7.4): Downloading (100%)         
  - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%)         
  - Installing phpoption/phpoption (1.7.2): Downloading (100%)         
  - Installing vlucas/phpdotenv (v3.6.0): Downloading (100%)         
  - Installing symfony/css-selector (v5.0.2): Downloading (100%)             
…
Generating optimized autoload files
> Illuminate\\Foundation\\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

Điều cuối cùng chúng ta cần làm trước khi kiểm thử ứng dụng là tạo một khóa ứng dụng (application key) duy nhất bằng công cụ dòng lệnh artisan của Laravel. Khóa này được sử dụng để mã hóa phiên làm việc của người dùng và các dữ liệu nhạy cảm khác:

$ docker-compose exec app php artisan key:generate
Output
Application key set successfully.

Bây giờ, hãy mở trình duyệt và truy cập tên miền hoặc địa chỉ IP của máy chủ của bạn trên cổng 8000:

http://server_domain_or_IP:8000

Lưu ý: Trong trường hợp bạn đang chạy bản demo này trên máy cục bộ, hãy dùng http://localhost:8000 để truy cập ứng dụng từ trình duyệt của bạn.

Bạn sẽ thấy một trang giống như sau:

Bạn có thể sử dụng lệnh logs để kiểm tra các log được tạo ra bởi các dịch vụ của bạn:

$ docker-compose logs nginx
Attaching to travellist-nginx
…
travellist-nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
travellist-nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:34 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:35 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"

Nếu bạn muốn tạm dừng môi trường Docker Compose của mình nhưng vẫn giữ nguyên trạng thái của tất cả các dịch vụ, hãy chạy lệnh:

$ docker-compose pause
Output
Pausing travellist-db    ... done
Pausing travellist-nginx ... done
Pausing travellist-app   ... done

Sau đó, bạn có thể tiếp tục các dịch vụ của mình với lệnh:

$ docker-compose unpause
Output
Unpausing travellist-app   ... done
Unpausing travellist-nginx ... done
Unpausing travellist-db    ... done

Để tắt môi trường Docker Compose của bạn và xóa tất cả các container, network và volume của nó, hãy chạy lệnh:

$ docker-compose down
Output
Stopping travellist-nginx ... done
Stopping travellist-db    ... done
Stopping travellist-app   ... done
Removing travellist-nginx ... done
Removing travellist-db    ... done
Removing travellist-app   ... done
Removing network travellist-laravel-demo_travellist

Để có cái nhìn tổng quan về tất cả các lệnh của Docker Compose, vui lòng tham khảo tài liệu tham chiếu dòng lệnh Docker Compose.

Kết luận

Trong hướng dẫn này, chúng ta đã thiết lập một môi trường Docker với ba container bằng cách sử dụng Docker Compose để định nghĩa hạ tầng trong một tệp YAML.

Từ đây, bạn có thể làm việc trên ứng dụng Laravel của mình mà không cần phải cài đặt và thiết lập máy chủ web cục bộ cho việc phát triển và kiểm thử. Hơn nữa, bạn sẽ làm việc với một môi trường có thể loại bỏ (disposable environment), dễ dàng được sao chép và phân phối, điều này rất hữu ích trong quá trình phát triển ứng dụng cũng như khi triển khai sang môi trường sản xuất.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất