在 Mac 上搭建 owncloud 环境

前言

没想到在Mac上搭建PHP开发环境会有这么多坑,手动编译真是坑到吐血;果然还是包管理器才是王道,不过经过此次折腾,确实是时候学习一些docker的用法了;

TL;DR

  1. 利用homebrew分别安装phpmysqlnginx

    1
    2
    3
    brew install php
    brew install mysql
    brew install nginx
  2. 启动服务:

    1
    2
    3
    brew services start php
    brew services start mysql
    brew services start nginx
  3. 下载对应版本的owncloud的安装包,解压后放到本地服务器路径下;

  4. 设置nginx的服务器配置文件[1]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    upstream php-handler {
    server 127.0.0.1:9000; # 本地php服务器默认地址
    #server unix:/var/run/php5-fpm.sock;
    }

    server {
    listen 80; # 要监听的本地端口
    server_name ***; # 服务器访问域名

    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this topic first.
    #add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;

    # Path to the root of your installation
    root /data/domains/cloud; # owncloud解压后部署的本地路径
    location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
    }

    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

    location = /.well-known/carddav {
    return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
    return 301 $scheme://$host/remote.php/dav;
    }

    location ^~ /.well-known/acme-challenge { }

    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;

    # Disable gzip to avoid the removal of the ETag header
    gzip off;

    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;

    error_page 403 /core/templates/403.php;
    error_page 404 /core/templates/404.php;

    location / {
    rewrite ^ /index.php$uri;
    }

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
    return 404;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
    return 404;
    }

    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    #fastcgi_param HTTPS on;
    fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
    fastcgi_param front_controller_active true;
    fastcgi_pass php-handler;
    fastcgi_intercept_errors on;
    fastcgi_request_buffering off; #Available since NGINX 1.7.11
    }

    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
    try_files $uri $uri/ =404;
    index index.php;
    }

    # Adding the cache control header for js and css files
    # Make sure it is BELOW the PHP block
    location ~* \.(?:css|js)$ {
    try_files $uri /index.php$uri$is_args$args;
    add_header Cache-Control "max-age=15778463";
    # Add headers to serve security related headers (It is intended to have those duplicated to the ones above)
    # Before enabling Strict-Transport-Security headers please read into this topic first.
    #add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    # Optional: Don't log access to assets
    access_log off;
    }

    location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
    try_files $uri /index.php$uri$is_args$args;
    # Optional: Don't log access to other assets
    access_log off;
    }
    }
  5. 重启nginx服务;

    1
    brew services restart nginx
  6. 访问配置的本地服务地址(域名+端口),然后按照页面指示初始化owncloud应用设置(管理员账号和数据库配置)即可;需要注意的是MySQL数据库地址需要带上端口号,默认端口为3306

owncloud不同的版本对于PHP版本会有不同的要求,以10.11.1版本为例,该版本不兼容7.3及以上版本的PHP

Homebrew加速镜像

由于homebrew安装包的服务器默认都在国外,因此下载包时速度较慢,对于体积大的包来说经常会出现超时而导致安装失败的问题;解决这种问题的套路那自然就是使用国内镜像,这里推荐使用中科大的镜像:

上面两个镜像建议都替换,上述页面都有详细的替换和还原说明;

nginx配置文件

nginx安装成功后,通过nginx -h命令可以看到默认配置文件的路径:

img

打开默认配置文件可以看到,默认servers文件夹(默认配置文件的同级目录)下的所有配置文件都会被自动解析,因此一般都在该文件下放入自定义的服务器配置文件;

遇到的坑

由于之前在windows系统上搭建过PHP开发环境,因此不自觉的以为在Mac上也是那么轻松,所以一开始就选了那种流行的PHP集成环境安装包的模式,结果就碰到了很多的坑……

集成环境安装包的问题

Mac上用集成环境安装包搭建PHP环境的最大问题是:一旦PHP需要额外的扩展模块时,需要自行安装手动编译;而在Windows系统上往往只需要在php.ini配置文件上将相应模块的注释取消即可,因为默认扩展模块的dll文件都编译好了;

owncloud10.11.1为例,该应用依赖intl(国际化)扩展模块,而集成环境默认都没有携带这个扩展模块的编译文件(.so),因此需要自行解决;

手动编译可能会遇到的问题

一般来说,PHP扩展模块在Mac上的手动编译流程大如下[2]

  1. PECL网站(专门托管PHP扩展模块源码的仓库)找到对应的扩展模块;

  2. 然后下载扩展模块相应版本的源码压缩包,进行解压;

  3. 命令行进入源码文件夹下(有config.m4文件的那级目录),运行:

    1
    phpize

    运行成功后,目录下会生成一个configure文件;

  4. 接着运行:

    1
    2
    # path-to-php为当前使用的PHP安装路径
    ./configure --with-php-config=path-to-php/bin/php-config
  5. 然后进行编译:

    1
    sudo make
  6. 最后将编译好的文件安装到PHP扩展模块目录中:

    1
    sudo make install

理想情况下,经过上面的一番操作,应该是生成对应扩展模块编译产物(.so文件)且安装到目录中的;然而,事实上运行的每个命令都可能会出现各种各样的错误……

icu4c包找不到

在运行./configure命令时,极有可能会出现下面的错误:

1
configure: error: Unable to detect ICU prefix or no failed. Please verify ICU install prefix and make sure icu-config works.

原因可能是:

  • 没有安装icu4c包;此时可以通过homebrew来安装解决:

    1
    brew install icu4c
  • 安装了但是没有暴露到环境变量中;可以尝试使用homebrewlink命令来解决:

    1
    brew link icu4c

    不过有可能会出现警告,但是也提示了如何手动暴露到环境变量中去:

    img

ext/standard/php_smart_str.h’ file not found

可能好不容易成功运行了./configure命令后,在执行编译命令时又会出现如下错误:

1
Fatal error: 'ext/standard/php_smart_str.h' file not found

很明显,php_smart_str.h这个头文件要么是缺失了,要么就是没有正确地暴露在环境变量中;

mysql加密方式不支持

在使用mysql8.0+版本时,其默认账号加密方式变为caching_sha2_password,而很多PHP版本不支持这种加密方式,因此就会出现如下错误:

1
mysqli_real_connect(): The server requested authentication method unknown to the client [sha256_password]

一般可以采用改写数据库中账号加密方式来解决[3]

1
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'

不过上述方式我试了后仍然无效,所以此时可以采用另一种方法,那就是使用mysql官方的Mac安装包来安装mysql,安装过程中可以选择采用mysql5.7的加密方式来兼容现有的PHP

相关文档


  1. Nginx+ownCloud+PHP+MySQL搭建私有云 - 云+社区 - 腾讯云owncloud默认带了Apache服务器的一些配置(.htaccess文件),使用Nginx作为服务器时,需要转化为相应的规则(.cnf文件),这篇文章就有现成的 ↩︎

  2. Mac环境下安装PHP扩展踩坑指南 - Renjie的文章 - 知乎PHP扩展模块编译的一般流程 ↩︎

  3. mysql 安装了最新版本8.x版本后的报错: the server requested authentication method unknown to the client_youcijibi的博客-CSDN博客mysql8.0+版本加密方式错误的解决办法之一 ↩︎