Hướng dẫn đầy đủ về Laravel Sail
Truman tiếp tục lái chiếc thuyền buồm bị đắm của mình về phía chân trời đang lùi xa vô tận. Tất cả chỉ bình lặng cho đến khi chúng ta thấy mũi thuyền bất ngờ va vào một bức tường xanh khổng lồ, hất tung Truman khỏi chân. Truman hồi phục và trèo qua boong tàu đến mũi thuyền. Thấp thoáng phía trên anh ta ngoài biển là một vòng xoáy của các kích thước khổng lồ. Bầu trời mà anh ấy đang chèo thuyền hướng tới không có gì khác ngoài một phông nền được sơn vẽ.
– Andrew M. Niccol, The Truman Show
Vào ngày 8 tháng 12 năm 2020, Taylor Otwell đã công bố sự ra mắt của Laravel Sail , một môi trường phát triển dựa trên Docker, cùng với một đợt đại tu tài liệu của Laravel:
Thông báo này đã gây ra một làn sóng phấn khích trên toàn cộng đồng, vì rất nhiều người đã xác định môi trường mới là cơ hội để cuối cùng tham gia vào Docker. Nhưng nó cũng để lại một số nhầm lẫn sau khi Sail không phải là một hướng dẫn chính xác để trở thành một chuyên gia Docker và nó giới thiệu một cách tiếp cận để phát triển hoàn toàn khác với những người tiền nhiệm của nó.
Bài đăng này nói về những gì mong đợi từ Laravel Sail, cách hoạt động và cách tận dụng tối đa nó. Nó cũng là một lời cầu xin các nhà phát triển thoát khỏi nó, ủng hộ giải pháp phù hợp của riêng họ.
Nhưng trước khi chúng ta đến đó, chúng ta cần xem xét kỹ dưới boong tàu, bắt đầu với lời giải thích cấp cao về Sail là gì.
Contents
Trong bài này
- Laravel Sail là gì?
- Làm thế nào để nó so sánh với những người tiền nhiệm của nó?
- Làm thế nào nó hoạt động?
- Mở rộng Cánh buồm Laravel
- Có gì sai với Laravel Sail?
- Cá voi trong cabin
- Bạn không cần Laravel Sail
- Sự kết luận
- Tài nguyên
Laravel Sail là gì?
Sail là môi trường phát triển mới nhất của Laravel. Đây là phần bổ sung gần đây nhất cho danh sách đã dài bao gồm các giải pháp chính thức như Homestead và Valet , mặt khác là các nỗ lực của cộng đồng như Laragon , Laradock , Takeout và Vessel (theo kho lưu trữ GitHub , Sail phần lớn được lấy cảm hứng từ sau này).
Laravel Sail dựa trên Docker , một công nghệ tận dụng các thùng chứa để đóng gói các ứng dụng về cơ bản để chúng có thể chạy nhanh chóng và dễ dàng trên bất kỳ hệ điều hành nào.
Tương lai của Sail dường như rất tươi sáng, vì tài liệu Laravel ngay lập tức cho thấy nó là cách ưa thích để cài đặt và chạy các dự án Laravel cục bộ, một vị trí mà Homestead và Valet đã chiếm giữ trong một thời gian dài.
Làm thế nào để nó so sánh với những người tiền nhiệm của nó?
Như một bản cập nhật mới, Homestead là một hộp Vagrant (một máy ảo) có mọi thứ mà hầu hết các ứng dụng Laravel cần. Điều đó bao gồm các thành phần thiết yếu như PHP, MySQL và máy chủ web (Nginx), nhưng cũng có các công nghệ khác như PostgreSQL, Redis hoặc Memcached.
Mặt khác, Valet là một môi trường nhẹ cho macOS tập trung vào hiệu suất. Nó dựa trên cài đặt cục bộ của PHP thay vì máy ảo và được dự định sử dụng cùng với các dịch vụ khác như DBngin hoặc Takeout để quản lý các phụ thuộc khác như cơ sở dữ liệu.
Trong khi Homestead và Valet trông khá khác nhau trên giấy tờ, chúng thúc đẩy cùng một cách tiếp cận chung để phát triển địa phương, cũng được chia sẻ bởi hầu hết các giải pháp nói trên: chúng cố gắng trở thành môi trường phù hợp với tất cả các dự án Laravel và nhằm mục đích quản lý tất cả chúng dưới một mái nhà.
Cách tiếp cận của Sail thì khác, ở chỗ các hướng dẫn xây dựng môi trường phát triển đi kèm với mã nguồn của dự án. Thay vì dựa vào sự hiện diện của giải pháp bên thứ ba như Homestead trên máy của nhà phát triển, Docker sẽ đọc bộ hướng dẫn và xây dựng môi trường tương ứng từ đầu.
Nói cách khác, ứng dụng đi kèm với pin và một lệnh duy nhất sẽ chạy lên và cấu hình các phần phụ thuộc của nó. Nó sẽ hoạt động bất kể hệ điều hành của nhà phát triển, miễn là Docker được cài đặt trên đó.
Laravel Sail giới thiệu khái niệm về một môi trường phát triển riêng cho ứng dụng, theo tôi, đó là đầu tàu thực sự của công nghệ.
Mặc dù cách tiếp cận này là một sự khác biệt lớn so với các giải pháp truyền thống, nhưng Sail vẫn mang một số điểm tương đồng với chúng xung quanh các công cụ mà nó đi kèm, một số là thiết yếu, một số khác thì không.
Hãy xem lại những điều quan trọng nhất và cách chúng được thực hiện.
Làm thế nào nó hoạt động?
Từ đây trở đi, sẽ dễ dàng hơn trong việc cài đặt mới Laravel, mặc dù các tệp tôi đề cập đến luôn trỏ đến kho lưu trữ GitHub chính thức . Nếu bạn có một chút thời gian, hãy làm theo hướng dẫn dành cho hệ điều hành của bạn ngay bây giờ và quay lại sau khi bạn đã chạy thành công ./vendor/bin/sail up
– Tôi sẽ lấy nó từ đó.
Mặc dù Sail cho phép chúng tôi chọn các dịch vụ mà chúng tôi quan tâm khi tạo một ứng dụng Laravel mới, theo mặc định, nó bao gồm ba thành phần chính – PHP, MySQL và Redis. Theo tài liệu , toàn bộ thiết lập tập trung xung quanh hai tệp – docker-compos.yml (nằm ở gốc của dự án sau khi cài đặt mới) và tập lệnh buồm (bên dưới vendor/bin
).
Tập docker-compose.yml
tin
Như đã đề cập, Laravel Sail dựa trên Docker, là một công nghệ sử dụng các container. Quy tắc chung là mỗi vùng chứa chỉ nên chạy một quy trình, tức là mỗi vùng chứa chạy một phần mềm duy nhất. Áp dụng quy tắc này cho thiết lập ở trên có nghĩa là chúng ta sẽ cần một vùng chứa cho PHP, một cho MySQL và một vùng thứ ba cho Redis.
Những vùng chứa này tạo nên ứng dụng của bạn và để nó hoạt động bình thường, chúng cần được sắp xếp . Có một số cách để thực hiện việc này, nhưng Laravel Sail dựa vào Docker Compose cho công việc, đây là giải pháp ưu tiên cho các thiết lập cục bộ.
Docker Compose mong đợi chúng tôi mô tả các thành phần khác nhau của ứng dụng của chúng tôi trong một docker-compose.yml
tệp, ở định dạng YAML. Nếu bạn mở tham số ở gốc của dự án, bạn sẽ thấy một version
tham số ở trên cùng, tiếp theo là một services
phần chứa danh sách các thành phần bao gồm các thành phần mà tôi vừa đề cập – laravel.test
và mysql
( redis
và một số thành phần khác mà tôi sẽ tóm tắt che sau).
Tôi sẽ mô tả và các mysql
dịch vụ theo thứ tự đó, vì hai cái đầu tiên đơn giản hơn cái cuối cùng.redis
laravel.test
Dịch mysql
vụ
Như tên cho thấy, mysql
dịch vụ xử lý cơ sở dữ liệu MySQL:
mysql:
image: 'mysql/mysql-server:8.0'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
volumes:
- 'sailmysql:/var/lib/mysql'
networks:
- sail
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
retries: 3
timeout: 5s
Tham image
số cho biết hình ảnh nào nên được sử dụng cho vùng chứa này. Một cách đơn giản để hiểu sự khác biệt giữa hình ảnh và vùng chứa là mượn từ các khái niệm Lập trình hướng đối tượng – một hình ảnh giống với một lớp và một vùng chứa đối với một thể hiện của lớp đó.
Ở đây, chúng tôi chỉ định rằng chúng tôi muốn sử dụng thẻ 8.0
của mysql/mysql-server
hình ảnh, tương ứng với MySQL Server phiên bản 8.0. Theo mặc định, hình ảnh được tải xuống từ Docker Hub , là cơ quan đăng ký hình ảnh Docker lớn nhất. Hãy xem trang dành cho Máy chủ MySQL – hầu hết các hình ảnh đều đi kèm với tài liệu đơn giản giải thích cách sử dụng chúng.
Phần ports
này cho phép chúng tôi ánh xạ các cảng địa phương thành các cảng container, theo local:container
ký hiệu. Trong đoạn mã ở trên, giá trị của FORWARD_DB_PORT
biến môi trường (hoặc 3306
nếu giá trị đó trống) được ánh xạ tới 3306
cổng của vùng chứa. Điều này chủ yếu hữu ích để kết nối phần mềm của bên thứ ba với cơ sở dữ liệu, như MySQL Workbench hoặc Sequel Ace (thiết lập cũng sẽ hoạt động nếu không có nó).
environments
là nơi chúng tôi xác định các biến môi trường cho vùng chứa. Ở đây, hầu hết chúng đều nhận giá trị của các biến môi trường hiện có, được tải từ .env
tệp ở gốc của dự án – docker-compose.yml
tự động phát hiện và nhập nội dung của tệp này. Ví dụ: trong MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
dòng, MYSQL_ROOT_PASSWORD
biến môi trường của vùng chứa sẽ nhận giá trị DB_PASSWORD
từ .env
tệp.
volumes
là khai báo một số tệp hoặc thư mục của vùng chứa dưới dạng ổ đĩa , bằng cách ánh xạ các tệp hoặc thư mục cục bộ cụ thể với chúng hoặc bằng cách để Docker xử lý.
Ở đây, một ổ đĩa do Docker quản lý được xác định sailmysql
:. Loại khối lượng này phải được khai báo trong một phần riêng biệt volumes
, cùng cấp với services
. Chúng tôi có thể tìm thấy nó ở cuối docker-compose.yml
tệp:
volumes:
sailmysql:
driver: local
sailredis:
driver: local
sailmeilisearch:
driver: local
Ổ sailmysql
đĩa được ánh xạ tới /var/lib/mysql
thư mục của vùng chứa, đây là nơi lưu trữ dữ liệu MySQL. Ổ đĩa này đảm bảo rằng dữ liệu vẫn tồn tại ngay cả khi vùng chứa bị phá hủy, đó là trường hợp khi chúng ta chạy ./vendor/bin/sail down
lệnh.
Phần networks
này cho phép chúng tôi chỉ định các mạng nội bộ mà vùng chứa sẽ có sẵn trên đó. Ở đây, tất cả các dịch vụ được kết nối với cùng một sail
mạng, cũng được định nghĩa ở cuối docker-compose.yml
, trong networks
phần phía trên volumes
một mạng:
networks:
sail:
driver: bridge
Cuối cùng, healthcheck
là một cách để chỉ ra những điều kiện nào cần phải đúng để dịch vụ sẵn sàng , thay vì chỉ được bắt đầu . Tôi sẽ quay lại vấn đề này sớm.
Dịch redis
vụ
Dịch redis
vụ này rất giống với dịch vụ mysql
:
redis:
image: 'redis:alpine'
ports:
- '${FORWARD_REDIS_PORT:-6379}:6379'
volumes:
- 'sailredis:/data'
networks:
- sail
healthcheck:
test: ["CMD", "redis-cli", "ping"]
retries: 3
timeout: 5s
Chúng tôi kéo alpine
thẻ của hình ảnh chính thức cho Redis ( Alpine là một bản phân phối Linux nhẹ) và chúng tôi xác định cổng nào sẽ chuyển tiếp. Sau đó, chúng tôi khai báo một khối lượng để duy trì dữ liệu, kết nối vùng chứa với sail
mạng và xác định kiểm tra tình trạng cần thực hiện để đảm bảo dịch vụ đã sẵn sàng.
Dịch laravel.test
vụ
Dịch laravel.test
vụ phức tạp hơn một chút:
laravel.test:
build:
context: ./vendor/laravel/sail/runtimes/8.0
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: sail-8.0/app
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- mysql
- redis
- meilisearch
- selenium
Đối với người mới bắt đầu, cái tên hơi khó hiểu, nhưng dịch vụ này là dịch vụ xử lý PHP (tức là dịch vụ phục vụ ứng dụng Laravel).
Tiếp theo, nó có một build
phần mà chúng ta chưa từng thấy trước đây, phần này trỏ đến Dockerfile có trong vendor/laravel/sail/runtimes/8.0
thư mục.
Dockerfiles là tài liệu văn bản chứa các hướng dẫn để xây dựng hình ảnh. Thay vì sử dụng hình ảnh hiện có từ Docker Hub, nhóm Laravel đã mô tả hình ảnh của riêng họ trong Dockerfile. Lần đầu tiên chúng tôi chạy ./vendor/bin/sail up
lệnh, chúng tôi xây dựng hình ảnh đó và tạo một vùng chứa dựa trên nó.
Mở Dockerfile và xem dòng đầu tiên:
FROM ubuntu:21.04
Điều này có nghĩa là thẻ hình ảnh 21.04
của Ubuntu được sử dụng làm điểm bắt đầu cho hình ảnh tùy chỉnh; phần còn lại của tệp về cơ bản là một danh sách các hướng dẫn để xây dựng dựa trên nó, cài đặt mọi thứ mà một ứng dụng Laravel tiêu chuẩn cần. Điều đó bao gồm PHP, các phần mở rộng khác nhau và các gói khác như Git hoặc Supervisor, cũng như Composer.
Phần cuối của tập tin cũng đáng được giải thích nhanh chóng:
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.0/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 8000
ENTRYPOINT ["start-container"]
Chúng ta có thể thấy rằng một loạt các tệp cục bộ được sao chép vào vùng chứa:
- tệp php.ini là một số cấu hình tùy chỉnh cho PHP;
- tệp supervisord.conf là tệp cấu hình cho Người giám sát , một trình quản lý quy trình ở đây chịu trách nhiệm khởi động quy trình PHP;
- tệp start-container là một tập lệnh Bash sẽ thực hiện một số việc mỗi khi vùng chứa khởi động, vì nó được định nghĩa là ENTRYPOINT của vùng chứa . Chúng ta có thể thấy rằng nó được thực thi bởi
RUN chmod +x
lệnh; - cuối cùng,
EXPOSE 8000
không làm bất cứ điều gì, ngoài việc thông báo cho người đọc rằng vùng chứa này lắng nghe trên cổng được chỉ định trong thời gian chạy (điều này thực sự có vẻ sai ở đây, vì ứng dụng được phục vụ trên cổng 80, không phải 8000).
Những thứ khác đang xảy ra trong Dockerfile này, nhưng ở trên là ý chính của nó. Lưu ý rằng cái này liên quan đến PHP 8.0, nhưng Laravel Sail cũng hỗ trợ các phiên bản khác có Dockerfiles mà bạn có thể trỏ đến từ laravel.test
dịch vụ docker-compose.yml
, thay vì PHP 8.0.
Đưa sự chú ý của chúng tôi trở lại docker-compose.yml
, chúng tôi có thể thấy rằng có một extra_hosts
phần mà chúng tôi chưa gặp phải trước đây. Tôi sẽ không đi vào quá nhiều chi tiết, nhưng nó ở đây để đảm bảo Xdebug chạy trơn tru trên các hệ điều hành .
Dịch vụ này cũng có một depends_on
phần chứa danh sách các dịch vụ sẽ có sẵn trước khi ứng dụng Laravel khởi động. Ở đây, chúng ta cần MySQL, Redis, Meilisearch và Selenium được thiết lập và chạy trước để tránh lỗi kết nối.
Đây là nơi mà các cuộc kiểm tra sức khỏe được mô tả trước đó rất hữu ích. Theo mặc định, depends_on
sẽ đợi các dịch vụ được chỉ định được bắt đầu , điều đó không nhất thiết có nghĩa là chúng đã sẵn sàng . Bằng cách chỉ định những điều kiện nào mà các dịch vụ này được coi là đã sẵn sàng, chúng tôi đảm bảo chúng ở trạng thái bắt buộc trước khi bắt đầu ứng dụng Laravel.
Phần còn lại của các cài đặt bây giờ sẽ quen thuộc, vì vậy tôi sẽ bỏ qua chúng.
Và meilisearch
các mailhog
dịch selenium
vụ
Đây là những dịch vụ nhỏ hơn mà tôi đã đề cập trước đó; chúng đã được ghi lại ở đây , ở đây và ở đây . Vấn đề là chúng hoạt động giống như những cái khác: chúng kéo các hình ảnh hiện có từ Docker Hub và sử dụng chúng như hiện tại, với cấu hình tối thiểu.
Kịch sail
bản
Nếu bạn đã làm theo hướng dẫn cài đặt của Laravel trước đó, bạn phải chạy lệnh sau tại một số điểm:
$ ./vendor/bin/sail up
Tệp buồm mà chúng tôi gọi ở đây là một tập lệnh Bash có chức năng là cung cấp giao diện thân thiện với người dùng để tương tác với Sail, giúp chúng tôi không phải chạy và nhớ các lệnh Docker đôi khi dài dòng.
Hãy mở nó ngay bây giờ để kiểm tra kỹ hơn (đừng lo lắng nếu bạn không quen thuộc với Bash – nó khá đơn giản).
Chúng ta có thể bỏ qua toàn bộ phần đầu tiên của tệp và tập trung vào if
câu lệnh lớn bắt đầu như sau:
if [ $# -gt 0 ]; then
# Proxy PHP commands to the "php" binary on the application container...
if [ "$1" == "php" ]; then
# ...
Trong tiếng Anh đơn giản, $# -gt 0
bit được dịch là “nếu số đối số lớn hơn 0”, có nghĩa là bất cứ khi nào chúng ta gọi sail
tập lệnh có đối số, việc thực thi sẽ nhập if
câu lệnh đó.
Nói cách khác, khi chúng ta chạy ./vendor/bin/sail up
lệnh, chúng ta gọi sail
tập lệnh với up
đối số và việc thực thi nằm bên trong if
câu lệnh lớn, nơi nó tìm kiếm một điều kiện phù hợp với up
đối số. Vì không có gì, nên kịch bản đi xuống tận cùng của phần lớn if
, theo kiểu tóm tắt else
mà chúng ta có thể tìm thấy ở đó:
# Pass unknown commands to the "docker-compose" binary...
else
docker compose "$@"
fi
Nhận xét đã cho chúng ta biết điều gì đang xảy ra – tập lệnh chuyển up
đối số sang docker-compose
hệ nhị phân. Nói cách khác, khi chúng tôi chạy , ./vendor/bin/sail up
chúng tôi thực sự chạy docker-compose up
, đó là lệnh Docker Compose tiêu chuẩn để bắt đầu các vùng chứa cho các dịch vụ được liệt kê trong đó docker-compose.yml
.
Lệnh này tải xuống các hình ảnh tương ứng một lần nếu cần và xây dựng hình ảnh Laravel dựa trên Dockerfile mà chúng ta đã nói trước đó.
Hãy thử một lần! Chạy ./vendor/bin/sail up
trước, sau đó docker compose up
– họ làm điều tương tự.
Bây giờ chúng ta hãy xem xét một ví dụ phức tạp hơn, một ví dụ liên quan đến Composer, nằm trong số các gói được cài đặt bởi Dockerfile của ứng dụng. Nhưng trước khi làm điều đó, hãy bắt đầu Sail ở chế độ tách rời để chạy các vùng chứa trong nền:
$ ./vendor/bin/sail up -d
Tập sail
lệnh cho phép chúng tôi chạy các lệnh của Trình soạn thảo, ví dụ:
$ ./vendor/bin/sail composer --version
Ở trên gọi sail
script với composer
và --version
là đối số, nghĩa là việc thực thi sẽ nhập if
lại câu lệnh lớn đó.
Hãy tìm kiếm điều kiện đối với Composer:
# ...
# Proxy Composer commands to the "composer" binary on the application container...
elif [ "$1" == "composer" ]; then
shift 1
if [ "$EXEC" == "yes" ]; then
docker-compose exec \
-u sail \
"$APP_SERVICE" \
composer "$@"
else
sail_is_not_running
fi
# ...
Dòng đầu tiên của điều kiện bắt đầu bằng shift
, là một Bash được tích hợp sẵn sẽ bỏ qua nhiều đối số như số mà nó được theo sau. Trong trường hợp này, shift 1
bỏ qua composer
đối số, tạo --version
đối số mới đầu tiên. Sau đó, chương trình đảm bảo rằng Sail đang chạy, trước khi thực hiện một lệnh lạ được chia thành bốn dòng, mà tôi chia nhỏ bên dưới:
docker-compose exec \
-u sail \
"$APP_SERVICE" \
composer "$@"
exec
là cách Docker Compose cho phép chúng ta thực thi các lệnh trên một vùng chứa đã chạy. -u
là một tùy chọn cho biết chúng ta muốn thực thi lệnh với tư cách người dùng nào và $APP_SERVICE
là vùng chứa mà chúng ta muốn chạy tất cả lệnh trên đó. Ở đây, giá trị của nó là laravel.test
, là tên của dịch vụ docker-compose.yml
như đã giải thích trong phần trước. Tiếp theo là lệnh mà chúng ta muốn chạy khi ở trong vùng chứa, cụ thể là composer
theo sau là tất cả các đối số của tập lệnh. Những điều này bây giờ chỉ bao gồm --version
, vì chúng tôi đã bỏ qua đối số đầu tiên.
Nói cách khác, khi chúng ta chạy:
$ ./vendor/bin/sail composer --version
Lệnh được thực hiện đằng sau hậu trường như sau:
$ docker compose exec -u sail "laravel.test" composer "--version"
Sẽ khá phức tạp nếu gõ loại lệnh này mỗi lần; đó là lý do tại sao sail
tập lệnh cung cấp các phím tắt cho chúng, giúp trải nghiệm người dùng mượt mà hơn nhiều.
Hãy xem phần còn lại của các if
câu lệnh nhỏ hơn bên trong câu lệnh lớn để xem những gì khác được đề cập – bạn sẽ thấy rằng nguyên tắc tương tự luôn được áp dụng ít nhiều.
Có một số tính năng khác có sẵn ngoài hộp (như đặt các vùng chứa cục bộ ở chế độ công khai ), nhưng hiện tại chúng tôi đã đề cập đến nội dung của những gì mà Laravel Sail hiện đang cung cấp. Mặc dù đây là một khởi đầu khá tốt nhưng nó có phần hạn chế, ngay cả đối với một ứng dụng cơ bản.
Tin tốt là nhóm Laravel nhận thức được điều này và đã xây dựng môi trường với tính năng mở rộng:
Vì Sail chỉ là Docker, bạn có thể tự do tùy chỉnh gần như mọi thứ về nó.
– Tài liệu Laravel
Hãy xem điều đó có ý nghĩa gì trong thực tế.
Mở rộng Cánh buồm Laravel
Mã được đề cập trong phần này cũng có sẵn dưới dạng kho lưu trữ GitHub mà bạn có thể tham khảo bất cứ lúc nào.
Chúng ta sẽ khám phá ba cách để mở rộng Laravel Sail, sử dụng MongoDB làm đối tượng thử nghiệm. Nhưng trước khi tiếp tục, hãy đảm bảo rằng chúng ta có càng nhiều tệp cấu hình càng tốt.
Thứ duy nhất mà chúng tôi có quyền truy cập ban đầu là tệp docker-compos.yml , nhưng chúng tôi có thể xuất bản nhiều nội dung hơn bằng lệnh sau, lệnh này sẽ tạo một docker
thư mục mới ở gốc của dự án:
$ ./vendor/bin/sail artisan sail:publish
Chúng tôi sẽ quay lại những điều đó sau một phút; Hiện tại, chúng ta hãy thử và cài đặt gói Laravel MongoDB , gói này sẽ giúp bạn dễ dàng sử dụng MongoDB với khung yêu thích của chúng tôi:
$ ./vendor/bin/sail composer require jenssegers/mongodb
Thật không may, Composer đang phàn nàn về một số tiện ích mở rộng bị thiếu:
...
- mongodb/mongodb[dev-master, 1.10.0, ..., v1.10.x-dev] require ext-mongodb ^1.11.0 -> it is missing from your system. Install or enable PHP's mongodb extension.
...
Hãy sửa lỗi này!
Cài đặt các tiện ích mở rộng bổ sung
Trước đó trong bài đăng này, chúng tôi đã nói về cách Sail sử dụng Dockerfiles để xây dựng hình ảnh phù hợp với yêu cầu của Laravel cho các phiên bản PHP khác nhau. Các tệp này đã được xuất bản bằng lệnh mà chúng tôi đã chạy ở đầu phần này – tất cả những gì chúng tôi cần làm là chỉnh sửa chúng để thêm các phần mở rộng chúng tôi cần và xây dựng lại các hình ảnh tương ứng.
Nhiều tiện ích mở rộng có sẵn và chúng tôi có thể liệt kê chúng bằng lệnh sau:
$ ./vendor/bin/sail php -m
MongoDB không phải là một phần của chúng; để thêm nó, hãy mở docker/8.0/Dockerfile
tệp và tìm RUN
hướng dẫn cài đặt các gói khác nhau:
RUN apt-get update \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
&& mkdir -p ~/.gnupg \
&& chmod 600 ~/.gnupg \
&& echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
&& apt-key adv --homedir ~/.gnupg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E5267A6C \
&& apt-key adv --homedir ~/.gnupg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C300EE8C \
&& echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu hirsute main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.0-cli php8.0-dev \
php8.0-pgsql php8.0-sqlite3 php8.0-gd \
php8.0-curl php8.0-memcached \
php8.0-imap php8.0-mysql php8.0-mbstring \
php8.0-xml php8.0-zip php8.0-bcmath php8.0-soap \
php8.0-intl php8.0-readline php8.0-pcov \
php8.0-msgpack php8.0-igbinary php8.0-ldap \
php8.0-redis php8.0-swoole php8.0-xdebug \
&& php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y mysql-client \
&& apt-get install -y postgresql-client \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
Thật dễ dàng để xác định khối liên quan đến các phần mở rộng PHP vì chúng đều bắt đầu bằng php8.0
. Thêm phần mở rộng MongoDB vào cuối danh sách:
php8.0-redis php8.0-swoole php8.0-xdebug php8.0-mongodb \
Bạn có thể xem chi tiết các phần mở rộng PHP có sẵn cho Ubuntu 21.04 tại đây .
Lưu tệp và chạy lệnh sau:
$ ./vendor/bin/sail build
Điều này sẽ đi qua tất cả các dịch vụ được liệt kê trong docker-compose.yml
và xây dựng các hình ảnh tương ứng nếu chúng đã thay đổi, bao gồm cả laravel.test
dịch vụ có Dockerfile mà chúng tôi vừa cập nhật.
Sau khi hoàn tất, hãy bắt đầu lại các vùng chứa:
$ ./vendor/bin/sail up -d
Lệnh sẽ phát hiện rằng hình ảnh tương ứng với laravel.test
dịch vụ đã thay đổi và tạo lại vùng chứa:
...
laravel-sail-extended_mailhog_1 is up-to-date
laravel-sail-extended_meilisearch_1 is up-to-date
Recreating laravel-sail-extended_laravel.test_1 ... done
Đó là nó! Phần mở rộng MongoDB cho PHP hiện đã được cài đặt và kích hoạt. Chúng tôi chỉ thực hiện điều đó cho hình ảnh PHP 8.0, nhưng bạn có thể áp dụng quy trình tương tự cho các phiên bản PHP khác bằng cách cập nhật Dockerfile của riêng chúng, với tên mở rộng phù hợp (ví dụ php7.4-mongodb
:).
Bây giờ chúng ta có thể nhập gói Laravel MongoDB một cách an toàn:
$ ./vendor/bin/sail composer require jenssegers/mongodb
Tiếp theo: thêm dịch vụ Docker cho MongoDB.
Thêm dịch vụ mới
MongoDB về cơ bản là một cơ sở dữ liệu khác, có nghĩa là dịch vụ tương ứng sẽ rất giống với MySQL và Redis. Một tìm kiếm nhanh trên Docker Hub cho thấy rằng có một hình ảnh chính thức cho nó mà chúng tôi sẽ sử dụng.
Tài liệu của nó chứa một cấu hình ví dụ cho Docker Compose, chúng tôi có thể sao chép và điều chỉnh theo nhu cầu của mình. Mở docker-compose.yml
và thêm dịch vụ sau ở dưới cùng, sau các dịch vụ khác:
mongo:
image: 'mongo:4.4'
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: '${DB_USERNAME}'
MONGO_INITDB_ROOT_PASSWORD: '${DB_PASSWORD}'
MONGO_INITDB_DATABASE: '${DB_DATABASE}'
volumes:
- 'sailmongo:/data/db'
networks:
- sail
Những thay đổi tôi đã thực hiện như sau: đầu tiên, tôi chỉ định thẻ 4.4
của mongo
hình ảnh. Nếu bạn không chỉ định một, Docker Compose sẽ kéo latest
thẻ theo mặc định, đây không phải là một phương pháp hay vì nó sẽ tham chiếu đến các phiên bản MongoDB khác nhau theo thời gian, khi các bản phát hành mới có sẵn. Việc giới thiệu các thay đổi vi phạm có thể tạo ra sự không ổn định trong thiết lập Docker của bạn, vì vậy tốt hơn nên nhắm mục tiêu một phiên bản cụ thể, lý tưởng nhất là phù hợp với phiên bản sản xuất.
Sau đó, tôi đã khai báo một MONGO_INITDB_DATABASE
biến môi trường cho vùng chứa để tạo cơ sở dữ liệu với tên tương ứng khi khởi động và tôi đã đối sánh giá trị của từng biến môi trường với một biến môi trường đến từ .env
tệp (chúng tôi sẽ quay lại với chúng sau một phút) .
Tôi cũng đã thêm một volumes
phần, gắn một ổ đĩa do Docker quản lý vào /data/db
thư mục của vùng chứa. Nguyên tắc tương tự như MySQL và Redis ở đây áp dụng – nếu bạn không duy trì dữ liệu trên máy cục bộ của mình, dữ liệu sẽ bị mất mỗi khi vùng chứa MongoDB bị phá hủy. Nói cách khác, vì dữ liệu MongoDB được lưu trữ trong /data/db
thư mục của vùng chứa, chúng tôi duy trì thư mục đó cục bộ bằng cách sử dụng một ổ đĩa.
Vì tập này chưa tồn tại, chúng ta cần khai báo nó ở cuối docker-compose.yml
, sau các tập khác:
volumes:
sailmysql:
driver: local
sailredis:
driver: local
sailmeilisearch:
driver: local
sailmongo:
driver: local
Finally, I added the networks
section to ensure the service is on the same network as the others.
We can now configure Laravel MongoDB as per the package’s instructions. Open config/database.php
and add the following database connection:
'mongodb' => [
'driver' => 'mongodb',
'host' => env('DB_HOST'),
'port' => env('DB_PORT'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'options' => [
'database' => env('DB_AUTHENTICATION_DATABASE', 'admin'),
],
],
Open the .env
file at the root of the project and change the database values as follows:
DB_CONNECTION=mongodb
DB_HOST=mongo
DB_PORT=27017
DB_DATABASE=laravel_sail
DB_USERNAME=root
DB_PASSWORD=root
The above makes MongoDB the main database connection. In a real case scenario, you might want to make it a secondary database like Redis, but for demonstration purposes, this will do.
DB_HOST
is the name of the MongoDB service from docker-compose.yml
. Behind the scenes, Docker Compose resolves the service’s name to the container’s IP on the networks it manages (in our case, that’s the single sail
network defined at the end of docker-compose.yml
).
DB_PORT
is the port MongoDB is available on, which is 27017
by default, as per the image’s description.
We’re ready for a test! Run the following command again:
$ ./vendor/bin/sail up -d
It will download MongoDB’s image, create the new volume and start the new container, which will also create the laravel_sail
database:
➜ ./vendor/bin/sail up -d
Pulling mongo (mongo:4.4)...
4.4: Pulling from library/mongo
7b1a6ab2e44d: Pull complete
90eb44ebc60b: Pull complete
...
Let’s make sure of that by running Laravel’s default migrations:
$ ./vendor/bin/sail artisan migrate
We can push the test further by updating the User
model so it extends Laravel MongoDB’s Authenticable
model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;
use Jenssegers\Mongodb\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
// ...
Use Tinker to try and create a model:
$ ./vendor/bin/sail tinker
Psy Shell v0.10.5 (PHP 8.0.0 — cli) by Justin Hileman
>>> \App\Models\User::factory()->create();
Great! Our MongoDB integration is functional.
We can keep interacting with it using Tinker and Eloquent, but oftentimes it is useful to have direct access to the database, through third-party software or via a command-line interface such as the Mongo shell.
Let’s add the latter to our setup.
Custom sail
commands
The good news is the Mongo shell is already available, as long as we know the right formula to summon it. Here it is, along with some extra commands to log into the database and list the users (run the first command from the project’s root):
$ docker-compose exec mongo mongo
MongoDB shell version v4.4.10
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("be711959-a359-4d1f-8fd4-9af7bad42c23") }
MongoDB server version: 4.4.10
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
https://community.mongodb.com
> use admin
switched to db admin
> db.auth("root", "root")
1
> use laravel_sail
switched to db laravel_sail
> db.users.find()
Lệnh docker-compose exec mongo mongo
sẽ trông quen thuộc – trước đó trong bài viết, chúng ta đã xem xét những gì sail
tập lệnh thực hiện đằng sau hậu trường, chủ yếu bao gồm việc dịch sail
các lệnh đơn giản thành các lệnh phức tạp docker-compose
hơn. Ở đây, chúng tôi đang nói với docker-compose
hệ nhị phân thực thi mongo
lệnh trên vùng mongo
chứa.
Công bằng mà nói, lệnh này không quá tệ và chúng ta có thể dễ dàng nhớ nó; nhưng để nhất quán, sẽ tốt hơn nếu có một cái sail
tương đương đơn giản hơn, như sau:
$ ./vendor/bin/sail mongo
Để đạt được điều này, chúng tôi cần phải hoàn thành sail
tập lệnh bằng cách nào đó, nhưng vì nó nằm bên trong vendor
thư mục – được tạo bởi Composer – chúng tôi không thể cập nhật trực tiếp. Chúng tôi cần một cách để xây dựng dựa trên nó mà không cần sửa đổi nó, mà tôi đã tóm tắt bên dưới:
- tạo một bản sao của
sail
tập lệnh ở gốc của dự án; - thay thế nội dung của
if
tuyên bố lớn của nó bằng các điều kiện tùy chỉnh; - nếu không có điều kiện tùy chỉnh nào phù hợp với các đối số hiện tại, hãy chuyển chúng sang
sail
tập lệnh gốc.
Nếu chúng ta xem xét kỹ hơn sail
tệp với ls -al
, chúng ta có thể thấy rằng đó là một liên kết tượng trưng đến vendor/laravel/sail/bin/sail
tệp:
➜ ls -al vendor/bin
total 0
drwxr-xr-x 8 yannick staff 256 26 Nov 10:37 .
drwxr-xr-x 48 yannick staff 1536 26 Nov 12:24 ..
...
lrwxr-xr-x 1 yannick staff 24 26 Nov 10:36 sail -> ../laravel/sail/bin/sail
...
Sao chép tệp đó và dán vào thư mục gốc của dự án của chúng tôi:
$ cp vendor/laravel/sail/bin/sail .
Mở bản sao mới và thay thế nội dung lớn của nó if
bằng phần sau, giữ nguyên phần còn lại:
if [ $# -gt 0 ]; then
# Initiate a Mongo shell terminal session within the "mongo" container...
if [ "$1" == "mongo" ]; then
if [ "$EXEC" == "yes" ]; then
docker-compose exec mongo mongo
else
sail_is_not_running
fi
# Pass unknown commands to the original "sail" script...
else
./vendor/bin/sail "$@"
fi
fi
Trong đoạn mã trên, chúng ta đã loại bỏ tất cả các if...else
điều kiện bên trong lệnh lớn if
và thêm một điều kiện của riêng chúng ta, lệnh này chạy lệnh mà chúng ta đã sử dụng trước đó để truy cập Mongo shell nếu giá trị của đối số đầu tiên của script là mongo
. Nếu không, quá trình thực thi sẽ nhấn vào else
câu lệnh cuối cùng và gọi sail
tập lệnh gốc với tất cả các đối số.
Bạn có thể thử điều này ngay bây giờ – lưu tệp và chạy lệnh sau:
$ ./sail mongo
Nó sẽ mở một phiên shell Mongo trong thiết bị đầu cuối của bạn.
Hãy thử một lệnh khác, để đảm bảo rằng sail
tập lệnh gốc đang tiếp quản khi nó phải:
$ ./sail artisan
Menu Artisan sẽ hiển thị.
Đó là nó! Nếu bạn cần thêm lệnh, bạn có thể thêm chúng dưới dạng if...else
điều kiện mới bên trong if
bản sao lớn của sail
tập lệnh ở gốc của dự án.
Nó hoạt động theo cùng một cách, ngoại trừ việc bây giờ bạn cần phải chạy ./sail
thay vì ./vendor/bin/sail
(hoặc cập nhật bí danh Bash của bạn nếu bạn đã tạo bí danh như được đề xuất trong tài liệu ).
Hiện chúng tôi đang chạy một phiên bản đầy đủ chức năng của MongoDB như một phần của thiết lập Docker của chúng tôi, được tích hợp độc đáo với Laravel Sail. Nhưng MongoDB chỉ là một ví dụ ở đây – bạn có thể làm điều tương tự với khá nhiều công nghệ bạn muốn sử dụng.
Hãy đi xem ngay bây giờ! Hầu hết các tác nhân chính đều có hình ảnh Docker – chính thức hoặc do cộng đồng duy trì – với các hướng dẫn dễ làm theo. Trong hầu hết các trường hợp, bạn sẽ có một phiên bản cục bộ của phần mềm chạy trong vài phút.
Có thể còn nhiều điều chúng tôi có thể làm để tùy chỉnh Laravel Sail, nhưng ba phương pháp được mô tả ở trên sẽ giúp bạn có được một chặng đường dài.
Ở giai đoạn này, bạn có thể nghĩ rằng môi trường mới của Laravel có rất nhiều thứ để làm, thậm chí có thể nhiều hơn bạn nghĩ ban đầu. Tuy nhiên, quan điểm của bài viết này là tránh xa nó …
Vậy tôi sẽ đi đâu với cái này?
Có gì sai với Laravel Sail?
Nếu bạn đã làm được đến mức này, có lẽ bạn đang tự hỏi có gì sai với Laravel Sail, bây giờ đã rõ chúng ta có thể đẩy nó đi bao xa.
Như hiện tại, đó là một giải pháp khá tốt. Trong phiên bản trước của bài viết này, tôi đã chỉ ra một danh sách toàn bộ các vấn đề hiện đã được giải quyết phần lớn. Vậy tại sao không sử dụng nó?
Hãy để tôi chia sẻ cho bạn ngay bây giờ: một khi bạn biết và hiểu mọi thứ tôi đã giải thích trong các phần trước, bạn không cần Laravel Sail nữa.
Đúng vậy – bạn có thể lấy kiến thức đó và bỏ đi.
Nhưng trước khi tôi nói rõ hơn về vấn đề này, chúng ta hãy xem xét một số điểm đau còn lại của Sail, mặc dù tôi hy vọng nhóm Laravel sẽ giải quyết hầu hết chúng sớm hơn là muộn.
Điều đầu tiên liên quan đến các sail
lệnh tùy chỉnh: mặc dù có thể mở rộng sail
tập lệnh như đã trình bày ở trên, nhưng quá trình này hơi xấu và hơi khó hiểu. Những người bảo trì của Sail có thể khắc phục điều này bằng một điểm mở rộng Bash rõ ràng cho phép người dùng thêm các phím tắt của riêng họ hoặc bằng cách xuất bản sail
tập lệnh cùng với các tệp khác.
Thứ hai, ứng dụng Laravel được phục vụ bởi máy chủ phát triển của PHP. Tôi sẽ không đi vào quá nhiều chi tiết ở đây, nhưng như đã đề cập trước đó, Supervisor quản lý quá trình PHP trong vùng laravel.test
chứa. Dòng này là nơi Người giám sát chạy php artisan serve
lệnh, lệnh này khởi động máy chủ phát triển của PHP.
Vấn đề ở đây là môi trường không sử dụng máy chủ web thích hợp (ví dụ: Nginx), có nghĩa là chúng ta không thể dễ dàng có tên miền cục bộ, cũng như không đưa HTTPS vào thiết lập. Điều này có thể tốt cho việc tạo mẫu nhanh, nhưng việc phát triển phức tạp hơn rất có thể sẽ cần những thứ đó.
Vấn đề cuối cùng thuộc về một danh mục riêng biệt, vì nó liên quan đến Docker tổng thể chứ không phải Laravel Sail cụ thể. Nó nên được xem xét cẩn thận trước khi đi xuống con đường Docker và xứng đáng là một phần của riêng nó.
Cá voi trong cabin
Một cảnh báo chính dường như không có trong cuộc trò chuyện cho đến nay liên quan đến hiệu suất. Mặc dù điều này không ảnh hưởng đến người dùng Linux, nhưng nếu bạn chạy Docker Desktop trên hệ thống của mình, rất có thể bạn sẽ gặp phải thời gian thực thi lâu, đặc biệt là trên macOS (có vẻ như việc sử dụng WSL 2 trên Windows có thể giảm thiểu sự chậm chạp).
Mặc dù thời gian phản hồi HTTP đã được cải thiện rất nhiều, nhưng việc chạy các lệnh cục bộ như Yarn hoặc Composer vẫn rất chậm. Có thể bạn đã tự mình trải nghiệm khi xem qua hướng dẫn này, chẳng hạn khi chúng tôi cài đặt gói Laravel MongoDB với Composer.
Tôi sẽ không đi vào quá chi tiết ở đây, nhưng lý do về cơ bản đến từ hệ thống tệp cơ bản của máy chủ lưu trữ, hệ thống này không hoạt động tốt xung quanh các thư mục cục bộ được gắn kết. Như chúng ta đã thấy, đây là cách Laravel Sail lấy mã nguồn của ứng dụng trong vùng chứa của ứng dụng Laravel.
Đây là lúc mà cách tiếp cận như Takeout có ý nghĩa, vì thay vì chạy PHP từ vùng chứa Docker, họ mong đợi các nhà phát triển chạy nó trên máy cục bộ của họ (ví dụ qua Valet ), đồng thời cung cấp các phiên bản dịch vụ như MySQL hoặc MongoDB, do đó mang lại sự tiện lợi mà không làm giảm hiệu suất. Nhưng từ thời điểm bạn chọn chạy PHP thông qua vùng chứa Docker (giống như Sail), giá trị gia tăng của Takeout sẽ giảm đi, theo ý kiến của tôi.
Có những chiến lược để giảm thiểu những vấn đề về hiệu suất này, nhưng tài liệu của Laravel không đề cập đến chúng, chứ đừng nói đến việc hiệu suất có thể bị suy giảm, điều mà tôi thấy rất ngạc nhiên.
Điều đó đang được nói, bạn có thể đủ thoải mái với hiệu suất như nó vốn có; Tôi, đối với một điều, đã ổn với nó trong nhiều năm, mặc dù tôi sử dụng Docker Desktop trên macOS. Điểm mấu chốt là khía cạnh này nên được xem xét cẩn thận trước khi chuyển toàn bộ thiết lập của bạn sang một giải pháp chạy PHP trong vùng chứa, có thể là Laravel Sail hoặc thứ gì đó khác.
Nhưng một khi bạn đã đưa ra quyết định đó và liệu các vấn đề khác cuối cùng có được giải quyết hay không, ý tưởng chính của bài viết này vẫn giữ nguyên.
Bạn không cần Laravel Sail
Nếu bạn đang cân nhắc xây dựng bất cứ thứ gì quan trọng bằng cách sử dụng Laravel Sail làm môi trường phát triển của mình, thì sớm muộn gì bạn cũng phải mở rộng nó. Bạn sẽ thấy mình đang dò dẫm trên Dockerfiles và cuối cùng là viết của riêng bạn; bạn sẽ phải thêm một số dịch vụ vào docker-compose.yml
và có thể đưa vào một vài lệnh Bash tùy chỉnh.
Khi bạn đến đó, có một câu hỏi bạn nên tự hỏi mình:
Điều gì ngăn cản tôi xây dựng thiết lập của riêng mình?
Câu trả lời là không có gì . Khi bạn cảm thấy thoải mái khi mở rộng Laravel Sail, bạn đã có kiến thức cần thiết để xây dựng môi trường của riêng mình.
Hãy suy nghĩ về nó: docker-compose.yml
tệp không dành riêng cho Laravel Sail, đó chỉ là cách Docker Compose hoạt động. Tương tự đối với Dockerfiles – chúng là những thứ Docker tiêu chuẩn. Lớp Bash? Đó là tất cả những gì cần làm – một số mã Bash, và như bạn có thể thấy, nó không quá phức tạp.
Vậy tại sao lại gò bó bản thân một cách giả tạo trong những ràng buộc của Cánh buồm?
Và quan trọng hơn: tại sao lại giới hạn bản thân sử dụng Docker trong ngữ cảnh của Laravel?
Ứng dụng của bạn có thể bắt đầu như một khối nguyên khối, nhưng không phải lúc nào cũng vậy. Có lẽ bạn đã có một giao diện người dùng riêng và bạn sử dụng Laravel làm lớp API. Trong trường hợp đó, bạn có thể muốn môi trường phát triển của mình quản lý cả hai; chạy chúng đồng thời để chúng tương tác với nhau giống như trên môi trường dàn dựng hoặc trong quá trình sản xuất.
Nếu toàn bộ ứng dụng của bạn là một monorepo , cấu hình Docker và tập lệnh Bash của bạn có thể nằm ở gốc của dự án và bạn có thể có các ứng dụng giao diện người dùng và phụ trợ của mình trong các thư mục con riêng biệt, ví dụ src
:
Chế độ xem dạng cây tương ứng sẽ trông giống như sau:
my-app/
├── bash-script
├── docker-compose.yml
└── src/
├── backend/
│ └── Dockerfile
└── frontend/
└── Dockerfile
Tệp docker-compose.yml
sẽ khai báo hai dịch vụ – một cho phụ trợ và một cho giao diện người dùng – cả hai đều trỏ đến Dockerfile tương ứng của chúng.
Nếu backend và frontend nằm trong các kho khác nhau, bạn có thể tạo một kho thứ ba, chứa riêng môi trường phát triển Docker của bạn. Chỉ cần git-bỏ qua thư src
mục và hoàn thành tập lệnh Bash của bạn để nó kéo cả hai kho ứng dụng vào đó, sử dụng các lệnh giống như bạn thường chạy bằng tay.
Ngay cả khi dự án của bạn là một khối Laravel, loại cấu trúc này đã gọn gàng hơn so với việc trộn các tệp liên quan đến phát triển với phần còn lại của mã nguồn. Hơn nữa, nếu ứng dụng của bạn phát triển lớn hơn và cần các thành phần khác ngoài Laravel, bạn đã sẵn sàng hỗ trợ chúng.
Một khi bạn đã nỗ lực để hiểu Laravel Sail để mở rộng nó, không có gì ngăn cản bạn xây dựng môi trường phát triển của riêng mình, cho dù Laravel có phải là một phần của phương trình hay không . Đúng vậy, bạn có thể xây dựng môi trường dựa trên Docker riêng cho bất cứ thứ gì.
Và nếu Laravel là một phần của ngăn xếp, không có gì ngăn cản bạn sử dụng lại Dockerfiles của Sail nếu bạn chưa cảm thấy thoải mái khi viết của riêng mình; sau tất cả, chúng đã được tối ưu hóa cho Laravel. Tương tự như vậy, bạn có thể lấy cảm hứng từ tệp của Sail docker-compose.yml
nếu điều đó hữu ích.
Sự kết luận
Đừng hiểu sai ý tôi – Sail có rất nhiều thứ để làm được điều đó, và tôi rất vui khi thấy một diễn viên đã thành danh như Laravel thúc đẩy việc áp dụng Docker để phát triển địa phương.
Chúng tôi yêu thích các khuôn khổ của mình vì chúng cung cấp các nguyên tắc để đạt được kết quả mong muốn theo cách mà chúng tôi biết là hiệu quả và đã được thử nghiệm trong trận chiến, và điều tự nhiên là họ cũng tìm cách cung cấp môi trường cho phép người dùng xây dựng dựa trên chúng. Nhưng có một điều mà Sail tình cờ cho chúng ta thấy là điều này không còn phải là một phần của nhiệm vụ của khuôn khổ nữa.
Giống như chiếc thuyền buồm của Truman giúp anh ta vượt qua nỗi sợ hãi về biển và đưa anh ta đến rìa của thế giới nhân tạo mà anh ta đang sống, Sail tiết lộ cả những giam giữ của Laravel và cách để thoát khỏi chúng.
Bạn có thể cảm thấy rằng Sail là quá đủ cho nhu cầu của bạn ngày hôm nay hoặc bạn chưa sẵn sàng để tự mình đi. Tốt rồi. Nhưng Laravel sẽ luôn bị giới hạn bởi bản chất nguyên khối của nó, và khi bạn phát triển với tư cách là một nhà phát triển, sẽ đến ngày ứng dụng Laravel của bạn chỉ là một thành phần duy nhất của một hệ thống lớn hơn, mà Sail sẽ không còn đủ nữa. Cuối cùng, chiếc thuyền buồm nhỏ của bạn sẽ va vào một phông nền được sơn.
Nếu bạn muốn khám phá thêm vấn đề này nhưng cảm thấy bạn cần thêm hướng dẫn, tôi đã xuất bản một loạt bài về chủ đề này sẽ giúp bạn tiếp tục. Nó không yêu cầu kiến thức trước về Docker và bao gồm máy chủ web, HTTPS, tên miền và nhiều thứ khác. Nó không có tất cả các câu trả lời nhưng sẽ đưa bạn đến một nơi mà bạn có thể tìm thấy câu trả lời của riêng mình.
Những gì bạn làm tiếp theo là hoàn toàn tùy thuộc vào bạn; chỉ cần biết rằng có cả một thế giới ngoài kia, đang chờ bạn.
Truman do dự. Có lẽ anh ta không thể vượt qua nó sau cùng. Máy ảnh từ từ phóng to khuôn mặt của Truman.
TRUMAN: “Trong trường hợp tôi không gặp bạn – xin chào buổi chiều, chào buổi tối và ngủ ngon.”
Anh ta bước qua cửa và biến mất.