VPS

Build APK Android trên VPS Linux từ A đến Z

Thanh Nguyễn Đăng 15 phút đọc 12 khối lệnh

Build APK Android trên VPS Linux từ A đến Z
Mục lục bài viết
  1. Chuẩn bị máy: ba thứ cần cài và một thứ dễ quên
  2. Chạy lệnh build và hiểu mình đang tạo ra file gì
  3. Ký file: phần quan trọng nhất và cũng dễ sai nhất
  4. Tự động hóa: mỗi lần đẩy code là có bản mới
  5. Cấu hình máy nên chọn và giới hạn phải biết
  6. Cài JDK và công cụ dòng lệnh
  7. Cài đúng thành phần và chấp nhận giấy phép
  8. Chạy thử và tinh chỉnh Gradle
  9. Chuẩn bị cho CI và nhiều người dùng chung
  10. Ký tệp: phần quan trọng nhất và dễ sai nhất
  11. Cấu hình máy và giới hạn cần biết
  12. Ba việc giảm thời gian dựng
  13. Câu hỏi thường gặp
  14. Bài viết liên quan

Trả lời nhanh: Build Android không cần máy có màn hình và không cần Android Studio. Trên một VPS Linux, bạn chỉ cần JDK, bộ Android SDK command line tools và Gradle là chạy được lệnh dựng ra file APK hoặc AAB. Đây là điểm khác biệt lớn so với iOS, vốn bắt buộc máy macOS. Phần tốn thời gian nhất là Gradle, và đó cũng là chỗ ổ đĩa nhanh giúp nhiều nhất.

Nhiều đội làm app Android vẫn build trên máy cá nhân của một bạn trong nhóm, và mọi thứ chỉ ổn cho tới khi bạn đó nghỉ phép hoặc máy hỏng. Chuyển việc build lên một máy chủ riêng giải quyết cả hai chuyện: ai cũng lấy được bản mới nhất, và máy cá nhân không còn phải è cổ mỗi lần đóng gói. Bài này đi trọn quy trình dựng máy build Android trên VPS Linux, từ lệnh cài đầu tiên tới lúc có file APK ký sẵn để đưa lên cửa hàng.

Chuẩn bị máy: ba thứ cần cài và một thứ dễ quên

Bắt đầu với một VPS Ubuntu sạch, tối thiểu 4GB RAM (8GB thì dễ thở, vì Gradle mặc định xin khá nhiều bộ nhớ). Cài JDK trước:

TerminalChuẩn bị máy: ba thứ cần cài và một thứ dễ quênbash
sudo apt update && sudo apt install -y openjdk-17-jdk unzip wgetjava -version   # xác nhận đã có JDK 17

Tiếp theo là Android SDK. Đừng tải Android Studio, chỉ cần bộ công cụ dòng lệnh:

TerminalChuẩn bị máy: ba thứ cần cài và một thứ dễ quênbash
mkdir -p ~/android/cmdline-tools && cd ~/android/cmdline-toolswget https://dl.google.com/android/repository/commandlinetools-linux-latest.zip -O tools.zipunzip tools.zip && mv cmdline-tools latestexport ANDROID_HOME=$HOME/androidexport PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools

Đường dẫn tệp tải về thay đổi theo thời gian, nên lấy liên kết mới nhất từ trang tải chính thức của Android thay vì chép cứng. Sau đó cài đúng các gói dự án cần và nhận giấy phép, đây chính là thứ dễ quên khiến lệnh build dừng giữa chừng với thông báo chưa chấp nhận điều khoản:

TerminalChuẩn bị máy: ba thứ cần cài và một thứ dễ quênbash
sdkmanager "platform-tools" "platforms;android-35" "build-tools;35.0.0"yes | sdkmanager --licenses

Cuối cùng thêm hai dòng export ở trên vào ~/.bashrc để lần đăng nhập sau không phải gõ lại.

Chạy lệnh build và hiểu mình đang tạo ra file gì

Vào thư mục dự án và dùng Gradle wrapper có sẵn trong repo, không cài Gradle riêng:

TerminalChạy lệnh build và hiểu mình đang tạo ra file gìbash
./gradlew assembleRelease     # tạo file APK bản release./gradlew bundleRelease       # tạo file AAB để nộp lên Google Play

Phân biệt cho đúng: APK là file cài trực tiếp lên máy, dùng để gửi cho khách thử hoặc phát hành ngoài cửa hàng. AAB là định dạng Google Play yêu cầu khi nộp bản mới, cửa hàng tự cắt ra APK phù hợp cho từng dòng máy. Nếu bạn định lên Play thì bản chính thức phải là AAB.

Lần build đầu luôn lâu vì Gradle tải toàn bộ phụ thuộc, thường vài phút tới hơn chục phút tùy dự án và đường truyền. Các lần sau nhanh hơn nhiều nhờ cache. Với dự án Flutter hay React Native, lệnh gọi khác một chút nhưng bên dưới vẫn là Gradle chạy đúng những bước này, nên phần chuẩn bị máy ở trên dùng chung được.

Ký file: phần quan trọng nhất và cũng dễ sai nhất

Google Play chỉ nhận bản đã ký bằng khóa của bạn. Tạo keystore một lần và giữ cẩn thận, vì mất keystore đồng nghĩa không cập nhật được ứng dụng đang có trên cửa hàng:

TerminalKý file: phần quan trọng nhất và cũng dễ sai nhấtbash
keytool -genkey -v -keystore shop.jks -keyalg RSA -keysize 2048   -validity 10000 -alias shop

Ba quy tắc bắt buộc. Một, không commit keystore vào Git, kể cả repo riêng tư. Hai, không viết mật khẩu vào file cấu hình trong repo, hãy đọc từ biến môi trường:

TerminalKý file: phần quan trọng nhất và cũng dễ sai nhấtbash
// trong build.gradle, đọc mật khẩu từ biến môi trườngsigningConfigs {    release {        storeFile file(System.getenv("KEYSTORE_PATH"))        storePassword System.getenv("KEYSTORE_PASS")        keyAlias System.getenv("KEY_ALIAS")        keyPassword System.getenv("KEY_PASS")    }}

Ba, sao lưu keystore ra ít nhất hai nơi ngoài máy chủ build, ví dụ trong trình quản lý mật khẩu tự host theo bài Vaultwarden. Đây là loại mất mát không có cách cứu.

Tự động hóa: mỗi lần đẩy code là có bản mới

Khi máy build đã chạy tay được, bước tiếp theo là để nó tự chạy. Hai đường phổ biến. Đường một, cài self hosted runner của GitHub Actions ngay trên VPS này, mỗi lần có commit vào nhánh phát hành thì runner tự build và cất file ra một thư mục hoặc đẩy lên nơi lưu trữ. Cách làm nằm ở bài runner tự host, và lý do tiết kiệm nằm ở bài CI/CD tự host.

Đường hai, viết một script build rồi gọi bằng cron hoặc gọi tay qua SSH, đủ dùng cho đội hai ba người. Dù chọn đường nào, hãy để agent AI viết giúp phần script và file cấu hình CI, vì đó là loại việc lặp khuôn mà nó làm nhanh và ít sai. Trước khi giao, đặt sẵn ràng buộc cho agent theo bài viết file luật CLAUDE.md, nhất là điều cấm đụng vào keystore. Nhớ ghi rõ trong yêu cầu là không được đưa mật khẩu keystore vào file cấu hình.

Một mẹo tiết kiệm thời gian đáng kể: bật cache Gradle dùng chung giữa các lần chạy thay vì để mỗi lần tải lại từ đầu. Chỉ riêng việc này thường cắt hơn một nửa thời gian build ở các lần sau.

Cấu hình máy nên chọn và giới hạn phải biết

Cấu hình: 4 vCPU và 8GB RAM là điểm dễ chịu cho dự án vừa. Gradle chạy song song nhiều tác vụ nên CPU nhiều nhân giúp thấy rõ, còn RAM dưới 4GB thì hay gặp lỗi hết bộ nhớ khi biên dịch. Về ổ đĩa, build Android là kiểu tải đọc ghi hàng vạn file nhỏ, giống hệt hiện tượng phân tích trong bài npm install chậm, nên ổ NVMe rút ngắn thời gian rõ rệt so với ổ thường. Dung lượng nên từ 60GB trở lên vì SDK, cache Gradle và các bản dựng tích lũy rất nhanh. Chính máy này cũng dùng được làm máy dev từ xa, khỏi phải nuôi hai máy riêng.

Giới hạn phải biết: máy Linux này không build được ứng dụng iOS. Ký và đóng gói file IPA bắt buộc chạy trên macOS, đó là ràng buộc của Apple chứ không phải chuyện cấu hình. Nếu dự án của bạn làm cả hai nền tảng, mô hình thực tế là dùng VPS Linux cho Android, cho backend và cho phần tự động hóa, còn phần iOS thì cần một máy Mac hoặc dịch vụ máy Mac đám mây. Nói rõ ranh giới này ngay từ đầu giúp bạn khỏi mua nhầm hạ tầng.

Cài JDK và công cụ dòng lệnh

TerminalCài JDK và công cụ dòng lệnhbash
sudo apt updatesudo apt install -y openjdk-17-jdk unzip wget git # Bo cong cu dong lenh cua Android SDKsudo mkdir -p /opt/android-sdk/cmdline-toolscd /tmpwget https://dl.google.com/android/repository/commandlinetools-linux-latest.zipunzip commandlinetools-linux-latest.zipsudo mv cmdline-tools /opt/android-sdk/cmdline-tools/latest

Phiên bản JDK phải khớp với yêu cầu của dự án. Dự án dùng plugin Android Gradle đời mới thường cần JDK 17, dự án cũ hơn có khi vẫn ở JDK 11. Cài sai bản là nguyên nhân của những thông báo lỗi rất khó hiểu, nên hãy mở file cấu hình Gradle của dự án ra xem trước.

Sau đó khai báo biến môi trường cho mọi phiên đăng nhập:

TerminalCài JDK và công cụ dòng lệnhbash
# /etc/profile.d/android.shexport JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64export ANDROID_HOME=/opt/android-sdkexport PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools

Cài đúng thành phần và chấp nhận giấy phép

TerminalCài đúng thành phần và chấp nhận giấy phépbash
# Xem du an yeu cau phien ban nao roi cai dung phien ban dosdkmanager "platform-tools"            "platforms;android-35"            "build-tools;35.0.0" # Buoc bat buoc, thieu la build dung giua chungyes | sdkmanager --licenses

Bước chấp nhận giấy phép là chỗ vấp kinh điển. Trên máy cá nhân, Android Studio hỏi và bạn bấm đồng ý nên không để ý. Trên máy chủ không có ai bấm, nên nếu quên thì bản dựng chạy được một lúc rồi dừng với thông báo về giấy phép chưa được chấp nhận, thường vào đúng lúc bạn đang vội.

Về số phiên bản: đừng cài bừa bản mới nhất. Mở file build.gradle của dự án, xem compileSdk và buildToolsVersion rồi cài đúng những bản đó. Cài dư chỉ tốn đĩa, cài thiếu thì Gradle tự tải và làm bản dựng đầu tiên lâu bất thường.

Chạy thử và tinh chỉnh Gradle

TerminalChạy thử và tinh chỉnh Gradlebash
git clone <repo> && cd <repo>chmod +x gradlew./gradlew assembleDebug

Lần đầu sẽ lâu vì Gradle tải toàn bộ thư viện phụ thuộc. Những lần sau nhanh hơn nhiều nhờ bộ nhớ đệm, miễn là bạn giữ nguyên thư mục ~/.gradle.

Hai tinh chỉnh đáng làm trong file gradle.properties:

TerminalChạy thử và tinh chỉnh Gradlebash
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1gorg.gradle.parallel=trueorg.gradle.caching=true

Con số bộ nhớ phải nhỏ hơn RAM thật của máy, chừa lại phần cho hệ điều hành. Đặt -Xmx bằng đúng dung lượng RAM là công thức chắc chắn dẫn tới tiến trình bị giết. Trên máy 8GB, mức 4g là an toàn.

Nếu máy hay chạm trần bộ nhớ vào lúc cao điểm, thêm vài GB swap. Swap chậm hơn RAM nhiều nhưng đóng vai trò lưới an toàn, giúp bản dựng chậm lại thay vì chết hẳn.

Chuẩn bị cho CI và nhiều người dùng chung

Vài việc biến máy này thành hạ tầng dùng được lâu dài:

  • Tạo người dùng riêng cho CI, không dùng tài khoản quản trị. Cấp cho nó quyền đọc SDK và quyền ghi trong thư mục làm việc, thế là đủ.
  • Dọn rác định kỳ. Thư mục build của các dự án và bộ nhớ đệm Gradle phình rất nhanh. Một tác vụ định kỳ hằng tuần xóa bản dựng cũ giúp bạn khỏi cảnh đầy ổ vào ngày phát hành.
  • Giữ keystore ở nơi an toàn, đừng để trong repo. Đây là chìa khóa ký ứng dụng, mất là mất luôn khả năng cập nhật app trên cửa hàng.
  • Cắm vào CI theo cách trong bài runner tự host, để mỗi lần đẩy code là có bản dựng mới.

Toàn bộ quy trình từ mã nguồn tới file APK cài được nằm ở bài build APK trên VPS Linux, đọc tiếp bài đó sau khi máy đã dựng xong.

Ký tệp: phần quan trọng nhất và dễ sai nhất

ViệcVì sao quan trọngHậu quả nếu sai
Giữ tệp khóa ký ở nơi an toànMất là không cập nhật được ứng dụng đã phát hànhPhải phát hành lại dưới tên gói khác, mất toàn bộ người dùng cũ
Không đưa tệp khóa vào kho mã nguồnAi có khóa là ký được ứng dụng giả danh bạnRủi ro rất cao
Sao lưu tệp khóa ở ít nhất hai nơiĐây là tài sản không thay thế đượcMất là không có cách khôi phục
Dùng khóa riêng cho bản thử và bản phát hànhTránh nhầm lẫn khi phát hànhKý nhầm khóa là bản cập nhật bị từ chối

Nói thẳng: mất tệp khóa ký là sự cố không sửa được. Người dùng đã cài ứng dụng của bạn sẽ không nhận được bản cập nhật nào nữa, và bạn phải phát hành lại như một ứng dụng hoàn toàn mới. Sao lưu nó như sao lưu giấy tờ nhà.

Cấu hình máy và giới hạn cần biết

TerminalCấu hình máy và giới hạn cần biếtbash
# Bo nho la thu cham tran truoc, khong phai so nhan# Toi thieu 4 GB, nen co 8 GB cho du an that # Kiem trong luc buildwatch -n2 'free -h'dmesg | tail -20 | grep -i "out of memory\|killed process" # Neu bi dung tien trinh: dat vung nho tamfallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfileecho '/swapfile none swap sw 0 0' >> /etc/fstab # Gioi han bo nho cho tien trinh buildexport GRADLE_OPTS="-Xmx3g" # Don bo nho dem dinh ky, no phinh rat nhanhdu -sh ~/.gradle ~/.android 2>/dev/nullrm -rf ~/.gradle/caches/build-cache-*
Quy mô dự ánBộ nhớỔ đĩa
Dự án nhỏ, ít thư viện4 GB40 GB
Dự án thật, nhiều thư viện8 GB80 GB
Dự án lớn, nhiều biến thể bản dựng16 GB160 GB

Ba việc giảm thời gian dựng

  • Giữ bộ nhớ đệm giữa các lần dựng. Đây là thay đổi cho hiệu quả lớn nhất, nhất là khi dựng trong container.
  • Ổ NVMe tạo khác biệt rõ, vì dựng là thao tác đọc ghi hàng chục nghìn tệp nhỏ.
  • Chỉ dựng biến thể cần thiết, đừng dựng tất cả biến thể mỗi lần.

Về máy chủ: xem VPS NVMe. Về quy trình dựng tự động, xem bài về triển khai tự động.

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

VPS Linux có build được app iOS không?

Không. Việc biên dịch, ký và đóng gói IPA phụ thuộc công cụ chỉ chạy trên macOS. VPS Linux vẫn hữu ích cho phần backend, API, kho lưu bản dựng và tự động hóa những bước không cần Mac, nhưng bước tạo file cài đặt iOS thì bắt buộc có máy Mac.

Build Flutter hoặc React Native có khác gì không?

Phần chuẩn bị máy giống hệt vì bên dưới vẫn là Gradle, chỉ khác lệnh gọi và cần cài thêm bộ công cụ tương ứng của Flutter hoặc Node. Thời gian build thường lâu hơn dự án Android thuần vì có thêm bước biên dịch của framework.

Lỗi hết bộ nhớ khi chạy Gradle thì xử lý thế nào?

Tăng RAM cho máy là cách chắc nhất, hoặc giới hạn bộ nhớ cho Gradle và daemon Kotlin trong file gradle.properties. Nếu máy chỉ có 4GB, hãy giảm số tác vụ chạy song song. Trên máy nhiều dự án, tắt daemon sau mỗi lần build để giải phóng bộ nhớ.

Có cần emulator trên máy build không?

Không cần nếu bạn chỉ đóng gói. Emulator chỉ cần khi muốn chạy kiểm thử giao diện tự động, và nó nặng hơn nhiều, đòi hỗ trợ ảo hóa lồng nhau nên phải kiểm tra trước với nhà cung cấp. Phần lớn đội nhỏ chỉ build trên máy chủ rồi cài thử trên máy thật.

Có cần cài Android Studio trên máy chủ không?

Không, và không nên. Bản có giao diện chiếm hàng chục GB cùng nhiều thành phần vô dụng trên máy không màn hình. Bộ công cụ dòng lệnh làm đúng phần việc build với dung lượng nhỏ hơn nhiều lần.

Máy build Android cấu hình bao nhiêu là đủ?

4 vCPU và 8GB RAM là mức khởi đầu tốt cho dự án vừa. Dự án lớn hoặc build nhiều nhánh song song nên lên 8 vCPU và 16GB. Dung lượng đĩa nên từ 60GB vì SDK và bản dựng trung gian chiếm nhanh.

Vì sao build chạy được một lúc rồi dừng?

Hai nguyên nhân phổ biến. Một là chưa chấp nhận giấy phép SDK, chạy lệnh sdkmanager với tham số licenses là xong. Hai là hết bộ nhớ nên tiến trình bị hệ điều hành giết, khi đó hãy giảm mức Xmx của Gradle hoặc nâng RAM.

Máy này build được app Flutter và React Native không?

Được, vì cả hai đều dùng chuỗi công cụ Android bên dưới cho nhánh Android. Bạn chỉ cần cài thêm bộ công cụ của nền tảng tương ứng. Riêng nhánh iOS thì vẫn phải qua máy Mac, không có đường vòng.

Chia sẻ:Facebook

Thanh Nguyễn

TND

Tư vấn bản quyền, VPS và máy chủ kèm hóa đơn VAT, hợp đồng đầy đủ cho doanh nghiệp.