<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### 管理 Rails 應用程序 **Rails** 是一個非常受歡迎的 Web 應用程序框架(從某種意義上說,是由于它被廣泛應用而不是人們真正喜歡它)。 因此,在某些時候,你可能會被要求管理它。 本節要介紹的處方包含了安裝一臺運行 Rails 應用程序服務器所要做的絕大部分工作。 本處方假定你會使用 Nginx 和 **Passenger** 作為 Web 服務器, 然而你也可以輕松地修改本處方,使用 Apache 替換它。 #### 操作步驟 1. 創建 rails 模塊的目錄結構: ``` # mkdir /etc/puppet/modules/rails # mkdir /etc/puppet/modules/rails/manifests # mkdir /etc/puppet/modules/rails/templates # mkdir /etc/puppet/modules/rails/files ``` 2. 使用如下內容創建 /etc/puppet/modules/rails/manifests/init.pp 文件: ``` class rails { include rails::passenger package { "bundler": provider =&gt; gem, ensure =&gt; installed, } define app( $sitedomain ) { include rails file { "/opt/nginx/sites-available/${name}.conf": content =&gt; template("rails/app.conf.erb"), require =&gt; File["/opt/nginx/sites-available"], } file { "/opt/nginx/sites-enabled/${name}.conf": ensure =&gt; link, target =&gt; "/opt/nginx/sites-available/${name}.conf", require =&gt; File["/opt/nginx/sites-enabled"], notify =&gt; Exec["reload-nginx"], } file { "/opt/nginx/conf/includes/${name}.conf": source =&gt; [ "puppet:///modules/rails/${name}.conf", "puppet:///modules/rails/empty.conf" ], notify =&gt; Exec["reload-nginx"], } file { [ "/var/www", "/var/www/${name}", "/var/www/${name}/releases", "/var/www/${name}/shared", "/var/www/${name}/shared/config", "/var/www/${name}/shared/log", "/var/www/${name}/shared/system" ]: ensure =&gt; directory, mode =&gt; 775, owner =&gt; "www-data", group =&gt; "www-data", } } } ``` 3. 使用如下內容創建 /etc/puppet/modules/rails/manifests/passenger.pp 文件: ``` class rails::passenger { $passenger_version = "3.0.7" $passenger_dependencies = [ "build-essential", "libcurl4-openssl-dev", "libssl-dev", "ruby", "rubygems" ] package { $passenger_dependencies: ensure =&gt; installed } exec { "install-passenger": command =&gt; "/usr/bin/gem install passenger --version=${passenger_version}", unless =&gt; "/usr/bin/gem list | /bin/grep passenger |/bin/ grep ${passenger_version}", require =&gt; [ Package["rubygems"], Package[$passenger_ dependencies] ], timeout =&gt; "-1", } exec { "install-passenger-nginx-module": command =&gt; "/usr/lib/ruby/gems/1.8/gems/passenger- ${passenger_version}/bin/passenger-install-nginx-module --auto --auto-download --prefix=/opt/nginx", creates =&gt; "/opt/nginx/sbin/nginx", require =&gt; Exec["install-passenger"], timeout =&gt; "-1", } file { [ "/opt/nginx", "/opt/nginx/conf", "/opt/nginx/conf/includes", "/opt/nginx/sites-enabled", "/opt/nginx/sites-available", "/var/log/nginx" ]: ensure =&gt; directory, owner =&gt; "www-data", group =&gt; "www-data", } file { "/opt/nginx/sites-enabled/default": ensure =&gt; absent, require =&gt; Exec["install-passenger-nginx-module"], } file { "/opt/nginx/conf/nginx.conf": content =&gt; template("rails/nginx.conf.erb"), notify =&gt; Exec["reload-nginx"], require =&gt; Exec["install-passenger-nginx-module"], } file { "/etc/init.d/nginx": source =&gt; "puppet:///modules/rails/nginx.init", mode =&gt; "700", require =&gt; Exec["install-passenger-nginx-module"], } service { "nginx": enable =&gt; true, ensure =&gt; running, require =&gt; File["/etc/init.d/nginx"], } exec { "reload-nginx": command =&gt; "/opt/nginx/sbin/nginx -t && /etc/init.d/nginx reload", refreshonly =&gt; true, require =&gt; Exec["install-passenger-nginx-module"], } } ``` 4. 使用如下內容創建 /etc/puppet/modules/rails/templates/app.conf.erb 文件: ``` server { listen 80; root /var/www/&lt;%= name %&gt;/current/public; server_name &lt;%= sitedomain %&gt;; access_log /var/log/nginx/&lt;%= name %&gt;.access.log; error_log /var/log/nginx/&lt;%= name %&gt;.error.log; passenger_enabled on; passenger_min_instances 1; } passenger_pre_start http://&lt;%= sitedomain %&gt;; ``` 5. 使用如下內容創建 /etc/puppet/modules/rails/templates/nginx.conf.erb 文件: ``` events { worker_connections 1024; use epoll; } http { passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-&lt;%= passenger_version %&gt;; server_names_hash_bucket_size 64; sendfile on; tcp_nopush on; tcp_nodelay off; client_body_temp_path /var/spool/nginx-client-body 1 2; client_max_body_size 100m; include /opt/nginx/conf/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] ' $request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' ; access_log /var/log/nginx/access.log main; gzip on; gzip_http_version 1.0; gzip_comp_level 2; gzip_proxied any; gzip_min_length 1100; gzip_buffers 16 8k; gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_disable "MSIE [1-6].(?!.*SV1)"; gzip_vary on; include /opt/nginx/sites-enabled/*; } ``` 6. 使用如下內容創建 /etc/puppet/modules/rails/files/nginx.init 文件: ``` #!/bin/sh ### BEGIN INIT INFO # Provides: nginx # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the nginx web server # Description: starts nginx using start-stop-daemon ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/opt/nginx/sbin/nginx NAME=nginx DESC=nginx test -x $DAEMON || exit 0 # Include nginx defaults if available if [ -f /etc/default/nginx ] ; then . /etc/default/nginx fi set -e # Return LSB status, grabbed from a newer lsb-base status_of_proc () { local pidfile daemon name status pidfile= OPTIND=1 while getopts p: opt ; do case "$opt" in p) pidfile="$OPTARG";; esac done shift $(($OPTIND - 1)) if [ -n "$pidfile" ]; then pidfile="-p $pidfile" fi daemon="$1" name="$2" status="0" pidofproc $pidfile $daemon &gt;/dev/null || status="$?" if [ "$status" = 0 ]; then log_success_msg "$name is running" return 0 else log_failure_msg "$name is not running" return $status fi } . /lib/lsb/init-functions case "$1" in start) echo -n "Starting $DESC: " start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ --exec $DAEMON -- $DAEMON_OPTS || true echo "$NAME." ;; stop) echo -n "Stopping $DESC: " start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ --exec $DAEMON || true echo "$NAME." ;; restart|force-reload) echo -n "Restarting $DESC: " start-stop-daemon --stop --quiet --pidfile \ /var/run/$NAME.pid --exec $DAEMON || true sleep 1 start-stop-daemon --start --quiet --pidfile \ /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true echo "$NAME." ;; reload) echo -n "Reloading $DESC configuration: " start-stop-daemon --stop --signal HUP --quiet --pidfile \ /var/run/$NAME.pid --exec $DAEMON || true echo "$NAME." ;; status) status_of_proc -p /var/run/$NAME.pid "$DAEMON" nginx \ && exit 0 || exit $? ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|reload|forcereload| status}" &gt;&2 exit 1 ;; esac exit 0 ``` 7. 添加如下代碼到一個節點: ``` rails::app { "furiouspigs": sitedomain =&gt; "furiouspigs.com", } ``` 8. 運行 Puppet: ``` # puppet agent --test info: Retrieving plugin info: Caching catalog for cookbook.bitfieldconsulting.com info: Applying configuration version '1309960678' notice: /Stage[main]/Rails::Passenger/File[/opt/nginx]/ensure: created notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/sitesenabled]/ ensure: created notice: /Stage[main]//Node[cookbook]/Rails::App[furiouspigs]/ File[/opt/nginx/sites-enabled/furiouspigs.conf]/ensure: created notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf]/ ensure: created notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/ includes]/ensure: created notice: /Stage[main]//Node[cookbook]/Rails::App[furiouspigs]/ File[/opt/nginx/conf/includes/furiouspigs.conf]/ensure: defined content as '{md5}d41d8cd98f00b204e9800998ecf8427e' notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/sitesavailable]/ ensure: created notice: /Stage[main]//Node[cookbook]/Rails::App[furiouspigs]/ File[/opt/nginx/sites-available/furiouspigs.conf]/ensure: defined content as '{md5}c1a4c2bc4e7381b1c2f88dfee004a594' notice: /Stage[main]/Rails::Passenger/Exec[install-passenger]/ returns: executed successfully notice: /Stage[main]/Rails::Passenger/Exec[install-passengernginx- module]/returns: executed successfully --- /opt/nginx/conf/nginx.conf 2011-07-06 14:04:33.231999538 +0000 +++ /tmp/puppet-file20110706-5343-k8ouds-0 2011-07-06 14:04:34.246867124 +0000 ... info: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/nginx. conf]: Filebucketed /opt/nginx/conf/nginx.conf to puppet with sum 34d60856b6570e9d59cd6eecde5da000 notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/nginx. conf]/content: content changed '{md5}34d60856b6570e9d59cd6eecde5 da000' to '{md5}72132deeb45e6ee5b83cd246dffefc5f' info: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/nginx. conf]: Scheduling refresh of Exec[reload-nginx] notice: /Stage[main]/Rails::Passenger/Exec[reload-nginx]: Triggered 'refresh' from 1 events notice: Finished catalog run in 398.73 seconds ``` #### 工作原理 這個處方比本書中其他的處方更長、更復雜,因此需要更詳細的解釋。 如果你覺得這有些煩人,盡管去使用這個配方吧,不必擔心它是如何工作的。 稍后當你想學習更多詳細工作過程時,可以再回過頭來看這些解釋。 上面所有代碼的目的就是可以讓你寫出如下的實例化代碼: ``` rails::app { "furiouspigs": sitedomain => "furiouspigs.com", } ``` 這需要不少幕后工作。我們需要安裝配置包含 Passenger 模塊的 Nginx, 配置應用程序的虛擬主機,包括所有應用程序特定的配置(比如重定向以及其他服務配置), 安裝 Ruby 和 Rubygems,安裝 Bundler,并創建要部署的應用程序所需的所有目錄。 ##### Nginx 和 Passenger 此處分離出的 passenger.pp 文件用于安裝 Nginx 和 Passenger 所需的一切。 之前曾經提到過,Nginx 沒有像 Apache 一樣的動態模塊概念, 因此,你不能僅僅通過安裝發行版中的 Nginx 并安裝提供 Passenger 功能的軟件包來實現。 Nginx 必須與你想要的任何模塊一起編譯。 幸好,**Phusion** 社區里的好心人已經為我們提供了一個編譯腳本(passengerinstall-nginx-module)。 一旦你已經安裝了 Passenger 的 gem 包,這個腳本就會幫你完成編譯工作。 所以首先需要做的事就是安裝 Passenger 的 **gem**: ``` class rails::passenger { $passenger_version = "3.0.7" $passenger_dependencies = [ "build-essential", "libcurl4-openssl-dev", "libssl-dev", "ruby", "rubygems" ] package { $passenger_dependencies: ensure => installed } exec { "install-passenger": command => "/usr/bin/gem install passenger --version=${passenger_version}", unless => "/usr/bin/gem list | /bin/grep passenger \ |/bin/grep ${passenger_version}", require => [ Package["rubygems"], Package[$passenger_ dependencies] ], timeout => "-1", } ``` 我們把要安裝的 Passenger 版本號設置在變量 $passenger_version 中, 因為 Nginx 需要知道 Passenger 的安裝路徑(路徑中包括版本號)。 所以我們會在 nginx.conf 模板中引用 $passenger_version 變量。 下一步是運行 passenger-install-nginx-module 腳本: ``` exec { "install-passenger-nginx-module": command => "/usr/lib/ruby/gems/1.8/gems/passenger-${passenger_ version}/bin/passenger-install-nginx-module --auto --autodownload --prefix=/opt/nginx", creates => "/opt/nginx/sbin/nginx", require => Exec["install-passenger"], timeout => "-1", } ``` > ![注記](https://box.kancloud.cn/2016-05-12_5733eec619643.png) > 你應該注意到了,此處 **gem** 的路徑是固定的 /usr/lib/ruby/gems/1.8/gems。 這有些脆弱?—?在大部分生產基礎設施中,我使用 **RVM** 管理 Ruby 版本和不同版本的 **gemsets**, 這就解決了由于使用固定路徑帶來的脆弱性。 然而,添加 RVM 會使本處方變得難于理解,所以我將使用 RVM 的部分放在 更多用法 小節中。 一旦你熟悉了這個處方,就可以修改它,使之適合你自己的需求,包括整合 RVM。 這也就意味著,如果你使用 Ruby 1.9,這個處方不會工作,當本書出版后你讀到此處時很可能會發生這種情況。 如果是這樣,或者你遇到其他問題,請手工運行 gem contents passenger 命令之后查找 passenger-installnginx-module 腳本的路徑。 下一步,我們創建了 Nginx 配置文件所需的目錄結構: ``` file { [ "/opt/nginx", "/opt/nginx/conf", "/opt/nginx/conf/includes", "/opt/nginx/sites-enabled", "/opt/nginx/sites-available", "/var/log/nginx" ]: ensure => directory, owner => "www-data", group => "www-data", } ``` 我們要刪除默認的 Nginx 虛擬主機配置,否則可能會干擾我們要創建的虛擬主機。 這可以通過如下代碼實現: ``` file { "/opt/nginx/sites-enabled/default": ensure => absent, require => Exec["install-passenger-nginx-module"], } ``` 實際上,如果你從源代碼構建 Nginx 或是通過 Passenger 構建(本例中的方法),這是不需要的, 但是如果要想使本處方也適用于發行版的 Nginx 軟件包,這會是有益的。 下面是 Nginx 的主配置文件: ``` file { "/opt/nginx/conf/nginx.conf": content => template("rails/nginx.conf.erb"), notify => Exec["reload-nginx"], require => Exec["install-passenger-nginx-module"], } ``` 主配置文件使用 nginx.conf.erb 模板生成,因為我們需要插入之前定義的 Passenger 版本號: ``` passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-<%= passenger_ version %>; ``` 否則,它就是一個標準的 Nginx 配置,你也可以在模板中添加任何你的服務器所需的特殊參數。 因為我們沒有使用發行版提供的軟件包,所以我們需要為節點應用一個 init 腳本 (改編自 Ubuntu 版本,僅做了輕微的修改): ``` file { "/etc/init.d/nginx": source => "puppet:///modules/rails/nginx.init", mode => "700", require => Exec["install-passenger-nginx-module"], } ``` 為了運行 Nginx 服務需要如下代碼: ``` service { "nginx": enable => true, ensure => running, require => File["/etc/init.d/nginx"], } ``` 要確保錯誤的配置不會使服務器宕機,配置文件的改變會通知如下的 “配置檢查和重載” 資源: ``` exec { "reload-nginx": command => "/opt/nginx/sbin/nginx -t \ && /etc/init.d/nginx reload", refreshonly => true, require => Exec["install-passenger-nginx-module"], } ``` ##### Rails 你已經設置好了 Passenger 和 Nginx,接下來配置 **Rails** 需求的類: ``` class rails { include rails::passenger package { "bundler": provider => gem, ensure => installed, } } ``` **Bundler** 是一個管理應用程序或解決 gem 依賴關系的工具。 你可以使用手工方式(或通過 Puppet)指定要安裝的所有 gem 包以及依賴的包, 取代這種方式的更好辦法是使用 Bundler 來實現,它是 Rails 部署的一部分。 例如,你應該注意到了,我們沒有安裝 rails 的 gem;這通常是通過 Bundler 安裝的, 或者在應用程序的 vendor 目錄中已經提供了一份特定版本的 rails。 如果你沒有使用 Bundler,或者你需要為你的 Rails 應用程序設置一些額外的依賴, 請在這個類中使用 Puppet 的 package 資源做相應的配置來安裝它們。 rails 類的的主要部分是 define 函數 app, 對于你要管理的每個應用程序,它都會被實例化一次: ``` define app( $sitedomain ) { include rails ``` 為應用程序做的第一件事是安裝 Nginx 虛擬主機配置文件,它由 app.conf.erb 模板生成: ``` file { "/opt/nginx/sites-available/${name}.conf": content => template("rails/app.conf.erb"), require => File["/opt/nginx/sites-available"], } file { "/opt/nginx/sites-enabled/${name}.conf": ensure => link, target => "/opt/nginx/sites-available/${name}.conf", require => File["/opt/nginx/sites-enabled"], notify => Exec["reload-nginx"], } ``` 虛擬主機配置文件的模板相當小: ``` server { listen 80; root /var/www/<%= name %>/current/public; server_name <%= sitedomain %>; access_log /var/log/nginx/<%= name %>.access.log; error_log /var/log/nginx/<%= name %>.error.log; passenger_enabled on; passenger_min_instances 1; } passenger_pre_start http://<%= sitedomain %>; ``` 通常一個應用程序需要特定的 Nginx 配置指令,比如 redirects。 你可以在 Rails 模塊中添加一個名為 files/furiouspigs.conf 的文件來包含這些配置指令。 Puppet 會從如下的這段代碼找到這個文件,并分發給節點: ``` file { "/opt/nginx/conf/includes/${name}.conf": source => [ "puppet:///modules/rails/${name}.conf", "puppet:///modules/rails/empty.conf" ], notify => Exec["reload-nginx"], } ``` 注意這個文件使用了多個源,第二個源 empty.conf 確保 Puppet 不會因為應用程序指定的配置文件不存在而抱怨。 最后我們要確保為準備部署的標準 Rails 目錄結構配置 www-data 用戶屬主及適當的權限(775)。 如果你的 Nginx 以及部署的應用程序以不同的用戶身份執行,請使用你的用戶名替換所有的 www-data。 ``` file { [ "/var/www", "/var/www/${name}", "/var/www/${name}/releases", "/var/www/${name}/shared", "/var/www/${name}/shared/config", "/var/www/${name}/shared/log", "/var/www/${name}/shared/system" ]: ensure => directory, mode => 775, owner => "www-data", group => "www-data", } } } ``` #### 更多用法 使用 Puppet 管理 Rails 應用程序,你可能還需要考慮一些其他的事情。 ##### RVM 正如我之前所提到的,使用 RVM 管理多版本 Ruby 和多版本的 gemsets 是一種強大的解決方案。 當然,使用 RVM 也帶來了自身的有趣問題?—?RVM 的開發活躍,其主體經常變化。 無論如何,RVM 為我們帶來的好處還是比其帶來的麻煩要多的多。 所以,我建議你對生產線上的 Rails 站點,或許可以通過類似這樣的代碼應用 RVM: ``` class rails::rvm { package { [ "autoconf", "bison", "curl", "libreadline-dev", "subversion", "zlib1g-dev" ]: ensure => installed } file { "/usr/local/bin/rvm-install-system-wide": source => "puppet:///modules/rails/rvm-install-system-wide", mode => "700", } exec { "install-rvm": command => "/usr/local/bin/rvm-install-system-wide", creates => "/usr/local/bin/rvm", require => [ Package["curl"], Package["subversion"], File["/usr/local/bin/rvm-install-system-wide"] ], logoutput => on_failure, } append_if_no_such_line { "setup-rvm-shell-environment": file => "/etc/bash.bashrc", line => "[[ -s /usr/local/rvm/scripts/rvm ]] \ && . /usr/local/rvm/scripts/rvm", } } ``` rvm-install-system-wide 腳本來自 RVM 網站: [https://rvm.beginrescueend.com/install/rvm](https://rvm.beginrescueend.com/install/rvm) 。 ##### 日志滾動 在生產環境中你可能會需要為 Nginx 和 Rails 生成的日志文件添加 logrotate 配置片段, 以確保這些日志不會逐步占滿你的磁盤。因為篇幅限制和保持簡單的原因,本例省略了對日志滾動的配置。 ##### 數據庫 本處方中,未對 Rails 應用程序創建任何數據庫及訪問數據庫的用戶; 配置何種數據庫取決于你團隊的開發者正在使用何種數據庫(MySQL、Postgres、MongoDB 等), 你需要自行添加管理數據庫的 Puppet 代碼。如果使用的是 MySQL, 你可以參考 [創建 MySQL 數據庫及用戶](#ch07sec04) 一節的內容并作適當的改寫。 ##### SSL 證書 一些應用程序會需要 SSL 證書并為 **vhost** 配置安全的 URLs,例如:處理網上支付。 這已超出了本處方的講解范圍,但你應該可以發現添加所需的代碼并不困難。 你可以在 rails::app 函數的定義中添加一個可選參數,例如: ``` define app( $sitedomain, $ssl = false ) { ``` 并添加如下代碼處理這個參數: ``` if $ssl { file { "/etc/ssl/certs/${name}.crt": source => "puppet:///modules/rails/${name}.crt", } } ``` 然后,只要使用如下的代碼對你的應用程序進行實例化即可: ``` rails::app { "irritatedbadgers": sitedomain => "irritatedbadgers.com", ssl => true, } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看