image.png
问:为什么是集成的环境,而并非独立的容器服务,这样用是否有违Docker的初衷?
答:要解决的问题就是快速部署,如果环境OK,我们甚至不需要Docker。虽然大多使用Docker推荐使用独立的容器去做服务化(曾闻Docker为微服务而生),但毕竟不同的问题,不同的解决方案。
集成环境需要哪些服务及程序:
php 7.1
nginx
mysql5.7
redis
supervidor
node v8.11.4
java
crond
以及一些工具:
JSignPdf 1.6.2
pdfbox-app-2.0.11
prince v11
composer
phpmyadmin
portainer
接下来就是在 Dockerfile 中去构建这些服务喽,编译源码安装可能比较费时,所以这一次我们使用系统提供的包管理器去处理,简化我们前期的一些工作。
Dockerfile的内容编写,大概是选定基础镜像后,执行各种命令,安装或编译各类软件,最后呢,再启动一个前台服务命令。
为了准确编写 Dockerfile, 这里,我们会创建一个基础容器后,在容器内执行各安装命令,然后逐步向 Dockerfile 中添加。
基础镜像选型
简单整理如下,可参考基础镜像选择
镜像名称 | 大小 | 使用场景 |
---|---|---|
busybox | 1.15MB | 临时测试用 |
alpine | 4.41MB | 主要用于测试,也可用于生产环境 |
centos | 200MB | 主要用于生产环境,支持CentOS/Red Hat,常用于追求稳定性的企业应用 |
ubuntu | 81.1MB | 主要用于生产环境,常用于人工智能计算和企业应用 |
debian | 101MB | 主要用于生产环境 |
OK,我们选 ubuntu,目前的 18.04 版本。(我本是centos党,但镜像太大,无爱了)
基础Dockerfile
#VERSION v2.0.0#base imageFROM ubuntu:18.04MAINTAINER faster "wang.wei@genecast.com.cn" CMD ["/bin/bash"]
通过 Dockerfile Build成镜像
docker build -t="gene/runtime:v2.0" -f runtime.dockerfile . docker images
通过镜像开启一个容器,并将主机的 /home/docker 目录 映射到容器内的 /opt/docker目录
docker run --name runtime --volume /home/docker:/opt/docker -d -it gene/runtime:v2.0docker ps
进入容器开始搞事情
docker exec -it runtime /bin/bash
删除容器
docker stop runtime && docker rm runtime
国内源: scripts/apt-source.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
源的事一直不太稳定,真心闹
各种安装命令记录
# 更换国内源 mv /etc/apt/sources.list /etc/apt/sources.list.bak cp /opt/docker/scripts/apt-source.list /etc/apt/sources.list && apt update cat /etc/apt/sources.list.bak >> /etc/apt/sources.list && apt update apt install nginx=1.14.* -y# 安装supervisorapt install supervisor=3.3* -y# 安装 php7.1apt install software-properties-common -y LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php -y && apt update apt install php7.1-fpm php7.1-mcrypt php7.1-cli php7.1-xml php7.1-mysql php7.1-gd php7.1-imagick php7.1-recode php7.1-tidy php7.1-xmlrpc php7.1-mbstring php7.1-curl php7.1-zip php7.1-bcmath -y#javaapt install openjdk-11-jre -y;
php的坑,必须在 ubutnu 18.04下使用
nodejs安装
nvm安装时,环境变量非常难受,历经3个小时的测试,在 dockerfile中编写如下
RUN git clone http://github.com/creationix/nvm.git /root/.nvm \ && chmod -R 777 /root/.nvm/ \ && bash -c "/root/.nvm/install.sh"; RUN export NVM_DIR="$HOME/.nvm" \ && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \ && export \ && nvm install v8.11.4;
为什么用两个RUN,一个RUN产生一个Layer,docker对此进行缓存,节约我们每次Build的时间噢
supervisors配置和启动
前置知识
在 docerfile 中,如果不添加CMD命令,貌似应该继承基础镜像的 CMD 命令,一般是 /bin/sh
CMD 命令,一定是 nodeamon 的形式运行,否则容器会自动退出
配置
前台启动 [supervisord] nodaemon=true.... 通过web页面管理 [inet_http_server] port=*:9001 username=xx password=xx
在 /etc/supervisor/conf.d中编写各个服务的配置,例如 config/nginx.conf
[program:nginx] command=/usr/sbin/nginx -c /etc/nginx/nginx.conf -g 'daemon off;'
启动
/usr/bin/supervisord -n
数据库
数据库还是独立吧。镜像搞太大,不方便,同时数据库很重要噢~~
完整的 dockerfile
#VERSION v2.0.0#base imageFROM ubuntu:18.04 MAINTAINER faster "wang.wei@genecast.com.cn" ENV TIMEZONE Asia/Shanghai ENV NGINX_VERSION 1.14.0-1~stretch ENV NJS_VERSION 1.14.0.0.2.0-1~stretch RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak COPY scripts/apt-source.list /etc/apt/sources.list RUN apt update \ && apt install nginx=1.14.* -y \ && apt install supervisor=3.3* -y \ && apt install git curl -y \ && apt install redis-server -y; RUN git clone http://github.com/creationix/nvm.git /root/.nvm \ && chmod -R 777 /root/.nvm/ \ && bash -c "/root/.nvm/install.sh"; RUN export NVM_DIR="$HOME/.nvm" \ && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \ && nvm install v8.11.4 && npm install yarn -g; RUN apt-get update --fix-missing && apt install software-properties-common -y \ && LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php -y && apt update RUN DEBIAN_FRONTEND=noninteractive apt install php7.1-fpm -y \ && apt install php7.1-mcrypt php7.1-cli php7.1-xml php7.1-mysql php7.1-gd php7.1-imagick php7.1-recode php7.1-tidy php7.1-xmlrpc php7.1-mbstring php7.1-curl php7.1-zip php7.1-bcmath -y \ && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && dpkg-reconfigure -f noninteractive tzdata; RUN mkdir /run/php; RUN apt install composer -y \ && composer config -g repo.packagist composer https://packagist.phpcomposer.com RUN apt install openjdk-8-jre -y; RUN apt clean;# 复制一些 java 包COPY files/pdfbox-app-2.0.11.jar /var/www COPY files/JSignPdf/ /var/www/JSignPdf# 安装 prince v11COPY files/prince-11.4-ubuntu18.04-amd64.tar.gz /var/www RUN cd /var/www && tar xvfz prince-11.4-ubuntu18.04-amd64.tar.gz \ && ./prince-11.4-ubuntu18.04-amd64/install.sh \ && rm -rf prince-11.4-ubuntu18.04-amd64* EXPOSE 22 80 82 CMD ["/usr/bin/supervisord", "-n"]
PS: 一个 RUN 对于 docker 镜像来说会产生一个层级(layer),有利于再次编译
发布镜像
首先 docker hub 注册个账户 http://docker.io
命令行 docker login 登录
将镜像和账户关联(我的账户名 thehappymouse):docker tag gene/runtime:2.0 thehappymouse/runtime
推 docker push thehappymouse/runtime
如果没有第3步,使用 docker push gene/runtime:2.0 会提示一些 ** denied: requested access to the resource is denied** 错误
直接使用命令
直接使用 docker pull thehappymouse/runtime:2.0
docker-compose 登场
如果你只需一个容器即完成工作, docker-compose 可能不需要。但需要多个容器协作才能完成的服务,则docker-compose 事半功倍。
曾经我对 docker-compose 是拒绝的,以为他太高级,需要熟悉docker本身。然而并不是。使过一次之后,感觉非常好。
加一个 phpmyadmin 去管理数据库
docker-compose.yml 内容
version: "2"services: mysql: image: mysql:5.7 container_name : mysql volumes: - ./conf/mysql/mysql.conf.d:/etc/mysql/mysql.conf.d:ro - ./www/genecast-sales-training:/var/www/genecast-sales-training:ro - ./data/mysql/:/var/lib/mysql/:rw - ./data/dbak:/var/dbak - ./log/mysql/:/var/log/mysql/:rw environment: MYSQL_ROOT_PASSWORD: "mysql123456" phpmyadmin: image: phpmyadmin/phpmyadmin:latest container_name: phpmyadmin ports: - "8206:80" links: - mysql:db supervisor: image: thehappymouse/runtime:2.0 container_name : supervisor ports: - "8280:80" - "8281:81" - "8201:9001" volumes: - ./www/genecast-sales-training:/var/www/genecast-sales-training:rw - ./log/nginx/:/var/log/nginx/:rw - ./conf/nginx/sites-enabled:/etc/nginx/sites-enabled/:ro - ./conf/supervisor:/etc/supervisor/:ro - ./conf/crontab:/etc/crontab:ro environment: BASH_ENV: "/root/.bashrc" links: - mysql:db protainer: image: portainer/portainer ports: - "8200:9000" volumes: - "/var/run/docker.sock:/var/run/docker.sock" - "./data/portainer_data:/data"
相对目录是相对于 docker-compose.yml 所在目录
各配置和日志,走宿主机,便于日后修改。所以这些配置和镜像本身的服务是有强关联的。比如 不同版本的mysql,配置可能不一样
links ,容器的内联。需要用的时候,将IP换成链接名。
启动及改配后:docker-compose up
查看:docker-compose ps
停止:docker-compose stop
删除:docker-compose down
docker-compose.yml 外挂配置
应用开启
下载代码,各种工具和程序的复制,数据库初始化,这些大都和源码相关,和 Docker 本身关系已经不大,但依然要测试一遍喽。
这里附上我为一个Laravel应用写的 docker-install.sh 内容,请参考:
要点:
需要一个数据库文件导入
执行应用需要的各类操作
#!/bin/bashbaseDirForScriptSelf=$(cd "$(dirname "$0")"; pwd)if [ $# != 1 ] ; then echo "USAGE: $0 sqlfile" echo " e.g.: $0 /var/dbak/dbbak.sql" exit 1; fi sqlfile=$1# composer安装类库docker-compose exec supervisor chmod -R 777 /var/www/genecast-sales-training/storage docker-compose exec supervisor composer install -d /var/www/genecast-sales-training docker-compose exec supervisor cp /var/www/genecast-sales-training/.env.example /var/www/genecast-sales-training/.env docker-compose exec supervisor php /var/www/genecast-sales-training/artisan key:generate# 配置文件# nodejs 安装类库docker-compose exec supervisor bash -c -i 'apt install g++ make -y'docker-compose exec supervisor bash -c -i 'yarn config set registry http://registry.npm.taobao.org/'docker-compose exec supervisor bash -c -i 'yarn --cwd /var/www/genecast-sales-training'# build css jsdocker-compose exec supervisor bash -c -i 'yarn --cwd /var/www/genecast-sales-training gulp prod'echo "start import data from sqlfile $sqlfile"cp $sqlfile $baseDirForScriptSelf/init.sql docker_path=/var/www/genecast-sales-training/init.sql# 导入数据docker-compose exec mysql bash -c "echo 'drop database if exists genecast_sales_training; create database genecast_sales_training;use genecast_sales_training; source $docker_path;' | mysql -u root -p"rm -f $baseDirForScriptSelf/init.sqlecho "over go http://127.0.0.1:8281/"
作者:勤劳一沙鸥
链接:https://www.jianshu.com/p/e76e7df41409