mysqldump 参数和使用方法介绍

mysqldump是MySQL数据库自带的一款命令行工具,mysqldump属于单线程,功能是非常强大的,不仅常被用于执行数据备份任务,甚至还可以用于数据迁移。

备份粒度相当灵活,既可以针对整个MySQL服务,也可以只备份某个或者某几个DB,或者还可以指定只备份某个或者某几个表对象,甚至可以实现只备份表中某些符合条件的记录。

mysqldump命令创建的是逻辑备份,它输出的结果集有两种格式:一种是将数据转换成标准SQL语句(一堆 CREATE , DROP ,INSERT等语句);另一种是将数据按照指定的分隔符,输出成定界格式的平面文件。

mysqldump 使用参数很多,但是实际上经常用到的并没有多少。下面我们来介绍一下这些参数:

mysqldump 具体有多少参数,我们可以使用

$ mysqldump  --help

命令查看

1. 常用参数

  • -?, –help: 显示帮助信息,英文的;
  • -u, –user: 指定连接的用户名;
  • -p, –password: 指定用户的密码,可以交互输入密码;
  • -S , –socket: 指定socket文件连接,本地登录才会使用。
  • -h, –host: 指定连接的服务器名称或者IP。
  • -P, –port=: 连接数据库监听的端口。
  • –default-character-set: 设置字符集,默认是UTF8。
  • -A, –all-databases: 导出所有数据库。不过默认情况下是不会导出information_schema库。
  • -B, –databases: 导出指定的某个/或者某几个数据库,参数后面所有名字参量都被看作数据库名,包含CREATE DATABASE创建库的语句。
  • –tables: 导出指定表对象,参数格式为“库名 表名”,默认该参数将覆盖-B/–databases参数。
  • -w, –where: 只导出符合条件的记录。
  • -l, –lock-tables: 默认参数,锁定读取的表对象,想导出一致性备份的话最后使用该参数,会导致无法对表执行写入操作。
  • –single-transaction:
    该选项在导出数据之前提交一个BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储 引擎,仅InnoDB。本选项和–lock-tables 选项是互斥的,因为LOCK TABLES 会使任何挂起的事务隐含提交,使用参数–single-transaction会自动关闭该选项。
    在InnoDB导出时会建立一致性快照,在保证导出数据的一致性前提下,又不会堵塞其他会话的读写操作,相比–lock-tables参数来说锁定粒度要低,造成的影响也要小很多。指定这个参数后,其他连接不能执行ALTER TABLE、DROP TABLE 、RENAME TABLE、TRUNCATE TABLE这类语句,事务的隔离级别无法控制DDL语句。
  • -d, –no-data: 只导出表结构,不导出表数据。
  • -t, –no-create-info: 只导出数据,而不添加CREATE TABLE 语句。
  • -f, –force: 即使遇到SQL错误,也继续执行,功能类似Oracle exp命令中的ignore参数。
  • -F, —flush-logs: 在执行导出前先刷新日志文件,视操作场景,有可能会触发多次刷新日志文件。一般来说,如果是全库导出,建议先刷新日志文件,否则就不用了。
  • –master-data[=#]: 该选项将二进制日志的位置和文件名写入到输出中。该选项要求有RELOAD权限,并且必须启用二进制日志。如果该选项值等于1,位置和文件名被写入CHANGE MASTER语句形式的转储输出,如果你使用该SQL转储主服务器以设置从服务器,从服务器从主服务器二进制日志的正确位置开始。如果选项值等于2,CHANGE MASTER语句被写成SQL注释。如果value被省略,这是默认动作。
  • –master-data选项会启用–lock-all-tables,除非还指定–single-transaction(在这种情况下,只在刚开始转储时短时间获得全局读锁定。又见–single-transaction。在任何一种情况下,日志相关动作发生在转储时。该选项自动关闭–lock-tables。
    所以,我在INNODB引擎的数据库备份时,我会同时使用–master-data=2 和 –single-transaction两个选项。
  • -x, –lock-all-tables: 在导出任务执行期间锁定所有数据库中的所有表,以保证数据的一致性。这是一个全局锁定,并且自动关闭–single-transaction 和–lock-tables 选项。这个参数副作用比较大,这是全库锁定,备份执行过程中,该库无法进行读写操作,不是所有业务场景都能接受的。请慎用。
  • -n, –no-create-db: 不生成建库的语句CREATE DATABASE … IF EXISTS,即使指定–all-databases或–databases这类参数。
  • –triggers: 导出表的触发器脚本,默认就是启用状态。使用–skip-triggers禁用它。
  • -R, –routines: 导出存储过程以及自定义函数。
    在转储的数据库中转储存储程序(函数和程序)。
  • -E, –events: 输出event。
  • –ignore-table: 指定的表对象不做导出,参数值的格式为[db_name,tblname],注意每次只能指定一个值,如果有多个表对象都不进行导出操作的话,那就需要指定多个–ignore-table参数,并为每个参数指定不同的参数值。
  • –add-drop-database: 在任何创建库语句前,附加DROP DATABASE 语句。
  • –add-drop-table: 在任何创建表语句前,附加DROP TABLE语句。这个参数是默认启用状态,可以使用– skip-add-drop-table参数禁用该参数。
  • –add-drop-trigger: 创建任何触发器前,附加DROP TRIGGER语句。
  • –add-locks: 在生成的INSERT语句前附加LOCK语句,该参数默认是启用状态。使用–skip-add-locks参数禁用。
  • -K, –disable-keys: 在导出的文件中输出 ‘/!40000 ALTER TABLE tb_name DISABLE KEYS */; 以及
    ‘/!40000 ALTER TABLE tb_name ENABLE KEYS */; ‘ 等信息。这两段信息会分别放在INSERT语句的前后,也就是说,在插入数据前先禁用索引,等完成数据插入后再启用索引,目的是为了加快导入的速度。该参数默认就是启用状态。可以通过–skip-disable-keys参数来禁用。
  • –opt: 功能等同于同时指定了 –add-drop-table, –add-locks, –create-options, –quick, –extended-insert, –lock-tables, –set-charset, 以及 –disable-keys这些参数。默认就是启用状态。使用–skip-opt来禁用该参数。
  • –skip-opt: 禁用–opt选项,相当于同时禁用 –add-drop-table, –add-locks, –create-options, –quick, –extended-insert, –lock-tables, –set-charset, 及 –disable-keys这些参数。
  • -q, –quick: 导出时不会将数据加载到缓存,而是直接输出。默认就是启用状态。可以使用–skip-quick 来禁用该参数。

2. mysqldump 默认参数

mysqldjmp 默认使用的参数由以下几个:

  • –opt
  • –add-drop-table
  • –add-locks
  • -i,–comments
  • -a,–create-options
  • -e, –extended-insert
  • -l, –lock-tables
  • -q, –quick
  • -K, –disable-keys
  • -Q, –quote-names
  • –dump-date
  • –ssl
  • –triggers
  • –tz-utc

上面这些参数,执行mysqldump 命令的时候默认就会带上的。

3. mysqldump 常用方法

(1) 获取一个完整备份
不锁库备份

$ mysqldump -uusername -p --triggers --routines --events -A -B --single-transaction --master-data=2 > backup.$(date +%F).sql

(2) 导出指定库

$ mysqldump -uusername -p -B dbname > backup.$(date +%F).sql

如果是导出单库也可以不使用-B 参数,无非就是没有创建库的语句。
如果是多个库可以使用如下命令,但是必须使用-B参数

$ mysqldump -uusername -p -B DB1 DB2 DB3 > backup.$(date +%F).sql

(3) 导出指定表的数据和结构

$ mysqldump -uusername -p DBNAME table1 table2 > tablename.sql    

或者使用 –tables 参数

$ mysqldump -uusername -p --tables DBNAME table1 table2 > backup.$(date +%F).sql  

或者

$ mysqldump  -uusername -p DBNAME  --tables table1 table2 table3 > tablename.sql

(4) 导出指定表的结构
不包含数据

$ mysqldump -ubackup -p --no-data  DBNAME table1 table2 > backup.$(date +%F).sql

或者使用–tables参数

$ mysqldump -ubackup -p --no-data DBNAME  --tables table1 table2 > backup.$(date +%F).sql

或者

$ mysqldump -ubackup -p --no-data  --tables DBNAME table1 table2 > backup.$(date +%F).sql

(5) 导出指定表的数据
不包含表结构

$ mysqldump  -uusername -p --no-create-info DBNAME  table1 table2 table3 > backup.$(date +%F).sql

或者使用–tables 参数

$ mysqldump  -uusername -p --no-create-info DBNAME --tables table1 table2 table3 > backup.$(date +%F).sql

或者

$ mysqldump  -uusername -p --no-create-info  --tables DBNAME table1 table2 table3 > backup.$(date +%F).sql

(6) 导出整个数据库结构 (包括表结构)
不包含数据

$ mysqldump -uusername -p --no-data DBNAME > backup.$(date +%F).sql

(7) 导出数据库表结构和数据时排除某些表
使用 –ignore-table 参数

$ mysqldump -uusername -p  --single-transaction --master-data=2 --add-drop-database  -B DBNAME --ignore-table=DBNAME.table1 --ignore-table=DBNAME.table2 > backup.$(date +%F).sql

(8) 导出数据直接压缩

$ mysqldump -uusername -p -B DBNAME | gzip > backup.sql.gz

解压命令:

$ gunzip backup.sql.gz

定制ENTRYPOINT自动修改Docker中volume的权限

volume的权限问题

在Docker中,需要把host的目录挂载到container中作为volume使用时,往往会发生文件权限问题。 常见的现象是,container对该路径并无写权限,以致其中服务的各种千奇百怪的问题。

导致这类问题的原因,是container内外的UID不同。 比如,host当前使用docker的用户UID是1000(这是默认第一个用户的UID)。 如果container内的UID是2000,那么host创建的目录对container来说就并非owner,默认情况下不可写入。

此外还有一种情况,那就是挂载前,host上不存在被挂载的目录。 Docker会以root权限,先创建该目录,再挂载。 这就导致,即使host与container的UID都是1000,也会出现无写权限的情况。 这种现象,只会在初始化时出现,但也足够令新手困惑,令老手厌烦。

为什么在Dockerfile中不能把volume的权限配置好? 因为Dockerfile是对image的描述,而volume则是container的内容。 Dockerfile中做出的权限配置,对非volume来说是可以生效的,而对volume则不然。 本质上,host挂载到volume上的目录,是属于host的。 Dockerfile是在docker build期间执行,而volume则是在docker run的时候产生。

其实,Docker在自动创建volume路径时,应该再自动地把它修改为container内前台进程的user:group。 然而Docker目前并无此类机制,俺们这些用户就只能另谋出路。

一般的临时方案,都是去手动修改权限。 要么通过chown,把owner改成container内用户的UID; 要么通过chmod 777,搞成所有用户通用。 这些当然不是什么好的长期方案,也违背了Docker方便部署的初衷。

目前看来,最好的方案,还是定制Dockerfile的ENTRYPOINT。

定制ENTRYPOINT

默认情况下ENTRYPOINT相当于是/bin/sh,只是准备简单的Shell运行环境。 定制ENTRYPOINT为一个复杂的脚本,就可以在每次container启动时,都执行一遍。 这个入口脚本,一般都是叫entrypoint.sh或docker-entrypoint.sh,并无强制约定。

COPY entrypoint.sh ./

ENTRYPOINT ["./entrypoint.sh"]

在volume产生时,是docker run的准备阶段(create),而执行entrypoint.sh则是在启动阶段(start)。 所以,在entrypoint.sh中可以对volume做权限配置。 当然,权限配置需要root权限,entrypoint.sh需要在root用户下启动。

当然,也可以在一般用户下启动,需要chown时在提升至root权限。 不过这样会有安全隐患。 反之,以root执行entrypoint.sh,在其中以普通用户启动真正的服务,这样在服务被黑的情况下,能确保仅当前服务受影响。

选择ENTRYPOINT的shell

Docker基础镜像的发行版,通常是Debian或Alpine。 Debian包含了Bash和Dash,而Alpine则默认只有Ash。

Ash的全称是Almquist shell,由Kenneth Almquist在1989年5月30日发布。 它是一种轻量级的Unix shell,在多个发行版上都有开枝散叶,详见ash variants。 现在,各大发行版上能看到的/bin/sh,基本都是[Ash]的一种。 Dash其实就是Debian上的一种[Ash]。

因此,用[Ash]来写ENTRYPOINT,会更具有通用性。 文件头可以使用以下形式的Shebang。

#!/bin/sh

当然,什么也不写其实也默认是这个。 写上后显得更专业,对自己也算是一个提示吧,以免把Bash特有的一些用法,如source、[[]]等,用在脚本中。

样例

#!/bin/sh

mkdir -p "${DJANGO_DATABASE}" "${DJANGO_LOGS}" "${DJANGO_STATIC}"
python manage.py collectstatic --noinput
python -Wd manage.py migrate --fake-initial
chown -R "${DJANGO_USER}":999 "${DJANGO_SITE}"

if [ $# -gt 0 ]
then
    su "${DJANGO_USER}" -c "exec $*"
else
    su "${DJANGO_USER}" -c "exec uwsgi --ini uwsgi.ini --http=0.0.0.0:${DJANGO_PORT}"
fi

以上是一个Django网站镜像的entrypoint.sh。 其中,和本文关系密切的是chown那一行。 把相关volume的UID设为${DJANGO_USER},是镜像内的读写需要; 把GID设为999,是因为在宿主机上,Docker安装后,默认的docker用户组的GID就是999,便于宿主机进行操作。 最后的if代码块,用${DJANGO_USER}执行前台进程,提高了安全性(相当于Dockerfile里使用USER); exec相关的配置,给了一个CMD为空时的默认命令。

其它关于collectstatic、migrate等操作,是Django网站相关的有用配置,不在本文详解。

另一个复杂的参考,是postgres的官方镜像docker-entrypoint.sh。 其中做了很多事,但比较核心的,还是chown、chmod那几行。

参考

还有一种方案,利用–volumes-from,可以指定一个Docker管控的非挂载数据卷。 这种数据卷没有权限问题,但宿主机的访问会有些麻烦。

Ubuntu通过apt-get安装指定版本和查询指定软件有多少个版本

一、通过apt-get安装指定版本

apt-get install <<package name>>=<<version>>

二、查询指定软件有多少个版本

说明:在Linux用这个查询并不能完全的把所有版本都列举出来,因为每个版本都与系统版本和CPU架构有关,比如一个软件支持Ubuntu系统的16.04的CPU架构为amd64的版本只有1.0和1.2,其余都不支持,所以列举时就只有两款。

列举版本列表

0、通过网站搜索:

https://packages.ubuntu.com/

1、

apt-cache madison <<package name>>

将列出所有来源的版本。如下输出所示:

apt-cache madison vim
   vim | 2:7.3.547-1 | http://debian.mirrors.tds.net/debian/ unstable/main amd64 Packages
   vim | 2:7.3.429-2 | http://debian.mirrors.tds.net/debian/ testing/main amd64 Packages
   vim | 2:7.3.429-2 | http://http.us.debian.org/debian/ testing/main amd64 Packages
   vim | 2:7.3.429-2 | http://debian.mirrors.tds.net/debian/ testing/main Sources
   vim | 2:7.3.547-1 | http://debian.mirrors.tds.net/debian/ unstable/main Sources

madison是一个apt-cache子命令,可以通过man apt-cache查询更多用法。

2、

apt-cache policy <<package name>>

将列出所有来源的版本。信息会比上面详细一点,如下输出所示:

apt-cache policy gdb
gdb:
  Installed: 7.7.1-0ubuntu5~14.04.2
  Candidate: 7.7.1-0ubuntu5~14.04.2
  Version table:
 *** 7.7.1-0ubuntu5~14.04.2 0
        500 http://fr.archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     7.7-0ubuntu3 0
        500 http://fr.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
        500 http://archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages

policy是一个apt-cache子命令,可以通过man apt-cache查询更多用法。

3、

apt-cache showpkg <<package name>>

4、

apt-get install -s <<package-name>>

说明:这个命令只是模拟安装时会安装哪些软件列表,但不会例举出每个软件有多少个版本

5、

aptitude versions <<package name>>

参考:https://manpages.debian.org/unstable/aptitude/aptitude.8.en.html

6、

apt-show-versions -a <<package name>>

说明:列举出所有版本,且能查看是否已经安装。还可以通过apt-show-versions -u <>来查询是否有升级版本。

参考:http://manpages.ubuntu.com/manpages/trusty/man1/apt-show-versions.1p.html

7、

whohas -d Debian,Ubuntu <<package name>> | tr -s ' ' 't' | cut -f 1-3 | column -t

8、

rmadison -u debian,ubuntu,bpo <<package name>> | cut -d "|" -f 1-3

单个详情

1、

apt-cache show <<package name>>

说明:查询指定包的详情,不管是否已经安装。

2、

dpkg -l <<package name>>

说明:效果和上面基本一致,但是结果是列表详情展示,会提示是否已经删除了之后还有依赖包没有删除等。

3、

dpkg -s <<package name>>

说明:必须是安装的包才能显示详情。

4、

dpkg-query -s <<package name>>

说明:同上,效果一致。

使用技巧

1、可以在查询后面带上一些参数来实现筛选

apt-cache show package | grep Version
apt-show-versions | more

linux shell grep/awk/sed 匹配tab

处理文件的命令实在是多, sed, awk, grep等。遇到了需要匹配tab的情况, 记录一下。

例子如下:找出文本中第一列是1的行。

文本a

1    2    3
12    3    31
21    1    3

解法1 : 直接使用正则表达式, ^表示开头, t表示tab

grep -P "^1t" a

解法2 : awk循环行,并判断

awk '{if($1 == 1) print $0}' a

解法3: sed 中使用正则,-n 只打印匹配行

sed -n '/^1t/p' a

awk的二维数组

awk二维数组练习

  • 现有f1,f2两个文档
$cat f2
    5   6   7   8   9   10
A   0.7 0.8 0.9 1   1.1 1.2
C   0.22    0.34    0.46    0.58    0.7 0.82
D   -0.26   -0.12   0.02    0.16    0.3 0.44
E   -0.74   -0.58   -0.42   -0.26   -0.1    0.06
F   -1.22   -1.04   -0.86   -0.68   -0.5    -0.32
G   -1.7    -1.5    -1.3    -1.1    -0.9    -0.7
H   -2.18   -1.96   -1.74   -1.52   -1.3    -1.08
I   -2.66   -2.42   -2.18   -1.94   -1.7    -1.46
K   -3.14   -2.88   -2.62   -2.36   -2.1    -1.84
L   -3.62   -3.34   -3.06   -2.78   -2.5    -2.22
M   -4.1    -3.8    -3.5    -3.2    -2.9    -2.6
$cat f1
5   A
8   C
10  G
11  D
12  F
13  H

需求:

根据f2文件的第一行第一列为序号,求出f1中各对应的结果,打印在第三列

[root@Web awk]# awk 'FNR==NR{for(i=0;i++<NF;){if(NR==1)a[i+1]=$i;if(NR>1)b[a[i],$1]=$i};next}{print $0,b[$1,$2]}'  f2  f1
5   A 0.7
8   C 0.58
10  G -0.7
11  D 
12  F 
13  H 

思路

awk 'FNR==NR{for(i=0;i++<NF;){if(NR==1)a[i+1]=$i;if(NR>1)b[a[i],$1]=$i};next}{print $0,b[$1,$2]}'  f2  f1
对每一行进行循环,对第一行进行对应数组处理
a[1]=$0,a[2]=5,a[3]=6,a[4]=7,a[5]=8,a[6]=9,a[7]=10
然后下次循环跳过第一列

b[a[1],$1]=$1,b[a[2],$1]=$2,b[a[3],$1]=$3,b[a[4],$1]=$4,b[a[5],$1]=$5,b[a[6],$1]=$6,b[a[7],$1]=$7

这样就形成了我们需要的二维数组
然后循环整个f2文件
最后对f1文件获取,将结果打印在f1文件的第三列

Cacti安装配置

被监控端配置:

1)安装配置net-snmp及依赖包lm_sensors

yum install -y net-snmp lm_sensors

修改snmpd的配置文件:

vi /etc/snmp/snmpd.conf

如图:

未分类

第一步:映射通信名称到安全用户名称;第二步:将用户加入到组中;第三步,为组创建systemvies视图;第四步:创建all视图并赋予组只读访问权限。

2)修改被控端防火墙规则:

iptables -I INPUT -p ucp –dport 161 -j ACCEPT
iptables -I INPUT -p tcp –dport 199 -j ACCEPT
service iptables save

3)启动snmpd服务:

service snmpd start
chkconfig snmpd on

监控端配置:

1)cacti是基于php的web监控管理系统,首先需要部署lamp环境,略。

2)安装依赖包:

yum -y install net-snmp net-snmp-devel net-snmp-utils net-snmp-libs lm_sensors php-xml zlib libpng freetype cairo-devel pango-devel gd

3)安装rrdtool:

yum -y install rrdtool

4)检查与客户端snmp通信:

snmpwalk -v 1 192.168.88.151 -c rose0011 system

5)配置apache虚拟主机:

vi /usr/local/apache2/conf/extra/httpd-vhosts.conf

如图:

未分类

6)修改php配置文件的时区配置,默认date.timezone为注释行。修改php.ini,date.timezone=”Aisa/Shanghai”

7)解压cacti包并移动至web根目录下,修改根目录权限为apache运行账户。

tar -zxf acti-0.8.8a.tar.gz
mv cacti-0.8.8a /usr/local/apache2/htdocs/cacti/cacti
chown -R daemon.daemon /usr/local/apache2/htdocs/cacti/
iptables -I INPUT -p tcp –dport 80 -j ACCEPT
service iptables save

8)初始化cacti数据库

mysql -uroot -p -e “create database cacti”;
mysql -uroot -p cacti < /usr/local/apache2/htdocs/cacti/cacti/cacti.sql
grant all on cacti.* to cactiuser@localhost identified by ‘rose0011’;
flush privileges;

9)编辑cacti配置文件/usr/local/apache2/htdocs/cacti/cacti/include/config.php

如图:

未分类

10)浏览器中输入网址,安装cacti

Ubuntu 16.04 下通过 apt 安装 ActiveMQ

  • 更新系统软件包
sudo apt update 
sudo apt upgrade
  • 安装 jdk
sudo apt install default-jdk
  • 安装、启动 ActiveMQ
sudo apt install activemq
sudo systemctl start activemq
  • 查看
sudo systemctl status activemq
netstat -nl|grep 61616

说明:截止到2018-01-26 这种方式都还是有问题的【active (exited)】,已有人提交 bug report。

  • Web 管理页:http://127.0.0.1:8161/admin/

  • 服务状态说明

loaded              # 系统服务已经初始化完成,加载过配置
active(running)     # 正有一个或多个程序正在系统中执行,守护进程 activemq 就应该是这种模式
atcive(exited)      # 仅执行一次就正常结束的服务,如 iptables
atcive(waiting)     # 正在执行中,不过还再等待其他的事件才能继续处理
inactive            # 服务关闭
enbaled             # 服务开机启动
disabled            # 服务开机不自启
static              # 服务开机启动项不可被管理
failed              # 系统配置错误

Docker nginx 反向代理设置

缘起

最近在公司搭建了一个基于 Gogs 的代码管理系统,以及基于 Kanboard 的任务管理系统等几个内部系统。由于部署在同一台机器上,基于不同的端口区分不同的服务。比如:

  • Git 服务 http://10.10.1.110:10080
  • 任务管理系统http://10.10.1.110:8888
  • 其他

为了更好的使用,通过内部域名区分,比如 :

  • Git 服务 http://gogs.vking.io
  • 任务管理系统 http://task.vking.io
  • 其他

注:vking.io 是内部域名,可通过 dnsmasq (http://www.thekelleys.org.uk/dnsmasq/doc.html) 配置。

方案一

现有服务都是通过 Docker 部署,nginx 同样通过 Docker 部署,使用官方提供的镜像即可。

  • 新建 nginx 配置文件, nginx.conf,存放路径为 /srv/docker/nginx/nginx.conf
# user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
# daemon off;
  • 新建反向代理设置文件 reverse-proxy.conf,存放路径为 /srv/docker/nginx/conf.d/reverse-proxy.conf
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
  default $http_x_forwarded_port;
  ''      $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
  default upgrade;
  '' close;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
  default off;
  https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent"';
access_log off;

# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
    server_name _; # This is just an invalid value which will never trigger on a real hostname.
    listen 80;
    access_log /var/log/nginx/access.log vhost;
    return 503;
}

# gogs.vking.io
upstream gogs.vking.io {
    # gogs
    server gogs:3000;
}

server
{
    server_name gogs.vking.io;
    listen 80;

    location / {
        proxy_pass http://gogs.vking.io;
    }
    access_log /var/log/nginx/access.log vhost;
}

# task.vking.io
upstream task.vking.io {
    # kanboard
    server kanboard:80;
}

server
{
    server_name task.vking.io;
    listen 80;

    location / {
        proxy_pass http://task.vking.io;
    }
    access_log /var/log/nginx/access.log vhost;
}

gogs 启动命令

docker container run -d --name gogs 
    --restart always 
    -p 10022:22  
    -p 10080:3000 
    --network gogs-net 
    -v /srv/docker/gogs:/data 
    gogs/gogs:latest

注: upstream gogs.vking.io 中的 server 中的 gogs:3000 分别指容器名称和原始expose 的端口。

  • 启动容器
docker container run -d --name nginx 
    --restart always 
    -p 80:80 
    --network gogs-net 
    -v /srv/docker/nginx/nginx.conf:/etc/nginx/nginx.conf 
    -v /srv/docker/nginx/conf.d:/etc/nginx/conf.d 
    nginx:alpines

注:–network gogs-net 指定三个容器在同一网络,如果用默认的 bridge的话,不需要设置

方案二

因为这些服务都是部署在一台机器上的,可以通过 Docker 的自动服务发现部署,原理见此。

  • gogs
docker container run -d --name gogs 
    --restart always 
    -p 10022:22  -p 10080:3000 
    --network gogs-net 
    -e VIRTUAL_HOST=gogs.vking.io 
    -e VIRTUAL_PORT=3000 
    -v /opt/docker/gogs:/data 
    gogs/gogs:latest
  • Kanboard
docker container run -d --name kanboard 
    --restart always 
    -p 8888:80 
    --network gogs-net 
    -e VIRTUAL_HOST=task.vking.io 
    -e VIRTUAL_PORT=80 
    -v /srv/docker/kanboard/data:/var/www/app/data 
    -v /srv/docker/kanboard/plugins:/var/www/app/plugins 
    kanboard/kanboard:latest
  • nginx
docker container run -d --name nginx 
    --restart always 
    -p 80:80 
    --network gogs-net 
    -v /var/run/docker.sock:/tmp/docker.sock:ro 
    jwilder/nginx-proxy:alpine

注:关键是容器通过 -e VIRTUAL_HOST 指定 url,通过 -e VIRTUAL_PORT=80 指定端口,同样端口也必须是原始镜像 expose 的端口。

延伸

目前服务都是通过 shell 启动,可改成通过 Docker Compose 统一编排任务,把 dnsmasq+nginx+gogs+… 等统一管理。如果是部署在公网上的话,还可以把 SSL 证书到期自动刷新等一起编排。

—EOF—

Apache配置http跳转https教程

用我的步骤前,请一定要保证自己的网站能够用https正常打开;方法也是非常的简单,具体步骤如下:

一、登陆服务器

不管你的服务器是linux还是windos,原理都是一样的,我拿windos服务器来举例吧!
登陆windos服器方法很简单,需要“远程桌面连接”。
我们直接点击左下角“开始” =》 “运行”,(或使用“WIN+R”快捷键),再输入”mstsc”即可打开远程桌面连接,输入你的IP+用户名+密码即可远程连接成功;

二、打开url重定向伪静态规则支持

1、打开Apache/conf/httpd.conf;

2、找到 #LoadModule rewrite_module modules/mod_rewrite.so;

3、去掉前面的#号;#LoadModule rewrite_module modules/mod_rewrite.so

未分类

三、修改网站目录的段:Directory

1、打开Apache/conf/httpd.conf;

2、找到你网站目录的段,例如我的是:“C:phpStudyPHPTutorialWWW”

3、修改其中的 AllowOverride None 为 AllowOverride All;

未分类

四、保存并重启apache服务

五、设置重定向伪静态规则

1、在你网站目录下放一个.htaccess文件。注意:windows环境下,不能把文件直接改名为.htaccess,会提示你必须输入文件名。所以我们先新建一个“新建文本文档.txt”文档,再用记事本打开,选择另存为,保存类型选择“所有文件(.)”,文件名输入“.htaccess”,保存。这样便生成了一个.htaccess文件。

2、打开并编辑.htaccess文件,写入如下规则:

RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} !^/tz.php
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R]

解释:

%{SERVER_PORT} —— 访问端口
%{REQUEST_URI} —— 比如如果url是 https://www.fujieace.com/tz.php,则是指 /tz.php
%{SERVER_NAME} —— 比如如果url是 https://www.fujieace.com/tz.php,则是指 www.fujieace.com

以上规则的意思是:

如果访问的url的端口不是443,且访问页面不是tz.php,则应用RewriteRule这条规则。
这样便实现了:访问了 https://www.fujieace.com/index.php 或者 https://www.fujieace.com/admin/index.php 等页面的时候会自动跳转到 https://www.fujieace.com/index.php 或者 https://www.fujieace.com/admin/index.php,
但是访问 https://www.fujieace.com/tz.php 的时候就不会做任何跳转,也就是说 https://www.fujieace.com/tz.php 和 https://www.fujieace.com/tz.php 两个地址都可以访问。

apache https配置

1、修改httpd.conf,将以下注释项放开

#LoadModule ssl_module modules/mod_ssl.so
#LoadModule socache_shmcb_module 
#modules/mod_socache_shmcb.so
#Include conf/extra/httpd-mpm.conf
#Include conf/extra/httpd-ssl.conf

2、修改httpd-ssl.conf,配置以下配置项

SSLCertificateKeyFile “”    //服务器私钥位置
SSLCertificateFile “”   //服务器证书位置
SSLCACertificatePath “”  //CA根证书位置

3、放开将注释项

#SSLVerifyClient require
#SSLVerifyDepth  10
修改SSLVerifyDepth 为1

4、执行httpd.exe

-t检查语法配置是否有误,一般都是文件路径的问题。
重新配置vhost,端口改443,重启apache,验证是否生效。