天天看點

在Ubuntu 14.04的生産環境上部署一個Symfony應用

提供:ZStack雲計算

前言

Symfony是一個使用PHP編寫的開源Web架構,它的結構設計精良,元件可複用,适用于大大小小的各類PHP項目開發。

本文将在Ubuntu 14.04伺服器上部署一個簡單的Symfony應用,其中涵蓋了伺服器的配置以及安全和性能的考慮,以使其适合在生産環境中使用。

如果你對Symfony還不熟悉,可以參閱這篇介紹文章。

準備工作

正式開始之前,你需要準備如下事宜:

  • 一個建立的Ubuntu 14.04雲主機,運作LAMP或LEMP堆棧
  • 一個具有sudo權限的非root使用者(設定方法見這個教程)

應用的部署涉及很多方面,很多地方取決于應用本身的需求。本文使用的應用是Symfony的一個執行個體todo應用,其源代碼可以在Github擷取。

步驟1:安裝伺服器依賴項

先更新一下系統軟體管理器緩存:

sudo apt-get update
           

我們需要使用

git

拉取應用代碼,需要

acl

設定應用路徑權限,以及兩個PHP擴充,

php5-cli

用于在指令行運作PHP,

php5-curl

用于運作Symfony。輸入如下指令安裝軟體包:

sudo apt-get install git php5-cli php5-curl acl
           

最後,我們還需要安裝

composer

以下載下傳應用依賴項:

sudo curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
           

步驟2:配置MySQL

現在需要設定MySQL為生産環境做好準備。你需要MySQL root賬号的密碼,并已經為MySQL做好安全加強(詳見LAMP安裝教程和LEMP安裝教程的步驟2)。

如果你使用一鍵安裝的方式安裝LAMP/LEMP,你的MySQL root密碼應該出現在伺服器登陸資訊中(message of the day),該資訊内容也可在

/etc/motd.tail

檔案中檢視。

設定預設字元集

Symfony建議将資料庫的字元集設定為

utf8

。大部分資料庫預設使用拉丁類字元集,這可能導緻之前存儲在資料庫中的資料變成亂碼。該設定無法在應用層面啟用,必須要到MySQL配置中更改。

使用編輯器打開

/etc/mysql/my.cnf

檔案:

sudo nano /etc/mysql/my.cnf
           

找到[mysqld]條目,在Basic Settings添加兩個選項

collation-server

character-set-server

[mysqld]
#
# * Basic Settings
#
collation-server     = utf8mb4_general_ci # Replaces utf8_general_ci
character-set-server = utf8mb4            # Replaces utf8
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock

. . .
           

儲存退出,重新開機MySQL以使變更生效:

sudo service mysql restart
           

為應用建立一個使用者和資料庫

首先以root賬号登陸MySQL用戶端:

mysql -u root -p
           

輸入你之前在運作

mysql_secure_installation

做安全加強時輸入的密碼。

登陸成功後,建立應用資料庫

todo

CREATE DATABASE todo;





Output
Query OK, 1 row affected (0.00 sec)
           

資料庫建立完畢。再建立一個專門用于通路此資料庫的MySQL使用者:

CREATE USER 'todo-user'@'localhost' IDENTIFIED BY 'todo-password';





Output
Query OK, 0 rows affected (0.00 sec)
           

如上,建立使用者名“todo-user”,登入密碼“todo-password”。生産環境中應該使用更不容易猜到的密碼。

然後,給該使用者設定權限:

GRANT ALL PRIVILEGES ON todo.* TO 'todo-user'@'localhost';





Output
Query OK, 0 rows affected (0.00 sec)
           

運作如下指令使變更生效:

FLUSH PRIVILEGES;





Output
Query OK, 0 rows affected (0.00 sec)
           

退出MySQL,準備測試:

quit;
           

現在使用“todo-user”登陸資料庫:

mysql -u todo-user -p
           

檢查該使用者的通路權限:

SHOW DATABASES;
           

輸出應該是這樣的:

Output
+--------------------+
| Database           |
+--------------------+
| information_schema |
| todo               |
+--------------------+
2 rows in set (0.00 sec)
           

看到以上資訊說明使用者配置成功了,你應該隻能看到

information_schema

todo

這兩個資料庫。

現在可以退出MySQL了:

quit;
           

步驟3:拉取應用代碼

應用的部署涉及很多方面,即使隻考慮Symfony應用也相當複雜,有些部署需要特定的操作——如資料庫遷移或者額外的設定指令,是以我無法描述一種通用的部署方式。

本文部署的應用是一個簡單的demo,部署過程相對簡單。你在部署自己的應用的時候,可能需要進行更多其他的操作。

本demo是一個簡單的todo清單,你可以在裡面添加、移除項目并編輯其中的内容。todo項目儲存在MySQL資料庫中。該項目代碼可在GitHub上下載下傳。

接下來我們使用Git來擷取該應用的代碼。我們将使用

/var/www/todo-symfony

這個目錄,是以第一步先要建立這個目錄:

sudo mkdir -p /var/www/todo-symfony
           

更改目錄的所有者,以在普通使用者權限下運作該應用。本教程中的使用者名和使用者組名均為“sammy”,你需要修改成自己的使用者名:

sudo chown sammy:sammy /var/www/todo-symfony
           

現在,将應用代碼通過git clone下載下傳到該目錄下:

cd /var/www

git clone https://github.com/php-demos/todo-symfony.git todo-symfony





Output
Cloning into 'todo-symfony'...
remote: Counting objects: 76, done.
remote: Compressing objects: 100% (61/61), done.
remote: Total 76 (delta 6), reused 76 (delta 6), pack-reused 0
Unpacking objects: 100% (76/76), done.
Checking connectivity... done.
           

步驟4:更改目錄權限

現在,應用代碼現在所在的目錄

/var/www/todo-symfony

是由系統使用者“sammy”所擁有。不過,Web伺服器使用者(通常是“www-data”)也需要能夠通路這些檔案,否則Web伺服器将無法以該目錄下的檔案提供服務。此外,還有兩個目錄

app/cache

app/logs

需要更改權限以開放給系統使用者和Web伺服器使用者。

我們将用ACL(Access Control Lists)進行上述位置的權限配置。使用ACL進行權限管理具有更好的細粒度,精确的控制權限可以避免将多餘的權限開放出去。

首先,給“www-data”使用者開放代碼目錄的讀權限+執行權限(rX):

sudo setfacl -R -m u:www-data:rX todo-symfony
           

然後,給“www-data”使用者開放

cache

log

目錄的讀+寫+執行權限(rwX):

sudo setfacl -R -m u:www-data:rwX todo-symfony/app/cache todo-symfony/app/logs
           

最後,将

app/cache

app/logs

目錄下所有以後要建立的檔案設定相同的權限。這同樣使用

setfacl

指令實作,隻是要添加一個

-d

選項:

sudo setfacl -dR -m u:www-data:rwX todo-symfony/app/cache todo-symfony/app/logs
           

現在可以使用

getfacl

檢查剛才設定的權限是否正确:

getfacl todo-symfony/app/cache
           

應該看到這樣的結果:

Output
# file: todo-symfony/app/cache
# owner: sammy
# group: sammy
user::rwx
user:www-data:rwx
group::rwx
mask::rwx
other::r-x
default:user::rwx
default:user:www-data:rwx
default:group::rwx
default:mask::rwx
default:other::r-x
           

這裡可以看到,

app/cache

的所有者是“sammy”,此外還有涉及“www-data”的一些額外權限。default部分代表此目錄下建立檔案将具有的權限。

步驟5:應用的設定

我們現在已經擷取了應用代碼,但相關依賴還需要安裝,而且還需要配置一些應用參數。

Symfony可以在多種環境下運作。其預設設定是開發環境,該環境會生成更加詳細的日志,使用較少的緩存,并且暴露更多的錯誤資訊以友善debug。而這些不是生産環境所需要的。

将運作環境更改為生産環境,可以執行如下指令:

export SYMFONY_ENV=prod
           

接下來我們安裝依賴項。進入項目目錄,運作

composer install

cd todo-symfony

composer install --no-dev --optimize-autoloader
           

安裝完畢之後,composer會要求你提供一些資訊以生成

parameters.yml

。該檔案包含了一些重要配置資訊,如資料庫連接配接的參數。大部分參數都可以直接回車接受預設值,但資料庫名稱(database name)、使用者名(username)、password(密碼)必須要正确填寫(即你在步驟2中輸入的内容):

Output
Creating the "app/config/parameters.yml" file
Some parameters are missing. Please provide them.
database_host (127.0.0.1): 
database_port (null): 
database_name (symfony): todo
database_user (root): todo-user
database_password (null): todo-password
. . .
           

完成後,可以使用

doctrine:schema:validate

指令檢查資料庫連接配接是否正确:

php app/console doctrine:schema:validate





Output
[Mapping]  OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file.
           

OK這一行代表資料庫連接配接正确。下面有一行FAIL,這是預期之内的,因為我們還沒有建立資料庫結構(schema)。下面我們來建立schema:

php app/console doctrine:schema:create





Output
ATTENTION: This operation should not be executed in a production environment.

Creating database schema...
Database schema created successfully!
           

如此将會根據應用提供的中繼資料資訊建立所有的資料表。

如果你是遷移原有的應用,則千萬别直接用

doctrine:schema:create

doctrine:schema:update

這兩個指令,而需要進行資料庫遷移。這兩個指令是建立新庫用的,可能會把原有的資料抹消。本文是建立應用而不需要遷移,是以使用這兩個指令。

現在,清空緩存:

php app/console cache:clear --env=prod --no-debug





Output
Clearing the cache for the prod environment with debug false
           

最後,生成應用的資源檔案(assets):

php app/console assetic:dump --env=prod --no-debug





Output
Dumping all prod assets.
Debug mode is off.

14:02:39 [file+] /var/www/todo-symfony/app/../web/css/app.css
14:02:39 [dir+] /var/www/todo-symfony/app/../web/js
14:02:39 [file+] /var/www/todo-symfony/app/../web/js/app.js
           

步驟6:設定Web伺服器

The only thing left to do is to configure the web server. This will involve 2 steps: setting the

date.timezone

directive in

php.ini

, and updating the default website config file (either on Apache or Nginx) for serving our application.

Web伺服器的設定包含兩個步驟:設定

php.ini

中的

date.timezone

條目,以及更新預設的網站配置檔案(Apache或Nginx)。

We’ll see how to accomplish these steps on both LEMP and LAMP environments.

Nginx + PHP-FPM 的配置

首先編輯

/etc/php5/fpm/php.ini

檔案,設定伺服器的時區。伺服器時區在預設的配置檔案中是注解掉的,而Symfony需要這個設定。

sudo nano /etc/php5/fpm/php.ini 
           

找到

date.timezone

條目,将其内容前面的分号删除,然後将時區修改為你所在地的時區(本文使用

Europe/Amsterdam

時區,你可以從這個頁面查找你的所在地時區):

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Europe/Amsterdam
           

儲存退出,重新開機PHP以使變更生效:

sudo service php5-fpm restart
           

然後,将預設的網站配置檔案替換為一個為Symfony定制的檔案。首先給現在的配置檔案做個備份以防萬一:

cd /etc/nginx/sites-available

sudo mv default default-bkp
           

建立一個新檔案替換老檔案:

sudo nano /etc/nginx/sites-available/default
           

将如下内容複制粘貼到該檔案中。記得将

server_name

改成你的伺服器域名或IP:

server {
    server_name example.com www.example.com your_server_ip;
    root /var/www/todo-symfony/web;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /app.php$is_args$args;
    }

    location ~ ^/app\.php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/app.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }

    error_log /var/log/nginx/symfony_error.log;
    access_log /var/log/nginx/symfony_access.log;
}
           

儲存退出,重新開機Nginx以使變更生效:

sudo service nginx restart
           

Apache + PHP5的配置

首先還是在

/etc/php5/apache2/php.ini

檔案中更改時區:

sudo nano /etc/php5/apache2/php.ini 
           

找到

date.timezone

條目,将前面的分号删除,并将你自己的時區寫入:

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Europe/Amsterdam
           

儲存退出。現在需要替換Apache的預設網站配置檔案。先把原來的檔案做一個備份:

cd /etc/apache2/sites-available

sudo mv 000-default.conf default-bkp.conf
           

建立一個新檔案替換老的:

sudo nano /etc/apache2/sites-available/000-default.conf
           

将如下内容複制粘貼到檔案中:

<VirtualHost *:80>

    DocumentRoot /var/www/todo-symfony/web
    <Directory /var/www/todo-symfony/web>
        AllowOverride None
        Order Allow,Deny
        Allow from All

        <IfModule mod_rewrite.c>
            Options -MultiViews
            RewriteEngine On
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^(.*)$ app.php [QSA,L]
        </IfModule>
    </Directory>

    # uncomment the following lines if you install assets as symlinks
    # or run into problems when compiling LESS/Sass/CoffeScript assets
    # <Directory /var/www/project>
    #     Options FollowSymlinks
    # </Directory>

    ErrorLog /var/log/apache2/symfony_error.log
    CustomLog /var/log/apache2/symfony_access.log combined
</VirtualHost>
           

如果你使用域名而不是IP位址通路網站,可以定義

ServerName

ServerAlias

,如下:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com

    DocumentRoot /var/www/todo-symfony/web
. . .
           

儲存退出。我們還需要啟用Apache的

mod_rewrite

sudo a2enmod rewrite
           

重新開機Apache以使變更生效:

sudo service apache2 restart
           

步驟7:通路應用

在浏覽器裡通路伺服器的IP或域名,應該可以看到這個頁面:

在Ubuntu 14.04的生産環境上部署一個Symfony應用

現在可以建立一些todo任務來測試應用的功能。

總結

在生産環境部署應用有很多細節需要注意,比如資料庫的使用者權限、應用目錄的通路權限等,這些安全步驟都是必要的。通過閱讀本文,你應該已經了解了在Ubuntu 14.04伺服器上部署一個簡單的Symfony應用的各個步驟。

本文來源自DigitalOcean Community。英文原文:How To Deploy a Symfony Application to Production on Ubuntu 14.04 by Erika Heidi

翻譯:lazycai