• 解决 Docker PHP “Failed opening required ‘xxx.php'” 的问题

    这个问题是我最近迁移本网站时遇到的。

    本网站是 Docker + PHP-FPM + nginx,迁移后,Wordpress 的 .php 访问报错:Failed opening required /xxx/wp-config.php

    很明显就是容器里没有权限。那么为什么会没权限呢?

    很久没搞这个的部署,忘得差不多了。经过重温与找资料,大概是这样解决的,不一定是完美的方案:

    原因:

    • Docker 的 PHP 运行的时候,默认是用www-data用户(并且uid=33),属于www-data用户组(且gid=33)
    • 某些系统自带了该用户与用户组(例如我网站迁移前所在的机器),某些没有自带(例如现机器)

    解决:

    1. 检查宿主机的用户、用户组是否有www-data,且 33 号的 uid/gid 是否被占用:
      # cat /etc/group
      # cat /etc/passwd
    2. 发现用户组 gid=33 被名为“tape”的用户组占用了(我的机器如此),似乎没有什么机会用到这个用户组,所以我把它的 id 改成 34:
      # groupmod -g 34 tape
    3. 创建 gid=33 的www-data用户组:
      # groupadd -g 33 www-data
    4. 创建 uid=33 的www-data用户,不创建home目录(-M),设置默认shell(-s)为nologin:
      # useradd -M -u 33 -g www-data -s /usr/sbin/nologin www-data

      至于为什么要这样创建,是为了尽可能模拟自带的www-data用户,在自带的机器上,passwd文件是这样的:
      # cat /etc/passwd | grep www-data
      www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

      而执行上述 useradd 后,passwd 是这样的,已经很像了:
      www-data:x:33:33::/home/www-data:/usr/sbin/nologin
    5. 最后,在宿主机,把缺少权限的整个目录所有权,赋予给www-data
      # chown -R www-data:www-data some_directory
  • 用 cron 表达式表示“每月的第几个星期几”

    这个需求不是很常用,但需要用时,在网上不是很好搜索到,故在此记录。

    例如,要表示“每月的第二个星期六的12:34:00”,是这样写:

    0 34 12 ? * SAT#2

    注意,这个不是标准的形式,不是所有所有程序都接受这样的格式。一般程序都会有校验功能,可以检查下次执行的时间来进行确认。(第一是”?”表示不指定不一定支持,第二是”SAT”不一定支持,第三是”#2″更不一定支持)

  • Google Colab 运行其他 Python 版本

    首先说明,这个运行其他 Python 版本并不是影响 jupyter notebook 的 Python 版本,而是在 notebook 中通过!python xxxxx.py执行我上传的脚本所使用的 Python。

    撰写本文时,Colab 的 Python 是 3.7。

    我的项目中用到了一些 3.8、3.9 的新语法,所以没法在 Colab 上面跑,但我也不想把这些语法改成旧的,所以只能在 Colab 上升级了。

    经过一番摸索,发现最靠谱的方法是在 apt 中安装新版 Python,然后全程使用 venv,而不用系统的 Python。系统的 Python 总是遇到 pip 安装库时的各种奇怪问题。

    所以,在 notebook 中的命令如下:

    !sudo apt-get update -y
    !sudo apt-get install python3.9 python3.9-distutils python3.9-venv
    
    !python3.9 --version
    
    !python3.9 -m venv venv

    之后运行 pip 安装第三方库、运行 python xxxx.py 时,都使用如下方式:

    !venv/bin/pip install xxx_library
    !venv/bin/python xxx.py
  • CTP Java API Linux/Windows x64 编译(SWIG 封装 C++ 动态库),并解决中文乱码问题

    前言

    网上有不少教程讲到 CTP API 的编译,但是我按照多数教程照着做都不太成功,只有一份是成功了。在此把过程记录下来,希望可以帮到更多的人。

    (2022年4月更新:补充 Windows 下的支持,写在文末)

    Linux

    1. 下载 CTP API

    在上期的官网下载,然后解压到某一个工作目录。我们只需要 Linux x64 的,工作目录的文件如下:

    error.dtd
    error.xml
    ThostFtdcMdApi.h
    ThostFtdcTraderApi.h
    ThostFtdcUserApiDataType.h
    ThostFtdcUserApiStruct.h
    thostmduserapi_se.so
    thosttraderapi_se.so
    阅读更多…
  • Docker 部署 Nginx+MariaDB(MySQL)+PHP 记录,与对应 docker-compose 实现

    Docker 火了这么多年,我也要学习体验一下。就在阿里云的服务器上部署一个 Nginx+MariaDB+PHP 环境吧。

    安装

    不同系统的安装方法见官方文档,包括了 Linux 的几个发行版和 Windows、MacOS 的详细步骤。我在 Linux 系统上安装。装完记得运行systemctl enable docker把 docker 调成自动启动。

    Docker Hub

    Docker 的各种 images 会发布在 Docker Hub,要善用这个网站来搜索想要的资源。

    网络

    在创建 docker 容器(container)之前,先考虑一下网络的架构。我打算创建 3 个容器:nginx、mariadb、php,其中,需要暴露的端口只有 nginx 容器的 80 (443) 端口。根据这篇文档中的:

    User-defined bridge networks are best when you need multiple containers to communicate on the same Docker host.

    我应该选择 bridge 网络,bridge 的具体的使用见此文档。在宿主机上运行

    docker network create --driver bridge my_bridge

    创建一个名称为 my_bridge 的bridge。

    Nginx

    先把 Nginx image 拉下来:docker pull nginx,默认会拉 latest 这个 tag (tags 可以在 Docker Hub 先搜索 nginx 然后点进去找到)。

    接下来创建容器:

    docker run --name my_nginx --network my_bridge -p 80:80 -v /var/www/php_env:/usr/share/nginx/html -e TZ="Asia/Shanghai" -d --restart always nginx

    参数解释:(详情见文档

    --name my_nginx           容器命名为my_nginx
    --network my_bridge       连接到my_bridge网络
    -p 80:80                  把容器的80端口(后)暴露为宿主机的80端口(前)
    -v /var/www/php_env:/usr/share/nginx/html   把宿主机的目录(前)mount到容器的指定路径
    -e TZ="Asia/Shanghai"     设置环境变量
    -d                        在后台运行
    --restart always          自动启动、重启
    nginx                     image名称

    如无意外,浏览器可以访问http://服务器IP的网页了。

    阅读更多…
  • 使用 Nginx+Gunicorn 部署 Flask,with venv+systemd

    记录一下我的部署过程。

    Flask

    文件为 /root/myproject/application.py,其中的 Flask 实例为

    app = Flask(__name__)

    Gunicorn

    /root/myproject/ 中新建一个虚拟环境 venv 并激活虚拟环境,使用 pip 安装 Flask 等模块。然后安装 gunicorn:

    pip install gunicorn

    装好之后,执行命令:

    gunicorn --bind 127.0.0.1:8000 application:app   # application为文件名 app为实例名

    http://127.0.0.1:8000 应该是可以访问的。(服务器可能需要做一下端口转发,不然就绑定 0.0.0.0)

    Systemd

    我希望服务器重启后,也可以自动启动 web server。

    新建 /usr/lib/systemd/system/gunicorn.service,内容如下:

    [Unit]
    Description=gunicorn daemon
    After=network.target
    
    [Service]
    WorkingDirectory=/root/myproject
    ExecStart=/root/myproject/venv/bin/gunicorn -w 1 --bind 127.0.0.1:8000 application:app
    PrivateTmp=true
    Environment=key=value
    
    [Install]
    WantedBy=multi-user.target

    然后执行 systemctl enable gunicorn,重启一下服务器,之后执行 systemctl status gunicorn 确认服务正常启动。这里备注一下“Environment=key=value”这一行,systemd 启动的服务是不带环境变量的,被这个坑了好久🤣。

    Nginx

    最后,我使用 nginx 进行转发,和实现 https 访问。修改 /etc/nginx/conf.d/default.conf

    server {
        listen       443 ssl;
        server_name  myproject;
    
        access_log  /var/log/nginx/access.log;
        error_log   /var/log/nginx/error.log;
    
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_redirect     off;
            proxy_set_header   Host                $host:$server_port;
            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;
         }
    
        ssl_certificate     /path/yourssl.cer;
        ssl_certificate_key /path/yourssl.key;
        ssl_session_timeout  5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
    }

    最后,测试一下 https://server_ip 看看能不能访问。

  • wine中文乱码的解决方法

    新装的wine中文全是乱码,需要修改一下几个配置文件,找到一篇比较详细的配置说明,分享一下:
    “ wine下中文的配置方案
    步骤:
    1. 初始设置
    运行 winecfg,把模拟的 Windows 系统设置为 Windows XP 或者 Windows 2000。
    2. 准备字体
    为了让 Windows 应用程序看上去更美观,所以需要 Windows 下面的字体。
    由于我已经将 simsun.ttc 复制到 /usr/share/fonts/windows/ 目录中了。所以我只需要在 ~/.wine/drive_c/windows/fonts/ 目录中为 simsun.ttc 创建一个符号连接:
    cd ~/.wine/drive_c/windows/fonts
    ln -s /usr/share/fonts/windows/simsun.ttc simsun.ttc
    ln -s /usr/share/fonts/windows/simsun.ttc simfang.ttc
    创建一个 simfang.ttc 是许多 Windows 应用默认使用 simfang.ttc 字体。
    3. 修改 ~/.wine/system.reg
    装好字体后,还要修改一下 Wine 的注册表设置,指定与字体相关的设置:
    gedit ~/.wine/system.reg
    (一定要使用 gedit 或其他支持 gb2312/utf8 编码的编辑器修改这些文件,否则文件中的中文可能变乱码)
    搜索: LogPixels
    找到的行应该是:[System\\CurrentControlSet\\Hardware Profiles\\Current\\Software\\Fonts]
    将其中的:
    “LogPixels”=dword:00000060
    改为:
    “LogPixels”=dword:00000070
    搜索: FontSubstitutes
    找到的行应该是:[Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes]
    将其中的:
    “MS Shell Dlg”=”Tahoma”
    “MS Shell Dlg 2″=”Tahoma”
    改为:
    “MS Shell Dlg”=”SimSun”
    “MS Shell Dlg 2″=”SimSun”
    4. 修改 ~/.wine/drive_c/windows/win.ini
    gedit ~/.wine/drive_c/windows/win.ini
    在文件末尾加入:
    [Desktop]
    menufontsize=13
    messagefontsize=13
    statusfontsize=13
    IconTitleSize=13
    5. 最关键的一步,网上很多文章中没有提到的一步──把下面的代码保存为zh.reg,然后终端执行regedit zh.reg。从Windows目录下的Fonts里的simsun.ttc复制到/home/user/.wine/drive_c/windows/fonts里面。

    REGEDIT4
    [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes]
    “Arial”=”simsun”
    “Arial CE,238″=”simsun”
    “Arial CYR,204″=”simsun”
    “Arial Greek,161″=”simsun”
    “Arial TUR,162″=”simsun”
    “Courier New”=”simsun”
    “Courier New CE,238″=”simsun”
    “Courier New CYR,204″=”simsun”
    “Courier New Greek,161″=”simsun”
    “Courier New TUR,162″=”simsun”
    “FixedSys”=”simsun”
    “Helv”=”simsun”
    “Helvetica”=”simsun”
    “MS Sans Serif”=”simsun”
    “MS Shell Dlg”=”simsun”
    “MS Shell Dlg 2″=”simsun”
    “System”=”simsun”
    “Tahoma”=”simsun”
    “Times”=”simsun”
    “Times New Roman CE,238″=”simsun”
    “Times New Roman CYR,204″=”simsun”
    “Times New Roman Greek,161″=”simsun”
    “Times New Roman TUR,162″=”simsun”
    “Tms Rmn”=”simsun”

    之后,中文正常显示哈哈!如图:

    本文转自 http://linux.chinaunix.net/bbs/thread-1027414-1-1.html
    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/41660/showart_1146355.html