美文网首页
Docker应用实践&一些使用技巧

Docker应用实践&一些使用技巧

作者: gao922699 | 来源:发表于2022-08-21 08:08 被阅读0次

    使用docker的理由:

    1. 不污染主系统就可以使用众多Linux程序(替代虚拟化技术)

    2. 保证项目运行环境一致(运行环境可加入版本控制,做成镜像更容易重复使用)

    3. 保证项目各个部分在一个封闭的空间内,不受外交干扰(微服务化)

    开发中的使用技巧

    OVERRIDE文件的使用

    docker-compose.override.yml文件里的内容会覆盖docker-compose.yml的内容,可以在里面定义本地环境自有的属性,还可以在里面添加service,这样本地的服务也可以使用同一个网络环境了。比如原docker-compose里没有mysql服务,可以在override里面加一个,还比如一些需要绑定本地目录的由于本地路径无法确定,需要写在override里面;如果一组service里面你只想启用部分,可以在override中用image:hello-world;entrypoint:[true]来覆盖不想启动的service

    使用npm环境编译vue项目

    docker run -it -d -v:~/code:/www -w /www node bash
    

    exec进入容器后就可以使用npm命令了

    删除名称为none的镜像

    docker rmi $(docker images | grep "none" | awk '{print $3}')
    

    docker run 的时候加上--rm可以避免生成名称为none的镜像

    固定容器IP

    每个docker-compose启动的时候会生成一个名称为default的network,通过配置network可以固化容器的IP

    例:php代码里面要调用www.site1.com这个站点的服务,这个站点运行在nginx服务下,需要配置hosts才能访问;如果不固化ip,每次重启服务都可能引起nginx服务IP变化,导致hosts实效。固化IP的方法如下:

    version: '3'
    
    services:
      nginx:
        networks:
          default:
            ipv4_address: 172.20.1.13
        depends_on:
          - php
      php:
        extra_hosts:
          - "www.site1.com:172.20.1.13"
        networks:
          default:
            ipv4_address: 172.20.1.14
    networks:
      default:
        ipam:
          config:
            - subnet: 172.20.1.0/24
    

    注意:这里固定的ip只是SERVER_IP,REMOTE_ADDR获取到的是网关的IP

    address不能设为.1,.1默认被网关占用了

    访问宿主机的服务

    一般推荐需要相互访问的服务写在一个docker-compose中,这样这些服务是在同一个网络中的可以直接访问。如果实在要访问不同的容器提供的服务,通过暴露端口绑定宿主机端口来实现。!!注意宿主机的防火墙设置!!容器中是可以访问宿主机的本地IP+端口的。

    建本地私有仓库

    registry 官方开源的仓库代码

    https://www.jianshu.com/p/fef890c4d1c2

    项目部署实践和遇到的问题

    项目部署推荐使用docker-compose编排容器。

    1. 项目代码目录权限问题

      使用volume方式绑定的项目文件会存在权限问题(项目文件在容器内可能没有执行权限)

      解决方式:通过dockerfile的COPY命令把项目文件拷贝到容器内,拷贝进去的文件默认是root权限,COPY命令也有 --chown 参数可以设置文件权限,但仅支持linux下。也可以在dockerfile内通过chown、chmod命令给文件授权;COPY和ADD的区别。推荐使用COPY

    2. 上下文(context)概念

    3. https://www.cnblogs.com/jiangzhaowei/p/10055425.html

    4. 多个服务部署同一台机器的问题

      宿主机起一个nginx服务,docker的nginx服务映射到本地的非80端口,然后通过宿主机的nginx的proxy服务转发到docker内nginx服务绑定的本地端口上。

    5. 生产环境和和测试环境不用env文件的维护

      部署的项目在git上使用dev,release分支来区分env文件,见下面的例子,不同分支上的env文件是不一样的。

    目前项目中遇到的相对最复杂的docker-compose案例

    image.png

    docker-compose.yml文件:

    version: '3'
    
    services:
      nginx:
        image: nginx:latest
        tty: true
        volumes://项目代码放在同级目录中
          - ../site-group/nginx.template:/etc/nginx/conf.d/nginx.template:ro 
          - ../site-group:/www:ro
        environment:
          - ADMIN_HOST=site-group.local
        command: ["bash", "/www/nginx-up.sh"] //替换nginx.template中的ADMIN_HOST环境变量的脚本
        depends_on:  //效果是先启动php再启动nginx
          - php
      php:
        build:  //生产环境用Dockerfile中的ADD命令来添加项目代码,可以解决文件权限问题,
                   开发环境可以直接在下面volumes中绑定项目代码,然后手动修改权限(ADD要时间)
          context: ../site-group
          dockerfile: Dockerfile
        tty: true
        working_dir: /www
        volumes:
          - ./site-group/.env:/www/.env   //使用目录中的env文件替换项目中的env文件
        command: ["bash", "/www/php-up.sh"]  //项目启动时运行的脚本
      mysql:
        image: mysql:5.7.22
        environment:
          - MYSQL_ROOT_PASSWORD=root
      site-group-spider:
        build:  //一个python程序,从dockerfile构建
          context: ../site-group-spider
          dockerfile: Dockerfile
        volumes:
          - ../site-group-spider:/app
          - ./site-group-spider/config.py:/app/config.py  //替换配置文件
        tty: true
        entrypoint: ["python", "/app/spider/spider.py"]  //替换entrypoint
    

    docker-compose.override.yml文件:

    version: '3'
    
    services:
      out-nginx:  //外层的nginx服务,用来模拟宿主机的nginx服务
        image: nginx:latest
        volumes:
          - ../site-group/out_admin_nginx.conf:/etc/nginx/conf.d/default.conf
          - ../site-group/out_nginx.conf:/etc/nginx/conf.d/out_nginx.conf
          - ../site-group/inotify:/www/inotify
        ports:
          - "80:80"
        depends_on:
          - php
          - nginx
        networks:
          default:
            ipv4_address: 172.20.1.11  //固化容器IP
      site-group-spider:
        image: hello-world
        entrypoint: ["true"]
        networks:
          default:
            ipv4_address: 172.20.1.12
      nginx:
        ports:
          - "8881:80"
        environment:  //替换env变量为本地值
          - ADMIN_HOST=www.site-group.com
        networks:
          default:
            ipv4_address: 172.20.1.13
        depends_on:
          - php
      mysql:
        ports:
          - "3306:3306"
        volumes:
          - ~/docker/mysql/backup:/backup
          - ~/docker/mysql/data:/var/lib/mysql
      php:
        extra_hosts:  //配置hosts,因为php服务中要调用nginx服务提供的站点,不配置hosts无法访问到
          - "www.site1.com:172.20.1.13"
        networks:
          default:
            ipv4_address: 172.20.1.14
    networks:
      default:
        ipam:
          config:
            - subnet: 172.20.1.0/24
    

    site-group项目中的文件:

    Dockerfile:

    FROM panwenbin/php-fpm-7.1-laravel-centos
    
    ADD . /www  //使用ADD方式添加项目代码到容器内
    
    WORKDIR /www
    
    RUN composer install --no-dev \      //执行安装vendor目录
      && chown -R apache:apache /www        //修改项目目录所有者,和php服务用户一致,就可以解决权限问题
    
    EXPOSE 9000
    

    nginx.template:nginx容器使用的配置文件模板

    server {
        listen       80;
    
        server_name _;  //不限制域名
    
        client_max_body_size 100m;
    
        root   /www/public;
        index  index.html index.php index.htm;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        #根据域名生成数据表前缀
        if ( $host ~ ^www\.(\w+)\.(\w+)$ ) {
            set $prefix $1_$2_;
        }
    
        if ( $host ~ ^www\.(\w+)\.(\w+)\.(\w+)$ ) {
            set $prefix $1_$2_$3_;
        }
    
        if ( $host != '${ADMIN_HOST}' ) {    //此处的环境变量为docker-compose文件中配置的值
            set $dbPrefix $prefix;
        }
    
        error_page 404 /index.php;
    
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    
        location ~ \.php$ {
            fastcgi_pass   php:9000;  //php服务名称和暴露的端口
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
            fastcgi_send_timeout 300;
            fastcgi_read_timeout 300;
            fastcgi_param DB_PREFIX $dbPrefix;
        }
    
        location ~ /\.(?!well-known).* {
            deny all;
        }
    
    }
    

    nginx-up.sh:替换环境变量的脚本

    #!/bin/bash
    envsubst '${ADMIN_HOST}' < /etc/nginx/conf.d/nginx.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'
    

    out_admin_nginx_conf.example:外部(宿主机)nginx服务使用的nginx配置,做了一层转发到内部的nginx服务,按注释要求修改后使用

    server {
        listen 80;
        #系统后台域名
        server_name site-group.com;
        return 301 http://www.$host$request_uri;
    }
    
    server {
        listen 80;
        #系统后台www域名
        server_name www.site-group.com;
        location = / {
            rewrite / /admin redirect;
        }
        location / {
            #转发到内部的nginx开放的端口
            proxy_pass    //本机IP+暴露端口 
            proxy_set_header Host $host;
        }
    }
    

    out_nginx_conf.example:同上

    server {
        listen 80;
        #路径替换为项目路径
        include /www/inotify/nginx_server_names.conf;  //inotify文件中生成的存放servername的文件,通过inotify服务监听自动重启外层的nginx服务
        return 301 http://www.$host$request_uri;
    }
    
    server {
        listen 80;
        #路径替换为项目路径
        include /www/inotify/nginx_www_server_names.conf;
        location / {
            #转发到docker的nginx开放的端口
            proxy_pass http://192.168.2.75:8881;
            proxy_set_header Host $host;
        }
    }
    

    php-up.sh

    #!/bin/bash
    php artisan nginx:up-servernames && php-fpm -F
    

    相关文章

      网友评论

          本文标题:Docker应用实践&一些使用技巧

          本文链接:https://www.haomeiwen.com/subject/qujugrtx.html