docker搭建简单运行的lnmp环境(含主从同步)(持续更新..)
这里使用docker-compose去搭建,
成功效果如下:
docker容器
访问php页面
远程链接mysql
好了,开始展示,目录结构如下:
目录
最新代码已经放上github仓库上,有需要可以下载查看,如果对你有所帮助,就点个小星星叭~
项目地址:github传送门
直接贴代码
dockerfile-php-fpm
# 使用官方的 PHP 基础镜像
FROM php:7.4-fpm
# 设置工作目录
WORKDIR /var/www
# 安装 PHP 扩展(根据需要安装其他扩展)
RUN docker-php-ext-install mysqli pdo_mysql
dockerfile-nginx
# 使用官方的 Nginx 基础镜像
FROM nginx:latest
# 设置工作目录
WORKDIR /var/www
dockerfile-mysql
# 使用官方的 MySQL 镜像作为基础镜像
FROM mysql:latest
# 设置 MySQL 环境变量
ENV MYSQL_ROOT_PASSWORD=root
docker-compose.yaml
version: '3'
services:
php-fpm:
build:
context: .
dockerfile: Dockerfile-php
volumes:
- /www/wwwroot:/var/www
networks:
- app-network
nginx:
build:
context: .
dockerfile: Dockerfile-nginx
ports:
- "80:80"
volumes:
- /www/wwwroot:/var/www
- /www/docker/nginx/conf.d:/etc/nginx/conf.d
depends_on:
- php-fpm
networks:
- app-network
links:
- php-fpm
mysql:
build:
context: .
dockerfile: Dockerfile-mysql
ports:
- "3306:3306"
volumes:
- /www/data:/var/lib/mysql
networks:
- app-network
networks:
app-network:
driver: bridge
nginx.conf
server {
listen 80;
server_name localhost;
root /var/www;
index index.php index.html index.htm;
#location / {
# try_files $uri $uri/ /index.php?$query_string;
#}
location ~ \.php$ {
try_files $uri =404;
#fastcgi_index index.php;
fastcgi_pass php-fpm:9000;
# fastcgi_buffers 16 16k;
# fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# fastcgi_param PATH_INFO $fastcgi_path_info;
# fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
}
然后运行docker-compose up -d
命令,成功启动容器。
远程数据库链接失败的问题:这里需要注意的是,这里用的mysql8.0,远程链接会出现类似Client does not support authentication protocol requested by server;的错误,这通常是因为 MySQL 8.0 默认使用了更安全的 caching_sha2_password 插件,而一些旧版本的 MySQL 客户端不支持这个插件。
解决方法:需要进入mysql容器 docker exec -it your_contianer_id bash
,mysql -u root -p 然后执行下面语句
ALTER USER 'your_user'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'your_password';
FLUSH PRIVILEGES;
其中,your_user 是你的用户,your_password 是你的密码。
关于配置主从同步
由于docker中允许新建并运行多个mysql容器,所以是可以一台服务器上配置主从的,效果如下。
主库:
从库:
首先这里添加mysql目录来配置mysql主从,代码如下
docker/mysql/mysql-1/conf.d 文件(主库)
[mysqld]
server-id = 1
log-bin = mysql-bin
# 同步的数据库,这里配置同步的是test数据库
binlog-do-db = test
log-error = /var/run/mysqld/mysql.log
docker/mysql/mysql-2/conf.d 文件(从库)
[mysqld]
server-id = 2
log-error = /var/run/mysqld/mysql.log
主库和从库的server-id
不能设置为一样
docker-compose.yaml 文件(改动)
version: '3'
services:
php-fpm:
build:
context: .
dockerfile: Dockerfile-php
volumes:
- /www/wwwroot:/var/www
networks:
- app-network
nginx:
build:
context: .
dockerfile: Dockerfile-nginx
ports:
- "80:80"
volumes:
- /www/wwwroot:/var/www
- /www/docker/nginx/conf.d:/etc/nginx/conf.d
depends_on:
- php-fpm
networks:
- app-network
links:
- php-fpm
# 主库
mysql_1:
build:
context: .
dockerfile: Dockerfile-mysql
ports:
- "3306:3306"
volumes:
- /www/data/mysql-1:/var/lib/mysql
- /www/docker/mysql/mysql-1/conf.d:/etc/mysql/conf.d
networks:
- app-network
# 从库,不需要用主从同步可以不加这块
mysql_2:
build:
context: .
dockerfile: Dockerfile-mysql
ports:
- "3307:3306"
volumes:
- /www/data/mysql-2:/var/lib/mysql
- /www/docker/mysql/mysql-2/conf.d:/etc/mysql/conf.d
networks:
- app-network
networks:
app-network:
driver: bridge
注意,映射的端口不能一样,这里主库是3306,从库是3307,不然容器会发生冲突启动不了。
mysql的名字最好是下划线不要用横杠(如:mysql-1),不然等下配置从库的时候会配置失败。
配置好之后,进入到docker目录运行docker-compose up -d
命令,启动容器。
进入主库容器,创建用于从库同步的用户
# master服务器上执行生成复制的用户数据
CREATE USER 'slave0001'@'%' IDENTIFIED BY 'slave0001';
GRANT REPLICATION SLAVE ON *.* TO 'slave0001'@'%';
ALTER USER 'slave0001'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'slave0001'
执行show master status;
命令
这里可以看到MASTER_LOG_FILE
和MASTER_LOG_POS
信息,等下配置从库会用到。
接着进入从库,执行语句
CHANGE MASTER TO
MASTER_HOST = 'mysql_1',
MASTER_USER = 'slave0001',
MASTER_PASSWORD = 'slave0001',
MASTER_LOG_FILE = 'mysql-bin.000011',
MASTER_LOG_POS = 5127;
# 开启同步
START SLAVE;
# 查看同步状态
SHOW SLAVE STATUS\G;
# 关闭同步
# STOP SLAVE IO_THREAD;
# 重置从库同步信息,包括reply_log等
# reset slave;
当看到Slave_IO_Running, Slave_SQL_Running:这两个值都为yes就可以确定同步应该是成功的了。这两个字段分别表示I/O线程和SQL线程的运行状态。它们的值应该是Yes,表示正常运行。如果不是,应该是配置错了,可以运行reset slave;
重新配置从库信息,再运行。以上~
主从同步失败问题以及解决办法
如果主从同步出现问题,例如下图:
Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction ‘ANONYMOUS’ at master log mysql-bin.000011, end_log_pos 5679. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
上述错误表明 MySQL 从库同步过程中的一个或多个工作线程出现了问题。错误日志中提到了 Worker 1 在执行某个事务 ‘ANONYMOUS’ 时失败,位置在 mysql-bin.000011
的某个位置。
可以尝试在从库重新设置同步位置来解决,代码:
STOP SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000011', MASTER_LOG_POS=5679;
START SLAVE;
如果设置提示:
ERROR 1802 (HY000): CHANGE MASTER cannot be executed when the slave was stopped with an error or killed in MTS mode. Consider using RESET SLAVE or START SLAVE UNTIL.
提示在多线程复制 (MTS) 模式下从库被停止时无法执行 CHANGE MASTER
命令。
可使用 RESET SLAVE;
命令清除从库的复制配置,包括同步位置等设置。然后再重新设置同步位置来解决。
本作品采用《CC 协议》,转载必须注明作者和本文链接