Docker建立站点优点
首先介绍一下Docker站点的最大好处就是,搬站真的超级超级方便,只需要将~path/dnmp/这个目录打包一下,便可以搬站了,因为网站所需的数据库、httpd软件、ssl证书、php环境等全都在~path/dnmp/这个文件夹里。
其次便是,环境不会打乱,而且布置起来超级快,再也不用担心安装的软件版本之间是否搭配,环境是否冲突等等;而且网站配置只需配置一次便可,对于主机到期不得不搬站或者升级主机得人来说,不要太诱惑;最后对于有多主机的人来说,建立cdn也方便了不少。
Docker站点安装方法
我是用的是这个项目:dnmp 。对于Ubuntu安装只需要
sudo apt install -y docker-compose
git clone https://github.com/yeszao/dnmp.git
cd dnmp#进入项目目录
cp env.sample .env# 复制环境变量文件
cp docker-compose.sample.yml docker-compose.yml# 复制 docker-compose 配置文件。默认启动3个服务:Nginx、PHP7和MySQL8。要开启更多其他服务,如Redis、PHP5.6、PHP5.4、MongoDB,ElasticSearch等,请删除服务块前的注释
docker-compose up# 启动如果不是root用户,还需将当前用户加入docker用户组:sudo gpasswd -a ${USER} docker
这几步便可以了。
Docker站点配置
Dnmp的基本配置:
dnmp里的nginx默认监听80、443;php默认监听9000;phpmyadmin默认监听8080;mysql默认监听3306;Docker镜像源默认为Aliyun镜像,镜像时间为上海。
如果要更改,建议更改~path/dnmp/.env 这里是对应宿主机的端口和位置以及镜像源和版本。
nginx的配置文件在~path/dnmp/services/nginx目录下,如果有ssl需要,把证书添加到~path/dnmp/services/nginx/ssl目录下,再更改一下~path/dnmp/services/nginx/conf.d/localhost.conf,将证书名称改为你的证书名称便可,路径不用更改。
站点地址在~path/dnmp/www/localhost/,从wordpress 上下载后解压进去就好了。
使用时注意
mysql的密码是123456,使用时务必修改。
mysql因为容器运行,wordpress链接数据库的时候,需要将wp-config.php更改为
define( 'DB_HOST', 'mysql:host=mysql' );
为了防止404,还要在wp-config.php 里添加
define("FS_METHOD", "direct");
define("FS_CHMOD_DIR", 0777);
define("FS_CHMOD_FILE", 0777);
同时保证~path/dnmp/www/localhost目录权限是可读写的
chmod -R 777 ~path/dnmp/www/localhost
Docker站点遇到的坑
这个两个坑还是挺大的,但看在这么方便建站搬站的基础上,我觉得还能接受。
第一个坑,php运行在容器下,php cgi可能有点问题,不能获得宿主的真实状态,比如硬盘的SMART数据、探针的网络状态等,需要靠一些手段来实现。
第二个坑,dnmp默认的安全配置非常简陋,需要极大的完善,redis几乎不设防,新手不会设置的话,建议不要开启redis,不然很大概率被抓去挖矿。
Dnmp使用体会
目前我建立了4个网站镜像,其中三个主机配置配置还非常的寒酸,如果大家知道cac(cloud at cost)7美元永久(实际上有猫腻)或者搬瓦工(bwh) 9美元一年主机的配置(单核E5-2690,512MB内存,10GB SSD),就知道有配置多寒酸了,连接性多差劲了。但目前这些镜像站点都运行得好好的,而且建立的速度不到半小时。
Dnmp开机启动实现
Ubuntu 18的开机启动方式已经不再是修改rc.local了,下面简单写一个脚本,实现开机启动。
#!/bin/bash
systemctl enable docker
cat>/etc/systemd/system/dnmp.service<<EOF
[Unit]
After=network.target
[Service]
ExecStart=/home/dnmp/scripts/dnmp.sh
[Install]
WantedBy=default.target
EOF
cat>/home/dnmp/scripts/dnmp.sh<<EOF
#!/bin/bash
cd /home/dnmp
docker-compose up -d
EOF
chmod a+x /home/dnmp/scripts/dnmp.sh
chmod 744 /usr/local/dnmp.service
systemctl daemon-reload
systemctl enable dnmp.service
systemctl start dnmp.service
我的dnmp是安装在/home下,脚本要根据自己的实际情况来修改。
PHP探针读取宿主网卡信息
我使用的刘海探针 ,这个探针读取网卡信息是通过读取/proc/net/dev,来实现的,要让探针读取到正确的网卡信息,需要做以下步骤。
修改探针文件,将/proc/net/dev替换为/www/dev写一个dev.sh脚本,来传递/proc/net/dev信息
#!/bin/bash
step=1
for (( i = 0; i < 60; i=(i+step) )); do
$(cat /proc/net/dev > /home/dnmp/www/dev)
sleep $step
done
exit 0
编辑crontab 添加
* * * * * /bin/bash ~path/dev.sh 这样可以实现每分钟运行一次脚本。 值得注意的是,直接建立软连接、硬链接以及挂载数据卷的方式,我都尝试过,是不行的。 网站备份方式 在真实环境下搭建的wordpress备份,搬站,不是个简单的事情,而在dnmp下搬站,只需要三条命令和半小时不到就可以了。
tar -zcvf dnmp.tar.gz dnmp#打包整个dnmp文件夹
docker-compose up -d#到dnmp文件夹下运行原来的镜像,数据都在~path/dnmp/data下,到新主机上只需要重新pull镜像就可以了,这一步最花时间。
Dnmp常用命令
docker-compose build php #重建PHP镜像
docker-compose down #停止并删除镜像
docker ps #查看所用镜像
docker-compose up -d #建立并后台运行镜像
Docker-compose设置静态ip
如果有的软件更改config.php来连接数据库的话,可以将docker-mysql的镜像设置为静态的ip,方便连接
更改docker-compose.yml如下
展开
version: "3"
services:
nginx:
build:
context: ./services/nginx
args:
NGINX_VERSION: ${NGINX_VERSION}
CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL}
NGINX_INSTALL_APPS: ${NGINX_INSTALL_APPS}
container_name: nginx
ports:
- "${NGINX_HTTP_HOST_PORT}:80"
- "${NGINX_HTTPS_HOST_PORT}:443"
volumes:
- ${SOURCE_DIR}:/www/:rw
- ${NGINX_SSL_CERTIFICATE_DIR}:/ssl:rw
- ${NGINX_CONFD_DIR}:/etc/nginx/conf.d/:rw
- ${NGINX_CONF_FILE}:/etc/nginx/nginx.conf:ro
- ${NGINX_FASTCGI_PHP_CONF}:/etc/nginx/fastcgi-php.conf:ro
- ${NGINX_FASTCGI_PARAMS}:/etc/nginx/fastcgi_params:ro
- ${NGINX_LOG_DIR}:/var/log/nginx/:rw
environment:
TZ: "$TZ"
restart: always
networks:
dnmpnet:
ipv4_address: 172.16.0.4
php:
build:
context: ./services/php
args:
PHP_VERSION: php:${PHP_VERSION}-fpm-alpine
CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL}
PHP_EXTENSIONS: ${PHP_EXTENSIONS}
TZ: "$TZ"
container_name: php
expose:
- 9501
extra_hosts:
- "www.site1.com:172.17.0.1"
volumes:
- ${SOURCE_DIR}:/www/:rw
- ${PHP_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro
- ${PHP_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw
- ${PHP_LOG_DIR}:/var/log/php
- ${DATA_DIR}/composer:/tmp/composer
restart: always
cap_add:
- SYS_PTRACE
networks:
dnmpnet:
ipv4_address: 172.16.0.3
# php56:
# build:
# context: ./services/php
# args:
# PHP_VERSION: php:${PHP56_VERSION}-fpm-alpine
# CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL}
# PHP_EXTENSIONS: ${PHP56_EXTENSIONS}
# TZ: "$TZ"
# container_name: php56
# expose:
# - 9501
# volumes:
# - ${SOURCE_DIR}:/www/:rw
# - ${PHP56_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro
# - ${PHP56_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw
# - ${PHP56_LOG_DIR}:/var/log/php
# - ${DATA_DIR}/composer:/tmp/composer
# restart: always
# cap_add:
# - SYS_PTRACE
# networks:
# - default
# php54:
# build:
# context: ./services/php54
# args:
# PHP_VERSION: php:${PHP54_VERSION}-fpm
# CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL}
# PHP_EXTENSIONS: ${PHP54_EXTENSIONS}
# TZ: "$TZ"
# container_name: php54
# volumes:
# - ${SOURCE_DIR}:/www/:rw
# - ${PHP54_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro
# - ${PHP54_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw
# - ${PHP54_LOG_DIR}:/var/log/php
# - ${DATA_DIR}/composer:/tmp/composer
# restart: always
# cap_add:
# - SYS_PTRACE
# networks:
# - default
mysql:
image: mysql:${MYSQL_VERSION}
container_name: mysql
ports:
- "${MYSQL_HOST_PORT}:3306"
volumes:
- ${MYSQL_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro
- ${DATA_DIR}/mysql:/var/lib/mysql/:rw
restart: always
networks:
dnmpnet:
ipv4_address: 172.16.0.2
environment:
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
TZ: "$TZ"
# mysql5:
# image: mysql:${MYSQL5_VERSION}
# container_name: mysql5
# ports:
# - "${MYSQL5_HOST_PORT}:3306"
# volumes:
# - ${MYSQL5_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro
# - ${DATA_DIR}/mysql5:/var/lib/mysql/:rw
# restart: always
# networks:
# - default
# environment:
# MYSQL_ROOT_PASSWORD: "${MYSQL5_ROOT_PASSWORD}"
# TZ: "$TZ"
# openresty:
# image: openresty/openresty:${OPENRESTY_VERSION}
# container_name: openresty
# ports:
# - "${OPENRESTY_HTTP_HOST_PORT}:80"
# - "${OPENRESTY_HTTPS_HOST_PORT}:443"
# volumes:
# - ${SOURCE_DIR}:/www/:rw
# - ${OPENRESTY_CONFD_DIR}:/etc/nginx/conf.d/:ro
# - ${OPENRESTY_SSL_CERTIFICATE_DIR}:/ssl:rw
# - ${OPENRESTY_CONF_FILE}:/usr/local/openresty/nginx/conf/nginx.conf:ro
# - ${OPENRESTY_FASTCGI_PHP_CONF}:/usr/local/openresty/nginx/conf/fastcgi-php.conf:ro
# - ${OPENRESTY_CONF_FASTCGIPARAMS_FILE}:/usr/local/openresty/nginx/conf/fastcgi_params:ro
# - ${OPENRESTY_LOG_DIR}:/var/log/nginx/:rw
# environment:
# TZ: "$TZ"
# networks:
# - default
# redis:
# image: redis:${REDIS_VERSION}
# container_name: redis
# ports:
# - "${REDIS_HOST_PORT}:6379"
# volumes:
# - ${REDIS_CONF_FILE}:/etc/redis.conf:ro
# - ${DATA_DIR}/redis:/data/:rw
# restart: always
# entrypoint: ["redis-server", "/etc/redis.conf"]
# environment:
# TZ: "$TZ"
# networks:
# - default
# memcached:
# image: memcached:${MEMCACHED_VERSION}
# container_name: memcached
# ports:
# - "${MEMCACHED_HOST_PORT}:11211"
# environment:
# MEMCACHED_CACHE_SIZE: "${MEMCACHED_CACHE_SIZE}"
# networks:
# - default
# rabbitmq:
# image: rabbitmq:${RABBITMQ_VERSION}
# container_name: rabbitmq
# restart: always
# ports:
# - "${RABBITMQ_HOST_PORT_C}:5672"
# - "${RABBITMQ_HOST_PORT_S}:15672"
# environment:
# TZ: "$TZ"
# RABBITMQ_DEFAULT_USER: "${RABBITMQ_DEFAULT_USER}"
# RABBITMQ_DEFAULT_PASS: "${RABBITMQ_DEFAULT_PASS}"
# networks:
# - default
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: phpmyadmin
ports:
- "${PHPMYADMIN_HOST_PORT}:80"
volumes:
- ${PHPMYADMIN_USER_CONF_FILE}:/etc/phpmyadmin/config.user.inc.php:ro
- ${PHPMYADMIN_PHP_CONF_FILE}:/usr/local/etc/php/conf.d/php-phpmyadmin.ini:ro
networks:
dnmpnet:
ipv4_address: 172.16.0.5
environment:
- PMA_HOST=mysql
- PMA_PORT=3306
- TZ=$TZ
# phpredisadmin:
# image: erikdubbelboer/phpredisadmin:latest
# container_name: phpredisadmin
# ports:
# - "${REDISMYADMIN_HOST_PORT}:80"
# networks:
# - default
# environment:
# - REDIS_1_HOST=redis
# - REDIS_1_PORT=6379
# - TZ=$TZ
# mongodb:
# image: mongo:${MONGODB_VERSION}
# container_name: mongodb
# environment:
# MONGO_INITDB_ROOT_USERNAME: "${MONGODB_INITDB_ROOT_USERNAME}"
# MONGO_INITDB_ROOT_PASSWORD: "${MONGODB_INITDB_ROOT_PASSWORD}"
# TZ: "$TZ"
# volumes:
# - ${DATA_DIR}/mongo:/data/db:rw
# - ${DATA_DIR}/mongo_key:/mongo:rw
# ports:
# - "${MONGODB_HOST_PORT}:27017"
# networks:
# - default
# command:
# --auth
# adminmongo:
# image: mrvautin/adminmongo
# container_name: adminmongo
# ports:
# - "${ADMINMONGO_HOST_PORT}:1234"
# environment:
# - HOST=0.0.0.0
# - DB_HOST=mongodb
# - DB_PORT=27017
# networks:
# - default
# elasticsearch:
# build:
# context: ./services/elasticsearch
# args:
# ELASTICSEARCH_VERSION: ${ELASTICSEARCH_VERSION}
# ELASTICSEARCH_PLUGINS: ${ELASTICSEARCH_PLUGINS}
# container_name: elasticsearch
# environment:
# - TZ=$TZ
# - discovery.type=single-node
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# volumes:
# - ${DATA_DIR}/esdata:/usr/share/elasticsearch/data
# - ${ELASTICSEARCH_CONF_FILE}:/usr/share/elasticsearch/elasticsearch.yml
# hostname: elasticsearch
# restart: always
# ports:
# - "${ELASTICSEARCH_HOST_PORT_C}:9200"
# - "${ELASTICSEARCH_HOST_PORT_S}:9300"
# kibana:
# image: kibana:${KIBANA_VERSION}
# container_name: kibana
# environment:
# TZ: "$TZ"
# elasticsearch.hosts: http://elasticsearch:9200
# hostname: kibana
# depends_on:
# - elasticsearch
# restart: always
# ports:
# - "${KIBANA_HOST}:5601"
# logstash:
# image: logstash:${LOGSTASH_VERSION}
# container_name: logstash
# hostname: logstash
# restart: always
# depends_on:
# - elasticsearch
# environment:
# TZ: "$TZ"
# ports:
# - "${LOGSTASH_HOST_PORT_C}:9600"
# - "${LOGSTASH_HOST_PORT_S}:5044"
networks:
dnmpnet:
ipam:
config:
- subnet: 172.16.0.0/16
这样连接mysql镜像时,地址只需要填写成172.16.0.2即可