Drupal
- Drupal7的Nginx設定檔
- Drupal的Nginx設定檔
- 安裝Drupal與維護更新
- Drupal架購物網站
- 模組
- Gmail API
- Pathauto
- Field Validation
- Feeds
- ShURLy
- Custom Twig Formatter
- Easy Breadcrumb
- amp
- Backup and Migrate
- YouTube Embed Formatter
- 很好玩的Drupal
- Drupal7零散的筆記
- Drupal零散筆記
- 救援
- Docker安裝Drupal 11 及 Php8.3環境
Drupal7的Nginx設定檔
server {
server_name site.com;
root /var/www/site; ## <-- Your only path reference.
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /ads.txt {
allow all;
log_not_found off;
access_log off;
}
# Very rarely should these ever be accessed outside of your lan
location ~* \.(txt|log)$ {
allow 192.168.0.0/16;
deny all;
}
location ~ \..*/.*\.php$ {
return 403;
}
location ~ ^/sites/.*/private/ {
return 403;
}
# Block access to scripts in site files directory
location ~ ^/sites/[^/]+/files/.*\.php$ {
deny all;
}
# Allow "Well-Known URIs" as per RFC 5785
location ~* ^/.well-known/ {
allow all;
}
# Block access to "hidden" files and directories whose names begin with a
# period. This includes directories used by version control systems such
# as Subversion or Git to store control files.
location ~ (^|/)\. {
return 403;
}
location / {
# try_files $uri @rewrite; # For Drupal <= 6
try_files $uri /index.php?$query_string; # For Drupal >= 7
}
location @rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
}
# Don't allow direct access to PHP files in the vendor directory.
location ~ /vendor/.*\.php$ {
deny all;
return 404;
}
# In Drupal 8, we must also match new paths where the '.php' appears in
# the middle, such as update.php/selection. The rule we use is strict,
# and only allows this pattern with the update.php front controller.
# This allows legacy path aliases in the form of
# blog/index.php/legacy-path to continue to route to Drupal nodes. If
# you do not have any paths like that, then you might prefer to use a
# laxer rule, such as:
# location ~ \.php(/|$) {
# The laxer rule will continue to work if Drupal uses this new URL
# pattern with front controllers other than update.php in a future
# release.
location ~ '\.php$|^/update.php' {
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
# Security note: If you're running a version of PHP older than the
# latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.
# See http://serverfault.com/q/627903/94922 for details.
include fastcgi_params;
# Block httpoxy attacks. See https://httpoxy.org/.
fastcgi_param HTTP_PROXY "";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
# PHP 5 socket location.
#fastcgi_pass unix:/var/run/php5-fpm.sock;
# PHP 7 socket location.
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
# Fighting with Styles? This little gem is amazing.
# location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
try_files $uri @rewrite;
}
# Handle private files through Drupal. Private file's path can come
# with a language prefix.
location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
try_files $uri /index.php?$query_string;
}
## PWA serviceworker support.
location ~ ^/pwa/[0-9a-z]+/serviceworker.js {
try_files $uri /index.php?$query_string;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff)$ {
expires max;
log_not_found off;
access_log off;
}
}
Drupal的Nginx設定檔
server {
server_name site.com;
root /var/www/site/web; ## <-- Your only path reference.
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Very rarely should these ever be accessed outside of your lan
location ~* \.(txt|log)$ {
allow 192.168.0.0/16;
deny all;
}
location ~ \..*/.*\.php$ {
return 403;
}
location ~ ^/sites/.*/private/ {
return 403;
}
# Block access to scripts in site files directory
location ~ ^/sites/[^/]+/files/.*\.php$ {
deny all;
}
# Allow "Well-Known URIs" as per RFC 5785
location ~* ^/.well-known/ {
allow all;
}
# Block access to "hidden" files and directories whose names begin with a
# period. This includes directories used by version control systems such
# as Subversion or Git to store control files.
location ~ (^|/)\. {
return 403;
}
location / {
# try_files $uri @rewrite; # For Drupal <= 6
try_files $uri /index.php?$query_string; # For Drupal >= 7
}
location @rewrite {
#rewrite ^/(.*)$ /index.php?q=$1; # For Drupal <= 6
rewrite ^ /index.php; # For Drupal >= 7
}
# Don't allow direct access to PHP files in the vendor directory.
location ~ /vendor/.*\.php$ {
deny all;
return 404;
}
# Protect files and directories from prying eyes.
location ~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {
deny all;
return 404;
}
# In Drupal 8, we must also match new paths where the '.php' appears in
# the middle, such as update.php/selection. The rule we use is strict,
# and only allows this pattern with the update.php front controller.
# This allows legacy path aliases in the form of
# blog/index.php/legacy-path to continue to route to Drupal nodes. If
# you do not have any paths like that, then you might prefer to use a
# laxer rule, such as:
# location ~ \.php(/|$) {
# The laxer rule will continue to work if Drupal uses this new URL
# pattern with front controllers other than update.php in a future
# release.
location ~ '\.php$|^/update.php' {
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
# Ensure the php file exists. Mitigates CVE-2019-11043
try_files $fastcgi_script_name =404;
# Security note: If you're running a version of PHP older than the
# latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.
# See http://serverfault.com/q/627903/94922 for details.
include fastcgi_params;
# Block httpoxy attacks. See https://httpoxy.org/.
fastcgi_param HTTP_PROXY "";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
# PHP 5 socket location.
#fastcgi_pass unix:/var/run/php5-fpm.sock;
# PHP 7 socket location.
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
try_files $uri @rewrite;
expires max;
log_not_found off;
}
# Fighting with Styles? This little gem is amazing.
# location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
try_files $uri @rewrite;
}
# Handle private files through Drupal. Private file's path can come
# with a language prefix.
location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
try_files $uri /index.php?$query_string;
}
# Enforce clean URLs
# Removes index.php from urls like www.example.com/index.php/my-page --> www.example.com/my-page
# Could be done with 301 for permanent or other redirect codes.
if ($request_uri ~* "^(.*/)index\.php/(.*)") {
return 307 $1$2;
}
}
https://www.nginx.com/resources/wiki/start/topics/recipes/drupal/
安裝Drupal與維護更新
安裝compoer與drush
安裝composer
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
安裝drush(使用8.2.3)
composer global require drush/drush:8.2.3
alias drush='/usr/bin/php ~/.config/composer/vendor/drush/drush/drush.php'
drush init
安裝Drupal7
composer create-project drupal/recommended-project:7.x drupal
調整目錄權限
chown -R www-data:www-data /var/www/drupal/web
更新
composer self-update --1
update-alternatives --set php /usr/bin/php7.4
cd /var/www/drupal
drush pm-update -y;drush updatedb;drush l10n-update-refresh;drush l10n-update;drush cc all
composer self-update --2
update-alternatives --set php /usr/bin/php8.1
更新Drupal7,我的站由於共存Drupal7及Drupal10以及使用php7.4和php8.x,因此需要做一些版次的轉換
Drupal7即將在 5 January 2025 EOL,除非你要執行的應用Drupal10沒有開發,建議直接用最新版
安裝Drupal
composer create-project drupal/recommended-project drupal
更新drush
cd drupal
composer require drush/drush
composer update
調整目錄權限
chown -R www-data:www-data web
更新程式
composer update
drush updatedb
drush cr
安裝程式模組
composer require 'drupal/pathauto:^1.12'
程式的最新的版本可於 https://www.drupal.org/project/pathauto 取得資訊
裝好後可以用drusn en pathauto或到管理後台啟用
停用及刪除模組
composer remove drupal/pathauto
如果要停用及刪除,先到管理後台停用後,再執行composer
Drupal從8版後,開始改成用composer維護資料,我從Drupal8的很後期才開始學會怎麼使用,我一開始也是架幾個測試站而已,之後再慢慢想辦法讓一些Drupal7的站移轉過去,由於架構不同,只能用移轉的方式,無法像之前D6升到D7用升級的方式,你也可以用這個機會整理網站 XD
如果你是Drupal新手,建議先佈建drupal預設的demo站,再去參考那個站的功能是如何設定
Drupal架購物網站
https://github.com/drupalcommerce/demo-project
直接參考這裡就能佈建出完整的購物站
對我來說,購物網站必須要有金流、物流、配送免運條件、三方登入、基本的折扣功能、訂單輸出,就足以應付當下的線上購物流程。
Drupal可惜的是後援,我後來無法再繼續用Ubercart的原因就是Ubercart的程式沒再繼續維護,且後來一些三方登入及金流功能我也跟不上,對於完全不會寫程式的人真的是蠻苦手的
Drupal架購物站我應該算是台灣極少數中的少數,我有使用Drupal6 + Ubercart佈建購物站,這個站運作到2022年的5月(運作了10幾年),後期的年營收有到1千多萬,也算是光榮退休
後期同事分享能用WooCommerce就開始學用WordPress系統,使用WooCommerce務必要注意,雖然外掛很多,但也很容易裝了一堆造成速度變慢,建議一定要在測試站測,試完沒問題且穩定再到主站使用
Drupal和WordPress各有各的特色及擁護者,我覺得能達成目地且後期有能力維護管理即可,就好比我現在用BookStack做筆記 XD
模組
Drupal 最新版本
Gmail API
https://www.drupal.org/project/gmail
Pathauto
https://www.drupal.org/project/pathauto
Field Validation
https://www.drupal.org/project/field_validation
Feeds
https://www.drupal.org/project/feeds
ShURLy
https://www.drupal.org/project/shurly
Custom Twig Formatter
https://www.drupal.org/project/custom_twig_formatter
用法如果有一個欄位值為 field_imageurl ,那麼可用這個方式呼叫
{{ field_imageurl.value }}
進階的語法,過濾掉 https://
{{ field_imageurl.value|replace({'https://': ''}) }}
呼出成html圖片語法
<img src="{{ field_imageurl.value }}" alt="{{ title.value }}" width="100%" />
這個模組就是用來替換 Custom Formatters 用的
Easy Breadcrumb
https://www.drupal.org/project/easy_breadcrumb
幫頁生成目錄式的結構連結(麵包屑)
在安排文章及頁面時,有一個技巧避免使用者在你的網站迷路
我會用的作法就是用 easy_breadcrumb + pathauto
例如你有一個文章類型是要專門記錄書,那你就先生成一個頁面 /book ,然後設定 pathauto 把每篇文章的自動生成路徑為 /book/[title]
/book 頁面要搭配用 views block 呈現內容
在這種規劃後,當你進入一般的文章後,最上面會有樹狀目錄
首頁 > book > 文章標題
使用者在逛站的時候,就不會迷路囉
amp
https://www.drupal.org/project/amp
要在在Drupal啟用amp的作法
安裝AMP及版型
composer require drupal/amp
composer require drupal/amptheme
composer require drupal/stable
啟用版型
到頁面 admin/appearance 啟用
ExAMPle Subtheme
設定AMP
到頁面 admin/config/services/amp
選擇剛啟用的 ExAMPle Subtheme 做預設版型
把內容類型加入AMP,點啟用會引導你去內容類型的設定頁,把AMP加入儲存
好了後用瀏覽器開頁面,接著在網址最後面加上 "?amp" 如果有 amp頁面就成功
當完成後先不要太高興,必須經過amp標準審核才算真正能用 https://search.google.com/test/amp
優化版型內容
https://search.google.com/test/amp
把連結貼到amp審查頁面,然後把沒用的及不符合的block移除,讓版面越乾淨越好
啟用自動廣告
目前有雷未拆,我啟用後廣告有出現,但他說我的內容不符合規則
「amp-ad」所需的「amp-ad extension script」標記遺失或不正確。這個問題很快就會導致錯誤發生。
不允許自訂 JavaScript。
因為這兩條被判定頁面不符合amp
一但啟用amp你就要心理有底,很多語法不能使用
特別注意,模組AMP和模組Feeds Extensible Parsers相沖,因為QueryPath JSON parser的關係,一旦共動啟用會讓整個站掛掉!
Backup and Migrate
https://www.drupal.org/project/backup_migrate
mkdir private;chown -R www-data:www-data private/;composer require 'drupal/backup_migrate:^5.0';drush en backup_migrate;echo "\$settings['file_private_path'] = '../private';" | tee -a web/sites/default/settings.php
安裝後執行上面的字串,然後再檢查是否能順利備份及還原
YouTube Embed Formatter
主要的功能是要把文字欄位 ( youtube_id ) 轉換成播放器
/web/modules/contrib/ 底下建立目錄 youtube_embed
接著在目錄底下建立 youtube_embed.info.yml
name: 'YouTube Embed Formatter'
type: module
description: 'Formats a field containing a YouTube ID as an embedded video.'
core_version_requirement: ^10|^11
package: Custom
dependencies:
- field
mkdir -p src/Plugin/Field/FieldFormatter/
cd src/Plugin/Field/FieldFormatter/
在目錄底下建立 YouTubeEmbedFormatter.php
<?php
namespace Drupal\youtube_embed\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
/**
* Plugin implementation of the 'youtube_embed' formatter.
*
* @FieldFormatter(
* id = "youtube_embed_formatter",
* label = @Translation("YouTube Embed with RWD and Autoplay"),
* field_types = {
* "string",
* "string_long"
* }
* )
*/
class YouTubeEmbedFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
foreach ($items as $delta => $item) {
// 取得 YouTube ID
$youtube_id = trim($item->value);
// 建立包含 RWD 功能和靜音自動播放的 iframe 標籤
$elements[$delta] = [
'#type' => 'markup',
'#markup' => '<div class="youtube-video-wrapper"><iframe src="https://www.youtube.com/embed/' . htmlspecialchars($youtube_id, ENT_QUOTES, 'UTF-8') . '?autoplay=1&mute=0" frameborder="0" allowfullscreen></iframe></div>',
'#allowed_tags' => ['iframe', 'div'],
];
}
return $elements;
}
}
然後要搭配CSS達成RWD顯示
<style>
/* 讓 YouTube 影片支援響應式 */
.youtube-video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 比例 */
height: 0;
overflow: hidden;
max-width: 100%;
background: #000;
margin-bottom: 20px; /* 可選 */
}
.youtube-video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
很好玩的Drupal
說到架站一般人對Drupal是望之卻步,跟WordPress架站比,確實在是不好上手,但你如果搞懂的話,其實後期會比WordPress好玩及好用
因為基本上Drupal使用 Views + Block ,就能創作出各式各樣的內容出來,撈資料過程中比WordPress友善
WordPress需要寫function再搭配shortcode才能把欄位的資料叫出來,這兩年由於可以透過AI協助寫程式,也讓WordPress撈資料呈現容易許多,但就是要寫php就是了
Drupal7零散的筆記
使用 Nginx FastCGI 生成AMP快取的conf
我的語法,由於我的頁面本身就有drupal的快取服務,但這個快取服務在amp起不了作用,所以才使用這招
作法就是只讓有*?amp產出快取;另外還要研究登入使用者不用快取,可能要研究drupal的cookie吧?
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=tainanoutook:200m max_size=10g inactive=2h use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
set $skip_cache 1;
if ($request_uri ~* "/.*?amp") {
set $skip_cache 0;
}
include snippets/fastcgi-php.conf;
fastcgi_cache tainanoutook;
fastcgi_cache_valid 200 301 302 2h;
fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
fastcgi_cache_min_uses 1;
fastcgi_cache_lock on;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
add_header X-FastCGI-Cache $upstream_cache_status;
Drupal7 Optimizing 優化速度
使用模組 chained_fast apcu registry_autoload xautoload
drush en chained_fast apcu registry_autoload xautoload expire -y
vi sites/default/settings.php
$conf['cache_backends'][] = 'sites/all/modules/apcu/apcu.cache.inc';
$conf['cache_backends'][] = 'sites/all/modules/chained_fast/chained_fast.cache.inc';
// Chained fast configuration.
$conf['chained_fast']['fast_backend'] = 'DrupalAPCuCache';
// Cache class configuration - This uses chained_fast for all caches except the form cache. This might not be suitable for all sites, but is a good default.
$conf['cache_default_class'] = 'ChainedFastBackend';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
admin/config/development/performance 下列全打勾
匿名使用者頁面快取
區塊快取
壓縮快取頁面
整合並壓縮 CSS 檔案
整合並壓縮 JavaScript 檔案
Self-updating APCu classmap (*) (Running and available)
APC (Running and available)
APCu (Running and available)
XCache (Not currently available)
Self-updating database classmap (*) (Running and available)
Postpone registration of module namespaces until the first cache miss (recommended)
Replace core class loader.
expire (Cache Expiration) 這個模組主要在控管內容更新後會清除快取
Status of implementation 勾選 Internal expiration
Modules that support external expiration 勾選 Include base URL in expires
Node expiration Node actions 全勾選
PS. 重要文章更新後,最好再用未登入的瀏覽器確認一次,如果內容仍然無法更新,就直接清除Drupal全站快取囉
Views PHP
Drupal 7能夠方便在views執行php的模組 https://www.drupal.org/project/views_php
顯示某個欄位內容 : field_dow
<?php
// 假設 $data 是你已經從資料庫或其他來源獲取的資料
$field_dow = $data->_field_data['nid']['entity']->field_dow['und'];
// 提取 [field_dow] 內的值
$dow_values = array_map(function($item) {
return $item['value'];
}, $field_dow);
// 印出結果
echo implode(', ', $dow_values);
?>
field_dow 的值為 1 ~ 7,接下來轉換成 一 ~ 日(星期)
<?php
// 假設 $data 是你已經從資料庫或其他來源獲取的資料
$field_dow = $data->_field_data['nid']['entity']->field_dow['und'];
// 數字對應的星期轉換表
$weekdays = [
1 => '一',
2 => '二',
3 => '三',
4 => '四',
5 => '五',
6 => '六',
7 => '日'
];
// 提取 [field_dow] 內的值並轉換成星期
$dow_names = array_map(function($item) use ($weekdays) {
return $weekdays[$item['value']];
}, $field_dow);
// 印出結果
echo implode(', ', $dow_names);
?>
我的站有一個功能是在撈夜市的的時間,例如今天是星期五,他就會只顯示星期五的夜市
使用 Views Day of Week (views_dow) 達成的,但由於他預出來的值是英文,不動原始碼的情況,就用這個作法去處理
Drupal零散筆記
Draupl 9 升級 Drupal 10
當你發現所有的模組相容性問題都搞定了
但是使用composer update 仍然無法觸發升級到Drupal 10
此時就要編修 composer.json
^9.5 || ^10.0
composer
Drupal(最新版) 比較建議使用 composer 做安裝管理
日後的升級以及模組的安裝,也會比較順暢
而且切記,一定要一開始就使用 composer ,所以就從 composer 開始囉!
使用Drupal(最新版)的第一步,安裝Drupal 及 Drush
composer create-project drupal/recommended-project drupal
cd drupal
chown -R www-data:www:data web
composer require drush/drush
安裝及啟用模組
composer require 'drupal/paragraphs:^1.14'
drush en paragraphs
反安裝模組
先到 /admin/modules/uninstall 勾選解除安裝
然後再執行
composer remove drupal/paragraphs
更新Drupal及模組
composer update
執行完composer的安裝或變動時,最好再做一下drush更新及清理快取
PS. 我後來發生直接用 composer update 後出現一些問題,後來我就根據模組更新,例如token有更新版,那就直接用 composer require drupal/token 讓新版蓋過去,然後再跑一下drush updatedb;drush cr
drush updatedb
drush cr
通常如果沒用到冷門的模組,理論上都有辧法用 composer update 一路升級上去
另外,有時候遇到無解的錯誤畫面,有候可以重啟 php-fpm
composer 更新不問權限
composer self-update --2
update-alternatives --set php /usr/bin/php8.1
export COMPOSER_ALLOW_SUPERUSER=1
cd /var/www/mysite/
composer update;drush updatedb -y;drush cr
Drupal 10安裝後設定檢查
裝好Drupal後,第一件事就是先檢查狀態,進入 admin/reports/status,儘可能讓所有的問題pass
更新通知 未啟用
Update notifications are not enabled. It is highly recommended that you install the Update Manager module from the module administration page in order to stay up-to-date on new releases. For more information, Update status handbook page.
執行
drush cdel update.settings
然後再進入 admin/modules
啟用 Update Manager
Trusted Host Settings 未啟用
The trusted_host_patterns setting is not configured in settings.php. This can lead to security vulnerabilities. It is highly recommended that you configure this. See Protecting against HTTP HOST Header attacks for more information.
參考頁面照寫即可 https://www.drupal.org/docs/getting-started/installing-drupal/trusted-host-settings
$settings['trusted_host_patterns'] = [
'^.+\.example\.com\.tw$',
];
安裝翻譯檔
如果裝好Drupal後發現語法仍然是英文版,可以這樣做
先到
/admin/config/regional/settings
設定預設國家
接下來到
/admin/reports/translations
更翻譯檔
最後到
/admin/config/development/performance
清快取
順利的話介面就會變成你所設定的語系環境
狀態報告中的錯誤及警告(docker)
先進 /admin/reports/status
第一次進來,一定會看到1個錯誤與幾個警告,接下來就來一一解決它們
錯誤
Trusted Host Settings
docker 一條直接處理
docker exec -it dp-drupal-1 bash -c "echo '\$settings[\"trusted_host_patterns\"] = [\"^.+\\.yoursite\\.com$\"];' >> /opt/drupal/web/sites/default/settings.php"
bash
echo '\$settings[\"trusted_host_patterns\"] = [\"^.+\\.yoursite\\.com$\"];' >> /opt/drupal/web/sites/default/settings.php
警告
Output buffering
docker exec -it dp-drupal-1 bash -c "echo 'output_buffering=On' > /usr/local/etc/php/conf.d/custom-php.ini"
docker exec -it dp-drupal-1 service apache2 restart
模組和版型更新狀態
drush cdel update.settings
然後再進入 admin/modules
啟用 Update Manager
啟用 PHP APCu available caching 及 上載進度
先進入主機
docker exec -it dp-drupal-1 bash
執行
pecl install apcu
直接按enter跑完
執行
pecl install uploadprogress
直接按enter跑完
到 /usr/local/etc/php/conf.d/custom-php.ini 加入
extension=uploadprogress.so
extension=apcu.so
接著再重啟docker環境,就能看到APCu及上載進度啟用
這裡的一些警告其實不見得沒個都要處理及解決,網站能順跑即可
這裡是用docker的筆記,非docker版有些問題或許不會遇到
drupal 10 升級 drupal 11筆記
composer why-not drupal/core 11.1.0
列出
composer why-not drupal/core 11.1.0
drupal/core-recommended 10.4.0 requires drupal/core (10.4.0)
drupal/core 11.1.0 requires symfony/console (^7.2)
drupal/recommended-project - does not require symfony/console (but v6.4.15 is installed)
drupal/core 11.1.0 requires symfony/dependency-injection (^7.2)
drupal/recommended-project - does not require symfony/dependency-injection (but v6.4.16 is installed)
drupal/core 11.1.0 requires symfony/event-dispatcher (^7.2)
drupal/recommended-project - does not require symfony/event-dispatcher (but v6.4.13 is installed)
drupal/core 11.1.0 requires symfony/filesystem (^7.2)
drupal/recommended-project - does not require symfony/filesystem (but v6.4.13 is installed)
drupal/core 11.1.0 requires symfony/finder (^7.2)
drupal/recommended-project - does not require symfony/finder (but v6.4.13 is installed)
drupal/core 11.1.0 requires symfony/http-foundation (^7.2)
drupal/recommended-project - does not require symfony/http-foundation (but v6.4.16 is installed)
drupal/core 11.1.0 requires symfony/http-kernel (^7.2)
drupal/recommended-project - does not require symfony/http-kernel (but v6.4.16 is installed)
drupal/core 11.1.0 requires symfony/mailer (^7.2)
drupal/recommended-project - does not require symfony/mailer (but v6.4.13 is installed)
drupal/core 11.1.0 requires symfony/mime (^7.2)
drupal/recommended-project - does not require symfony/mime (but v6.4.13 is installed)
drupal/core 11.1.0 requires symfony/routing (^7.2)
drupal/recommended-project - does not require symfony/routing (but v6.4.16 is installed)
drupal/core 11.1.0 requires symfony/serializer (^7.2)
drupal/recommended-project - does not require symfony/serializer (but v6.4.15 is installed)
drupal/core 11.1.0 requires symfony/validator (^7.2)
drupal/recommended-project - does not require symfony/validator (but v6.4.16 is installed)
drupal/core 11.1.0 requires symfony/process (^7.2)
drupal/recommended-project - does not require symfony/process (but v6.4.15 is installed)
drupal/core 11.1.0 requires symfony/yaml (^7.2)
drupal/recommended-project - does not require symfony/yaml (but v6.4.13 is installed)
drupal/core 11.1.0 requires doctrine/annotations (^2.0)
drupal/recommended-project - does not require doctrine/annotations (but 1.14.4 is installed)
drupal/core 11.1.0 requires symfony/psr-http-message-bridge (^7.2)
drupal/recommended-project - does not require symfony/psr-http-message-bridge (but v6.4.13 is installed)
Not finding what you were looking for? Try calling `composer update "drupal/core:11.1.0" --dry-run` to get another view on the problem.
然後執行
composer require drupal/core-recommended:^11.0 --update-with-all-dependencies
出現錯誤
Problem 1
- Root composer.json requires drupal/core-recommended ^11.0 -> satisfiable by drupal/core-recommended[11.0.0, ..., 11.1.0].
- drupal/core-recommended[11.0.0, ..., 11.0.9] require symfony/console ~v7.1.3 -> found symfony/console[v7.1.3, ..., v7.1.8] but these were not loaded, likely because it conflicts with another require.
- drupal/core-recommended 11.1.0 requires symfony/console ~v7.2.0 -> found symfony/console[v7.2.0, v7.2.1] but these were not loaded, likely because it conflicts with another require.
rm composer.lock
rm -rf vendor/
再執行
composer require drupal/core-recommended:^11.0 --update-with-all-dependencies
然後 drush updatedb ; drush cr
一定要備份再執行!
救援
萬一不幸更新出錯,第一件事就要先去看 nginx log 找出問題的來源
cat /var/log/nginx/error.log
如果是版型的問題,可以用 drush 改回預設版型
drush config:set system.theme default olivero
或 bartik
Docker安裝Drupal 11 及 Php8.3環境
Yaml這樣寫
# Drupal 11 with MySQL and PHP 8.3
#
# Access via "http://localhost:8080"
# (or "http://$(docker-machine ip):8080" if using docker-machine)
#
# During initial Drupal setup,
# Database type: MySQL
# Database name: drupal
# Database username: root
# Database password: example
# ADVANCED OPTIONS; Database host: mysql
version: '3.1'
services:
drupal:
image: drupal:11-apache
ports:
- 8080:80
environment:
PHP_VERSION: "8.3"
volumes:
- /var/www/html/modules
- /var/www/html/profiles
- /var/www/html/themes
- /var/www/html/sites
restart: always
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: drupal
restart: always
Nginx conf
server {
server_name www.yoursite.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
後續維護
首先要學會用composer及drush來更新及管理程式
安裝 7zip,composer 會用得到
docker exec -it dp-drupal-1 apt update
docker exec -it dp-drupal-1 apt install unzip
裝好後把drush更新到最新版
docker exec -it dp-drupal-1 composer require drush/drush
然後更主程式
docker exec -it dp-drupal-1 composer update
更新及整理資料庫
docker exec -it dp-drupal-1 drush updatedb
docker exec -it dp-drupal-1 drush cr