Reading Time: 15 minutes

Container hóa một ứng dụng là quá trình đóng gói ứng dụng cùng tất cả các thành phần phụ thuộc (mã nguồn, thư viện, framework, runtime, v.v.) vào các môi trường độc lập được gọi là container. Những môi trường này được cách ly và dễ dàng thay thế, và có thể được tận dụng để phát triển, kiểm thử và triển khai ứng dụng ra môi trường production.

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

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

Để cho phép một quy trình phát triển hợp lý và tạo điều kiện thuận lợi cho việc gỡ lỗi ứng dụng, chúng ta sẽ giữ các tệp ứng dụng đồng bộ bằng cách sử dụng shared volumes. Chúng ta cũng sẽ xem xét cách sử dụng các lệnh docker-compose exec để chạy ComposerArtisan trên container app.

Chuẩn bị

Để thực hiện theo hướng dẫn này, bạn cần:

  • Truy cập máy chủ Ubuntu 22.04 với người dùng không phải root và quyền sudo.
  • Cài đặt Docker trên máy chủ của bạn.
  • Cài đặt Docker Compose trên máy chủ của bạn.

Bước 1: Tải ứng dụng Demo

Để bắt đầu, chúng ta sẽ tải ứng dụng Laravel demo từ kho lưu trữ GitHub của nó. Chúng ta quan tâm đến nhánh tutorial-01.

Để lấy 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 chính 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ã ứng dụng. Nếu bạn chưa cài đặt gói này trước đây, hãy cài đặt ngay bây giờ bằng lệnh:

sudo apt update
sudo apt install unzip

Bây giờ, hãy giải nén nội dung ứng dụng và đổi tên thư mục đã 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

Điều hướng đế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ấu hình môi trường, chẳng hạn như thông tin đăng nhập và bất kỳ thông tin nào có thể thay đổi giữa các lần triển khai.

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à khóa bảo mật. Vì lý do đó, bạn không bao giờ nên chia sẻ tệp này công khai.

Các giá trị trong tệp .env sẽ được ưu tiên hơn các giá trị được đặt 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 yêu cầu một tệp môi trường được tùy chỉnh để định nghĩa các thứ như cài đặt kết nối cơ sở dữ liệu, tùy chọn gỡ lỗi, URL ứng dụng, cùng với các 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 .env.example mà chúng ta có thể sao chép để tạo tệp 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 bạn chọn:

nano .env

Tệp .env hiện tại từ ứng dụng demo travellist chứa các cài đặt để 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 service cơ sở dữ liệu mà chúng ta sẽ tạo trong môi trường Docker của mình. Trong hướng dẫn này, chúng ta sẽ gọi service cơ sở dữ liệu của mình là db. Hãy thay thế giá trị của DB_HOST bằng tên service cơ sở dữ liệu:

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. Các biến này sẽ được sử dụng trong một bước sau, nơi chúng ta sẽ thiết lập tệp docker-compose.yml để cấu hình các service của mình.

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

Bước 3: Thiết lập Dockerfile của ứng dụng

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

Image travellist của chúng ta sẽ dựa trên image PHP chính thức php:7.4-fpm từ Docker Hub. Ngoài 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 là cần thiết để thực thi các lệnh artisancomposer khi phát triển ứng dụng. Cài đặt 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 của bạn trên máy chủ (host machine), nơi bạn đang chạy Docker. Bằng cách này, bất kỳ tệp nào được tạo bởi các lệnh này sẽ được sao chép vào host với quyền chính xác. Điều này cũng có nghĩa là bạn sẽ có thể sử dụng trình soạn thảo mã bạn chọn 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 Dockerfile của bạn:

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 khi bạn đã hoàn tất.

Dockerfile của chúng ta bắt đầu bằng cách định nghĩa base image 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à phần mở rộng 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 của nó vào 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 đối số useruid đã được khai báo ở đầu Dockerfile. Các giá trị này sẽ được Docker Compose inject vào tại thời điểm 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 được tạo. Điều này sẽ đảm bảo bạn đang kết nối với tư cách một người dùng thông thường và bạn đang ở đúng thư mục khi chạy các lệnh composerartisan trên container ứng dụng.

Bước 4: Thiết lập cấu hình Nginx và tệp dump cơ sở dữ liệu

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 khởi tạo với các service container để thiết lập hoặc khởi động các service đó. Việc làm này giúp dễ dàng thực hiện các thay đổi đối với tệp cấu hình để tinh chỉnh môi trường của bạn 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 với các tệp sẽ được sử dụng để cấu hình và khởi tạo các service container của chúng ta.

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

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 đó:

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 index mặc định. Nó sẽ đặt root tài liệu là /var/www/public, và sau đó cấu hình Nginx để sử dụng service app trên cổng 9000 để xử lý các tệp *.php.

Lưu và đóng tệp 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ơ sở dữ liệu sẽ được import khi container được khởi tạo. Đây là một tính năng được cung cấp bởi image MySQL 5.7 mà chúng ta sẽ sử dụng trên container đó.

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 của chúng tôi. Nó sẽ tạo một bảng mới có tên places. Sau đó, nó sẽ điền vào bảng một tập hợp các địa điểm mẫu.

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

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ờ được sử dụng để xác định các địa điểm vẫn còn “cần đi”. Bạn có thể thay đổi các địa điểm mẫu hoặc thêm mới. Lưu và đóng tệp khi bạn hoàn tất.

Chúng ta đã hoàn thành việc thiết lập Dockerfile của ứng dụng và các tệp cấu hình service. 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 các service của mình.

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 service (service definitions) để xây dựng môi trường hoàn toàn tùy chỉnh với nhiều container có thể chia sẻ mạng và 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 ứng dụng.

Để thiết lập các định nghĩa service của chúng ta, 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 nằm ở thư mục gốc của thư mục ứng dụng và nó định nghĩa môi trường container hóa của bạn, bao gồm các base image mà bạn sẽ sử dụng để xây dựng các container của mình và cách các service của bạn sẽ tương tác.

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

Service app sẽ xây dựng 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 service này sẽ chạy một máy chủ php-fpm để phân tích cú pháp mã PHP và gửi kết quả trở lại service nginx, service này sẽ chạy trên một container riêng biệt. Service mysql định nghĩa một container chạy máy chủ MySQL 5.7. Các service của chúng ta sẽ chia sẻ một mạng bridge có tên travellist.

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

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

nano docker-compose.yml

Một tệp docker-compose.yml điển hình bắt đầu bằng định nghĩa phiên bản, theo sau là một node services, dưới đó tất cả các service được định nghĩa. Các mạng chia sẻ thường được định nghĩa ở cuối tệp đó.

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

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 service app, dbnginx.

Service app

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

Mặc dù root tài liệu được phục vụ làm ứng dụng nằm trong container nginx, chúng ta vẫn cần các tệp ứng dụng ở đâu đó 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.

Sao chép định nghĩa service sau vào node services của bạn, bên trong tệp 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 cài đặt này thực hiện những điều sau:

  • build: Cấu hình này yêu cầu Docker Compose xây dựng một image cục bộ cho service app, sử dụng đường dẫn (context) và Dockerfile được chỉ định để hướng dẫn. Các đối số useruid được inject vào Dockerfile để tùy chỉnh các lệnh tạo người dùng tại thời điểm build.
  • image: Tên sẽ được sử dụng cho image đang được xây dựng.
  • container_name: Đặt tên container cho service này.
  • restart: Luôn khởi động lại, trừ khi service bị dừng.
  • working_dir: Đặt thư mục mặc định cho service này là /var/www.
  • volumes: Tạo một volume chia sẻ sẽ đồng bộ hóa 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à root tài liệu của bạn, vì nó sẽ nằm trong container nginx.
  • networks: Thiết lập service này để sử dụng một mạng có tên travellist.

Service db

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

Bao gồm định nghĩa service sau trong node services của bạn, ngay sau service app:

db:
    image: mysql:8.0
    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 cài đặt này thực hiện những điều sau:

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

Service nginx

Service nginx sử dụng một image Nginx được xây dựng sẵn dựa trên Alpine, một bản phân phối Linux nhẹ. Nó tạo một container có tên travellist-nginx, và nó sử dụng định nghĩa ports để tạo một chuyển hướng từ cổng 8000 trên hệ thống host sang cổng 80 bên trong container.

Bao gồm định nghĩa service sau trong node services của bạn, ngay sau service db:

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 cài đặt này thực hiện những điều sau:

  • image: Định nghĩa Docker image sẽ được sử dụng cho container này. Trong trường hợp này, chúng ta đang sử dụng image Nginx 1.17 Alpine.
  • container_name: Đặt tên container cho service này: travellist-nginx.
  • restart: Luôn khởi động lại service này, trừ khi nó bị dừng rõ ràng.
  • ports: Thiết lập chuyển hướng cổng sẽ cho phép truy cập bên ngoài qua cổng 8000 đến máy chủ web đang chạy trên cổng 80 bên trong container.
  • volumes: Tạo hai volume chia sẻ. Volume đầu tiên sẽ đồng bộ hóa nội dung từ thư mục hiện tại sang /var/www bên trong container. Bằng cách này, khi bạn thực hiện các thay đổi cục bộ đối với tệp ứng dụng, chúng sẽ nhanh chóng được phản ánh trong ứng dụng đang được Nginx phục vụ bên trong container. Volume thứ hai sẽ đả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 của container.
  • networks: Thiết lập service này để sử dụng một mạng có tên travellist.

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

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

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:8.0
    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 chắc chắn bạn đã lưu tệp 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 để xây dựng image ứng dụng và chạy các service mà chúng ta đã chỉ định trong phần thiết lập của mình.

Xây dựng image app bằng lệnh sau:

docker-compose build app

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

OutputBuilding app
Sending build context to Docker daemon  377.3kB
Step 1/11 : FROM php:7.4-fpm
 ---> 8c08d993542f
Step 2/11 : ARG user
 ---> e3ce3af04d87
Step 3/11 : ARG uid
 ---> 30cb921ef7df
Step 4/11 : RUN apt-get update && apt-get install -y     git     curl     libpng-dev     libonig-dev     libxml2-dev     zip     unzip
. . .
 ---> b6dbc7a02e95
Step 5/11 : RUN apt-get clean && rm -rf /var/lib/apt/lists/*
 ---> 10ef9dde45ad
. . .
Step 6/11 : RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
. . .
 ---> 920e4f09ec75
Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
 ---> dbbcd44e44af
Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user
 ---> db98e899a69a
Step 9/11 : RUN mkdir -p /home/$user/.composer &&     chown -R $user:$user /home/$user
 ---> 5119e26ebfea
Step 10/11 : WORKDIR /var/www
 ---> 699c491611c0
Step 11/11 : USER $user
 ---> cf250fe8f1af
Successfully built cf250fe8f1af
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:

docker-compose up -d

OutputCreating travellist-db    ... done
Creating travellist-app   ... done
Creating travellist-nginx ... done

Điều 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 service đang hoạt động, hãy chạy:

docker-compose ps

Bạn sẽ thấy output như thế này:

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   nginx -g daemon off;            Up      0.0.0.0:8000->80/tcp,:::8000->80/tcp

Môi trường của bạn hiện đang chạy, nhưng chúng ta vẫn cần thực thi 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 để thực thi các lệnh trong các container service, chẳng hạn như ls -l để hiển thị thông tin chi tiết về các tệp trong thư mục ứng dụng:

docker-compose exec app ls -l

Outputtotal 256
-rw-r--r-- 1 sammy sammy    737 Apr 18 14:21 Dockerfile
-rw-r--r-- 1 sammy sammy    101 Jan  7  2020 README.md
drwxr-xr-x 6 sammy sammy   4096 Jan  7  2020 app
-rwxr-xr-x 1 sammy sammy   1686 Jan  7  2020 artisan
drwxr-xr-x 3 sammy sammy   4096 Jan  7  2020 bootstrap
-rw-r--r-- 1 sammy sammy   1501 Jan  7  2020 composer.json
-rw-r--r-- 1 sammy sammy 179071 Jan  7  2020 composer.lock
drwxr-xr-x 2 sammy sammy   4096 Jan  7  2020 config
drwxr-xr-x 5 sammy sammy   4096 Jan  7  2020 database
drwxr-xr-x 4 sammy sammy   4096 Apr 18 14:22 docker-compose
-rw-r--r-- 1 sammy sammy   1017 Apr 18 14:29 docker-compose.yml
-rw-r--r-- 1 sammy sammy   1013 Jan  7  2020 package.json
-rw-r--r-- 1 sammy sammy   1405 Jan  7  2020 phpunit.xml
drwxr-xr-x 2 sammy sammy   4096 Jan  7  2020 public
-rw-r--r-- 1 sammy sammy    273 Jan  7  2020 readme.md
drwxr-xr-x 6 sammy sammy   4096 Jan  7  2020 resources
drwxr-xr-x 2 sammy sammy   4096 Jan  7  2020 routes
-rw-r--r-- 1 sammy sammy    563 Jan  7  2020 server.php
drwxr-xr-x 5 sammy sammy   4096 Jan  7  2020 storage
drwxr-xr-x 4 sammy sammy   4096 Jan  7  2020 tests
-rw-r--r-- 1 sammy sammy    538 Jan  7  2020 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 rm -rf vendor composer.lock
docker-compose exec app composer install

Bạn sẽ thấy output tương tự như thế này:

OutputNo composer.lock file present. Updating dependencies to latest instead of installing from lock file. See <https://getcomposer.org/install> for more information.
. . .
Lock file operations: 89 installs, 0 updates, 0 removals
  - Locking doctrine/inflector (2.0.4)
  - Locking doctrine/instantiator (1.4.1)
  - Locking doctrine/lexer (1.2.3)
  - Locking dragonmantank/cron-expression (v2.3.1)
  - Locking egulias/email-validator (2.1.25)
  - Locking facade/flare-client-php (1.9.1)
  - Locking facade/ignition (1.18.1)
  - Locking facade/ignition-contracts (1.0.2)
  - Locking fideloper/proxy (4.4.1)
  - Locking filp/whoops (2.14.5)
. . .
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 89 installs, 0 updates, 0 removals
  - Downloading doctrine/inflector (2.0.4)
  - Downloading doctrine/lexer (1.2.3)
  - Downloading dragonmantank/cron-expression (v2.3.1)
  - Downloading symfony/polyfill-php80 (v1.25.0)
  - Downloading symfony/polyfill-php72 (v1.25.0)
  - Downloading symfony/polyfill-mbstring (v1.25.0)
  - Downloading symfony/var-dumper (v4.4.39)
  - Downloading symfony/deprecation-contracts (v2.5.1)
. . .
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 tra ứng dụng là tạo một khóa ứng dụng duy nhất bằng công cụ dòng lệnh Laravel artisan. Khóa này được sử dụng để mã hóa các phiên người dùng và dữ liệu nhạy cảm khác:

docker-compose exec app php artisan key:generate

OutputApplication key set successfully.

Bây giờ hãy vào trình duyệt của bạn 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ộ của mình, hãy sử 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 như thế này:

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

docker-compose logs nginx

Attaching to travellist-nginx
. . .
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:49:16 +0000] "GET / HTTP/1.1" 200 627 "-" "curl/7.82.0"
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:51:27 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:51:27 +0000] "GET /favicon.ico HTTP/1.1" 200 0 "<http://localhost:8000/>" "Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"

Nếu bạn muốn tạm dừng môi trường Docker Compose của mình trong khi vẫn giữ trạng thái của tất cả các service của nó, hãy chạy:

docker-compose pause

OutputPausing travellist-db    ... done
Pausing travellist-nginx ... done
Pausing travellist-app   ... done

Sau đó bạn có thể tiếp tục các service của mình với:

docker-compose unpause

OutputUnpausing 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:

docker-compose down

OutputStopping 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 Docker Compose, vui lòng kiểm tra tài liệu tham khảo 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 sử dụng Docker Compose để định nghĩa hạ tầng của chúng ta trong một tệp YAML. Đây là một bước tiến lớn trong việc chuẩn hóa môi trường phát triển và triển khai ứng dụng.

Từ thời điểm này trở đi, 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ử.

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