Chia sẻ kinh nghiệm deploy Ruby on Rails trên CentOS
This post hasn't been updated for 8 years
Chào mọi người, việc deploy Ruby on Rails trên Ubuntu hẳn nhiên đã quá quen thuộc, tuần vừa qua mình có việc cần deploy trên CentOS, khi đó cả đống vấn đề nảy sinh. Có thể do kiến thức mình chưa nắm được nên gặp khó khăn, tuy nhiên mình vẫn muốn chia sẻ mọi người kinh nghiệm deploy với bọn CentOS này.
Tiện đang mượn được tài khoản AWS, mình hướng dẫn luôn việc tạo và deploy trên AWS. Đầu tiên là cần tạo một instance trong trang quản lý EC2 của AWS. Mình chỉ muốn lưa ý một số điều như sau :
-
Để có thể tạo instance CentOS, sau khi chọn Lauch Instance, bạn cần chọn tab AWS Marketplace, vì mặc định bạn sẽ chỉ tìm thấy Ubuntu và Windows. Tại đây bạn search theo từ khóa CentOS và chọn một bản mà bạn thích.
-
Trong khi tạo instance, tới bước thứ 6 : Step 6: Configure Security Group. Bạn hay thêm ít nhất là rule HTTP vào nhé, default chỉ có SSH
Vậy là xong, giờ bạn có một instance CentOS đủ để thí nghiệm.
Giờ đến phần chính, tạo môi trường để deploy.
Chuẩn bị môi trường
Mặc định bên EC2 sẽ tạo cho bạn account centos
, bạn hãy thạo thêm một account khác là deploy
cho nó chuyên nghiệp cũng như rõ ràng hơn cho việc quản lý sau này. .
Trước khi làm gì, update phát cho mới mẻ nhỉ, mình rất thích update
sudo yum -y update
Rồi, giờ tới tạo tài khoản deploy
và set password cho nó :
sudo adduser deploy
sudo passwd deploy
Mở file visudo
bằng lệnh sudo visudo
và thêm đoạn code này và vào
deploy ALL=(ALL) ALL
Vậy là tạm ổn rồi, hãy chuyển sang sử dụng account này để nghịch
su - deploy
Việc cần làm tiếp theo là thêm công 80 vào IP table, mở file /etc/sysconfig/iptables
bằng công cụ gì bạn thích, tìm dòng
-A INPUT -i lo -j ACCEPT
và đưa đoạn này vào ngay dưới nó :
-A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
Tóm lại bạn sẽ có nội dung tương tự như sau : ...
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
...
Sau đó restart lại server iptables :
sudo service iptables restart
Cài đặt các phần mềm cần thiết
Nếu thích bạn có thể cài cả gói công cụ này vào, trong đó có sẵn Git, hoặc trong trường hợp này bạn cài mỗi Git không thôi cũng được. Mình thì mình cứ cài cả, không dùng trước thì dùng sau
sudo yum groupinstall -y "development tools"
Trước khi cài những gói tiếp theo, bạn sẽ cần phải enable EPEL repository lên, như bản thân bọn CentOS từ AWS này, base repo sẽ không có nginx, NodeJS ... :
sudo yum install epel-release
(Dùng cho CentOS 6.x, bản 7 không biết dùng được không, nếu không bạn cứ search theo từ khóa EPEL repo là ra)
Xong, giờ ung dung cài lần lượt các gói sau:
sudo yum install -y nodejs
sudo yum install -y nginx
sudo yum install mysql-server
sudo yum install mysql-devel
Nếu bạn sử dụng server CentOS do khách hàng đã cấu hình từ trước, hoặc vấn đề nào đó các app bạn cài bên trên không start được hoặc không như mong muốn, thì khả năng cao bên đó đang để cài default app từ repo mà họ sắp đặt từ trước. Khi đó bạn có thể gỡ app ra, và cài lại app trực tiếp từ repo base. Mình đã thử và thành công khi cài xong mysql-server
và mysql-devel
nhưng không thể nào cài nổi gem mysql2
...
sudo yum --disablerepo="*" --enablerepo="base" install APP_U_WANT
Cài Ruby on Rails
Mình sẽ dùng rvm
để cài Ruby.
gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
curl -L https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
rvm requirements
rvm install 2.3.1
rvm use 2.3.1 --default
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
gem install bundler
gem install rails
Xong !
Cấu hình SSH
Đầu tiên là bạn cần add SSH pubic key của máy client bạn muốn deploy lên server. Nếu máy bạn chưa có SSH public key thì có thể tạo bằng lệnh :
ssh-keygen
Nếu trên server của bạn chưa có sẵn file /.ssh/authorized_keys
(Nếu dùng tài khoản deploy mình vừa tạo thì chắc chắn sẽ không có). Dùng lệnh sau để tạo :
mkdir ~/.ssh
touch ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Rồi, giờ lấy SSH pubic key của máy bạn cat ~/.ssh/id_rsa.pub
, rồi vất lên file authorized_keys
ta vừa tại trên server.
Giờ đến lượt làm sao để server có thể lấy được code từ GitHub về. Tương tự trên, bạn lấy SSH public key của server, đưa vào danh sách Deploy keys trên trang cài đặt repo của bạn trên GitHub.
Khởi tạo database
Phải start service của mysql lên đã nhỉ?
sudo service mysqld start
Sau đó tạo một database bằng lệnh
mysql -u root -e "create database database_name_u_want"
Init project
Mình sẽ để project cần chạy theo đường dẫn /usr/local
, còn bạn muốn đặt đâu thì tùy. Giả sử project của mình tên ZZZ
sudo mkdir /usr/local/ZZZ
sudo mkdir -p /usr/local/ZZZ/shared/config
sudo vi /usr/local/ZZZ/shared/config/database.yml
(Điền thông tin database của bạn vào)
sudo vi /usr/local/ZZZ/shared/config/application.yml
(Có thể sử dụng rake secret
trên máy local để tạo đoạn mã, rồi đưa vào file). Ví dụ :
SECRET_KEY_BASE: "775864793bfac59b168ad8928d612fe0057a4f36351e146c97da37f412c0c482723bced521598c26cfc6ceefc49f9186c50db04f656fd410138e50f93b687a17"
Rồi, giờ thì đổi quyền để account deploy
của ta có quyền đọc, ghi vào thư mục ta vừa tạo :
sudo chown -R deploy:root /usr/local/ZZZ
Xử lý vụ SELinux
Khái niệm chi tiết mình kiếm được, đọc cũng dễ hiểu nên post lại nguyên văn chính chủ cho mọi người tham khảo :
SELinux - Security-Enhanced Linux, là một module bảo mật trong Linux kernel được phát triển đầu tiên bởi Cơ quan An ninh Quốc Gia Hoa Kỳ (NSA), nhằm cung cấp một cơ chế an ninh và kiểm soát truy cập bắt buộc đối với các dịch vụ hoạt động trong hệ thống theo tiêu chuẩn của Bộ Quốc Phòng Hoa Kỳ.
SELinux kiểm soát các sửa đổi kernel và các công cụ trong không gian người dùng được thêm vào trong các bản phân phối Linux khác nhau. Kiến trúc của nó cố gắng tách biệt việc thực thi các quyết định an ninh với việc phân loại các dịch vụ cần thi hành các chính sách an ninh.
SELinux khoanh vùng các tập tin và tài nguyên mà các chương trình người dùng và máy chủ hệ thống được phép truy cập, qua đó hạn chế thiệt hại do các ứng dụng độc hại hoặc những ứng dụng lỗi gây ra. Cơ chế khoanh vùng của SELinux hoạt động độc lập với cơ chế kiểm soát truy cập truyền thống của Linux, bỏ qua tất cả các khái niệm và ưu tiên của super-user, và vì thế không có các thiếu sót của hệ thống cũ.
SELinux cung cấp nhiều lựa chọn như kiểm soát truy cập bắt buộc, điều khiển toàn vẹn bắt buộc, kiểm soát truy cập dựa trên vai trò người dùng, an ninh đa cấp và kiểu kiến trúc thực thi.
Đấy, nghe thì rất là tuyệt vời, nhưng nó có thể gây rắc rối cho Nginx của chúng ta. Có thể bạn sẽ gặp lỗi Nginx không thể động vào được socket, mất khá nhiều thời gian mới biết nó là do SELinux (Kiến thức hạn hẹp nó khổ vậy đó). Cụ thể ta sẽ làm đích xác như trong trả lời của post sau : (13: Permission denied) while connecting to upstream:[nginx]
sudo cat /var/log/audit/audit.log | grep nginx | grep denied | audit2allow -M mynginx
sudo semodule -i mynginx.pp
Sau khi chạy 2 lệnh do Joseph Barbere
hướng dẫn mà không có tác dụng, bạn chịu khó chạy lại 2 lệnh đó lần nữa. Hiện tại mình cũng chưa rõ tạo sao nhưng chạy 2 lần có tác dụng cho mình. Bác nào nghiên cứu ký hơn vụ này thì để lại comment bên dưới nhé.
Tổng kết
Bài viết trên là những kinh nghiệm mình gặp phải, cũng như cách thức xử lý mà mình tìm hiểu, lọ mọ tra cứu trên mạng. Còn những phần còn lại để deploy thì mình xin không đưa vào đây vì nó cũng không có vấn đề gì cần chia sẻ.
Bài viết được soạn bởi kiến thức còn non trẻ về Linux cũng như việc deploy, vậy nên sẽ không tránh khỏi sai sót, mong mọi người tích cực đóng góp ý kiến để mình hoàn thiện bài viết cũng như trau dồi thêm kiến thức.
All Rights Reserved