Clear docker

  1. 移除意外停止运行的container

     $ sudo docker rm -v $(sudo docker ps --filter status=exited -q)
    
  2. 移除不在使用中的image

     $ sudo docker rmi $(sudo docker images --filter "dangling=true" -q --no-trunc) 
    
  3. 移除不在使用中的volume

     $ sudo docker volume rm $(sudo docker volume ls -qf dangling=true)
    
  4. 移除不在使用中的镜像(没运行容器的镜像)

     $ docker images | awk '{print $3}' | xargs docker rmi
    
  5. 清除所有不再运行中的容器, 镜像, 挂载目录, 网络层(所有未运行中的, 包括有用的和dangling)

     $ docker container prune -a
     $ docker image prune -a
     $ docker network prune -a
     $ docker volume prune -a
     $ docker system prune -a
    


  1. 如果还没有docker group就添加一个:

     $ sudo groupadd docker
    
  2. 将用户加入该group内。然后退出并重新登录就生效啦。

     $ sudo gpasswd -a ${USER} docker
    
  3. 重启docker

     $ sudo service docker restart
    
  4. 如果是ssh, 退出ssh再重新登录

本文基础环境为DigitalOcean Droplet下的centos


安装Ghost

ghost的安装方法,请点击这里。本文将ghost安装在nginx默认根目录 /home/wwwroot/ghost

让 Ghost 一直运行

前面提到的启动 Ghost 使用 npm start 命令。这是一个在开发模式下启动和测试的不错的选择,但是通过这种命令行启动的方式有个缺点,即当你关闭终端窗口或者从 SSH 断开连接时,Ghost 就停止了。为了防止 Ghost 停止工作,有多种方式解决这个问题。本文采用pm2。

$ npm install pm2 -g //安装pm2
$ NODE_ENV=production pm2 start index.js --name "ghost" //将production写入环境变量,将服务命名为ghost
$ pm2 startup centos pm2 save //随系统一块启动
$ pm2 kill ghost //杀掉所有名为ghost的进程
$ pm2 start ghost
$ pm2 stop ghost
$ pm2 status ghost 查看ghost进程状态

配置 Ghost 域名

如果你已经让 Ghost 在后台运行了,你也可以设置一个代理服务器让你的博客可以使用域名访问。以下的示例使用 Nginx 作为你的Web服务器。

安装 nginx

$ sudo apt-get install nginx

这个命令将会安装nginx并且设定好所有必需的目录和基础配置。

配置你的站点

在 /usr/local/nginx/conf/vhost 创建一个 ghost.conf 文件 使用文本编辑器打开这个文件 (e.g. sudo vim /usr/local/nginx/conf/vhost/ghost.conf) 把以下内容复制进这个文件

server {
listen 80;
server_name example.com;
location / {
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host      $http_host;
    proxy_pass         http://127.0.0.1:2368;
    }
access_log /home/wwwlogs/access.example.com.log  access;
}

将 server_name 的值改为你的域名,重启nginx

$ sudo service nginx restart

更改默认数据库

ghost默认数据库为sqlite3,我们可以替其换成更安全的mysql来存储数据。

安装 mysql

$ yum install -y mysql-server mysql mysql-devel

在mysql内新建一个名为ghost的数据库

在ghost根目录找到config.js,将production下的database替换成以下内容:

database: {
client: 'mysql',
connection: {
    host: 'localhost',
    user: 'root',
    password: 'your password',
    database: 'ghost',
    charset: 'utf8'
},

Tips: nginx和mysql都可以利用lnmp包一键安装,可以点击这里查看

参考文章

开始 Ghost 之旅

权限有三种类型,r(读)、w(写)、x(执行),且每种类型有对应的值:

r=4
w=2
x=1

文件权限由三组 rwx 组成:

xxx xxx xxx
按从左到右,分别是文件所属用户,文件所属用户组,所有用户

赋值的时候按所需权限的值求和:

-rw-r--r-x   chmod -R 645  file(dir)

Symfony 是一系列可复用的PHP组件结合的Web后台框架,可以通过引用不同的bundle来构建我们的项目。其中最流行的就是构建RESTful API。


  1. 安装lnmp环境或vagrant开发环境

  2. 下载最新的symfony安装包

     $ sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
     $ sudo chmod a+x /usr/local/bin/symfony 
     $ symfony new project
    
  3. 下载最新composer安装包

     $ curl -sS https://getcomposer.org/installer | php
     $ mv composer.phar /usr/local/bin/composer
    
  4. 安装相关bundle

    • FOSRestBundle
      • composer require friendsofsymfony/rest-bundle(网络不好时,可以先在composer.json文件中添加 "friendsofsymfony/rest-bundle": "^1.7", 然后运行composer update nothing, 再运行composer install
      • 在app/AppKernel.php file中添加 new FOS\RestBundle\FOSRestBundle(),
      • 在app/config/config.yml->framework 启用serializer属性

           serializer:
               enable_annotations:true
        
      • 在app/config/config.yml添加如下配置

          fos_rest:
              body_converter:
                  enabled: true
              view:
                  view_response_listener: 'force'
                  formats:
                      json: true
              format_listener:
                  rules:
                      - { path: ^/api, priorities: [ json ], fallback_format: json, prefer_extension: true }
                      - { path: '^/', priorities: [ 'html', '*/*'], fallback_format: html, prefer_extension: true }
        
      • 在app/config/routing.yml设置prefix,例子如下:

          clash_api:
              resource: "@ClashApiBundle/Resources/config/routing.yml"
              prefix:   /api
        
    • JMSSerializerBundle
      • composer require jms/serializer(网络不好时,可以先在composer.json文件中添加 "jms/serializer-bundle": "^1.0", 然后运行composer update nothing, 在运行composer install
      • 在app/AppKernel.php file中添加 new JMS\SerializerBundle\JMSSerializerBundle(),
  5. 创建rest风格的class时,use FOS\RestBundle\Controller\FOSRestController; 继承 FOSRestController, 例子如下:

     class PostController extends FOSRestController
     {
         // code something here .....
     }
    
  6. 声明rest api的几种方式:

    • use FOS\RestBundle\Controller\Annotations; 在function的上方添加注释,例子如下:

        /**
         * @Annotations\Get("/posts/category/{id}")
         */
        public function getPostsByCategoryAction() 
        {
            // code something here .....
        }
      
    • 当直接通过id获取对象时,也可以省略不写,例子如下:

        public function getPostAction(Post $post)
        {
            // code something here .....
        }
      
  7. 返回json view的几种方式:

    • GET 方法通过查询直接获取对象时,可以通过系列化的方式,返回特定的字段。
      • 现在entity中设置好需要返回的字段

          /**
           * @ORM\Entity()
           */
          class Post
          {
              /**
               * @var int
               *
               * @ORM\Id
               * @ORM\Column(type="integer")
               * @ORM\GeneratedValue
               * @Serializer\Groups({"ManyPosts"})
               */
              private $id;
                    
              /**
               * @Serializer\Groups({"ManyPosts"})
               * @Serializer\VirtualProperty
               * @Serializer\SerializedName("owner")
               */
              public function degenerateOwner()
              {
                  return [
                      'id' => $this->user->getId(),
                      'username' => $this->user->getUsername(),
                      'picture_id' => $this->user->getPictureId(),
                  ];
              }
          }
        
      • 在对应的class里 use FOS\RestBundle\View\View; 在function的上方添加注释,例子如下:

          /**
           * @Annotations\View(serializerGroups={"Default", "ManyPosts"})
           */
          public function getPostsOwnerAction()
          {
              // code something here .....
              return $posts;
          }
        
    • POST/PUT/PATCH等方法返回自定义view时,不用注释,在return构建自定义view,例子如下:

        return $this->handleView(
            new View(
                array(
                    'id' => $post->getId(),
                ),
                Response::HTTP_CREATED
            )
        );