提供: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或域名,應該可以看到這個頁面:
現在可以建立一些todo任務來測試應用的功能。
總結
在生産環境部署應用有很多細節需要注意,比如資料庫的使用者權限、應用目錄的通路權限等,這些安全步驟都是必要的。通過閱讀本文,你應該已經了解了在Ubuntu 14.04伺服器上部署一個簡單的Symfony應用的各個步驟。
本文來源自DigitalOcean Community。英文原文:How To Deploy a Symfony Application to Production on Ubuntu 14.04 by Erika Heidi
翻譯:lazycai