树莓派搭建NAS(SMB, ARIA2,流播放器)

最近,买了一个树莓派,发现可玩性很强. 在研究一天后,记录一下感受。

挂载移动硬盘

我是先把硬盘用gpart格式为ext4

$ sudo mkdir -p /mnt/usbdrive
$ sudo mount /dev/sda1 /mnt/usbdrive

为了能让树莓派启动的时候,自动挂载硬盘,我们要写一个脚本,然后让它开机自动启动。

创建/usr/bin/脚本名字

以下是,我的文件 /usr/bin/aria

#!/bin/bash

sudo mount /dev/sda1 /mnt/usbdrive
sudo chmod -R 777 /mnt/usbdrive

把文件的权限改成777是让所有人都可以读写文件。后面Samba会用到。

并且修改/etc/rc.local文件,在exit 0之前加上以下的语句

sudo sh /usr/bin/aria

这个脚本就可以开机执行了。

安装并配置 Samba

首先安装Samba

$ sudo apt-get install samba samba-common-bin

编辑文件sudo vim /etc/samba/smb.conf

[nas]
comment = NAS Storage
Path = /mnt/usbdrive
valid users = root pi
force group = users
create mask = 0664
directory mask = 0775
read only = no
writeable = yes

在文件末尾插入就可以了,你也可以把文件中用不到的东西删掉。

然后创建用户pi并设密码

sudo smbpasswd -a pi

配备完后,重启Samba

sudo /etc/init.d/samba restart

aria2 安装及配置

刚装完官方的debian, nginx和aria2 的时候,发现怎么也不好使(webui连到了aria2 RPC server 但下载不了东西。aria2命令行可以下东西)。于是重新装debian, 换成用docker来装aria2和webui

首先,安装docker.这个可以通过树莓派官方的包管理器安装,因为我把树莓派的图形界面关掉了,所以就不贴图了。

安装完docker, 下载镜像

docker pull abrahammouse/raspbian-aria2-webui

运行镜像

mkdir -p /mnt/usbdrive/downloads

docker run -d --name aria -p 6800:6800 -p 80:80 -v /mnt/usbdrive/downloads:/data abrahammouse/raspbian-aria2-webui

遇到问题的话,可以进入cotainer里面看出了什么问题

docker exec -it aria /bin/bash

没有问题,继续下面的教程

为了能够让这个container 再开机运行,修改/usr/bin/aria(修改你自己之前的脚本文件)

#!/bin/bash

sudo mount /dev/sda1 /mnt/usbdrive
sudo chmod -R 777 /mnt/usbdrive
docker start aria
exit 0

这里面包括了之前的脚本,其实只加了docker start aria. 注意的是docker start aria一定要放到后面,因为我们要先mount硬盘之后,才能map硬盘里的文件夹.

minidlna

其实,我感觉安装了Smba就没有必要安装minidlna了。但因为我已经踩过了这个坑,就记录一下好了。

首先,安装minidlna

sudo apt install minidlna

修改minidlan 配置文件(/etc/minidlna.conf)

# If you want to restrict a media_dir to a specific content type, you can
# prepend the directory name with a letter representing the type (A, P or V),
# followed by a comma, as so:
#   * "A" for audio    (eg. media_dir=A,/var/lib/minidlna/music)
#   * "P" for pictures (eg. media_dir=P,/var/lib/minidlna/pictures)
#   * "V" for video    (eg. media_dir=V,/var/lib/minidlna/videos)
#   * "PV" for pictures and video (eg. media_dir=PV,/var/lib/minidlna/digital_camera)

media_dir=/var/lib/minidlna

media_dir=PV,/mnt/usbdrive/downloads

media_dir=V,/mnt/usbdrive/videos

media_dir=A,/mnt/usbdrive/music

上面的comment是说明,根据说明配置自己的文件。因为,minidlna会开机自己启动。所以也不需要写脚本文件了.

结语

至此,我们就完成了NAS的搭建。其实还有一些改善的东西,比如加入ngrok外网穿透,ftp连接。因为比较简单,我就没写到里面。在研究树莓派的时候,遇到了很多的坑没有写到里面。比如64GB内存卡,一定要用gpart格式成FAT32等问题(树莓派只识别FAT32USB启动),我都研究了很久,很痛苦。当然,也有完成之后的成就感。在接下来的几天里,我也会继续研究树莓派,享受它的乐趣。

apache 换成 nginx

https://www.howtoforge.com/tutorial/dockerizing-wordpress-with-nginx-and-php-fpm/

之前在DO的VPS上搭建的博客(LAMP),如果不开swap space 有时会因为内存不过杀掉mysql,导致网站无法打开。虽然最近打开了swap space, 情况大幅度好转,但从网上看到说nginx比apache 省内存。所以,动手试试:). 这篇文章根据网上教程写的(链接在最上面), 内容非原创. 因为,网上已经有教程了。所以,我也就只把配置文件贴出来就好了,具体请看教程.

docker-compose.yml

version: '2'

services:

   nginx:
    image: nginx:latest
    ports:
        - '80:80'
    volumes:
        - ./nginx:/etc/nginx/conf.d
        - ./logs/nginx:/var/log/nginx
        - ./wordpress:/var/www/html
    links:
        - wordpress
    restart: always

   db:
     image: mariadb:latest
     ports:
       - '3306:3306'
     volumes:
       - ./db-data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: qinjingfei
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
     container_name: qinjingfei_db

   wordpress:
     depends_on:
       - db
     image: wordpress:4.7.1-php7.0-fpm
     volumes:
       - ./wordpress:/var/www/html
     restart: always
     ports:
       - "9000:9000"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
     container_name: qinjingfei_wp

效果:比apache省100MB内存

Vue.js 2.0 教程

### Vue

首先,我们要先全局安装vue-cli.

$ sudo npm install -g vue-cli

然后,我们来创建一个新的项目

$ vue init webpack vueapp01

进入项目的文件夹,安装dependencies

$ cd vueapp01
$ npm install

安装完之后,我们就可以打开一个web server 了

$ npm run dev

这个命令会自动在localhost:8080创建一个server并把output显示在浏览器里。

项目结构

我们来看一下在新建项目里的文件结构

  • package.json文件里包括项目所有的dependecies
  • npm install 会把package.json里列出的dependecies 安装到 node_modules文件夹中

下面是index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>vueapp01</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

接下来,我们看一下在src文件夹中的main.js

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

  • App是项目的根组件(root component)
  • Vue 是项目的主要框架

我们再看一下 App.vue 的内容

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <hello></hello>
  </div>
</template>
<script>
import Hello from './components/Hello'
export default {
  name: 'app',
  components: {
    Hello
  }
}
</script>
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

我们可以看到App 需要Hello 组件。Hello 组件被定义到了component 文件中的Hello.vue.

下面是Hello.vue文件

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li><a href="https://gitter.im/vuejs/vue" target="_blank">Gitter Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
      <br>
      <li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a></li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

值得注意的是这里的data不是object. 这里的data是一个function return to an object.


下面我们可以来改一下Hello.vue

<template>
  <div class="hello box">
    <ul>
      <li v-for="name in names">{{name.name}}</li>
    </ul>

    <input type="text" placeholder="THis is my input" v-model="input">
    <div >
      Input Name: {{input}}
    </div>

    <button type="button" @click="counter++">You've clicked this button
      {{counter}} times</button>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      names:[
        {name:"Jaime Lannister"},
        {name:"John Snow"},
        {name: "Sansa Stark"},
        {name: "Arya Stark"}
      ],
      input:"",
      counter:0

    }
  }
}
</script>

<style media="screen">
  .box{
    width:20%;
    margin:0 auto;
  }
</style>

效果如下

至此,我们已经完成了一个用vue-cli写的小demo.

用vue写一个to do list

最近,想学一些前端的知识。但感觉无从下手,因为前端的框架好多,不知道选哪一个 Angular, Vue, reat,backbone… 想想还是先学一下最近最火的vue好了,毕竟以前用vue写过一个网站而且vue也是中国人写的。但已经快一年没碰过vue了,什么都不记得了,就写一个to do list来复习一下vue好了。

构思

  • 用什么储存数据?

因为, 要做一个简单to do list,就不想考虑数据库了,用一个数组来储存数据就可以了。

  • 需要什么功能?

to do list 的功能的话,只需要有增加任务和删除任务就好。所以,需要两个function就可以了。

实际效果

全部代码可以到codepen上去查看,https://codepen.io/jingfei/pen/Npppya

下面我就讲一下关于vue的代码好了.

 <input v-model="task" @keyup.enter="add_task"  type="text" placeholder="Enter Your Task" />

v-model实现输入的内容和task进行双向绑定。用v-on来监听DOM事件,如果enter(按回车),执行add_task function.

下面是Vue实例

var app = new Vue({
  el: '#app',
  data: {
    task:"",
    todos:[]
  },
  methods:{
  add_task: function(){
    if(this.task){
      this.todos.push({text:this.task,isCompleted:false})
      this.task=""
    }else{
      alert("content cannot be empty")
    }
  },
  completed: function(index){
    this.todos[index].isCompleted=!this.todos[index].isCompleted
  }
}
})
<div class="box1">
     <ul v-for="todo,index in todos">
     <li>
       <input type="checkbox":checked="todo.isCompleted" @click="completed(index)">
       <span :class="todo.isCompleted?'completed':'' ">
        {{todo.text}}
       </span>
     </li>
   </ul>
  </div>

v-for来遍历todos的数组。用v-bind来把checkedhtml 属性和todo.isCompleted绑定。用v-on来监听鼠标左键,如果按了左键,执行completed(index) function. 利用v-bind来绑定class, 如果todo.isCompleted 是真的话,加入completed class.

总结

以上就是关于vue的代码了。在这个小项目里,对双向绑定,自定义触发和监听,绑定hmtl属性和class进行了实践。

如何满速在linux下载

  • aria2c

Aria2 本质是一个下载工具,支持多协议、多来源. 对我们来说,它是一个可以支持任何下载方式的工具。

Aria2有两种模式,一种是命令行模式,另一种是RPC Server模式。网上比较流行的是RPC Server + webui.

命令行模式和配置文件

使用配置文件的方式管理配置(可以添加 -D 选项以后台运行):

配置文件

$ aria2c --conf-path=aria2c.conf

下面是我的配置文件(网上的配置文件很多,我也是抄别人的)

## '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 ##
## 被注释的选项填写的是默认值, 建议在需要修改时再取消注释  ##

## 文件保存相关 ##

# 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置
dir=~/downloads
# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
#disk-cache=32M
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
file-allocation=none
# 断点续传
continue=true

## 下载连接相关 ##

# 最大同时下载任务数, 运行时可修改, 默认:5
max-concurrent-downloads=5
# 同一服务器连接数, 添加时可指定, 默认:1
max-connection-per-server=5
# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
split=5
# 整体下载速度限制, 运行时可修改, 默认:0
#max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0
#max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0
#max-overall-upload-limit=0
# 单个任务上传速度限制, 默认:0
#max-upload-limit=0
# 禁用IPv6, 默认:false
disable-ipv6=true

## 进度保存相关 ##

# 从会话文件中读取下载任务
input-file=/etc/aria2/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
save-session=/etc/aria2/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
#save-session-interval=60

## RPC相关设置 ##

# 启用RPC, 默认:false
enable-rpc=true
# 允许所有来源, 默认:false
rpc-allow-origin-all=true
# 允许非外部访问, 默认:false
rpc-listen-all=true
# 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同
#event-poll=select
# RPC监听端口, 端口被占用时可以修改, 默认:6800
#rpc-listen-port=6800
# 设置的RPC授权令牌, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项
#rpc-secret=<TOKEN>
# 设置的RPC访问用户名, 此选项新版已废弃, 建议改用 --rpc-secret 选项
#rpc-user=<USER>
# 设置的RPC访问密码, 此选项新版已废弃, 建议改用 --rpc-secret 选项
#rpc-passwd=<PASSWD>
# 是否启用 RPC 服务的 SSL/TLS 加密,
# 启用加密后 RPC 服务需要使用 https 或者 wss 协议连接
#rpc-secure=true
# 在 RPC 服务中启用 SSL/TLS 加密时的证书文件,
# 使用 PEM 格式时,您必须通过 --rpc-private-key 指定私钥
#rpc-certificate=/path/to/certificate.pem
# 在 RPC 服务中启用 SSL/TLS 加密时的私钥文件
#rpc-private-key=/path/to/certificate.key

## BT/PT下载相关 ##

# 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true
#follow-torrent=true
# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999
listen-port=51413
# 单个种子最大连接数, 默认:55
#bt-max-peers=55
# 打开DHT功能, PT需要禁用, 默认:true
enable-dht=false
# 打开IPv6 DHT功能, PT需要禁用
#enable-dht6=false
# DHT网络监听端口, 默认:6881-6999
#dht-listen-port=6881-6999
# 本地节点查找, PT需要禁用, 默认:false
#bt-enable-lpd=false
# 种子交换, PT需要禁用, 默认:true
enable-peer-exchange=false
# 每个种子限速, 对少种的PT很有用, 默认:50K
#bt-request-peer-speed-limit=50K
# 客户端伪装, PT需要
peer-id-prefix=-TR2770-
user-agent=Transmission/2.77
# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0
seed-ratio=0
# 强制保存会话, 即使任务已经完成, 默认:false
# 较新的版本开启后会在任务完成后依然保留.aria2文件
#force-save=false
# BT校验相关, 默认:true
#bt-hash-check-seed=true
# 继续之前的BT任务时, 无需再次校验, 默认:false
bt-seed-unverified=true
# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false
bt-save-metadata=true

命令行

我比较常用的:

$ aria2c -x10 '网址\torrent' --all-proxy=<PROXY>
  • -x
    多线程下载 
  • -x10
    10个线程同时下载这个文件
  • --all-proxy=<PROXY>
    开代理,有时候我会开代理。

下载 text 文本文件中的链接:

$ aria2c -i uris.txt

RPC Server + webui

我是把webui 放到容器里用的(docker)

$ docker run -d \
  --publish 80:80 \
  timonier/webui-aria2:latest

然后打开aria2c 的RPC server 模式

$ aria2c --enable-rpc --rpc-listen-all=true

打开浏览器输入 localhost, 你就可以看到界面了

现在,就可以开始下载了。

当然,你也可以用aria2来替代百度云和迅雷。但我对这个没有太大的需求,所以就先不写它们的教程了。

PHP (1) Types and Variables

<?php //php code must be enclosed with <?php tags

// If your php fiel only contains PHP code, it is best
// practice to omit the php closing tag to prevent accidental ouput.

// Two forward slashes start a one-line comment.

# So will a hash but // is more common

/*
   surrounding text in slash-asterisk and asterisk-slash
   makes it a multi-line comment.
*/

// Use "echo" or "print"  to print output

print('Hello '); // prints "Hello " with no line break

echo "World\n"; // prints "World" with a line break

// Anything outside <?php tags is echoed automatically
?>

Hello World Again!

Types and Variables

  • Variables begin with the $ symbol.
  • A valid variable name starts with a letter or underscore, followed by any number of letters, or underscores.
  • Boolean values are case-insensitive
$boolean = true;  // or TRUE or True
$boolean = false; // or FALSE or False

Integers

$int1 = 12;
$int2 = -12;
$int3 = 012; // => 10 (a leading 0 denotes an octal number)
$int4 = 0x0F; // => 15 (a leading 0x denotes a hex literal)
$int5 = 0b11111111 // => 255 (a leading 0b denotes a binary number)

Floats (aka doubles)

$float = 1.234;
$float = 1.2e3;
$float = 7E-10;

Delete Variable

unset($int1);

Arithmetic

$sum        = 1 + 1; // 2
$difference = 2 - 1; // 1
$product    = 2 * 2; // 4
$quotient   = 2 / 1; // 2

Shorthand Arithmetic

$number = 0;
$number += 1;      // Increment $number by 1
echo $number++;    // Prints 1 (increments after evaluation)
echo ++$number;    // Prints 3 (increments before evaluation)
$number /= $float; // Divide and assign the quotient to $numbe

String

// Strings should be enclosed in single quotes;
$sgl_quotes = '$String'; // => '$String'

// Avoid using double quotes except to embed other variables
$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'

// Special characters are only escaped in double quotes
$escaped   = "This contains a \t tab character.";
$unescaped = 'This just contains a slash and a t: \t';

// Enclose a variable in curly braces if needed
$apples = "I have {$number} apples to eat.";
$oranges = "I have ${number} oranges to eat.";
$money = "I have $${number} in the bank.";

// Since PHP 5.3, nowdocs can be used for uninterpolated multi-liners
$nowdoc = <<<'END'
Multi line
string
END;

// Heredocs will do string interpolation
$heredoc = <<<END
Multi line
$sgl_quotes
END;

// String concatenation is done with .
echo 'This string ' . 'is concatenated';

// Strings can be passed in as parameters to echo
echo 'Multiple', 'Parameters', 'Valid';  // Returns 'MultipleParametersValid'

ubuntu安装popcorn

1. Download Popcorn

$ wget https://get.popcorntime.sh/build/Popcorn-Time-0.3.10-Linux-64.tar.xz -O popcorntime.tar.xz

2. Unpacking

$ sudo mkdir /opt/popcorntime; sudo tar Jxf popcorntime.tar.xz -C /opt/popcorntime

3. Creating a shortcut

$ sudo ln -sf /opt/popcorntime/Popcorn-Time /usr/bin/Popcorn-Time
  • /opt
    This directory is reserved for all the software and add-on packages that are not part of the default installation.
  • /usr/bin

This directory contains the vast majority of binaries on your system. Executables in this directory vary widely. For instance vi, gcc, gnome-session and mozilla and are all found here.

4. Creating the application launcher

$ sudo vim /usr/share/applications/popcorntime.desktop
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Name=popcron
Exec=/opt/popcorntime/Popcorn-Time
Icon=/opt/popcorntime/src/app/images/icon.png
Categories=Application;
  • /usr/share

This directory contains ‘shareable’, architecture-independent files (docs, icons, fonts etc).

5. Delete the donwloaded file

$ rm popcorntime.tar.xz

Uninstall

$ sudo rm -Rf /opt/popcorntime
$ sudo rm /usr/bin/Popcorn-Time
$ sudo rm /usr/share/applications/popcorntime.desktop

安装mysql

mysql

安装

docker pull mysql:latest
latest: Pulling from library/mysql
Digest: sha256:96edf37370df96d2a4ee1715cc5c7820a0ec6286551a927981ed50f0273d9b43
Status: Image is up to date for mysql:latest

现在运行mysql服务器

$ docker run  -d --name=test-mysql --env="MYSQL_ROOT_PASSWORD=mypassword" mysql

docker inspect test-mysql 来查看ip地址和端口

现在用mysql客户端连接服务器

$ mysql -uroot -pqinjingfei -h 172.17.0.2 -P 3306
  • -u

user

  • -p

password

  • -P

port

  • -h

host

基本命令

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)


mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| db                        |
| engine_cost               |
| event                     |
| func                      |
| general_log               |
| gtid_executed             |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| innodb_index_stats        |
| innodb_table_stats        |
| ndb_binlog_index          |
| plugin                    |
| proc                      |
| procs_priv                |
| proxies_priv              |
| server_cost               |
| servers                   |
| slave_master_info         |
| slave_relay_log_info      |
| slave_worker_info         |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
31 rows in set (0.01 sec)

mysql> select * from db;
...

PHP

PHP 是什么

PHP(“Hypertext Preprocessor”, 超文本预处理器)是一种被广泛应用的开放源代码的多用途脚本语言。

PHP能做什么

  • 收集表单数据
  • 生成动态网页
  • 发送/接受cookies

安装

sudo apt install php php-mysql

用PHP 连接 mysql

demo.php

<?php
        $dbhost = '172.17.0.2:3306';
        $dbuser = 'root';
        $dbpass = 'mypassword';
        $conn = mysqli_connect($dbhost, $dbuser, $dbpass);
        if(! $conn ) {
           die('Could not connect: ' . mysql_error());
        }
        echo 'Connected successfully';
        mysqli_close($conn);
?>

执行

$ php demo.php
Connected successfully⏎   

使用VPS搭建自己的WordPress

准备

  • 一个运行linux的VPS
  • 一个 non-root 用户
  • 域名

租用VPS

  • 请自己google

下面的图片是我刚创建的vps

申请域名

域名申请

  • 略过(请Google)

我自己用的是namecheap

配备域名解析

Digital Ocean

Namecheap

-配置成功的话后,打开terminal, ping 自己的域名


现在,你就成功的将你的网址解析到你的ip地址了。

用Docker 来搭建wordpress

第一步 安装Docker

Ubuntu

$ sudo apt install docker docker.io

第二步 测试Docker是否安装成功(可略过)

$ sudo docker run hello-world

第三部 安装后的配置

  • 安装docker-compse
$ sudo -i
$ curl -L https://github.com/docker/compose/releases/download/1.13.0/docker-compose-Linux-x86_64 > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

  • 开机重启docker
$ sudo systemctl enable docker

  • Non-root access

如果,你没有创建普通用户的话。执行下面的命令

# adduser jing
# usermod -aG sudo jing

如果,你有普通用户,请执行下面的命令

$ sudo groupadd docker      # 创建docker组
$ sudo usermod -aG docker jing  # 把user加入到docker组

第四步 用LAMP来测试Docker

  • 什么是LAMP
    • Linux
    • Apache
    • MySQL
    • PHP/Python/Perl

    在non-root 用户执行下面的指令

    $ mkdir $HOME/apache && cd $HOME/apache
    $ printf '<?php\n  phpinfo(); \n?>' > info.php
    $ docker run -d --name=apache -p 8080:80 -v $HOME/apache:/var/www/html php:apache
    
    

docker run

  • 创建和开始一个容器

-d

  • “detach” from it, 跟我们连ssh和tmux 一样

--name=apache

  • 给容器一个名字apache

-p 8080:80

  • 把本机的端口8080和容器的端口80连在一起

-v $HOME/apache:/var/www/html

  • map 以上的文件夹
  • $HOME/apache 的文件map到 /var/www/html

现在你可以看到容器在运行

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
d1fbdb7e0c5f        php:apache          "docker-php-entryp..."   3 seconds ago       Up 3 seconds        0.0.0.0:8080->80/tcp   apache

现在,你应该可以访问http://YOUR-SERVER-IP:8080/info.php

现在关掉并且删掉容器

$ docker stop apache
$ docker rm apache
$ docker rmi php:apache

第五步 搭建wordpress

$ mkdir wp_test && cd wp_test # 创建文件夹

创建docker-compose.yml

version: '2'

services:
   db:
     image: mariadb:latest
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
     container_name: wp_test_db

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     volumes:
       -db_app:/var/www/html
     ports:
       - "8080:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
     container_name: wp_test

mariadb 比mysql 省内存
第一次运行容器

$ docker-compose up -d

docker ps 查看容器

$ docker ps
20570a5eb798        wordpress:latest    "docker-entrypoint..."   3 seconds ago       Up 2 seconds        0.0.0.0:8080->80/tcp   wp_test
c1872cb1443d        mysql:5.7           "docker-entrypoint..."   3 seconds ago       Up 3 seconds        3306/tcp               wp_test_db

http://YOUR-SERVER-IP:8080 安装WordPress, 用docker-compose down停止运行容器

在安装完WordPress后,你就可以用http://YOUR-SERVER-IP:8080 访问你的WordPress网站了。

Docker 教程系列 二

使用Dockerfile 定制镜像

  • Dockerfile

镜像的定制实际上是定制每一层所添加的配置、文件。我们可以吧每一层修改、安装、构建、操作的命令写在一个脚本,用这个脚本来构建、定制镜像。 这个脚本叫做Dockerfile。

$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile

Dockerfile 内容

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

FROM 指定基础镜像

所谓定制镜像,那一定是以一个基础镜像为基础,在其上定制。

FROM 就是制订基础镜像

在Dockerfile中FROM 是必备的指令,并且是第一个指令。

FROM scratch # 空白镜像
...

RUN 执行指令

  • shell格式: RUN <命令>
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.htm
  • exec 格式: RUN [“可执行文件”,“参数1”,“参数2”]

错误的写法

FROM debian:jessie

RUN apt-get update
RUN apt-get install -y gcc libc6-dev make
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz"
RUN mkdir -p /usr/src/redis
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install

Dockerfile 中每一个指令都会建立一层

上面的写法创建了7层镜像

正确的写法

FROM debian:jessie

RUN buildDeps='gcc libc6-dev make' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDeps

&&将各个所需命令串联起来,将7层,简化为1层。

\换行

#注释

构建镜像

Dockerfile 文件所在目录执行:

$ docker build -t nginx:v3 .
Step 1/2 : FROM nginx
 ---> b8efb18f159b
Step 2/2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Running in 23d1b8a55e02
 ---> 2c1c0dc5e64e
Removing intermediate container 23d1b8a55e02
Successfully built 2c1c0dc5e64e
Successfully tagged nginx:v3

RUN指令启动了一个容器23d1b8a55e02,执行命令,并提交了最后一层2c1c0dc5e64e, 随后删掉了23d1b8a55e02

dokcer build指令

docker build [选项] <上下文路径/URL/->
  • -t

tag list — Name and optionally a tag in the name:tag format

其它docker build 的用法

直接用Git repo

$ docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14

用tar压缩包构建

$ docker build http://server/context.tar.gz

从标准输入中读取 Dockerfile 进行构建

$ docker build - < Dockerfile

从标准输入中读取上下文压缩包进行构建

$ docker build - < context.tar.gz