Docker系列 搭建nextcloud-fpm + nginx网络服务器
本文最后更新于 4 天前,如有失效请评论区留言。

有需要可加电报群获得更多帮助。本博客用什么VPS?创作不易,请支持苯苯!推荐购买本博客的VIP喔,10元/年即可畅享所有VIP专属内容!也欢迎大佬对本文进行慈善承包(ฅ´ω`ฅ)

日志

  • 2023-07-30:最新版本(2023-07-29)的nextcloud:fpm存在bug,其build成full镜像后php的imap.so缺失从而导致初始化失败。具体见该issue:Unable to load dynamic library ‘imap.so’ · Issue #2037 · nextcloud/docker。推荐暂时使用2023-7-21或之前的nextcloud:fpm来buildfpm-bensz镜像。
  • 2023-06-21:优化Nginx Proxy Manager的教程。感谢@zeyueguo的提醒。

前言

Docker系列 搭建个人云盘服务nextcloud》中包含排障教程(警告&Bug小节),比如不安全URL、caldav解析、数据库丢失索引、无法预览常见格式的文件、无法上传>512M的文件等。有需要者自行食用。

之前我在《Docker系列 搭建个人云盘服务nextcloud》中描述了一种基于Apache网络服务器的Nextcloud部署方法,它相对简单,可以体验很多Nextcloud的日常功能。不过,如果你准备在一台性能较强的机器(CPU性能高、内存大、磁盘空间大)里安装Nextcloud,我更加推荐本文将要介绍的Nextcloud-FPM-FULL + Nginx服务器方案。经过合理的配置,Nextcloud可以充分利(ya)用(zha)宿主机的性能,在响应速度和稳定性上有较大提升;功能也因为更多依赖的安装而更加强大,比如原生支持图片/视频的实时预览

Nextcloud-FPM 使用 FastCGI 进程管理器 (FPM) 来处理 PHP 请求,包括文件同步、共享、用户管理等功能;但未集成 Web 服务器,因此需要用 Nginx 来处理对 Nextcloud 的请求。FULL的概念主要来源于官方文档,即在布署Nextcloud时安装所有扩展功能的相关依赖,比如CRON via supervisor、bz2、imap、gmp、smbclient、ffmpeg、imagemagick 甚至是 LibreOffice[可选,默认禁用]等。

不同于以往使用别人制作好的镜像,我们将直接使用自定义的Dockerfile来生成一个本地镜像。自定义Dockerfile可以提供最大的自由度,这应该才是Nextcloud这种灵活而复杂的应用的最好安装方式了。实际上在Docker的高级用户中,基于Dockerfile的安装方式也是比较流行的。

值得注意的是,《Docker系列 搭建个人云盘服务nextcloud》安装的Nextcloud应该可以迁移至本方案中,但目前还没有测试成功(提示504 Gateway Time-out错误)。所以已经使用了旧版安装方法的小伙伴要考虑一下是否有必要换新,毕竟重构数据也是挺麻烦的。我自己的数据不多(10G+),已经迁移过来了。从长远使用的角度看,本教程的方案是强烈推荐的,毕竟总有一天我们会拥有一台性能强大的机器!

闲话少说,下面咱们讲一下如何部署Nextcloud-FPM-FULL + Nginx服务器吧!

测试环境

系统环境如下:

uname -a # Linux pveomv 5.19.17-2-pve #1 SMP PREEMPT_DYNAMIC PVE 5.19.17-2 (Sat, 28 Jan 2023 16:40:25  x86_64 GNU/Linux
docker --version # Docker version 23.0.5, build bc4487a
docker-compose --version # Docker Compose version v2.4.1

Nextcloud的版本号为26.0.2,为2023-06-08时的最新版本。

准备工作

Nextcloud-fpm镜像

本教程使用的是这个镜像

msedge_ch0FzT1OnI

值得注意的是,官方仓库还有一个类似的镜像,叫fpm-alpinefpm镜像基于基于Debian/PVE操作系统作为基础镜像,它提供更广泛的软件包支持和易用性,但镜像比较大;而fpm-alpine基于 Alpine Linux 的操作系统作为基础镜像,它比较轻量一些。

我注意到fpm-alpine管理www目录的用户是82:82,与Debian系的33:33不太一样;加上自己是在NAS里安装Nextcloud的,对磁盘容量并不敏感,故没有使用fpm-alpine。我测试过这两个镜像,都是可以用的,大家根据实际情况选择即可。

我们创建一个工作目录:

work=~/docker/nextcloud-fpm
mkdir -p $work/custom; cd $work

克隆nextcloud/docker项目:

git clone https://github.com/nextcloud/docker.git

进入nextcloud-fpm的Dockerfile目录:

cd $work/docker/.examples/dockerfiles/full/fpm

build这个镜像:

# docker build -t <容器名> <Dockerfile所在目录>
docker build -t nextcloud:fpm-bensz .

耐心等待。如果错误,一般是apt-get安装依赖的过程不顺利造成的(网络问题),重试直至成功即可。成功时会出现类似字样:

Successfully built 0339xxxxxxxx
Successfully tagged nextcloud:fpm-bensz
# 或者:
# => => writing image # sha256:9e2f042044d24aaxxx 0.0s
# => => naming to docker.io/library/nextcloud:fpm-bensz

如果你的网络环境不好,我也可以考虑将build好的镜像发布到gitee之类的地方。有需要的在评论区留言吧!

我们查看一下该镜像:

docker image list | grep -E 'fpm-bensz'

输出类似:

nextcloud fpm-bensz 033xxxx   3 minutes ago 1.4G

表明该image已经成功安装。如果之后有版本更新,先下线整个stack,然后git pull更新至最新版,再依上述步骤在本地build新镜像即可。强烈推荐RSShub订阅Nextcloud的docker镜像release更新。

部署脚本

地址:https://github.com/nextcloud/docker/tree/master/.examples/docker-compose/insecure/mariadb/fpm

我们主要基于Nextcloud的官方仓库进行布署。首先,进入insecure/mariadb/fpm中:

msedge_yzhJ1cjW2n

请注意,这里的insecure指的是本地部署后以http://局域网ip:端口的方式访问Nextcloud,这是我们想要的,因为我的教程体系中常规使用Nginx Proxy Manager进行https反向代理。选mariadb是因为我们将使用mysql或mariadb作为Nextcloud的后端数据库。

执行以下代码即可复制到docker stack的根目录:

cd $work/docker/.examples/docker-compose/insecure/mariadb/fpm && cp -rp * $work

Dockerfile

web文件夹只有Dockerfile和nginx配置:

total 9.0K
-rw-r--r-- 1 root bensz   57 Jun  7 16:52 Dockerfile
-rw-r--r-- 1 root bensz 7.4K Jun  7 20:24 nginx.conf

Dockerfile要求安装一个nginx容器并使用定制好的nginx.conf。

msedge_EJUMhOjnix

nginx.conf

建议在nginx.conf文件中做一些修改,这是一个示例。具体如下:

msedge_vROA4M53LT

msedge_ZpU0zH26iW

这些改动可以帮助更好地通过Nextcloud的安全检查。

db.env

db.env指定了MYSQL帐户信息等在多个docker app中会被用到的环境变量:

MYSQL_PASSWORD=
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud

在以往的教程中,我一般直接在docker-compose.yml重复地声明这些变量。但在一些有经验的docker使用者中,定义1个或多个*.env文件是更加流行和方便的策略。感兴趣的小伙伴以后也可以多应用这个技巧!

www.conf

我们需要在custom目录中创建一个www.conf,这是一个示例。它定义了Nextcloud-fpm中PHP的一些行为。在Nextcloud 26.0.2中,该文件在容器中的位置为/usr/local/etc/php-fpm.d/www.conf。我对这个文件的理解也不多,但知道一些比较重要的参数。

在官方文档 Server tuning — Nextcloud latest Administration Manual latest documentation中有这个描述:For example on a machine with 4GB of RAM and 1GB of MySQL cache following values in your www.conf file should work:

pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18

目前,我在自己的NAS里也是使用这个配置。大致的原则就是pm.max_children最大,而pm.start_serverspm.min_spare_serverspm.max_spare_servers。它们定义了php并发请求的一些基础值和上下限;配置好可以增强Nextcloud在多并发场景的表现。

大家可以使用这个设置,然后根据日志调试。这些参数在www.conf中的实际位置如下:

image-20230608093631731

最后,记得修改一下文件夹的权限:

sudo chown -R 33:33 $work/custom

其它准备

最后,$work目录的文件分布大致如下:

├── [   3]  custom
│   └── [ 22K]  www.conf
├── [  78]  db.env
├── [1.6K]  docker-compose.yml
└── [   4]  web
    ├── [  57]  Dockerfile
    └── [7.4K]  nginx.conf

如果你的VPS还使用了ufw等防火墙,要开放相应的端口。这里以1234为例:

ufw allow 1234/tcp comment 'nextcloud-fpm' && ufw reload

如果VPS后台管理中还有其它防火墙,也要依次放行。

准备好域名解析,比如nextcloudtest.hwb0307.com

安装Nextcloud-fpm

db.env

修改文件:

vim $work/db.env

自定义MYSQL数据库的相关信息,比如:

MYSQL_PASSWORD=test0test0!
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud

实际使用时一般是这样调用:

env_file:
  - db.env

docker-compose.yml

我们在原版的基础上进行了优化,大家要根据实际情况微调:

version: '3'

services:
  db:
    # image: mariadb:10.6.5-focal # mariadb和mysql二选一即可
    image: mysql:8.0
    container_name: nextcloud-fpm-db
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW --max-binlog-size=200M --expire-logs-days=2 # 优化mysql配置
    restart: unless-stopped
    volumes:
      - ./db:/var/lib/mysql:Z
    environment:
      - MYSQL_ROOT_PASSWORD=nextclouddb_root_password
    env_file:
      - db.env
    networks:
      - default

  cache:
    image: redis:latest
    container_name: nextcloud-fpm-cache
    restart: unless-stopped
    expose:
     - "6379" # 可用此默认。因为这是暴露而不是映射
    volumes:
     - ./cache:/data
    networks:
      - default

  app:
    image: nextcloud:fpm-bensz
    container_name: nextcloud-fpm-app
    restart: unless-stopped
    volumes:
      - ./app:/var/www/html:z
      - ./custom/www.conf:/usr/local/etc/php-fpm.d/www.conf
    environment:
      - MYSQL_HOST=db
      - REDIS_HOST=cache
    env_file:
      - db.env
    depends_on:
      - db
      - cache
    networks:
      - default

  web:
    build: ./web
    container_name: nextcloud-fpm-web
    restart: unless-stopped
    ports:
      - 1234:80 # 按需要修改
    volumes:
      - ./app:/var/www/html
    depends_on:
      - app
    networks:
      - default

  cron:
    image: nextcloud:fpm-bensz
    container_name: nextcloud-fpm-cron
    restart: unless-stopped
    volumes:
      - ./app:/var/www/html
    entrypoint: /cron.sh
    depends_on:
      - db
      - cache
    networks:
      - default

networks:
  default:
    name: nextcloud-fpm

请注意,在这里我指定了数据库的版本号mariadb:10.6.5-focalmysql:8.0。你可以改为自己正在使用的版本号,这样比较节省空间。我个人比较推荐mysql,因为mysql可以随便转到mariadb中,但mariadb转到mysql里比较困难。

web直接使用一个nginx:alpine镜像+自定义nginx.conf。cron就是利用nextcloud:fpm中的/cron.sh脚本自动配置后台作业。

然后,直接上线整个docker stack即可:

docker-compose up -d

在线安装

耐心等一段时间,之后访问 http://局域网ip:1234即可。装的过程可能地址会失效,继续访问即可:

image-20230607134033753

整个过程和旧版的安装过程是差不多的。

配置NPM

不了解Nginx Proxy Manager用法的小伙伴,请看《Docker系列 两大神器NPM和ddns-go的安装》。

ddns-go或者域名托管商后台解析好域名nextcloudtest.hwb0307.com。假设NAS的局域网IP是192.168.1.123

添加一个Proxy Host,反代地址是http://192.168.1.123:1234。可用泛域名的SSL证书。

最后,我们需要在Nginx Proxy Manager的Advanced里添加一些内容:

msedge_StAWl6FboT

家用搭建的服务器一般是用别的端口来代替443。假设我们使用2443作为Nginx Proxy Manager的默认443端口,那么添加内容为:

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

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

location /.well-known/webfinger {
    return 301 $scheme://$host:2443/index.php/.well-known/webfinger;
}

location /.well-known/nodeinfo {
    return 301 $scheme://$host:2443/index.php/.well-known/nodeinfo;
}

如果你使用的是默认的443端口,则不需要加端口号:

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/webfinger {
    return 301 $scheme://$host/index.php/.well-known/webfinger;
}

location /.well-known/nodeinfo {
    return 301 $scheme://$host/index.php/.well-known/nodeinfo;
}

这些代码有助于通过Nextcloud的安全检查:

msedge_UMhvT98v0v

有时候webfingernodeinfo的安全警告会比较难以消失,可以通过退出帐号重新登陆docker-compose down && docker-compose up -d重新部署整个stack等方法进一步去除。

config.php

完成安装后,先不要正式使用Nextcloud,而是检查一下$work/app/config/config.php文件的内容。这是一个示例

  • Redis缓存信息
'memcache.local' => '\\OC\\Memcache\\APCu', // 默认是APCu。好像没法改为Redis?
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => 
array (
    'host' => 'cache', // 和docker-compose.yml中Redis的“小名”要一致。
    'password' => '', // docker-compose.yml中没声明,故留空。
    'port' => 6379,
),
  • 域名限制性。如果使用的是https访问,可以这样写:
array (
    0 => '192.168.1.123', 
    1 => 'nextcloudtest.hwb0307.com',
  ),
'overwritehost' => 'nextcloudtest.hwb0307.com:4443',
'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'http://nextcloudtest.hwb0307.com:4443',

这里假定使用的443端口为4443。如果你直接使用443,这个端口号可以不写。

如果仅在本地访问,可以这样写:

array (
    0 => '192.168.1.123', 
  ),
'overwritehost' => 'http://192.168.1.123:1234',

修改完成后,直接重启docker stack即可:

docker-compose restart

管理设置

看看管理设置的安全与后台有没有问题,有问题按《Docker系列 搭建个人云盘服务nextcloud》的“警告&Bug”小节。 不过,由于我们使用了Nginx作为Web服务器,一些bug的解决方法和之前的Apache服务器是不同的。具体情况具体分析喽!我暂时是没遇到太多问题:

msedge_X3JUwkCNw2

msedge_9igZ5pzeLu

小结

整个布署过程比Nextcloud-Apache稍复杂些。不过,如果你对Docker和Nextcloud比较熟悉,应该难度不大。如果你有一台强大的服务器,这个方案是很推荐的,可拓展性和性能都可以上一个档次!官方仓库的教程也十分贴心,有相见恨晚的感觉!其它使用技巧见学习地图的“Nextcloud”系列,这里不多说了。

以后有什么使用心得会继续更新内容。请拭目以待!

扩展阅读

---------------
完结,撒花!如果您点一下广告,可以养活苯苯😍😍😍

基于m2w创作。版权声明:除特殊说明,博客文章均为Bensz原创,依据CC BY-SA 4.0许可证进行授权,转载请附上出处链接及本声明。VIP内容严禁转载!由于可能会成为AI模型(如chatGPT)的训练样本,本博客禁止将AI自动生成内容作为文章上传(特别声明时除外)。如有需要,请至学习地图系统学习本博客的教程。加Telegram群可获得更多帮助喔! | 博客订阅:RSS | 广告招租请留言 | 博客VPS | 致谢渺软公益CDN |

评论

  1. Macintosh Safari 16.6
    21小时前
    2023-9-22 11:02:59

    按照您的步骤,到:Dockerfile要求安装一个nginx容器nginx:alpine,pull了nginx:alpine镜像,直接启动安装容器即可吗?或者说这步具体应该怎么操作(是个菜鸟,一直没搞明白)。

    • 博主
      Windows Edge 117.0.2045.31
      已编辑
      21小时前
      2023-9-22 11:31:06

      做好准备工作,最后文件夹包含这些文件就行:

      ├── [   3]  custom
      │   └── [ 22K]  www.conf
      ├── [  78]  db.env
      ├── [1.6K]  docker-compose.yml
      └── [   4]  web
          ├── [  57]  Dockerfile
          └── [7.4K]  nginx.conf

      之后严格按照教程的顺序来走即可。

      • san
        Bensz
        Macintosh Safari 16.6
        13小时前
        2023-9-22 19:07:45

        再请教:部署成功后,通过npm反代,用苹果手机的app登录出错,无法登录。还需要设置哪里吗?

  2. san
    Windows Edge 116.0.1938.81
    5天前
    2023-9-17 20:57:43

    debian12最新版,apt upgrade更新时速度太慢,只有15K左右的速率,更换了国内的阿里等源,仍然从deb.debian.org更新文件,速度太慢。有什么办法解决吗?

    • 博主
      san
      Windows Edge 117.0.2045.31
      3天前
      2023-9-19 22:06:52

      如果你是指build镜像的过程,你可以了解一下docker build image时镜像源是不是可以选。 我暂时没研究过这个问题 (ฅ´ω`ฅ)

  3. Linux Firefox 116.0
    已编辑
    4周前
    2023-8-26 16:02:11

    先用 apache 镜像部署的,性能实在太拉,直接切换 fpm 镜像部署,没遇到问题(没有切换域名,仅更换了镜像)

    • 博主
      HE-SB
      Windows Edge 116.0.1938.54
      4周前
      2023-8-26 16:31:02

      确实,Apache只是简单,但性能是拉一点 ~ 总之我自己是越来越受不了Apache那一套了,所以使用的Nginx 😔

  4. yueshu123
    Windows Chrome 115.0.0.0
    2月前
    2023-7-29 20:29:32

    大佬,家用nas部署是不是要配合frp内网穿透啊,我按照教程用ddns-go和npm反代之后外网环境还是没法访问

    • 博主
      yueshu123
      Windows Edge 115.0.1901.188
      2月前
      2023-7-29 22:52:29

      这可能会由很多原因造成。你家的宽带如果没有公网IP,则不能用ddns-go/NPM的体系来访问,只能用frp之类的内网穿透方案。

  5. Windows Chrome 86.0.4240.198
    2月前
    2023-7-19 10:28:15

    按照教程搭建 运行起来 访问502了⌇●﹏●⌇

    • 博主
      Windows Edge 114.0.1823.82
      2月前
      2023-7-19 12:00:08

      方便的话可以远程帮你看一下。我加你QQ啦!

  6. zeyueguo
    Windows Edge 114.0.1823.51
    3月前
    2023-6-21 14:29:56

    遇到下面的安全警告:
    您的网页服务器未正确设置以解析“/.well-known/webfinger”
    您的网页服务器未正确设置以解析“/.well-known/nodeinfo”
    在Nginx Proxy Manager里面添加
    location /.well-known/webfinger {
    return 301 $scheme://$host:$server_port/index.php/.well-known/webfinger;
    }
    location /.well-known/nodeinfo {
    return 301 $scheme://$host:$server_port/index.php/.well-known/nodeinfo;
    }

    • 博主
      zeyueguo
      Windows Edge 114.0.1823.51
      3月前
      2023-6-21 15:50:42

      如图:

      查看图片
      msedge_IMjrN49bl8

      。 而且,你没发现下面那位大佬,也有说到你的这个问题嘛! 我用的nginx.conf和官网的是不一样的。你仔细比较一下。 你可以直接复制我的使用,我也给出示例了

    • 博主
      zeyueguo
      Windows Edge 114.0.1823.51
      3月前
      2023-6-21 15:59:47

      喔,我知道你的意思了,我之前也加了。 忘了说了! 谢谢提醒哈! 教程更新了。

  7. iscay
    Windows Chrome 95.0.4638.69
    3月前
    2023-6-20 14:25:47

    文档写的很棒,很有参考性,谢谢分享。
    实践时没仔细看文档www.conf缺了user和group的配置
    直接配置了https,重定向的路径没有给全,nextcloud安全性检查难以通过。
    就碰到这两问题,浪费了点时间。
    文档写的很详细,再次感谢

    • 博主
      iscay
      Windows Edge 114.0.1823.51
      3月前
      2023-6-20 16:19:05

      谢谢提醒! “重定向的路径没有给全,nextcloud安全性检查难以通过”是指什么,可否讲得详细些?

      • iscay
        Bensz
        Windows Chrome 95.0.4638.69
        3月前
        2023-6-20 16:38:14

        可能是在修改config.php时,没有添加’overwritehost’ 和’overwriteprotocol’ ,
        nextcloud安全性检查时carddav、caldav、webfinger、nodeinfo没有能通过,最后直接修改了nginx.conf配置
        location = /.well-known/carddav { return 301 https://domain.com:8080/remote.php/dav/; }
        location = /.well-known/caldav { return 301 https://domain.com:8080/remote.php/dav/; }
        location =/.well-known/webfinger {return 301 https://domain.com:8080/index.php/.well-known/webfinger;}
        location =/.well-known/nodeinfo {return 301 https://domain.com:8080/index.php/.well-known/nodeinfo;}

      • 博主
        iscay
        Windows Edge 114.0.1823.51
        3月前
        2023-6-20 16:41:16

        噢噢,这些点我之前都有讲过。 成功就行,这个版本还是不错的! 另外,如果你使用Onlyoffice的话,尽量不要使用它的预览功能,否则进入一个多文档文件夹时可能会拖慢甚至是卡死nextcloud。 之后还有什么经验也欢迎分享哈!

      • iscay
        Bensz
        Windows Chrome 95.0.4638.69
        3月前
        2023-6-20 16:57:51

        谢谢提醒
        我的nextcloud主要是给Obsidian和Typora多机同步用的,nextcloud本身使用率不高,一直感觉nextcloud太臃肿。

  8. ovst
    Windows Chrome 114.0.0.0
    3月前
    2023-6-13 11:08:55

    对于不确定怎么移植数据的我,不太敢换新玩意。

    • 博主
      ovst
      Windows Edge 114.0.1823.43
      已编辑
      3月前
      2023-6-13 11:11:09

      嗯嗯,总之是一个方案。 你可以开个测试容器体验一下。迁移数据的方案我也没折腾成功,只能说将数据重新上传了。因为在nextcloud的根目录下,文件目录格式是保持的,所以直接拉取上传也挺方便。 当时我就10来个G的数据(主要是手机相册),上传很快。

      • ovst
        Bensz
        Windows Chrome 114.0.0.0
        3月前
        2023-6-13 11:13:08

        搭好容器,然后文件夹形式重新上传文件。可是系统配置,如分享链接等不就得重新配置了么。

      • 博主
        ovst
        Windows Edge 114.0.1823.43
        3月前
        2023-6-13 11:14:16

        是啊 当时NAS的没有多少分享链接,所以直接重建。 分享比较多的就挺难受的。 以后折腾一下看看有没有万全之策,哎!

      • ovst
        Bensz
        Windows Chrome 114.0.0.0
        3月前
        2023-6-13 11:19:05

        我现在用思源笔记+nextcloud配合使用。
        笔记中我可以直接贴nextcloud的内链,如https://****/f/746。很方便文件管理
        对应的就是,直接上新容器这些内链肯定会变化。

      • 博主
        ovst
        Windows Edge 114.0.1823.43
        3月前
        2023-6-13 11:19:59

        也不失为一种可考虑的方案。 以后有机会研究 (ฅ´ω`ฅ)

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇