基于Docker部署LNMP架构



一、 什么是 docker 
环境配置的难题 
软件开发最大的麻烦事之一,就是环境配置.用户计算机的环境都不相同,你怎么知道自家的软件,能在那些机器跑起来? 
用户必须保证两件事:操作系统的设置,各种库和组件的安装.只有它们都正确, 软件才能运行. 
举例来说,安装一个 Python 应用,计算机必须有 Python 引擎,还必须有各种依赖,可能还要配置环境变量. 

如果某些老旧的模块与当前环境不兼容,那就麻烦了. 
开发者常常会说:"它在我的机器可以跑了"(It works on my machine),言下之意就是,其他机器很可能跑不了. 

环境配置如此麻烦,换一台机器,就要重来一次,旷日费时. 
很多人想到,能不能从根本上解决问题,软件可以带环境安装? 也就是说,安装的时候,把原始环境一模一样地复制过来. 

虚拟机 
虚拟机(virtual machine)就是带环境安装的一种解决方案. 
它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统. 
应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样, 
而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响. 
 

 

虽然用户可以通过虚拟机还原软件的原始环境.但是,这个方案有几个缺点: (1)资源占用多 
虚拟机会独占一部分系统资源,它运行的时候,其他程序就不能使用这些资源了. 哪怕虚拟机里面的应用程序真正使用的内存只有 1MB,虚拟机依然需要几百 MB 的内存才能运行. 
(2)冗余步骤多 
虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录等, 操作繁琐. 
(3)启动慢 
启动操作系统需要多久,启动虚拟机就需要多久. 可能要等几分钟,应用程序才能真正运行. 

Docker 出现的背景 
虽然虚拟机解决了带环境安装的问题, 不过在公司日常的研发和项目场景中, 以下情况仍普遍存在: 
A. 个人开发环境为了做大数据相关项目,需要安装一套大数据集群,常见的做法是在自己电脑里搭建 3 台与大数据版本对应的虚拟机,把大数据集群装起来后,考虑到以后很有可能还要使用一个干净的大数据集群,为了避免以后重复安装环境,通常会对整套大数据集群做一个备份,这样电脑里就有 6 个虚拟机镜像了。另外,后面在学习其他技术时,比如学习 Ambari 大数据集群,那么为了不破坏已有的虚拟机环境,又要重新搭建 3 台虚拟机,本机磁盘很快被一大堆的虚拟机镜像占满。 

B. 公司内部开发环境公司里往往会以小团队的方式来做项目,一般由运维部门从他们管理的服务器资源中分配出虚拟机供团队内部开发测试使用。 
比如做一个与机器学习相关的项目: 
• 小明在运维部门分配的虚拟机上搭建了一套 Ambari 集群,拿来跑大数据相关业务 
• 小刚用 python3 写了一个机器学习算法,放到虚拟机上运行发现虚拟机里是python2,算法不兼容,于是把虚拟机里的 python 版本升级了,算法跑通了, 但 Ambari 用到 python 的部分功能可能就报错了 
• 小李开发了应用,放到虚拟机上启动 tomcat,发现虚拟机里的是 OpenJDK, 导致 tomcat 起不来,于是又安装了一个 JDK,这时候可能 Ambari 里的 Java 代码可能就报错了 
• 小赵想利用服务器资源做性能测试,发现虚拟机严重削减了性能,最终还是直接找物理机来跑测试,破坏了物理机原来的环境 
• 做完项目后,这些虚拟机上安装的东西往往变得没用了,下个项目组来还是得新申请虚拟机重新部署软件 

C. 开发/测试/现场环境研发人员在开发环境里写好了代码做好测试后,提交给测试部门,测试人员在测试环境跑起来发现有 BUG,研发人员说在开发环境没这个 BUG,和测试人员多次扯皮解决 BUG 后发布版本. 在生产环境部署后,又发现有 BUG,这下又到工程人员和测试人员扯皮... 有时候为了兼容特殊的现

 

场环境,还需要对代码进行定制化修改,拉出分支,这样导致了每次到现场升级都是一场噩梦 

D. 升级或迁移项目在每次发版本要升级到现场时,如果现场起了多个 tomcat 应用,那么需要对每个 tomcat 都先停掉,替换 war 包,然后再起起来,轮流着做,不仅繁琐而且很容易出错,如果遇到升级后出现严重 BUG,还要手工做回退。另外,如果项目想上云,那么在云上部署后要重新进行一轮测试,如果后面考虑其他云厂商,可能相同的测试还要再进行一次(比如更换了数据存储组件),费时费力。 

总结以上列举的场景,他们存在的一个共同的问题是:没有一种既能够屏蔽操作系统差异,又能够以不降低性能的方式来运行应用的技术,来解决环境依赖的问题。 
Docker 解决了这些问题。 

二、 Docker 的安装 
(一) 安装方式一: 安装 docker 源 
CentOS 7 (使用 yum 进行安装)


(二) 安装方式二: 直接下载 rpm 包进行安装: 
官 方 下 载 地 址 : https://download.docker.com/linux/centos/7/x86_64/stable/Packa ges/ 
找到相应的包下载下来rpm -ivh 包名 


三、 Docker 基本操作 
查看本机的 image 
# docker image ls 
# docker images 

获取 image 
# docker search centos #此命令会在 docker 官方仓库查找所需镜像,速度慢. 
# docker pull centos # 从默认仓库拉取 centos 镜像最新版 

删除 image 
# docker image rm 镜像 #镜像指 镜像 ID 或 镜像名称:tag 
# docker rmi 镜像 

查看容器 
# docker ps # 查看正在运行的容器 
# docker ps -a # 查看所有容器 

启动容器 
# docker run -itd -h http://centos.docker.qf.com --name centos centos 
常用选项: 
-i # 允许你对容器内的标准输入 (STDIN) 进行交互 
-t # 在新容器内指定一个伪终端或终端 

 

-d # 在后台运行容器,返回容器 ID 
-h # 指定容器的主机名,如果不指定,会随机生成一个 
--rm # 容器停止后删除掉,默认不会删除 
--name # 指定容器的名称 
-p <宿主端口>:<容器端口> # 端口映射,将容器指定端口映射到宿主机的指定端口. 可以用多个-p 选项指定多个端口映射 
-p 80 # 将容器的 80 端口映射到宿主机的随机端口 
-P # 将容器的所有端口映射到宿主机的随机端口 
-v <宿主目录>:<容器目录> #将宿主机的指定目录映射到容器的指定目录 
--privileged #需要修改某些特定的参数需要加上此选项, 正常运行一个容器不建议开放这个权限 

连接容器 
对于正在运行的容器,我们可以在宿主机上连接容器 
# docker exec -it centos /bin/bash # 可用 exit 命令退出,不影响容器,
centos 是容器名字 
四、 基于 Docker 容器部署 LNMP 分离架构 
1) 获取镜像 
# docker pull centos:7.6.1810 #获取镜像 
 


# docker images 
2) 准备容器 
# docker run -it -d --name nginx -h apache --privileged -p 80:80 -v 
/html:/usr/share/nginx/html f1cb7c7d58b7(IMAGE ID) 
# 准备 nginx 容器 

# docker run -it -d –name php -h php --privileged -p 9000:9000 -v 
/html:/var/www/html f1cb7c7d58b7(IMAGE ID) 
# 准备 php 容器 

# docker run -it -d –name mysql -h mysql --privileged -p 3306:3306 - v /mysql:/var/lib/mysql f1cb7c7d58b7(IMAGE ID) 
# 准备 mysql 容器 

3) 准备环境 

 

Nginx 
# docker exec -it apache /bin/bash #连接容器 
# hostname -I # 查看容器 ip 
#建立 nginx 的安装源 
# vim /etc/yum.repos.d/nginx.repo 
[nginx-stable] 
name=nginx stable repo 
baseurl=http://nginx.org/packages/centos/$releasever/$basearc h/ 
gpgcheck=1 
enabled=1 
gpgkey=https://nginx.org/keys/nginx_signing.key 
module_hotfixes=true 

[root@qianfeng_nginx ~]# yum -y install nginx nfs-utils 

#设置 nginx 服务配置 
[root@qianfeng_nginx ~]# cd /etc/nginx/conf.d [root@qianfeng_nginx conf.d]# vim default.conf server { 
listen 80; 
server_name www.qianfeng.com; 

location / { 
root /usr/share/nginx/html; 
index index.php index.html index.htm; 


error_page 500 502 503 504 /50x.html; 
location = /50x.html { 
root /usr/share/nginx/html; 


location ~ \.php$ { 
root /usr/share/nginx/html; 
fastcgi_pass <nfsphp 主机 IP 地址>:9000; 
fastcgi_index index.php; 
fastcgi_param SCRIPT_FILENAME 
$document_root$fastcgi_script_name; 
include fastcgi_params; 

 

Mysql 
[root@qianfeng_db ~]# yum -y install mariadb-server mariadb 
# 安装 mysql 
[root@qianfeng_db ~]# systemctl start maraidb && systemctl enable mariadb 

[root@qianfeng_db ~]# mysql -uroot 
mysql> create database qqfarm; # 创建 qqfarm 数据库mysql> grant all privileges on qqfarm.* to 'qqfarm'@'*' 
identified by 'qqfarm'; # 授 权mysql> exit 

Php 
[root@qianfeng_nfsphp ~]# yum -y install nfs-utils php php-mysql php-devel php-gd php-fpm php-mcrypt php-mbstring php-xml 
[root@qianfeng_nfsphp ~]# groupadd -g 996 nginx [root@qianfeng_nfsphp ~]# useradd -u 998 -g nginx -M -s 
/sbin/nologin nginx 
[root@qianfeng_nfsphp ~]# vim /etc/php-fpm.d/www.conf listen=<本机 IP 地址>:9000 
listen_allower_client=<nginx 主机 IP 地址>,<。。。> user=nginx 
group=nginx 
[root@qianfeng_nfsphp ~]# sytemctl start php-fpm && systemctl enable php-fpm 

[root@qianfeng_nfsphp ~]# vim /etc/exports 
/usr/share/nginx/html <nginx 应用服务器 IP 网段>(rw,sync) [root@qianfeng_nfsphp ~]# mkdir -p /usr/share/nginx/html [root@qianfeng_nfsphp ~]# systemctl start nfs && systemctl enable 
nfs 

4) 部署项目 
将项目包上传 farm-ucenter1.5.zip 到服务器/html 目录下 


php 容器端 
# unzip farm-ucenter1.5.zip 
# chmod 777 -R upload/ #给予权限 

 

# mysql -ufarm -pfarm -h mysql 的 IP -D qqfarm < upload/qqfarm.sql 
# 导入数据库 
 



修改/etc/php.ini 文件
 


# vim /etc/php.ini
进入 nginx 端 
# nginx -s reload # 重启 nginx 



5) 访问 
 


 

 

 

 

安装完成后用浏览器访问:

http://服务器 IP 地址 /upload/home

# docker搭建lnmp环境 <!-- TOC --> - [docker搭建lnmp环境](#docker搭建lnmp环境) - [一、Dockerfile定制镜像](#一dockerfile定制镜像) - [二、docker-compose](#二docker-compose) - [三、docker-compose编排lnmp环境](#三docker-compose编排lnmp环境) - [1、mysql](#1mysql) - [2、redis](#2redis) - [3、mongo](#3mongo) - [4、nginx](#4nginx) - [5、php](#5php) - [6、完整版](#6完整版) - [四、参考](#四参考) <!-- /TOC --> 有收获的话请**加颗小星星**,没有收获的话可以 **反对** **没有帮助** **举报**三连 ## 一、Dockerfile定制镜像 ```bash # FROM 指定基础镜像 FROM 镜像 FROM php:7.2-fpm # RUN 执行 RUN or RUN ["可执行文件", "参数1", "参数2"] RUN echo 'Hello, Docker!' > /usr/share/nginx/html/index.html RUN ["php", "-S", "0.0.0.0:8080"] # COPY 复制文件 COPY ... COPY swoole-4.2.10.tgz /home COPY nginx.conf /etc/nginx/nginx.conf # ADD 复制文件或目录,如果是.tgz,会被解压缩 ADD ... ADD nginx.conf /etc/nginx/nginx.conf # CMD 容器启动 CMD echo $HOME => CMD [ "/bin/sh", "-c", "echo $HOME" ] CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ] # ENTRYPOINT 入口点 ENTRYPOINT ["docker-entrypoint.sh"] 存在 ENTRYPOINT 后,CMD 的内容将会作为参数传给 ENTRYPOINT # ENV 环境变量 ENV ENV MYSQL_ROOT_PASSWORD root # ARG与ENV差不多 ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的 ENV MYSQL_ROOT_PASSWORD root # VOLUME 匿名卷 VOLUME ["", ""...] VOLUME ["/data"] # EXPOSE 暴露端口 EXPOSE [...] EXPOSE 80 443 # WOEKDIR 指定工作目录,进入容器后的落地目录 WORKDIR WORKDIR /var/www # USER 指定当前用户 USER USER root ``` ## 二、docker-compose - 服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。 - 项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。 ## 三、docker-compose编排lnmp环境 ### 1、mysql 这里我们使用了mysql5.5版本,没其它用意,相比5.7以上版本,占内存和硬盘最小的一个版本 我们准备了一个`my.cnf`作为额外配置,这里我修改了数据库的时区 ```cnf [mysqld] default-time-zone = '+8:00' ``` ```Dockerfile FROM mysql:5.5 COPY my.cnf /etc/mysql/conf.d EXPOSE 3306 ``` ### 2、redis 我们使用准备的配置文件`redis.conf`覆盖容器默认启动的配置文件,修改了`ip绑定`和`密码` ```conf bind 0.0.0.0 requirepass root ``` ```Dockerfile FROM redis:latest COPY redis.conf /usr/local/etc/redis/redis.conf CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ] EXPOSE 6379 ``` ### 3、mongo mongodb我们没有特殊处理 ```Dockerfile FROM mongo:latest EXPOSE 27017 ``` ### 4、nginx 我们准备了一份`nginx.conf`和虚拟目录`conf.d`,为了以后可以动态的配置网站的代理和负载均衡 还有一个日志目录,放在外层`logs`目录里面,记录nginx的访问日志 特别注意的是`fastcgi_pass php:9000;`而不是`fastcgi_pass 127.0.0.1:9000;`,目前自己也没明白 ```Dockerfile FROM nginx:alpine COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 80 ``` ### 5、php php算是这里面最难搞定的,因为我们需要额外的添加php扩展,虽然php的docker官方提供了`docker-php-ext-configure`, `docker-php-ext-install`, `docker-php-ext-enable`,还是有些扩展需要通过`手动编译`或者`pecl`安装 由于pecl官网下载慢,我们事先下载好了几个需要的扩展 php-fpm用的是debian的linux系统,下载也很慢,我们备用了阿里云的镜像`sources.list` 我们还准备了php的默认配置`php.ini`和`opcache.ini` 比如swoole扩展安装,记得安装包用完后清理,还有得用`COPY`命令,`ADD`会解压缩 ```Dockerfile # swoole COPY swoole-4.2.10.tgz /home RUN pecl install /home/swoole-4.2.10.tgz && \ docker-php-ext-enable swoole && \ rm /home/swoole-4.2.10.tgz ``` ### 6、完整版 ```yml version: '3' networks: frontend: driver: bridge backend: driver: bridge volumes: mysql: driver: local mongo: driver: local redis: driver: local services: php: build: ./php volumes: - ${WORKER_DIR}:/var/www ports: - 9100:9000 depends_on: - mysql - redis - mongo networks: - backend nginx: build: ./nginx volumes: - ${WORKER_DIR}:/var/www - ./logs/nginx:/var/log/nginx - ./nginx/conf.d:/etc/nginx/conf.d ports: - 8000:80 depends_on: - php networks: - frontend - backend mysql: build: ./mysql environment: - MYSQL_ROOT_PASSWORD=root volumes: - ${DATA_PATH}/mysql:/var/lib/mysql ports: - 3310:3306 networks: - backend mongo: build: ./mongo environment: - MONGO_INITDB_ROOT_USERNAME=root - MONGO_INITDB_ROOT_PASSWORD=root ports: - 27010:27017 volumes: - ${DATA_PATH}/mongo:/data/db networks: - backend redis: build: ./redis volumes: - ${DATA_PATH}/redis:/data ports: - 6310:6379 networks: - backend ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值