SELF HOSTING

Expose – Giải pháp Tunnel mã nguồn mở thay thế Ngrok toàn diện

Expose là một ứng dụng tunnel mã nguồn mở được phát triển bởi BeyondCode (tác giả Marcel Pociot), viết hoàn toàn bằng PHP. Công cụ này cho phép bạn chia sẻ môi trường phát triển cục bộ (localhost) của mình với người khác trên internet thông qua một URL công khai, đồng thời hỗ trợ nhận và kiểm tra webhook trong quá trình phát triển ứng dụng.

Nếu bạn đã từng sử dụng ngrok, bạn sẽ nhanh chóng nhận ra Expose cung cấp tập tính năng tương tự nhưng với một ưu điểm quan trọng: toàn bộ lõi là mã nguồn mở, có thể tự host server trên hạ tầng của chính mình và được viết bằng PHP – ngôn ngữ quen thuộc với đại đa số PHP developer, đặc biệt là cộng đồng Laravel.

Kể từ khi ra mắt vào năm 2020, Expose đã thu hút hơn 4.500 sao trên GitHub và trở thành lựa chọn hàng đầu cho PHP developer cần một giải pháp tunnel linh hoạt, có thể kiểm soát hoàn toàn.

Expose hoạt động như thế nào?

Expose tạo một đường hầm (tunnel) giữa URL cục bộ trên máy của bạn và một máy chủ công khai. Tất cả request gửi đến máy chủ công khai sẽ được chuyển tiếp qua tunnel về máy của bạn, và phản hồi được gửi trả lại tự động. Bên dưới lớp vỏ, Expose sử dụng framework ReactPHP để xử lý kết nối bất đồng bộ hiệu năng cao.

Expose bao gồm hai thành phần chính:

  • Client (máy khách): Chạy trên máy phát triển cục bộ của bạn, tạo kết nối tunnel đến server.
  • Server (máy chủ): Có thể là server quản lý của Expose.dev, hoặc server tự host của chính bạn.

Các tính năng nổi bật của Expose

  • Mã nguồn mở và tự host: Toàn bộ mã nguồn của Expose được công bố công khai trên GitHub dưới giấy phép MIT. Bạn có toàn quyền tự host server tunnel trên hạ tầng của mình, đảm bảo dữ liệu luôn nằm trong tầm kiểm soát.
  • Dashboard cực đẹp và nhiều tính năng: Ngay sau khi bắt đầu chia sẻ một site, Expose khởi động một dashboard web tại http://localhost:4040. Dashboard này cho phép:
    • Xem các HTTP request đến theo thời gian thực
    • Xem chi tiết đầy đủ của từng request và response (headers, body, status code, duration)
    • Replay bất kỳ request nào mà không cần kích hoạt lại webhook gốc – đặc biệt hữu ích khi test các payment webhook
    • Sao chép lệnh curl tương đương của từng request
  • Terminal UI: Song song với dashboard web, giao diện dòng lệnh cũng hiển thị các request đến, giúp bạn quan sát nhanh mà không cần mở trình duyệt.
  • Mã QR để test trên thiết bị di động: Khi bắt đầu chia sẻ một site, Expose hiển thị mã QR để bạn có thể quét bằng điện thoại hoặc máy tính bảng và truy cập ngay lập tức vào URL công khai.
  • Xác thực cơ bản (Basic Authentication): Có thể thêm lớp bảo vệ username/password cho tunnel, hữu ích khi chia sẻ với khách hàng hoặc đội ngũ nội bộ.
  • Hỗ trợ subdomain tùy chỉnh: Plan Pro cho phép đặt tên subdomain cố định, giúp bạn không cần cập nhật lại URL mỗi khi kết nối lại.
  • Tích hợp Laravel Herd: Nếu bạn đang sử dụng Laravel Herd, Expose đã được tích hợp sẵn, chỉ cần cấu hình token là dùng được ngay.
  • Hỗ trợ Docker: Expose cung cấp Docker image chính thức để triển khai server tự host một cách nhanh chóng và nhất quán.

Các phương án sử dụng Expose

Expose có ba hình thức sử dụng chính:

  1. Free Plan (Managed): Dùng server miễn phí tại trung tâm dữ liệu ở Đức (EU), subdomain ngẫu nhiên, có giới hạn thời gian kết nối. Phù hợp với việc thử nghiệm nhanh hoặc demo tạm thời.
  2. Expose Pro (Managed): Mạng lưới server toàn cầu, subdomain cố định, custom domain, không giới hạn thời gian, hỗ trợ đội nhóm. Phù hợp với môi trường làm việc chuyên nghiệp hoặc team.
  3. Self-hosted: Tự host server trên hạ tầng của bạn, toàn quyền kiểm soát dữ liệu, phù hợp với các tổ chức có yêu cầu bảo mật hoặc riêng tư cao.

Yêu cầu hệ thống

Trước khi cài đặt Expose, cần đảm bảo:

  • PHP: Phiên bản hiện đại (PHP 8.0 trở lên được khuyến nghị)
  • Composer (nếu cài đặt qua Composer)
  • Kết nối internet để kết nối đến server Expose hoặc server tự host

Cài đặt Expose Client

Cách 1: Qua PHAR Archive (Khuyến nghị cho máy tính cá nhân)

Đây là phương pháp đơn giản nhất, chỉ cần có PHP trên máy:

# Tải file thực thi
curl https://github.com/exposedev/expose/raw/master/builds/expose -L --output expose

# Cấp quyền thực thi
chmod +x expose

# Chuyển vào thư mục trong PATH để gọi từ bất kỳ đâu
sudo mv expose /usr/local/bin/expose

Sau bước này, lệnh expose có thể được gọi từ bất kỳ thư mục nào trong hệ thống.

Cách 2: Qua Composer Global

Nếu bạn đã sử dụng Composer trong quá trình phát triển PHP:

composer global require exposedev/expose

Tiếp theo, đảm bảo thư mục bin của Composer global được thêm vào biến môi trường PATH. Thêm dòng sau vào file ~/.bash_profile hoặc ~/.bashrc (Linux/macOS):

export PATH=~/.composer/vendor/bin:$PATH

Sau đó áp dụng thay đổi:

source ~/.bash_profile

Cách 3: Laravel Herd

Nếu bạn đang sử dụng Laravel Herd, Expose đã được cài sẵn. Không cần thêm bước nào, chỉ cần cấu hình token là sử dụng được.

Cập nhật Expose lên phiên bản mới nhất

expose self-update

Cấu hình xác thực (Authentication Token)

Sau khi cài đặt, bước tiếp theo là cấu hình token xác thực. Truy cập expose.dev/register để tạo tài khoản miễn phí và lấy
token.

Thiết lập token bằng lệnh:

expose token YOUR_TOKEN_HERE

Lệnh này sẽ tự động cập nhật file cấu hình tại ~/.expose/config.php.

Nếu bạn dùng Laravel Herd, có thể cấu hình token trực tiếp trong giao diện cài đặt của Herd mà không cần dùng dòng lệnh.

Chia sẻ site đầu tiên với Expose

Chia sẻ một URL localhost cơ bản

# Chia sẻ ứng dụng chạy trên cổng 3000
expose share http://localhost:3000

# Chia sẻ ứng dụng chạy trên cổng 8000
expose share http://localhost:8000

Ngay sau khi chạy, Expose hiển thị URL công khai để chia sẻ, ví dụ: https://random-name.sharedwithexpose.com.

Chia sẻ một local domain

Nếu bạn sử dụng Laravel Valet, Laravel Herd hoặc cấu hình host tùy chỉnh:

expose share my-local-site.dev

# Chia sẻ qua HTTPS cục bộ
expose share https://my-local-site.dev

Chia sẻ với subdomain tùy chỉnh (Pro)

expose share http://localhost:8000 --subdomain=myapp

Lệnh trên sẽ tạo URL cố định dạng myapp.sharedwithexpose.com, rất hữu ích khi phải cấu hình endpoint webhook một lần cho cả dự án.

Chia sẻ với xác thực cơ bản

Để bảo vệ tunnel bằng username và password:

expose share my-site.test --basicAuth="admin:secret"

# Kết hợp với subdomain tùy chỉnh
expose share my-site.test --subdomain=site --basicAuth="admin:secret"

Ngoài ra, bạn có thể khai báo thông tin xác thực trong file expose.yml ở thư mục gốc của dự án để không cần truyền tham số mỗi lần chạy:

auth:
  username: admin
  password: secret

Sử dụng Dashboard để kiểm tra Request

Sau khi bắt đầu chia sẻ, mở trình duyệt và truy cập:

http://localhost:4040

Dashboard hiển thị toàn bộ các HTTP request đến theo thời gian thực. Đối với mỗi request, bạn có thể:

  • Xem đầy đủ headers của request và response
  • Xem body nội dung
  • Xem status code và thời gian xử lý
  • Replay request: Gửi lại đúng y request đó mà không cần kích hoạt lại webhook trên
    hệ thống ngoài – đặc biệt hữu ích khi debug payment gateway hoặc các hệ thống webhook
    phức tạp như Stripe, PayPal, hay các nền tảng thương mại điện tử

Kể từ Expose 3.0, tính năng replay còn cho phép chỉnh sửa nội dung request trước khi gửi lại, giúp việc kiểm thử trở nên linh hoạt hơn nhiều so với các công cụ tương tự.

Tự host Expose Server với Docker

Yêu cầu

  • Máy chủ đã cài Docker và Docker Compose
  • Tên miền trỏ đến IP máy chủ
  • Chứng chỉ SSL (có thể dùng Let’s Encrypt miễn phí)

Tạo cấu trúc thư mục

mkdir expose-server && cd expose-server
mkdir -p database

Tạo file docker-compose.yml

services:
  expose:
    image: beyondcodegmbh/expose-server:latest
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      - 8080:${PORT}
    environment:
      port: ${PORT}
      domain: ${DOMAIN}
      username: ${ADMIN_USERNAME}
      password: ${ADMIN_PASSWORD}
    restart: always
    volumes:
      - ./database/expose.db:/root/.expose

Cấu hình này sẽ:

  • Sử dụng Docker image chính thức của Expose server
  • Map cổng container ra cổng 8080 trên máy chủ
  • Lưu trữ cơ sở dữ liệu SQLite ra ngoài container để dữ liệu không bị mất khi restart
  • Tự động khởi động lại nếu container bị lỗi hoặc máy chủ reboot

Tạo file .env

PORT=8080
DOMAIN=yourdomain.com
ADMIN_USERNAME=yourusername
ADMIN_PASSWORD=yourpassword

Thay thế yourdomain.com, yourusernameyourpassword bằng thông tin thực tế của
bạn.

Khởi động server

docker compose up -d

Kiểm tra trạng thái:

docker compose ps

Giao diện quản trị có thể truy cập tại expose.yourdomain.com sau khi server hoạt động.

Cấu hình Nginx Reverse Proxy (Khuyến nghị)

Để bảo mật kết nối bằng HTTPS và hỗ trợ WebSocket đầy đủ, cấu hình Nginx như sau:

server {
    listen 443 ssl;
    server_name *.yourdomain.com yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_session_cache shared:SSL:10m;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Lưu ý quan trọng: Vì Expose tạo tunnel trên các subdomain động, Nginx phải được cấu hình với wildcard subdomain (*.yourdomain.com). Chứng chỉ SSL cũng cần là wildcard certificate tương ứng. Nếu dùng Let’s Encrypt, có thể lấy wildcard cert thông qua DNS challenge với Certbot.

Cấu hình Client kết nối đến Server Tự Host

Sau khi server tự host hoạt động, cần cấu hình client để kết nối vào đó thay vì server mặc định của Expose.

Tạo file cấu hình

expose publish

Lệnh này tạo file cấu hình tại ~/.expose/config.php.

Chỉnh sửa file cấu hình

Mở file ~/.expose/config.php và thêm thông tin server tự host:

return [
    // ... các tùy chọn khác

    'servers' => [
        'main' => [
            'host' => 'sharedwithexpose.com',
            'port' => 443,
        ],
        'my-server' => [
            'host' => 'yourdomain.com',
            'port' => 443, // hoặc 8080 nếu không dùng reverse proxy
        ],
    ],

    // Đặt server tự host làm mặc định
    'default_server' => 'my-server',

    // ... các tùy chọn khác
];

Thiết lập token cho server tự host

expose token YOUR-AUTH-TOKEN

Chia sẻ site qua server tự host

# Sử dụng server mặc định đã cấu hình
expose share http://localhost:8000

# Hoặc chỉ định rõ tên server
expose share http://localhost:8000 --server=my-server

Sử dụng cấu hình riêng cho từng dự án

Đối với các team làm việc trên nhiều dự án khác nhau với cấu hình Expose riêng biệt:

EXPOSE_CONFIG_FILE="/path/to/project-config.php" expose share myapp.test

Các lệnh CLI hay dùng

LệnhMô tả
expose share http://localhost:3000Chia sẻ ứng dụng trên cổng 3000
expose share myapp.testChia sẻ local domain
expose share myapp.test --subdomain=demoChia sẻ với subdomain tùy chỉnh
expose share myapp.test --basicAuth="user:pass"Chia sẻ với xác thực cơ bản
expose share myapp.test --server=my-serverChỉ định server cụ thể
expose token YOUR_TOKENThiết lập token xác thực
expose publishXuất file cấu hình
expose self-updateCập nhật lên phiên bản mới nhất

So sánh Expose với các giải pháp tương tự

Tính năngExposengrokCloudflare Tunnel
Mã nguồn mởKhông (client đóng)Không
Tự host serverKhôngCó (zero trust)
Viết bằng PHPKhôngKhông
Dashboard webHạn chế
Replay requestCó (plan trả phí)Không
Chỉnh sửa request trước replayCó (v3.0+)KhôngKhông
Basic authQua Access policy
Docker support
Tích hợp Laravel HerdKhôngKhông
Miễn phíCó (có giới hạn)Có (có giới hạn)
Giấy phépMITĐộc quyềnĐộc quyền

Xử lý một số lỗi thường gặp

Không kết nối được đến server

  • Kiểm tra tên miền đã trỏ đúng vào IP máy chủ chưa
  • Kiểm tra tường lửa (firewall) trên máy chủ đã mở cổng tương ứng chưa
  • Kiểm tra lại thông tin hostport trong file cấu hình client
  • Một số mạng nội bộ chặn kết nối WebSocket; thử dùng cổng 443 với SSL

Test kết nối nhanh bằng:

curl -vI https://yourdomain.com

Lỗi xác thực token

  • Kiểm tra token đã được sao chép chính xác chưa
  • Chạy lại expose token YOUR_TOKEN để ghi đè cấu hình cũ
  • Kiểm tra tùy chọn “Validate Authentication Tokens” trong admin dashboard của server

Xác nhận token đã được lưu đúng bằng cách:

expose token YOUR_TOKEN
cat ~/.expose/config.php

Dashboard không hiển thị request

  • Đảm bảo đang truy cập đúng http://localhost:4040 (không phải HTTPS)
  • Kiểm tra cổng 4040 có bị chặn bởi firewall cục bộ không
  • Thử khởi động lại expose share nếu dashboard bị treo

Lỗi SSL với wildcard certificate

  • Xác nhận chứng chỉ SSL đã bao gồm wildcard subdomain (*.yourdomain.com)
  • Nếu dùng Let’s Encrypt, sử dụng DNS challenge thay vì HTTP challenge để lấy wildcard cert
  • Kiểm tra cấu hình Nginx đã bao gồm cả *.yourdomain.com trong server_name

Câu hỏi thường gặp

Expose có hoàn toàn miễn phí không?

Lõi của Expose là mã nguồn mở và miễn phí. Dịch vụ managed miễn phí có giới hạn thời gian kết nối và sử dụng server EU với subdomain ngẫu nhiên. Nếu cần subdomain cố định, mạng toàn cầu hoặc custom domain, cần nâng lên Expose Pro.

Expose có thể dùng để nhận webhook không?

Có. Đây là một trong những use case chính của Expose. Tính năng replay request trên dashboard giúp việc debug webhook trở nên đơn giản hơn nhiều so với các công cụ khác.

Có thể tự host Expose Server mà không cần Docker không?

Có. Expose server cũng là một ứng dụng PHP và có thể chạy trực tiếp bằng PHP mà không cần Docker, tuy nhiên Docker là phương án được khuyến nghị vì đơn giản hóa việc cài đặt và bảo trì.

Expose có hỗ trợ tunnel TCP không?

Expose hiện tại tập trung chủ yếu vào HTTP/HTTPS tunnel. Hỗ trợ TCP thuần chưa được tích hợp chính thức như ngrok. Nếu cần tunnel TCP, ngrok hoặc frp có thể là lựa chọn phù hợp hơn cho use case đó.


Expose là lựa chọn xuất sắc cho các PHP developer và Laravel developer đang cần một công cụ tunnel linh hoạt, có thể tự host và hoàn toàn có thể kiểm soát. Việc được viết bằng PHP giúp toàn bộ cộng đồng PHP dễ dàng đóng góp, tùy chỉnh và mở rộng công cụ này theo nhu cầu thực tế.

Với khả năng tự host trên Docker, dashboard trực quan, tính năng replay và chỉnh sửa webhook, tích hợp sẵn trong Laravel Herd, và giấy phép MIT cho phép sử dụng tự do, Expose đáp ứng được cả nhu cầu phát triển cá nhân lẫn môi trường nhóm hoặc doanh nghiệp có yêu cầu bảo mật dữ liệu nghiêm ngặt.

Duy Nghiện
Hãy làm khán giả, đừng làm nhân vật chính :)

You may also like

Nhận thông báo qua email
Nhận thông báo cho
guest

0 Bình luận
Mới nhất
Cũ nhất Nhiều like nhất
Phản hồi nội tuyến
Xem tất cả bình luận