关于docker-compose:yum安装dockercompose

装置Docker参考yum装置Docker 2. 装置docker-compose# 装置epel源yum install -y epel-release# 装置docker-compose,如果没有python3会装置python3yum install -y docker-compose3. 问题记录问题一: 执行docker-compose命令提醒门路找不到如查看版本docker-compose -version可能提醒谬误:-bash: /usr/local/bin/docker-compose: No such file or directory 解决办法查看docker-compose装置目录 [root@iZj6cc2b8rasevvzjixv5qZ bin]# whereis docker-composedocker-compose: /usr/bin/docker-compose倡议软链接 ln -s /usr/bin/docker-compose /usr/local/bin/docker-compose

April 19, 2023 · 1 min · jiezi

关于docker-compose:dockercompose安装-yapi接口管理工具

docker-compose装置 yapi接口管理工具 version: '3'services: yapi-web: image: jayfong/yapi:latest container_name: yapi-web ports: - 40001:3000 environment: - YAPI_ADMIN_ACCOUNT=admin@docker.yapi - YAPI_ADMIN_PASSWORD=adm1n - YAPI_CLOSE_REGISTER=true - YAPI_DB_SERVERNAME=yapi-mongo - YAPI_DB_PORT=27017 - YAPI_DB_DATABASE=yapi - YAPI_MAIL_ENABLE=false - YAPI_LDAP_LOGIN_ENABLE=false - YAPI_PLUGINS=[] depends_on: - yapi-mongo links: - yapi-mongo restart: unless-stopped yapi-mongo: image: mongo:latest container_name: yapi-mongo volumes: - ./data/db:/data/db expose: - 27017 restart: unless-stopped

April 8, 2023 · 1 min · jiezi

关于docker-compose:docker-物联网-开发

version: '3'services:# vsftpd:# image: fauria/vsftpd# volumes:# - "/media/hdd/videos:/home/vsftpd"# restart: always# network_mode: "host"# ports:# - "20:20"# - "21:21"# - "21100-21110:21100-21110"# environment:# - FTP_USER=camera# - FTP_PASS=camera# - PASV_MIN_PORT=21100# - PASV_MAX_PORT=21110# emqx: image: "emqx:4.3.22" container_name: "emqx" environment: - EMQX_LOADED_PLUGINS="emqx_management,emqx_auth_http,emqx_dashboard" - EMQX_DASHBOARD__DEFAULT_USER__LOGIN=admin - EMQX_DASHBOARD__DEFAULT_USER__PASSWORD=public - EMQX_NODE__MAX_PORTS=65535 - EMQX_MQTT__MAX_PACKET_SIZE=16MB ports: - "18083:18083" - "1883:1883" - "8080:8081" - "8883:8883" volumes: - ./logs:/opt/emqx/log - /etc/localtime:/etc/localtime restart: always mongodb: image: mongo:5.0.5 volumes: - "/media/hdd/mongo:/data/db" tty: true network_mode: "host" ports: - "27017:27017" environment: - MONGO_INITDB_ROOT_USERNAME=backend - MONGO_INITDB_ROOT_PASSWORD=backend进入容器后 ...

November 30, 2022 · 1 min · jiezi

关于docker-compose:记录一次用dockercompose配置-mysql的过程

本周次要事件都在设计原型或者是设计er图,没有呈现什么技术上的问题。然而本周在学第的发问中却呈现了问题,我原本想间接在学第给的近程代码拉到本地执行来解决问题,然而在运行时呈现了问题,mysql又出问题了。 依据前几次的教训可知最快解决mysql问题的办法就是重新安装mysql,然而如此重复装置配置也会耗费不少工夫,不能总是这样。 于是就尝试用docker-compose来启动mysql。配置的第一部就是间接查看docker的官网文档而不是间接搜寻“怎么用docker-compose来启动mysql“ docker-hub官网网址 关上官网网址点击explore 间接搜寻咱们想要配置的服务 上面就有通过docker-compose启动的教程 之后咱们还能够在这里查看它反对的环境变量 如果我么想要设定数据库数据的存储地位还能够持续查看所给的提醒1阐明我么能够把数据存储在咱们自定义的卷中(如:/my/own/datadir)2.通知了咱们应用的格局(xxx:/var/lib/mysql)所以咱们只需在数据库中如下配置即可 volumes: - ./db:/var/lib/mysql总结通过此次自行配置docker-compose发现docker的确要比间接配置对应服务到本地要不便很多,之前没有把握正确的办法(总是间接搜寻如何用docker-compose配置XXX,而不是间接查看官方网站)导致对docker-compose总是有些冲突,自行按官网配置后才发现docker-compose的不便。

August 29, 2022 · 1 min · jiezi

关于docker-compose:解决-dockercompose-配置postgresql中登陆失败的错误

问题: 运行完docker容器后无奈失常登陆docker-compose: version: '3.1'services: db: image: postgres:12.10 restart: always environment: POSTGRES_USER: druser POSTGRES_PASSWORD: abc123@ POSTGRES_DB: data_recorde volumes: - ./data:/var/lib/postgresql/data ports: - 5432:5432实践上来说运行以上的doccker-compose文件之后就能够间接依据所设置的用户名明码来登陆postgresql,然而尝试了很多此却总是报如下谬误:用户名、明码不匹配,然而在其他人的设施上却没有问题。经查看docker容器也失常启动并且在运行中。起初狐疑是docker版本或是docker-compose的问题,然而通过和别人比对发现版本差距不大,应该不是版本的问题。起初又尝试打印容器运行日志依据报错查问后也没有找到适合的办法。 起初又发现在执行docker-compose时会依据volumes生成对应文件夹,而这个文件夹时用来存储数据库文件的。而咱们登陆认证的角色实践上就存储在数据库中。 所以猜想可能和这个无关,又依据这个关键词进行搜寻发现,docker-compose在执行时会依据volumes(卷)生成相应的文件夹,然而如果对docker-compose进行更改后再从新运行docker-compose并不会同时更新其对应的volumes中的内容,也就是说如果之前曾经用此文件夹进行过初始化,那么更改配置后依然用此文件夹很有可能发生冲突。所以咱们要做的就是 删除`data`文件夹 -> 删除容器 -> 从新运行docker-compose删除容器: sudo docker rm -v 'containerName'-v示意连带其volums同时进行删除 此时再应用用户名明码进行登陆就能够失常登陆了

August 9, 2022 · 1 min · jiezi

关于docker-compose:容器dockercomopse安装案例练习

概述Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。应用 Compose,您能够应用 YAML 文件来配置应用程序的服务。而后,应用单个命令,从配置创立并启动所有服务。简略来说,docker-compose治理运行多docker容器,管制整个docker容器的生命周期。 利用场景docker-compose实用环境: 生产暂存开发测试CI 工作流。生命周期Compose 具备用于管理应用程序整个生命周期的命令: 启动、进行和从新生成服务查看正在运行的服务的状态流式传输正在运行的服务的日志输入在服务上运行一次性命令compose装置官网下载地址 下载 Docker Compose 的以后稳固版本 $ curl -SL https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose*留神:要装置不同版本的 Compose,请替换v2.5.0 为您要应用的 Compose 版本。* 对二进制文件增加可执行权限:$ sudo chmod +x /usr/local/bin/docker-compose测试是否装置实现$ docker-compose --versioncompose卸载删除下载的二进制文件即可 $ rm -rf /usr/local/bin/docker-compose来个案例练习一下!案例练习地址目录抉择:应用 Docker Compose 装置 GitLab 实际效果如图所示:

May 5, 2022 · 1 min · jiezi

关于docker-compose:使用Docker-Compose-Halo-搭建博客

博客搭建应用了Halo开源博客零碎,因为是Java实现的,不便本人做定制,顺便学习源码联合应用Docker Compose实现服务搭建装置docker-composesudo curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose如果呈现网络问题,间接用浏览器下载可执行文件放到/usr/local/bin目录下即可筹备配置文件Nginx配置文件mkdir -p /root/blog/halo && mkdir -p /root/blog/nginx/ \echo 'server { listen 80; server_name blog.demoli.xyz; rewrite ^(.*)$ https://blog.demoli.xyz$1 permanent; } location / { proxy_pass http://halo:8090; proxy_cache_bypass $http_upgrade; # Proxy headers proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; # Proxy timeouts proxy_connect_timeout 600s; proxy_send_timeout 600s; proxy_read_timeout 600s; } }' >> /root/blog/nginx/nginx.conf证书能够从阿里云收费申请,绑定到对应的域名即可,并搁置到/root/blog/nginx/目录下(能够自在批改,留神与下边的yaml文件保持一致即可)Halo配置文件cd /root/blog/halo && wget https://dl.halo.run/config/application-template.yaml -O ./application.yamldocker-compose yaml配置文件version: '3.1'services:nginx: image: nginx container_name: nginx restart: unless-stopped ports: - 443:443 - 80:80 volumes: - /root/blog/nginx/nginx.conf:/etc/nginx/conf.d/blog.conf - /root/blog/nginx/blog.demoli.xyz/:/etc/nginx/ssl/halo: image: halohub/halo container_name: halo restart: unless-stopped volumes: - /root/blog/halo:/root/.halo' >> /root/blog/blog.yaml如果镜像下载迟缓,尝试应用阿里云的镜像加速器配置网络与域名只须要在域名提供商,为本人购买的域名,增加A类型的子域名记录比方blog.demoli.xyz,而后将解析值设置为本人服务器的公网IP即可启动并拜访服务docker-compose -f blog.yaml up -d拜访域名即可更新很简略的步骤:数据备份(重要):cp -r ./halo ./halo.archive关停服务:docker-compose -f blog.yaml down更新镜像:docker pull halohub/halo重启服务:docker-compose -f blog.yaml up -d引入TraefikTraefik是云原生时代与Docker、K8s都能配合应用的新一代网关产品,可应用Traefik代替Nginx,参考Treafik学习的案例篇章补充举荐开启两步验证的登录形式,安全性高一点,能够在用户设置中增加

April 27, 2022 · 1 min · jiezi

关于docker-compose:docker-compose中的两级networks作用

1. 阐明本博客目标:解释 docker compose 两个不同level 的 networks 作用,不便初学者。注: 本文探讨的 Compose file format >= 3.0 2. 定义两级networksversion: "3.9"services: proxy: build: ./proxy networks: ## Service-level networks key - frontend app: build: ./app networks: ## Service-level networks key - frontend - backend db: image: postgres networks: - backendnetworks: ## Top-level networks key frontend: driver: brige backend: # Use a custom driver which takes special options driver: brige3. Top-level networks key3.1 作用指定将要创立的 networks.(The top-level networks key lets you specify networks to be created.)能够指定的networks 信息: driver(比方 bridge, overlay), driver_opts 等 ...

March 14, 2022 · 1 min · jiezi

关于docker-compose:Docker-入门私人笔记十六回顾和总结3-命令-docker-和-dockercompose-的区别

Docker-Compose 我的项目是 Docker 官网的开源我的项目,负责实现对 Docker 容器集群的疾速编排。是 harbor 的默认容器编排工具。 docker 命令能够查看和操作宿主机中所有正在运行的容器;docker-compose 只能看到和操作由它负责管理的正在运行的容器(本次实操中能看到组成 harbor 服务的所有容器。此时还并未向 harbor 提交任何镜像),而看不到也不能操作用 docker 命令部署的容器。例如:后者看不到 mydocker 这个容器: [root@k8s-master /data]# docker start mydockermydocker[root@k8s-master /data]# [root@k8s-master /data]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdfc449918143 goharbor/harbor-jobservice:v1.9.1 "/harbor/harbor_jobs…" 6 hours ago Up 6 hours (healthy) harbor-jobservicec0fbf43a4c94 goharbor/nginx-photon:v1.9.1 "nginx -g 'daemon of…" 6 hours ago Up 6 hours (healthy) 0.0.0.0:80->8080/tcp nginxca2f560f89b0 goharbor/harbor-core:v1.9.1 "/harbor/harbor_core" 6 hours ago Up 6 hours (healthy) harbor-core3d94c08a202e goharbor/harbor-portal:v1.9.1 "nginx -g 'daemon of…" 6 hours ago Up 6 hours (healthy) 8080/tcp harbor-portal67e04d48d8d6 goharbor/redis-photon:v1.9.1 "redis-server /etc/r…" 6 hours ago Up 6 hours (healthy) 6379/tcp redis2d7d3d209834 goharbor/harbor-db:v1.9.1 "/docker-entrypoint.…" 6 hours ago Up 6 hours (healthy) 5432/tcp harbor-db70f5f7392eeb goharbor/registry-photon:v2.7.1-patch-2819-2553-v1.9.1 "/entrypoint.sh /etc…" 6 hours ago Up 5 minutes (healthy) 5000/tcp registryfa8811cc14a3 goharbor/harbor-registryctl:v1.9.1 "/harbor/start.sh" 6 hours ago Up 6 hours (healthy) registryctlcf7b6f399df5 goharbor/harbor-log:v1.9.1 "/bin/sh -c /usr/loc…" 6 hours ago Up 6 hours (healthy) 127.0.0.1:1514->10514/tcp harbor-log2bc93c16c234 centos "/bin/bash" 5 weeks ago Up 10 seconds mydocker[root@k8s-master /data]# [root@k8s-master /data]# docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------harbor-core /harbor/harbor_core Up (healthy) harbor-db /docker-entrypoint.sh Up (healthy) 5432/tcp harbor-jobservice /harbor/harbor_jobservice ... Up (healthy) harbor-log /bin/sh -c /usr/local/bin/ ... Up (healthy) 127.0.0.1:1514->10514/tcpharbor-portal nginx -g daemon off; Up (healthy) 8080/tcp nginx nginx -g daemon off; Up (healthy) 0.0.0.0:80->8080/tcp redis redis-server /etc/redis.conf Up (healthy) 6379/tcp registry /entrypoint.sh /etc/regist ... Up (healthy) 5000/tcp registryctl /harbor/start.sh Up (healthy)[root@k8s-master /data/dockerfile/app/harbor/harbor]# docker-compose stop mydockerERROR: No such service: mydocker[root@k8s-master /data/dockerfile/app/harbor/harbor]# docker-compose stop 2bc93c16c234ERROR: No such service: 2bc93c16c234同理,docker images 和 docker-compose images 命令的区别也相似。 ...

March 10, 2022 · 3 min · jiezi

关于docker-compose:docker-compose

version: "3"networks: overnet: name: overnet attachable: trueservices: jenkins: image: "jenkins/jenkins:2.303.3" restart: always ports: - 8080:8080 networks: - overnet volumes: - /data/jenkins_home:/var/jenkins_home mysql: image: "mysql:5.7.31" restart: always ports: - 3306:3306 networks: - overnet environment: MYSQL_ROOT_PASSWORD: "123456789" command: [ '--character-set-server=utf8mb4', '--collation-server=utf8mb4_general_ci', '--max_connections=3000' ] volumes: - /data/mysql/initdb.d:/docker-entrypoint-initdb.d - /data/mysql/log:/var/log/mysql - /data/mysql/conf:/etc/mysql/conf.d - /data/mysql/data:/var/lib/mysql psql_db: image: "postgres:13-alpine" restart: always ports: - 5432:5432 environment: - POSTGRES_PASSWORD=123456789 networks: - overnet volumes: - /data/postgres/initdb.d:/docker-entrypoint-initdb.d - /data/postgres/postgresql.conf:/etc/postgresql/postgresql.conf - /data/postgres/data:/var/lib/postgresql/data redis: image: redis restart: always ports: - 6379:6379 networks: - overnet volumes: - /data/redis/conf:/etc/redis command: ["redis-server", "/etc/redis/redis.conf"] mongo: image: mongo restart: always ports: - 27017:27017 networks: - overnet volumes: - /data/mongo/db:/data/db nginx: container_name: nginx-master image: nginx restart: always ports: - 80:80 - 443:443 networks: - overnet extra_hosts: - host.docker.internal:192.168.0.16 volumes: - /data/nginx/nginx.conf:/etc/nginx/nginx.conf - /data/nginx/conf.d:/etc/nginx/conf.d - /data/nginx/sites-available:/etc/nginx/sites-available - /data/nginx/sites-enabled:/etc/nginx/sites-enabled - /data/www/serve:/usr/share/nginx/html - /data/nginx/cert:/etc/nginx/certinit 文件/data/mysql/initdb.d/init.sh#!/bin/bashmysql --protocol=socket -uroot -p$MYSQL_ROOT_PASSWORD <<EOSQLCREATE USER 'test'@'%' IDENTIFIED BY '123456';create database test default charset utf8;grant all on *.* to 'test'@'%';flush privileges;EOSQL/data/postgres/initdb.d/init.sh#!/bin/bashset -epsql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL create user test_user with password '123456'; create DATABASE test ENCODING='UTF8' owner test_user; grant all privileges on database test to test_user;EOSQL

January 13, 2022 · 1 min · jiezi

关于docker-compose:dockercompose-入门

docker-compose.yml 文件内容 version: '3.1'services: mysql: restart: always image: mysql container_name: weiwei_mysql ports: - 3307:3306 environment: MYSQL_ROOT_PASSWORD: 123456 TZ: Asia/Shanghai volumes: - /opt/docker_mysql_tomcat/mysql_data:/var/lib/mysql tomcat: restart: always image: tomcat container_name: weiwei_tomcat ports: - 8088:8080 environment: TZ: Asia/Shanghai volumes: - /opt/docker_mysql_tomcat/tomcat_webapps:/usr/local/tomcat/webapps - /opt/docker_mysql_tomcat/tomcat_logs:/usr/local/tomcat/logs创立文件夹:/opt/docker_mysql_tomcat 而后:docker-compose up -d firewall-cmd --zone=public --list-portsfirewall-cmd --zone=public --add-port=8080/tcp —-permanentfirewall-cmd --reload

November 7, 2021 · 1 min · jiezi

关于docker-compose:Docker-Compose-简单使用

Docker Compose 是Docker 官网的开源我的项目, 负责实现对 Docker 容器集群的疾速编排。通过应用一个 docker-compose.yml模板文件来定义一个或者多个容器,满足一个软件应用运行环境。Docker Compose 有三大应用场景 Dockerfile 文件构建容器,定制镜像docker-compose.yml 构建软件环境docker-compose 启动容器装置在window和mac 中,只有装置docker 就会捆绑装置Docker Compose Linux 用户应用以下命令进行装置 sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose对二进制文件可执行权限 sudo chmod +x /usr/local/bin/docker-compose查看是否装置胜利 $ docker-compose versiondocker-compose version 1.29.1, build c34c88b2docker-py version: 5.0.0CPython version: 3.9.0OpenSSL version: OpenSSL 1.1.1g 21 Apr 2020编写docker-compose.ymlversion: "3.9"# 服务 在它上面能够定义利用须要的一些服务,每个服务都有本人的名字、应用的镜像、挂载的数据卷、所属的网络、依赖哪些其余服务等等。services: #服务名称 webapp: # docker 运行在名字,在docker ps -a 看到的名字 container_name: mynginx # 镜像 : 标签 image: nginx:syf # 端口映射 主机端口: 容器端口 ports: - "80:80" # 物理卷挂载 将本地门路挂载到容器内 volumes: - D:/docker-compose/html:/usr/share/nginx/html dns: - 192.168.123.1Compose 有多个版本反对2.x 、3.x,上面提供版本对应docker版本 ...

June 26, 2021 · 1 min · jiezi

dockercompose构建mysql主从复制集群

docker-compose构建mysql主从复制集群docker-compose构建 mysql 主从复制(读写分离)集群 MySQL master-slave replication with using Docker. 源码在github上: https://github.com/docker-box... 运行git clone https://github.com/docker-box/mysql-cluster.gitcd mysql-cluster./build.sh可以在build.sh内自定义对应参数提示: 运行前需要确保安装了docker和docker-compose,具体安装方法请参考官网 如果想手动安装, 则可以按照build.sh内的命令来手动执行即可 测试看看效果给主库创建一个表, 并添加两条数据docker exec mysql_master sh -c "export MYSQL_PWD=111; mysql -u root mydb -e 'create table code(code int); insert into code values (100), (200)'"查看两个从库是否同步了该表以及数据docker exec mysql_slave sh -c "export MYSQL_PWD=111; mysql -u root mydb -e 'select * from code \G'"docker exec mysql_slave2 sh -c "export MYSQL_PWD=111; mysql -u root mydb -e 'select * from code \G'"如果前边的安装正确的话, 就可以看到第一步插入的两条数据了相关命令查看docker-compose运行日志docker-compose logs查看运行的docker容器docker-compose ps查看主库运行状态docker exec mysql_master sh -c 'mysql -u root -p111 -e "SHOW MASTER STATUS \G"'查看从库运行状态docker exec mysql_slave sh -c 'mysql -u root -p111 -e "SHOW SLAVE STATUS \G"'docker exec mysql_slave2 sh -c 'mysql -u root -p111 -e "SHOW SLAVE STATUS \G"'进入主库docker exec -it mysql_master bash进入从库docker exec -it mysql_slave bashdocker exec -it mysql_slave2 bash

November 5, 2019 · 1 min · jiezi

Verdaccio-使用-Docker-安装及迁移教程

前言Verdaccio 是一个 npm 私有源,代码在 GitHub 开源,公司由于业务需要使用也有一段时间,非常稳定,社区也很活跃。入门可以看我之前写的一篇文章: npm私服安装教程 - verdaccio 入门 前一段时间由于所在服务器升级,顺便更新了下 Verdaccio 版本,并将之前的数据都迁移过来。由于公司服务器上有 docker,所以就使用 docker 来安装。 安装下载镜像先下载最新的 Verdaccio 镜像,使用官方的 docker 镜像 docker pull verdaccio/verdaccio上面命令拉取的即是 latest 的镜像 启动前配置如果没有安装 docker-compose,可以看文末链接。 在工作目录新建文件夹 npm,然后新建 docker-compose.yml 文件 mkdir npm && touch npm/docker-compose.yml然后将以下配置粘贴到 docker-compose.yml 文件中: version: '3.4'services: verdaccio: image: verdaccio/verdaccio container_name: "verdaccio" networks: - node-network environment: - VERDACCIO_PORT=4873 ports: - "4873:4873" volumes: - "./storage:/verdaccio/storage" - "./config:/verdaccio/conf" - "./plugins:/verdaccio/plugins"networks: node-network: driver: bridge上面配置即使用了刚才下载的 verdaccio 镜像,容器和宿主机都绑定在 4873 端口。同时挂载了当前目录的 storage,config, plugins 文件夹到容器内部。 ...

October 14, 2019 · 2 min · jiezi

使用docker从零开始搭建私人代码仓库之gogs搭建

docker搭建gogs教程上一篇教程《使用docker从零开始搭建私人代码仓库之MySQL搭建》已经搭建好了MySQL,也是搭建gogs代码仓库的前置准备。今天我们来用docker搭建gogs代码仓库的教程。添加gogs容器打开上一个教程中的docker-compose.yml文件,填入如下内容: gogs: image: gogs/gogs depends_on: - mysql tty: true networks: frontend: restart: always volumes: - ${DATA_DIR}/gogs:/data最终docker-compose.yml文件内容如下: version: "3"networks: frontend:services: mysql: image: mysql:${MYSQL_VERSION} networks: frontend: tty: true restart: always ports: - 3306:3306 volumes: - ${DATA_DIR}/mysql/:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - MYSQL_USER=${MYSQL_USER} - MYSQL_PASSWORD=${MYSQL_PASSWORD} gogs: image: gogs/gogs depends_on: - mysql tty: true networks: frontend: restart: always volumes: - ${DATA_DIR}/gogs:/data启动gogs容器> docker-compose up -d gogs 看到该界面时候证明gogs已经成功启动。下一个教程我们通过nginx转发请求到gogs容器,实现可以通过域名访问代码仓库。 更多精彩文章,请关注我的博客SOCKSTACK,分享我的工作经验。

October 9, 2019 · 1 min · jiezi

使用docker从零开始搭建私人代码仓库之mysql搭建

docker搭建MySQL教程本教程非零基础教程,本教程不需要你具备docker和docker-compose基本知识,照葫芦画瓢也能把代码仓库搭建起来使用,但如果对docker和docker-compose感兴趣的可以在网上找一下相关的教程学习,后面也会出一个简单的docker入门教程,前提是机器必须先安装好了docker和docker-compose。本教程搭建mysql数据是为了搭建代码仓库gogs做准备的,这里不对mysql做过多的解析,做开发的都知道MySQL是干嘛用的。 MySQL搭建创建项目1.命令行输入以下命令创建项目: > mkdir docker注意:该命令只在类unix系统生效的,window系统的可以使用makedir docker或者手动创建 2.进入项目目录并创建docker-compose.yml文件: > cd docker && touch docker-compose.yml注意:该命令只在类unix系统生效的,window系统的可以使用type null>docker-compose.yml或者手动创建 3.编辑docker-compose.yml: > vim docker-compose.yml添加mysql的编排内容: version: "3"networks: frontend:services: mysql: image: mysql:${MYSQL_VERSION} networks: frontend: tty: true restart: always ports: - 3306:3306 volumes: - ${DATA_DIR}/mysql/:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - MYSQL_USER=${MYSQL_USER} - MYSQL_PASSWORD=${MYSQL_PASSWORD}编排内容中的DATA_DIR、MYSQL_ROOT_PASSWORD、MYSQL_USER、MYSQL_PASSWORD是环境变量,我们可以项目的根目录创建.env文件: > vim .env在.env中定义环境变量: #容器映射数据存储的路径DATA_DIR=./data#mysql相关环境变量的定义MYSQL_VERSION=5.7 #mysql数据库的版本MYSQL_ROOT_PASSWORD=root # root账户的密码MYSQL_USER=default # 创建一个default用户MYSQL_PASSWORD=secret # default用的密码mysql的编排内容就绪完毕。 4.启动MySQL > docker-compose up -d mysql如果是第一次启动会进行build构建进行,等待构建完成后,MySQL容器就启动成功了。 测试MySQL这里使用navicat进行测试的,添加MySQL链接,然后填入主机,端口,账号,密码,点击链接测试。 出现该界面证明MySQL搭建成功。 更多精彩文章,请关注我的博客SOCKSTACK,分享我的工作经验。

October 9, 2019 · 1 min · jiezi

使用docker从零开始搭建私人代码仓库之nginx搭建

docker搭建nginx教程通过《使用docker从零开始搭建私人代码仓库之MySQL搭建》和《使用docker从零开始搭建私人代码仓库之gogs搭建》的搭建其实已经可以搭建成功了代码仓库的了,但是为了访问方便,我们有时候需要绑定域名,那么我们可以通过nginx进行转发。添加nginx容器打开上一个教程中的docker-compose.yml文件,填入如下内容: gogs_nginx: build: context: nginx tty: true depends_on: - gogs restart: always networks: frontend: ports: - 80:80 volumes: - ./nginx/conf:/etc/nginx/conf.d - ${DATA_DIR}/nginx/conf:/var/log/nginx最终docker-compose.yml文件内容如下: version: "3"networks: frontend:services: mysql: image: mysql:${MYSQL_VERSION} networks: frontend: tty: true restart: always ports: - 3306:3306 volumes: - ${DATA_DIR}/mysql/:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - MYSQL_USER=${MYSQL_USER} - MYSQL_PASSWORD=${MYSQL_PASSWORD} gogs: image: gogs/gogs depends_on: - mysql tty: true networks: frontend: restart: always volumes: - ${DATA_DIR}/gogs:/data gogs_nginx: build: context: nginx tty: true depends_on: - gogs restart: always networks: frontend: ports: - 80:80 volumes: - ./nginx_conf:/etc/nginx/conf.d - ${DATA_DIR}/nginx/conf:/var/log/nginx在项目根目录创建nginx_conf目录并创建nginx的配置文件default.conf ...

October 9, 2019 · 1 min · jiezi

docker从入门到实战实战篇

docker从入门到实战-实战篇前言本文是我通过三个星期业余时间学习后而写的文章,对docker的了解还处于入门阶段。希望本文能帮忙一些想学习docker的朋友快速入门。练习及实战代码都在github仓库中。如果我的文章能帮助到你的话,可以给我的docker项目点个赞哦 docker实战本次实战案例是todolist。技术栈为vue、node、mysql。具体代码见项目目录todolist,下面就不一一贴代码了。就讲下重点。 下面我就顺着依赖关系来讲,所以先从mysql开始讲起 构建mysql执行:docker run --name mymysql -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql --name 给mysql容器设置匿名-d表示后台运行-p表示将容器的3306端口的映射到本地的3308端口,如果不设置的话,本地是无法访问该MySQL服务的。-e MYSQL_ROOT_PASSWORD 设置root的账号密码。mysql 后面不指定版本话,默认会latest版本在执行该语句之前,假如你之前没有pull过mysql镜像。docker在本地找不到你要的镜像就会帮你从docker仓库拉取mysql:latest镜像。 这个时候容器就启动成功了。 尝试下用navicat连接下试试 鼠标放入黄色小三角出现如下报错。 2013 - Lost connection to MySQL server at 'reading initial communication packet', system error: 0 "Internal error/check (Not system error)"这是因为mysql8以上,都会使用新的验证方式。 不妨查下信息: select host,user,plugin,authentication_string from mysql.user; mysql> select host,user,plugin,authentication_string from mysql.user;+-----------+------------------+-----------------------+------------------------------------------------------------------------+| host | user | plugin | authentication_string |+-----------+------------------+-----------------------+------------------------------------------------------------------------+| % | root | caching_sha2_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 || localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED || localhost | mysql.session | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED || localhost | mysql.sys | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |)7k44VulAglQJgGpvgSG.ylA/rdbkqWjiqQJiq3DGsug5HIy3 |ord | $A$005$0pU+sGm[on+-----------+------------------+-----------------------+------------------------------------------------------------------------+plugin一栏可看到都是caching_sha2_password。 ...

July 7, 2019 · 3 min · jiezi

docker从入门到实战基础篇

docker从入门到实战-基础篇docker基础前言本文是我通过三个星期业余时间学习后而写的文章,对docker的了解还处于入门阶段。希望本文能帮忙一些想学习docker的朋友快速入门。练习及实战代码都在github仓库中。如果我的文章能帮助到你的话,可以给我的docker项目点个赞哦 介绍docker是一个开源的应用容器引擎,开发者可以打包自己的应用到容器里面,然后迁移到其他机器的docker应用中,可以实现快速部署。如果出现的故障,可以通过镜像,快速恢复服务。 举个例子,公司一般都会有多套环境,那么如何保持多套的运行环境一致,这个时候就可以用到docker。且当要求增加一套环境的时候,你无需在一个新服务器上一个个环境安装、配置。只需要运行下docker。同时官方还提供了Docker Hub,拥有大量的高质量的官方镜像。你可以将自己的镜像上传上去。有点类似于github。 安装官方提供了安装教程,挺详细的。官方安装教程 docker起步第一步:执行下docker -v确认下是否成功安装了docker 如果成功安装了,命令行将会输出入docker的版本号。如下:Docker version 18.09.2, build 6247962 docker的整个生命周期大致可分为: 镜像容器仓库这里以ubuntu镜像为例,介绍下镜像 在下载ubuntu镜像之前运行下docker images(查看镜像命令)查看下本地的镜像。如果你还没下载过镜像的话,当然会出现空。这里贴下我本地的镜像 ➜ study-docker git:(master) ✗ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEtodolist_static latest de5e325037e9 2 hours ago 1.05GBtodolist_nodejs latest 53efd80e03e1 2 hours ago 898MBubuntu 18.04 7698f282e524 4 weeks ago 69.9MBmysql latest 990386cbd5c0 5 weeks ago 443MBnode 8 a5c31320f223 6 weeks ago 895MBmysql 5.6 73829d7b6139 6 weeks ago 256MB使用拉取镜像命令docker pull 拉取ubuntu镜像:docker pull ubuntu。当你不指定版本时,默认拉取latest版本。 ...

July 7, 2019 · 2 min · jiezi

linux安装docker-compose

当编写好docker-compose.yml,运行docker-compose up命令时,可能会报如下错误 docker-compose: line 1: {error:Not Found}: command not found这种情况是因为尚未安装docker compose对缘故。可以根据下面命令进行手动安装。 sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose具体细节可以参考官网文档。

June 26, 2019 · 1 min · jiezi

Docker学习之Compose介绍6

Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。其代码目前在 https://github.com/docker/com... 上开源。介绍Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and runningmulti-container Docker applications)」。 我们知道通过Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。 Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。 Compose 中有两个重要的概念: 服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。项目 ( project ):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml 文件中定义。Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。 Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用Compose 来进行编排管理。 安装与卸载Compose 支持 Linux、macOS、Windows 10 三大平台。Compose 可以通过 Python 的包管理工具 pip 进行安装,也可以直接下载编译好的二进制文件使用,甚至能够直接在 Docker 容器中运行。前两种方式是传统方式,适合本地环境下安装使用;最后一种方式则不破坏系统环境,更适合云计算场景。 接下来看看在Linux系统上的安装。 二进制包的安装在 Linux 上的也安装十分简单,从 官方 Github Realease 处直接下载编译好的二进制文件即可。比如64为的linux下可以通过如下命令进行安装: ...

June 21, 2019 · 1 min · jiezi

DevOps-基于Walle的小型持续集成实战五基于Walle发布Java应用

本章用于讲解如何在walle下构建和运行JavaWeb。主要包含SpringBoot,ScalaAkkaWeb应用,以Java -jar和Docker运行两种方式(Tomcat方式不讲,大家自行研究)新建项目项目中心 > 项目管理 > 新建项目以下是一份配置好的项目表 分组项目参考备注基本配置项目名称dev-我的JavaDemo项目随便填写,名称不要太长(不好看),最好把环境卸载最前,例如dev(开发环境)基本配置环境开发环境提前在环境管理配置好即可基本配置Git Repogit@gitlab.xxx.com:xxx/java-demo.gitGit仓库地址目标集群目标集群192.168.0.122提前配置服务器管理目标集群目标集群部署路径/data/walle-build/java-demo实际运行的环境目标集群目标集群部署仓库/data/walle-run会存放多个版本编译后的项目目标集群目标集群部署仓库版本保留数5可以回滚的版本数配置脚本Java生态下基本脚本大致一致,无细微差别 基本脚本任务配置 - 部署包含文件包含方式 docker-compose.ymltarget/${SERVER_NAME}.jar该方式用于描述从源码包到发布包中,排除/包含的内容。一般java使用target即可 任务配置 - 自定义全局变量# 运行目录JAVA_HOME=/data/walle-javaRUN_ROOT=/data/walle-runSERVER_NAME=java-demoMVN_HOME=/usr/local/maven3PORT=2223【SpringBoot to Docker】任务配置 - 高级任务-Deploy前置任务pwd/usr/local/maven3//bin/mvn -v任务配置 - 高级任务-Deploy后置任务${MVN_HOME}/bin/mvn clean compile package -Dmaven.test.skip=true -DartifactId=${SERVER_NAME}# cp target/${SERVER_NAME}.jar .sed -i 's/${container_port}/'${PORT}'/g' docker-compose.yml sed -i 's/${container_name}/'${SERVER_NAME}'/g' docker-compose.yml 任务配置 - 高级任务-Release前置任务docker-compose -p ${SERVER_NAME} -f ${WEBROOT}/docker-compose.yml down || echo "服务不存在"docker stop ${SERVER_NAME} || echo "服务不存在"docker rm ${SERVER_NAME} || echo "服务不存在"rm -rf ${WEBROOT}任务配置 - 高级任务-Release后置任务docker-compose -p ${SERVER_NAME} up -decho "服务启动完成"项目 - Maven pom.xml配置<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <build> <finalName>${artifactId}</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.walle.main.DevelopToolApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> </execution> </executions> <configuration> <includeScope>system</includeScope> </configuration> </plugin> </plugins> </build></project>此处配置了finalName=${artifactId},用于可自定义生成的包名称此处使用了org.springframework.boot进行打包,mainClass设置执行的main方法项目 - docker-compose.yml配置version: '2'services: web: # 镜像:版本 image: openjdk:8-jdk container_name: ${container_name} ports: - "${container_port}:${container_port}" volumes: - ./target/${container_name}.jar:/usr/local/${container_name}.jar - /etc/localtime:/etc/localtime command: /bin/bash -c "echo "Asia/Shanghai" > /etc/timezone && java -Dserver.port=${container_port} -jar /usr/local/${container_name}.jar"映射宿主机./target下的文件${container_name}.jar,到/usr/local/${container_name}.jar映射宿主机的时区到容器启动命令设置时区到上海,随后调用启动参数java -jar,此处可以设置更多的启动参数此处的参数传递方式较差(linux变量替换),可以寻求更好的参数传递方式【ScalaAkka to Docker】任务配置 - 高级任务-Deploy前置任务pwd/usr/local/maven3//bin/mvn -v任务配置 - 高级任务-Deploy后置任务${MVN_HOME}/bin/mvn clean scala:compile compile package -Dmaven.test.skip=true -DartifactId=${SERVER_NAME}# cp target/${SERVER_NAME}.jar .sed -i 's/${container_host}/'${HOST}'/g' docker-compose.yml sed -i 's/${container_port}/'${PORT}'/g' docker-compose.yml sed -i 's/${container_name}/'${SERVER_NAME}'/g' docker-compose.yml 任务配置 - 高级任务-Release前置任务docker-compose -p ${SERVER_NAME} -f ${WEBROOT}/docker-compose.yml down || echo "服务不存在"docker stop ${SERVER_NAME} || echo "服务不存在"docker rm ${SERVER_NAME} || echo "服务不存在"rm -rf ${WEBROOT}任务配置 - 高级任务-Release后置任务docker-compose -p ${SERVER_NAME} up -decho "服务启动完成"项目 - Maven pom.xml配置<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <build> <finalName>${artifactId}</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.walle.main.DevelopToolApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-shade-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>allinone</shadedClassifierName> <artifactSet> <includes> <include>*:*</include> </includes> </artifactSet> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>reference.conf</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>com.main.Boot</Main-Class> </manifestEntries> </transformer> </transformers> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> </execution> </executions> <configuration> <includeScope>system</includeScope> </configuration> </plugin> </plugins> </build></project>如为SpringBoot混合编译,则单独加上scala编译即可 ...

June 17, 2019 · 3 min · jiezi

DevOps-基于Walle的小型持续集成实战四搭建Walle

上篇文章中,讲到了如何搭建docker下的服务mysql,gitlab,nexus。其他例如npm/maven/java环境安装则不再讲解。本篇会开始正式使用Walle作为持续集成方案,进行小型服务的快速构建发布。Walle官网:http://www.walle-web.io/ 基本概述walle 让用户代码发布终于可以不只能选择 jenkins!支持各种web代码发布,php、java、python、go等代码的发布、回滚可以通过web来一键完成。walle 一个可自由配置项目,更人性化,高颜值,支持git、多用户、多语言、多项目、多环境同时部署的开源上线部署系统。宿主机、目标机群、操作用户 权限模型 信任关系 构建流程 Docker安装WalleDocker安装Centos系统 sudo yum install -y yum-utils device-mapper-persistent-data lvm2sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.reposudo yum install docker-ce -ysudo systemctl enable dockersudo systemctl start dockerMac系统 https://docs.docker.com/docke... Windowshttps://docs.docker.com/docke... Python安装请安装至少版本2.7.15及以上,版本3以下。(推荐2.7.15,不然会出现各种莫名其妙的问题,官方未解释原因) Docker-compose 安装pip install docker-compose -i https://mirrors.aliyun.com/pypi/simple/ 如果pip不存在,可以尝试 sudo yum install python-pip sudo pip install --upgrade pip创建Walle容器编排配置编辑mysql配置文件:cd ${walle运行目录} && vim docker-compose.yml # Set MySQL/Rails environmentMYSQL_USER=rootMYSQL_PASSWORD=walleMYSQL_DATABASE=walleMYSQL_ROOT_PASSWORD=walleMYSQL_HOST=dbMYSQL_PORT=3306编辑docker-compose walle配置文件:vim docker-compose.yml # docker version: 18.06.0+# docker-compose version: 1.23.2+# OpenSSL version: OpenSSL 1.1.0hversion: "3.7"services: web: image: alenx/walle-web:2.1 container_name: walle-nginx hostname: nginx-web ports: # 如果宿主机80端口被占用,可自行修改为其他port(>=1024) # 0.0.0.0:要绑定的宿主机端口:docker容器内端口80 - "80:80" depends_on: - python networks: - walle-net restart: always python: image: alenx/walle-python:2.1 container_name: walle-python hostname: walle-python env_file: # walle.env需和docker-compose在同级目录 - ./walle.env command: bash -c "cd /opt/walle_home/ && /bin/bash admin.sh migration && python waller.py" expose: - "5000" volumes: - /opt/walle_home/plugins/:/opt/walle_home/plugins/ - /opt/walle_home/codebase/:/opt/walle_home/codebase/ - /opt/walle_home/logs/:/opt/walle_home/logs/ - /root/.ssh:/root/.ssh/ depends_on: - db networks: - walle-net restart: always db: image: mysql container_name: walle-mysql hostname: walle-mysql env_file: - ./walle.env command: [ '--default-authentication-plugin=mysql_native_password', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci'] ports: - "3306:3306" expose: - "3306" volumes: - /data/walle/mysql:/var/lib/mysql networks: - walle-net restart: alwaysnetworks: walle-net: driver: bridgedocker-compose概要参考文章:https://blog.csdn.net/u011781...以上配置文件有以下几个特点: ...

June 17, 2019 · 1 min · jiezi

DevOps-基于Walle的小型持续集成实战一概述

该文章用于概述一个小型持续集成环境的搭建的方案什么是持续集成?持续集成作为当今软件开发实践,可以简单理解为团队开发相对频繁的集成他们的工作,一般让每个成员每天至少集成一次,而这回造成每天会有多次的版本发布。于是我们需要应用到自动化的构建模式(编译发布到测试监控),从而尽早的发现集成中的错误。 持续集成流程常用生态仓库管理 Git 代码仓库(Gitlab,Gitee)Nexus 包私服库构建工具 Jenkins 热门-构建发布工具Ansible 配置管理工具Walle 构建发布工具运行环境 Linux 系统Docker 容器Nginx 负载均衡域名解析构建环境 mavennodejspythonjava经典流程手工发布 - Java SpringBoot应用到一台服务器特征:一个环境,一台服务,少量应用 1、Maven打包 mvn clean compile package -Dmaven.test.skip=true2、放到服务器 scp -r xxx.jar username@192.168.0.1:/data/app/ or FTP工具3、登录服务器 ssh root@192.168.0.14、停用旧应用 ps -ef | grep java -> kill -9 xxxx4、启用新应用 nohup java -server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -jar /data/app/xxx.jar > /data/app/xxx.log 2>&1 &手工发布 - React-Antdpro 应用到一台服务器特征:一个环境,一台服务,少量应用 1、Npm打包器 npm run build2、放到服务器 本地压缩dist.rar -> scp -r dist.rar username@192.168.0.1:/data/nginx/ or FTP工具 -> 解压内容3、登录服务器 ssh root@192.168.0.14、停用旧应用5、启动新应用 https://segmentfault.com/a/11...延伸问题⚠️ 在低频次小规模更新下,该方案可以在用最少的资源和适度的时间花费上得到平衡。如果出现 多人协作,发布频繁,多台服务,多套环境我们该如何管理这些内容?多人协作,如何代码管理?以及相关依赖引用?以下方案供选择,解决代码管理问题(他们比svn拥有更灵活更开放的管理手段)Gitlab 公网 / 私服Gitee 国内较好的代码仓库管理服务Githubhttps://git-scm.com/ ...

June 14, 2019 · 1 min · jiezi

docker-搭建lnmp环境

使用docker搭建项目创建项目目录 mkdir php创建如下项目结构sites 目录放置项目文件services 目录放置服务相关配置script 放置自定义脚本├── Readme.md├── docker-compose.yml├── script├── services│   ├── mariadb│   │   └── Dockerfile│   ├── nginx│   │   ├── Dockerfile│   │   ├── conf.d│   │   │   └── default.conf│   │   └── nginx.conf│   ├── php│   │   └── Dockerfile│   └── redis│   └── Dockerfile└── sites ├── index.html └── index.php8 directories, 10 files编辑docker-compose文件version: "3"services: php: build: ./services/php # ports: # - "9001:9000" container_name: lnmp-php restart: always volumes: - ./sites:/www networks: lnmp_net: ipv4_address: 101.11.11.10 nginx: build: ./services/nginx ports: - "81:80" - "444:443" container_name: lnmp-nginx restart: always volumes: - ./sites:/www - ./services/nginx/nginx.conf:/etc/nginx/nginx.conf - ./services/nginx/conf.d:/etc/nginx/conf.d:rw networks: lnmp_net: ipv4_address: 101.11.11.11networks: lnmp_net: driver: bridge ipam: config: - subnet: 101.11.11.0/20编辑services/nginx文件FROM nginx:1.17.0-alpine# 更新安装源RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories# 设置时区为上海RUN apk update && apk add --upgrade \ && apk add tzdata \ && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone \ && apk del tzdata编辑services/php文件FROM php:7.3.6-fpm-alpine3.9# 更新安装源RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories# 设置时区为上海RUN apk update && apk add --no-cache tzdata autoconf gcc g++ make zlib-dev curl-dev\ && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone \ && apk del tzdata \ && docker-php-ext-install mysqli pdo_mysql opcache \ && pecl install grpc protobuf xdebug yaf yar swoole \ && docker-php-ext-enable xdebug yaf yar swoole grpc protobuf 以上我们的lnmp环境基本搭建完毕,下面我们针对Php解析做相关的配置修改services/nginx/nginx.conf,可根据需求自行修改user nginx;worker_processes auto;error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;events { worker_connections 1024;}http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf;}修改services/nginx/conf.d目录下文件该目录是各个项目的配置文件,可根据需求配置单个或多个服务server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; #root /usr/share/nginx/html; root /www; index index.php index.html index.htm; #error_page 404 /404.html; # 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; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { # root html; fastcgi_pass 101.11.11.10:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #}}启动服务cd php && docker-compose up --build -d 上述的步骤根据网速的docker的配置执行时间个不相同,因为php中编译了些许扩展,也可根据自身需求做响应的删减通过浏览器访问http://127.0.0.1:81,如果看到了phpinfo的输出信息,那么恭喜你,你的lnmp环境已经部署完成

June 9, 2019 · 2 min · jiezi

5Compose编排nginxphp

上一篇的手工操作多容器运行nginx+php,很麻烦,该怎么办?Docker Compose 跟上先删掉上篇创建的容器和网络,如若不然,完成本章会产生冲突 docker stop nginxdocker stop fpm docker network rm lnmp先将上节手工运行的nginx容器命令拿过来作为编写docker-compose.yml文件的参考: docker run -d --network lnmp --ip 192.169.0.3 --link fpm:php --name nginx --rm -p 80:80 -v ~/www:/usr/share/nginx/html -v ~/nginx.conf:/etc/nginx/nginx.conf nginx:1.15.0-alpine继续编辑前面章节创建的 mycompose/docker-compose.yml文件 version: "3"services: fpm: container_name: fpm image: "php:7.1-fpm-alpine3.8" volumes: - ~/www:/php networks: lamp: ipv4_address: 192.158.0.2 httpd: container_name: httpd image: "httpd:2.4-alpine" ports: - 8080:80 links: - fpm:php volumes: - ~/www:/usr/local/apache2/htdocs - ~/httpd.conf:/usr/local/apache2/conf/httpd.conf networks: lamp: ipv4_address: 192.158.0.3 nginx: container_name: nginx image: "nginx:1.15.0-alpine" ports: - 8081:80 links: - fpm:php volumes: - ~/www:/usr/share/nginx/html - ~/nginx.conf:/etc/nginx/nginx.conf networks: lamp: ipv4_address: 192.158.0.4networks: lamp: driver: bridge ipam: config: - subnet: 192.158.0.0/16docker-compose启动项目 ...

May 21, 2019 · 1 min · jiezi

如何使用docker和dockercompose在EOS本地Testnet上开发

EOS区块链的开发并不是立竿见影的,因为需要一些非显而易见的组件,需要对它们进行配置和协同工作。 nodeos:块生成器守护程序。keosd:钱包守护进程,存储私钥。eosio-cpp:智能合约编译器。eosio.token:平台的参考标记。cleos:用于与EOS区块链远程交互的CLI。scatter:为本地Testnet配置的EOS钱包。 我将学到什么?如何运行和初始化EOS本地Testnet。如何编译和运行EOS智能合约。如何通过cleos进行EOS交易。要求要学习本教程,你需要使用下面的软件: Ubuntu Linux(推荐)docker/docker-compose困难程度中间教程内容Dockerfile(你需要的软件)docker-compose.yml(该软件应该如何运行)cleos,命令行EOS钱包。部署eosio.token,即EOS货币系统智能合约。Dockerfile(你需要的软件)。你可以直接在Linux操作系统上安装以下组件,但这样可以使你的开发环境更加干净,更易于维护和测试。 以下所有文件均为官方文件,并由EOSIO发布: FROM ubuntu:18.04RUN apt-get update && apt-get install -y curl libicu60 libusb-1.0-0 libcurl3-gnutlsRUN curl -LO https://github.com/EOSIO/eos/releases/download/v1.7.0/eosio_1.7.0-1-ubuntu-18.04_amd64.deb \ && dpkg -i eosio_1.7.0-1-ubuntu-18.04_amd64.debRUN curl -LO https://github.com/EOSIO/eosio.cdt/releases/download/v1.6.1/eosio.cdt_1.6.1-1_amd64.deb \ && dpkg -i eosio.cdt_1.6.1-1_amd64.debRUN curl -LO https://github.com/EOSIO/eosio.cdt/archive/v1.6.1.tar.gz && tar -xvzf v1.6.1.tar.gz --one-top-level=eosio.cdt --strip-components 1RUN cd /eosio.cdt/ && curl -LO https://github.com/EOSIO/eosio.contracts/archive/v1.6.0-rc3.tar.gz && tar -xvzf v1.6.0-rc3.tar.gz --one-top-level=eosio.contracts --strip-components 1你可以使用以下命令生成打包的镜像沙箱: docker build -t my/eos .docker-compose.yml(该软件应该如何运行)正如我所说,需要一些配置来互相讨论所需的所有部分。 default.wallet是一个预配置的钱包,带有用于测试的私钥。config.ini是Block Producer(BP)的文件,在EOS Mainnet中你不会/不能改变它。version: '3'services: nodeos: container_name: nodeos image: my/eos command: nodeos -e -p eosio --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin --plugin eosio::http_plugin --http-server-address=0.0.0.0:8888 --access-control-allow-origin=* --contracts-console --http-validate-host=false --filter-on="*" stop_grace_period: 3m0s volumes: - ./:/eosio.cdt/contract - ./config.ini:/root/.local/share/eosio/nodeos/config/config.ini ports: - '8888:8888' - '9830:9876' depends_on: - keosd keosd: container_name: keosd hostname: keosd image: my/eos command: keosd --http-server-address=0.0.0.0:8901 --http-validate-host 0 --verbose-http-errors --unlock-timeout=9999999 volumes: - ./default.wallet:/root/eosio-wallet/default.wallet expose: - 8901 ports: - '8901:8901'运行在新终端中运行以下命令: ...

May 14, 2019 · 2 min · jiezi

基于-Docker-GogsJenkinsKubernetes-实践工程源代码的自动构建和持续集成与部署交付

本期目标 : 基于 Centos 7.6 , 封装出一个可用于运行 php 项目的开箱即用镜像本文不讨论 dockerfile 语法 , 并且假设你懂得基本的类unix 操作系统常识并拥有类unix 运行环境 (包括但不限于安装了mac 或 linux 的实体机 , 类unix虚拟机 , 安装了 MinGW 或 CygWin 的 windows 机器) , 并且认为你懂得基本的 docker 操作和有一定的 dockerfile 阅读能力准备工作建立工作目录 mkdir ~/docker-learncd ~/docker-learn创建Dockerfile touch Dockerfile然后拷贝你常用的 nginx.conf 到工作目录 cp xxx/nginx.conf nginx.conf封装基础镜像编辑我们创建好的 Dockerfile 基础内容声明本镜像继承自 centos 最新版 FROM centos安装 nginx创建nginx源文件 由于 centos 仓库里是没有 nginx 的 , 所以我们要自力更新添加nginx的源到 docker 里复制 nginx.org 里关于 RHEL 源的内容到 nginx.repo 文件也可以本地执行以下命令创建 nginx.repo ...

April 25, 2019 · 4 min · jiezi

Docker-之-ubuntu-安装

Docker 作为一种新兴的虚拟化方式,Docker 跟传统的虚拟机方式相比具有众多的优势。Docker 可以更高效的利用系统资源、更快速的启动时间、一致的运行环境、持续交付和部署、更轻松的迁移、更轻松的维护和扩展。 博主第一次使用Docker就深深喜欢上了这种方式,一次配置,到处运行,不用再反反复复的配置环境可以说是非常的方便了。本篇博客就来说一说Docker的安装及基本使用方法,后续还会不定时的更新Docker系列博客。 对比传统虚拟机Docker是什么?Docker属于容器的一种技术封装,提供更为简单易用的使用接口,让开发运维人员可以更方便快捷的使用容器。 特性容器虚拟机启动秒级分钟级硬盘使用一般为 MB一般为 GB性能接近原生弱于系统支持量单机支持上千个容器一般几十个从上面对比来看,容器的各方面性能及特性是优于虚拟机的。 Docker 的安装Docker是一个开放源码的产品,分为 社区版(Community Edition,缩写为 CE)和 企业版(Enterprise Edition,缩写为 EE)。社区版是免费的,而企业版包含一些收费服务,一般来说个人开发者用社区版就足够了,本篇博文的教程也只是针对社区版。 安装环境及版本: 系统:ubuntu 18.04 LTSDocker 版本:18.9.05英文好的小伙伴也可以直接阅读官方文档,本文只详细介绍 Ubuntu 系统下的 Docker 安装,其他系统的安装请自行参考官方文档。 MacWindowsCentOSDebianFedoraUbuntu其他Linux版本卸载老版本一般来说Ubuntu系统中默认是不会安装Docker的,但是如果安装了老版本的话可以使用下面的命令进行卸载。 $ sudo apt-get remove docker docker-engine docker.io containerd runc安装 Docker CE安装Docker CE有多种不同的方式: 设置Docker的存储库,然后安装。这种方式便于安装及更新,也是最推荐的方式。下载DEB软件包,手动安装并完全手动管理升级。在测试和开发环境中,部分用户选择使用自动便捷脚本来安装Docker。本篇博客将介绍第一种安装方式。 设置 Docker 存储库 更新apt包索引:$ sudo apt-get update允许apt通过HTTPS使用存储库来安装软件:$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common添加Docker官方 GPG 密钥:$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -添加完成之后,使用下面命令进行验证秘钥,通过搜索指纹的最后8个字符,验证现在是否具有指纹9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88的密钥 ...

April 25, 2019 · 2 min · jiezi

Docker 使用简介

Docker 是使用 GoLang 开发的开源容器引擎,可以方便的打包开发好的应用,然后分发到任意 linux 主机上。 与传统的虚拟机相比拥有以下优势: 高效的系统资源利用率由于不需要进行硬件虚拟和运行完整的操作系统等额外开销,无论是应用执行速度、内存损耗或者文件存储速度, Docker 都更加高效 更快的启动速度Docker 容器应用直接运行与宿主内核,无需启动完整的操作系统,可以做到秒级启动 一致的运行环境Docker 镜像提供了除内核外的完整运行环境,确保了应用运行环境的一致性 持续交付和部署可以通过 Docker 镜像来实现服务的持续交付、部署。使用 Dockerfile 来构建镜像,使用持续集成系统进行集成测试;使用镜像结合持续部署系统进行自动部署 迁移轻松只需要迁移镜像及镜像运行的数据就可在其他主机或平台运行 易于维护和扩展由于使用镜像进行部署,使维护更为容易。由于支持在镜像的基础上进行定制,使得扩展变得更简单。而官方也维护了一大批高质量的镜像,大大降低了镜像的制作成本 基本概念仓库Docker 提供了仓库(Repository)用于存放制作好的镜像,方便使用者获取,在本地可通知配置多个 Repository 。 拉取可以使用命令来拉取镜像: docker pull [repo url>/]image name> 默认的 repo url 是 hub.docker.com ,拉取默认仓库中的镜像时是不需要 url 的。如拉取 debian : docker pull debian 。 推送我们也可将自己制作好的镜像推送到仓库,以便分发,使用命令: docker push [<repo url>/]<image name>[:<image tag>> 搜索使用 docker search 命令则可搜索默认 repo url 内的镜像。 镜像加速 由于默认 repo url 在国外,为了加快拉取速度,需要指定其为国内的,向 /etc/docker/daemon.json 中添加: { "registry-mirrors": ["https://registry.docker-cn.com"]}便可使用 Docker 在中国的镜像加速站。 ...

April 21, 2019 · 2 min · jiezi

Docker容器化从零开始搭建Spring Cloud微服务系统:安装docker-compose

前言在没有docker-compose之前,我们创建和启动一个容器方式如下:1.通过类似下面两种方式的命令来构建或者拉取一个docker镜像。方式1:创建Dockerfile文件来构建镜像(命令最后的点别漏了~):docker build -t registry.cn-beijing.aliyuncs.com/wangjihong/nacos-server:1.0.0 .方式2: 直接从Docker Hub或者阿里云或者网易云等等平台拉取镜像。docker pull registry.cn-beijing.aliyuncs.com/wangjihong/nacos-server:1.0.02.使用命令docker run …来来依赖镜像创建并运行一个容器,中间还要加一些复杂的参数。docker run –restart always –privileged=true -e MODE=standalone -e SPRING_DATASOURCE_PLATFORM=“mysql” -e MYSQL_MASTER_SERVICE_HOST=“www.wangjihong.com.cn” -e MYSQL_MASTER_SERVICE_PORT=“3300” -e MYSQL_MASTER_SERVICE_DB_NAME=“nacos” -e MYSQL_MASTER_SERVICE_USER=“root” -e MYSQL_MASTER_SERVICE_PASSWORD=“123456” -e MYSQL_SLAVE_SERVICE_HOST=“www.wangjihong.com.cn” -e MYSQL_SLAVE_SERVICE_PORT=“3301” -v=/usr/local/dockerfiles/nacos/data:/home/nacos/data -v=/usr/local/dockerfiles/nacos/logs:/home/nacos/logs –name docker-nacos-server1.0.0 -d -p 8848:8848 registry.cn-beijing.aliyuncs.com/wangjihong/nacos-server:1.0.03.使用命令docker exec …进入容器操作。docker exec -it docker-nacos-server1.0.0 bash4.查看容器启动日志。docker logs -f docker-nacos-server1.0.0综上我们可以看出,运行单个docker容器我们要用命众多命令来管理容器,这种情况下若是只运行一个容器还好,但如果我们有一堆容器(如: mysql 、kibana、 elasticsearch 等等…)需要执行的话,这样管理是极其麻烦的,利器docker-compose 的出现便解决了此类问题。What-什么是docker-composedocker-compose是一个批处理工具,我们可以通过配置一个docker-compose.yml文件去定义多个容器的应用,通过一条命令就可以根据docker-compose.yml文件创建出指定的容器,文件格式如下(使用docker-compose.yml部署微服务调用链监控组件skywalking):version: ‘2’services: elasticsearch: image: elasticsearch:5.6 container_name: elasticsearch ports: - 9200:9200 volumes: - ./es/data:/usr/share/elasticsearch/data - ./es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml kibana: image: kibana:5.6 container_name: kibana ports: - 5601:5601 links: - elasticsearch:elasticsearch depends_on: - elasticsearch environment: ELASTICSEARCH_URL: http://elasticsearch:9200 skywalking: image: weihanli/skywalking:5.0.0-GA container_name: skywalking ports: - 10800:10800 - 11800:11800 - 12800:12800 - 8090:8080 volumes: - ./skywalking/application.yml:/app/skywalking/config/application.yml links: - elasticsearch:elasticsearch depends_on: - elasticsearchWhy-为什么要用docker-compose可参考前言介绍。How-如何使用docker-compose安装docker-compose从github上下载docker-compose二进制文件 https://github.com/docker/com… 并按描述安装。1.下载最新版的docker-compose文件。sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s-uname -m` -o /usr/local/bin/docker-compose2.添加可执行权限。sudo chmod +x /usr/local/bin/docker-compose3.测试安装结果。docker-compose –version4.安装pip。sudo pip install docker-compose运行docker-compose1.在centos上创建一个docker-compose.yml文件,里面写上自己的多容器内容,如上述skywalking对应的文件内容。2.最后在centos上打开docker-compose.yml所在的文件夹路径下执行docker-compopse up就可以启动了,如果需要后台启动则为docker-compopse up -d。总结本文只是介绍了docker-compose基本内容,想深入了解可以自行查资料,嘿嘿。 ...

April 19, 2019 · 1 min · jiezi

Docker|基础篇

简介Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。概念Docker 包括三个基本概念镜像(Image)容器(Container)仓库(Repository)如果按面向对象思想:镜像类比如类,容器类比如实例公有仓库:https://hub.docker.com/Docker 引擎Docker 引擎是一个包含以下主要组件的客户端服务器应用程序。一种服务器,它是一种称为守护进程并且长时间运行的程序。REST API用于指定程序可以用来与守护进程通信的接口,并指示它做什么。一个有命令行界面 (CLI) 工具的客户端。Docker 引擎组件的流程如下图所示:安装以下基于Centos7以上版本。centos7安装:https://www.osyunwei.com/arch…docker安装:下载安装$ curl -fsSL get.docker.com -o get-docker.sh$ sudo sh get-docker.sh –mirror Aliyun启动$ sudo systemctl enable docker$ sudo systemctl start docker配置Docker 国内加速器$ curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.ioDocker基本操作指令下载镜像:$ docker pull tomcat解析:docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]启动容器:1.交互式运行$ docker run -it –rm tomcat bash后台运行$docker run –name webserver -d -p 8080:8080 tomcat解析: -it 指:i为交互式操作,t为终端;–rm指容器退出后随之将其删除;tomcat指你要启动的镜像;bash指tomcat中的shell控制台;–name 指定名称;-d 后台运行; -p 8080:8080 指定端口号(第一个为宿主机端口,第二个为docker的端口。交互式进入容器:docker exec -it <容器id> bash查看运行中的容器:docker ps -a删除容器:docker rm <容器id>查看容器运行日志:docker logs -f -t <容器id或容器名称>解析:-f:跟踪容器日志的最近更新;-t:显示容器日志的时间戳;清除虚悬镜像:docker image prune -a -f标记本地镜像,将其归入某一仓库docker tag [options “o”>] <image>[:tag “o”>] [repository/ “o”>][username/]name “o”>[:tag]解析:-f 覆盖已有标记。将镜像推送至远程仓库,默认为 Docker Hubdocker push name[:tag “o”>]更多命令可以参考【这里】Docker操作(基于Dockerfile)在一个/usr/local/docker文件中写一个名为Dockerfile的文件#pull down centos imageFROM centosMAINTAINER test@test.com#copy jdk and tomcat into imageADD ./apache-tomcat-7.0.70.tar.gz /rootADD ./jdk-7u80-linux-x64.tar.gz /root#set environment variableENV JAVA_HOME /root/jdk1.7.0_80ENV PATH $JAVA_HOME/bin:$PATH#define entry point which will be run first when the container starts upENTRYPOINT /root/apache-tomcat-7.0.70/bin/startup.sh && tail -F /root/apache-tomcat-7.0.70/logs/catalina.out解析:总体看来就是按照Dockerfile的命令规则进行运行shell指令关键命令:FROM: 指定基础镜像RUN: 执行命令COPY: <源路径>… <目标路径>ADD:跟COPY相似,如果源文件是tar包时,会自动解压。(一般用copy指令)CMD: 容器启动命令ENTRYPOINT: 入口点VOLUME: 定义匿名卷EXPOSE: 暴露端口WORKDIR: 指定工作目录USER : 指定当前用户ENV: 设置环境变量编译构建:docker build [选项] <上下文路径/URL/->### 最后有一个点的,它表示上下文。docker build -t app .看到 docker build 命令最后有一个 .。. 表示当前目录,而 Dockerfile 就在当前目录。-t app :指定了最终镜像的名称为app参考文档Dockerfie 官方文档Dockerfile 最佳实践文档Docker 官方镜像 DockerfileDocker操作(基于Compose)Docker Compose 将所管理的容器分为三层,工程(project) 由一组关联应用容器组成的一个完整的业务单元。服务(service) 一个应用的容器,实际上若干个运行着相同镜像的容器实例。容器(container)Compose就是通过命令对项目中的一组容器的生命周期进行便捷的管理。安装:官网地址:https://github.com/docker/com…$ sudo curl -L “https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose$ sudo chmod +x /usr/local/bin/docker-compose$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose$ docker-compose –version部署项目在/usr/local/docker目录下新建一个docker-compose.yml文件version: “3"services: web: restart: always image: tomcat container_name: web ports: - 8080:8080 volumes: - /usr/local/docker/nblog/webapps:/usr/local/tomcat/webapps mysql: restart: always image: mysql:5.7.25 container_name: mysql ports: - 3306:3306 environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: root command: –character-set-server=utf8mb4 –collation-server=utf8mb4_general_ci –explicit_defaults_for_timestamp=true –lower_case_table_names=1 –max_allowed_packet=128M volumes: - db_data:/var/lib/mysqlvolumes: db_data: docker-compose.yml常用参数解析:restart:启动容器自自启动。image:镜像container_name:自定义容器名ports:端口,第一个是宿主机,第二个是docker中的端口volumes: 数据卷,就是宿主机的目录被docker共享。这里就是你将你的应用放到指定目录,它就会自动引用进docker容器中。environment:环境变量设置。更多配置:https://docs.docker.com/compo…启动$ docker-compose up -d-d:指后台运行跟踪日志$ docker-compose logs -f tomcat -f:类似于tail -f卸载$ docker-compose down后续Docker持续集成总结Docker与微服务更配哦。资源:Docker官方文档DockerHub仓库DockerCompose一些常用的镜像最后如果对 Java、大数据感兴趣请长按二维码关注一波,我会努力带给你们价值。觉得对你哪怕有一丁点帮助的请帮忙点个赞或者转发哦。 ...

April 13, 2019 · 2 min · jiezi

解决Windows10下无法对docker容器进行端口访问(端口映射的问题)

解决Windows10下无法对docker容器进行端口访问(端口映射的问题)在Windows10系统服务器中安装了docker和docker-compose并尝试在其中运行Nginx服务,映射也做好问题:在主机的浏览器中,打开localhost:port无法访问对应的Web服务。问题解析原因:docker是运行在Linux上的,在Windows中运行docker,实际上还是在Windows下先安装了一个Linux环境,然后在这个系统中运行的docker。也就是说,服务中使用的localhost指的是这个Linux环境的地址,而不是我们的宿主环境Windows10。解决办法启动docker命令行窗口输入命令docker-machine ip defaultLinux的ip地址,一般情况下这个地址是192.168.99.100然后在Windows的浏览器中,输入 http://IP:port 即可启用(http://192.168.99.100:8069)

March 19, 2019 · 1 min · jiezi

odoo部署遇到的问题 yaml.parser.ParserError

ERROR: yaml.parser.ParserError: while parsing a block mapping in “./docker-compose.yml”, line 15在写docker-compose.yml文件version: ‘2’services: # PostgreSQL mydb: image: postgres:10 ports: - “5432:5432” environment: - POSTGRES_DB=postgres - POSTGRES_USER=odoo - POSTGRES_PASSWORD=odoo volumes: - odoo-db-data:/var/lib/postgresql/data # Odoo web web: build: context: ../odoo_demo dockerfile: Dockerfile hostname: web command: ./docker_run_web.sh volumes: - ../odoo_demo:/app # mount current directory inside container - odoo-web-data:/app/odoo-web-db # 把此路径/app/odoo-ee-web-db配置到odoo conf data_dir参数中 ports: - “8069:8069” # set up links so that web knows about db, rabbit and redis depends_on: - mydbvolumes: odoo-web-data: odoo-db-data:文件写完运行docker-compose up -d报错:ERROR: yaml.parser.ParserError: while parsing a block mapping in “./docker-compose.yml”, line 15, column 5expected <block end>, but found ‘<block mapping start>’ in “./docker-compose.yml”, line 25, column 4查看发现问题(vim)原因文件内块对齐有问题,使用notepad++打开查看如下:volumes: - ../odoo_demo:/app # mount current directory inside container - odoo-web-data:/app/odoo-web-db # 把此路径/app/odoo-ee-web-db配置到odoo conf data_dir参数中解决办法:在下面这句话前面添加两个空格,使他能和上面保持对其 - odoo-web-data:/app/odoo-web-db # 把此路径/app/odoo-ee-web-db配置到odoo conf data_dir参数中 ...

March 18, 2019 · 1 min · jiezi

docker-compose 搭建 nginx/php/mysql/redis/go 环境

Dockerfiles项目路径: https://github.com/hopher/doc…用 Docker 容器服务的方式搭建 nginx/php/mysql/redis/go 环境,易于维护、升级。相关软件版本:PHP 7.2Golang 1.12MySQL 5.7Nginx 1.15Redis 3.2PHP 扩展swoole v4.3.0使用1.下载下载 zip 压缩包 && 解压wget -c https://github.com/hopher/dockerfiles/archive/master.zip -O dockerfiles.zipunzip dockerfiles.zipmv dockerfiles-master ~/app其中, ~/app 为个人工作目录,请根据自己需要更改2.docker-compose 构建项目进入 docker-compose.yml 所在目录:执行命令:docker-compose up如果没问题,下次启动时可以以守护模式启用,所有容器将后台运行:docker-compose up -d使用 docker-compose 基本上就这么简单,Docker 就跑起来了,用 stop,start 关闭开启容器服务。 更多的是在于编写 dockerfile 和 docker-compose.yml 文件。 可以这样关闭容器并删除服务:docker-compose down3. 测试将项目源码放到 src 目录下, 并运行cd srcecho “<?php phpinfo();” > index.php打开 url 访问 http://localhost/index.php4.帮助执行命令:docker-compose –help参数说明-p 指定项目名称,默认为当前目录名, 也可以直接在docker-compose.yml中设置image, container_name 这2个属性5.目录结构dockerfiles |– services # docker 相关服务 |– src # 工作源码目录, 如 nginx /usr/share/nginx/html |– docker-compose.yml # docker-compose.yml 定义 |– deprecated.sh # 已弃用 shell 脚本, 勿使用各系统软件源Ubuntu系统代号版本precise12.04trusty14.04vivid15.04xenial16.04zesty17.04Debian系统代号版本squeeze6.xwheezy7.xjessie8.xstretch9.xbuster10.x阿里源修改 /etc/apt/sources.list 为以下内容deb http://mirrors.aliyun.com/debian stretch main contrib non-freedeb-src http://mirrors.aliyun.com/debian stretch main contrib non-freedeb http://mirrors.aliyun.com/debian stretch-updates main contrib non-freedeb-src http://mirrors.aliyun.com/debian stretch-updates main contrib non-freedeb http://mirrors.aliyun.com/debian-security stretch/updates main contrib non-freedeb-src http://mirrors.aliyun.com/debian-security stretch/updates main contrib non-freeNOTE: 查询自己的Linux版本 cat /etc/issue常用shell组合# 删除所有容器docker stop docker ps -q -a | xargs docker rm# 删除所有标签为none的镜像docker images|grep &lt;none&gt;|awk ‘{print $3}’|xargs docker rmi参考资料[[官方] Compose file version 3 reference](https://docs.docker.com/compo…清华大学开源软件镜像站-Debian 镜像使用帮助[官方] mysql 镜像说明[官方] php 镜像说明 ...

March 10, 2019 · 1 min · jiezi

zabbix 4.0.3 use docker-compose deploy

CentOS 7 使用 docker-compose 部署zabbix 4.0.3docker-compose.yaml 配置文件如下:version: ‘3.1’services: db: image: mysql command: –default-authentication-plugin=mysql_native_password –character-set-server=utf8mb4 –collation-server=utf8mb4_unicode_ci –default-time-zone=’+08:00’ restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: “MysqlPasswd” MYSQL_ALLOW_EMPTY_PASSWORD: “no” ports: - 9306:3306 volumes: - /data/dockerdata/db/data:/var/lib/mysql - /data/dockerdata/db/conf:/etc/mysql/conf.d - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime server: image: zabbix/zabbix-server-mysql:centos-4.0.3 restart: unless-stopped environment: DB_SERVER_HOST: db MYSQL_USER: root MYSQL_PASSWORD: MysqlPasswd ZBX_TIMEOUT: 30 ports: - 9051:10051 - 8444:10051 volumes: - /data/dockerdata/server/alertscripts:/usr/lib/zabbix/alertscripts - /data/dockerdata/server/externalscripts:/usr/lib/zabbix/externalscripts - /data/dockerdata/server/modules:/var/lib/zabbix/modules - /data/dockerdata/server/enc:/var/lib/zabbix/enc - /data/dockerdata/server/ssh_keys:/var/lib/zabbix/ssh_keys - /data/dockerdata/server/ssl/certs:/var/lib/zabbix/ssl/certs - /data/dockerdata/server/ssl/keys:/var/lib/zabbix/ssl/keys - /data/dockerdata/server/ssl/ssl_ca:/var/lib/zabbix/ssl/ssl_ca - /data/dockerdata/server/snmptraps:/var/lib/zabbix/snmptraps - /data/dockerdata/server/mibs:/var/lib/zabbix/mibs - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime web: image: zabbix/zabbix-web-nginx-mysql:centos-4.0.3 restart: unless-stopped environment: DB_SERVER_HOST: db MYSQL_USER: root MYSQL_PASSWORD: MysqlPasswd ZBX_SERVER_HOST: server PHP_TZ: “Asia/Shanghai” ZBX_SERVER_NAME: aws ports: - 8081:80 volumes: - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime ...

March 6, 2019 · 1 min · jiezi

用Docker搭建Laravel和Vue项目的开发环境

在这篇文章中我们将通过Docker在个人本地电脑上构建一个快速、轻量级、不依赖本地电脑所安装的任何开发套件的可复制的Laravel和Vue项目的开发环境(开发环境的所有依赖都安装在Docker构建容器里),加入Vue只是因为有的项目里会在Laravel项目中使用Vue做前后端分离开发,开发环境中需要安装前端开发需要的工具集,当然前后端也可以分成两个项目开发,这个话题不在本篇文章的讨论范围内。所以我们的目标是:不在本地安装Mamp/Wamp这样的软件不使用类似Vagrant这样的虚拟机不在本地电脑全局安装PHP开发所需要的工具集不在本地电脑全局安装前端开发所需要的工具集不在本地电脑全局安装Mysql和Nginx开始前你需要先去安装一个Docker客户端,Docker的官网中有详细的安装方法。第一步:获取Laravel的源码包因为我们电脑上不安装Composer,所以就不能使用Composer来创建Laravel项目了, 这里我使用cURL直接从github上下载了最新的Laravel源码包,你也可以使用wget或者git clone 来获取源码包。curl -L -O https://github.com/laravel/laravel/archive/v5.5.0.tar.gz /&& tar -zxvf v5.5.0.tar.gz /&& rm v5.5.0.tar.gz上面的命令在curl下载完源码包后会解压源码压缩包,解压完成后在把源码压缩包v5.5.0.tar.gz删掉,执行完后你会看到一个laravel-5.5.0的项目目录。第二步:添加docker-compose.yml在项目中创建docker-compose.yml文件。Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。我们知道使用一个 Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。在这里我们会用到四个容器分别将PHP、Mysql、Nginx放在四个不同的容器中,通过compose`将四个应用容器关联到一起组成项目。编排文件的开头如下:version: ‘2’services: # our services will go here在编排文件中,把每个容器叫做一个服务,services下定义整个应用中用到的所有服务(即容器)。App服务APP服务的容器将执行我们项目中的代码。app: build: context: ./ dockerfile: app.dockerfile working_dir: /var/www volumes: - ./:/var/www environment: - “DB_PORT=3306” - “DB_HOST=database"Notes:我们使用app.dockerfile这个镜像文件来构建我们的App容器,在镜像文件中我们会对项目中用到的PHP模块镜像配置,也会额外安装NPM用来构建前端代码。working_dir: /var/www把工作目录设置成了/var/www,在容器中项目代码将会被放在/var/www目录下面,包括使用docker exec app执行的命令也都是以/var/www为当前工作目录的。volumes是容器内数据卷所挂载路径设置,在这里我们只定义一个数据卷,把宿主机项目目录挂到在容器中的/var/www上,这样我们在本地电脑对项目代码进行的更改就会马上同步到容器中去,反过来也是一样,容器中对代码做的更改也会及时反馈到本地电脑的项目中。environment设置环境变量名,这里我们设置了DB_PORT和DB_HOST 这样就不用修改项目中的.env文件里关于这两项的值了,当然任何你需要在开发环境单独设置的环境变量都可以写到这里,Laravel读取配置使用的DotEnv会检测是否系统有指定环境变量的设置,有的话就不会在去读取.env文件了。现在我们需要创建上面build环节中提到的app.dockerfile这个文件了,具体内容如下:FROM php:7.1.22-fpm# Update packagesRUN apt-get update# Install PHP and composer dependenciesRUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev# Clear out the local repository of retrieved package files# RUN apt-get clean# Install needed extensions# Here you can install any other extension that you need during the test and deployment processRUN apt-get clean; docker-php-ext-install pdo pdo_mysql mcrypt zip gd pcntl opcache bcmath# Installs Composer to easily manage your PHP dependencies.RUN curl –silent –show-error https://getcomposer.org/installer | php – –install-dir=/usr/local/bin –filename=composer# Install NodeRUN apt-get update &&\ apt-get install -y –no-install-recommends gnupg &&\ curl -sL https://deb.nodesource.com/setup_10.x | bash - &&\ apt-get update &&\ apt-get install -y –no-install-recommends nodejs &&\ npm config set registry https://registry.npm.taobao.org –global &&\ npm install –global gulp-cliCMD php-fpmNotes:我在这里先将NPM和Composer装到了app容器中,因为在开发时经常需要执行他们,如果发布到生产环境,一般是使用单独的composer对项目代码进行构建而不是放在运行应用的容器里,容器的核心思想之一就是保持单一,这样才能做到快速增加相同角色的容器。Web服务接下来,我们需要配置一个Web服务器用,我们把这个容器在编排文件中命名成webweb: build: context: ./ dockerfile: web.dockerfile working_dir: /var/www volumes_from: - app ports: - 8080:80Notes:volumes_from用来复用在app服务中定义的数据卷路径通过ports将本地电脑的8080端口映射到web容器的80端口,这样在开发环境中我们就不用设置hosts文件,直接通过IP加端口就能访问服务了。Web服务器选用nginx,所以我们需要用一个nginx镜像文件来构建这个容器,在这之前我们需要在nginx镜像的基础上再设置一下项目中用到的vhost,所以我们需要一个web.dockerfile文件,它的定义如下:FROM nginx:1.10ADD vhost.conf /etc/nginx/conf.d/default.conf根据镜像文件的定义,我们把项目中的vhost.conf复制到了容器的/etc/nginx/conf.d/default.conf中,这样基本的nginx配置就配置好了,vhost.conf中的定义如下:server { listen 80; index index.php index.html; root /var/www/public; location / { try_files $uri /index.php?$args; } location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; }}Notes:因为是开发环境我们就只进行最简单的配置,不做调优考虑了。fastcgi_pass app:9000; nginx将对PHP的请求通过fastcgi传递给了app服务的9000端口,docker-compose会自动把services中定义的容器服务连接起来,各个服务相互之间使用服务名称引用。Mysql服务接下来我们将配置Mysql服务,与上面两个服务有点不一样的是,在PHP-FPM和Nginx的容器中,我们配置本地电脑的文件可以同步到容器中供容器访问,这让我们开发时对文件作的更改能够快速的在容器中得到反馈加快我们的开发过程。但是在数据库容器中我们希望容器中创建的文件能够持久化(默认容器销毁时,容器内创建的文件也会被销毁),我们可以通过Docker的数据卷来实现上述功能,只不过这次不用再把本地电脑的文件挂在到数据卷上了,Docker客户端会管理创建的数据卷的在本地电脑上具体存储的位置。下面是编排文件中对database服务的设置version: ‘2’services: database: image: mysql:5.7 volumes: - dbdata:/var/lib/mysql environment: - “MYSQL_DATABASE=homestead” - “MYSQL_USER=homestead” - “MYSQL_PASSWORD=secret” - “MYSQL_ROOT_PASSWORD=secret” ports: - “33061:3306"volumes: dbdata:Notes:在文件的最下面我们通过volumes命令创建了一个名为dbdata的数据卷(dbdata后面的冒号是有意写上去的,这是YML文件的一个语法限制,不用太关心)定义完数据卷后,在上面我们使用<name>:<dir>的格式,通知Docker,将dbdata数据卷挂在到容器中的/var/lib/mysql目录上environments中设置的是Mysql的docker镜像需要的四个必要参数。ports端口映射中,我们将本地电脑的33061端口映射到容器的3306端口,这样我们就能通过电脑上的数据库工具连接到docker内的Mysql了。将所有服务编排到一起下面是完整的docker-compose.yml文件,通过编排文件我们将三个应用容器关联在一起组成了项目的服务端version: ‘2’services: # The Application app: build: context: ./ dockerfile: app.dockerfile working_dir: /var/www volumes: - ./:/var/www environment: - “DB_PORT=3306” - “DB_HOST=database” # The Web Server web: build: context: ./ dockerfile: web.dockerfile working_dir: /var/www volumes_from: - app ports: - 8080:80 # The Database database: image: mysql:5.6 volumes: - dbdata:/var/lib/mysql environment: - “MYSQL_DATABASE=homestead” - “MYSQL_USER=homestead” - “MYSQL_PASSWORD=secret” - “MYSQL_ROOT_PASSWORD=secret” ports: - “33061:3306"volumes: dbdata:启动服务按照上面的步骤配置好编排文件还有指定的docker镜像文件后,我们就可以通过下面的命令启动服务了,执行完后会启动上面文件里定义的三个服务。docker-compose up -d 第一次启动时,由于docker客户端要下载上面提到的三个镜像并且构建服务所以启动速度会慢一些,等到下载完镜像并构建完成后,以后的启动都会非常快。初始化Laravel项目启动完服务后我们可以初始化Laravel项目了,步骤跟官方文档里介绍的一样,但是需要在启动的app服务的容器里执行:docker-compose exec app composer installdocker-compose exec app npm install // 如果包含前端项目的话再执行相关命令docker-compose exec app cp .env.example .envdocker-compose exec app php artisan key:generatedocker-compose exec app php artisan optimizedocker-compose exec app php artisan migrate –seeddocker-compose exec app php artisan make:controller MyControllerNotes:docker-compose exec 将命令发送到指定的容器中去执行app是定义在docker-compose.yml中的一个服务,它是一个运行着php-fpm的容器php artisan migrate 是要在容器里执行的命令查看nginx日志的方法:docker ps 找到nginx服务的container iddocker exec -it <contianer id> /bin/bash 进入nginx容器nginx日志的具体路径请查看项目中的vhost.conf执行完上面的命令后你就能通过http://127.0.0.1:8080/访问到项目啦。在我的Github gist有一组参考文件方便同学们参考https://gist.github.com/kevin…gist里的文件稍微旧一些,后来在使用的过程中又加入些新的PHP模块和Node,之前composer也单独放到了一个容器中,不过相信聪明的你看到这里应该已经会根据需求更改这些文件啦。 ...

March 4, 2019 · 2 min · jiezi

Swoft 系列教程:(1)使用 Docker 安装部署 Swoft

之前有写过一篇 Docker 安装部署 Swoft 的文章,但有些冗余混乱,故重写作为教程的开篇。要不读读看?Swoft项目:https://github.com/swoft-clou…Swoft文档:https://doc.swoft.org/Swoft镜像:https://hub.docker.com/r/swof…Swoft 简介首个基于 Swoole 原生协程的新时代 PHP 高性能协程全栈框架,内置协程网络服务器及常用的协程客户端,常驻内存,不依赖传统的 PHP-FPM,全异步非阻塞 IO 实现,以类似于同步客户端的写法实现异步客户端的使用,没有复杂的异步回调,没有繁琐的 yield, 有类似 Go 语言的协程、灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等,可以用于构建高性能的Web系统、API、中间件、基础服务等等。即异步非阻塞IO,EventLoop,事件驱动。cpu_num 个 worker 即可承载高并发请求,提供协程/异步IO客户端,数据库连接池,对象连接池,任务进程池。优雅的注解声明,IOC/DI容器,严格遵循PSR规范。Swoft 镜像的主要用途Swoft 官方提供了基于 Debine 的 Docker 镜像。镜像中已安装配置好运行 Swoft 的所需组件及依赖:PHP 7.0+ / Swoole / Composer / Pecl。虽然不使用镜像从头安装部署以上几项组件也不难,但镜像内置可以开箱即用,免去了这些略繁琐的工作,让我们尽可能快的投入到 Swoft 的开发中去。此外Swoft 镜像与开发的配合如果只是单纯的想快速体验 Swoft,使用 docker run -p 80:80 swoft/swoft 拉取创建容器访问即可。如何正确的在 Swoft 项目的开发中使用镜像呢?如果是要将镜像好好利用到开发工作中,则需要清楚一下几点。镜像内置完全安装的 Swoft 框架,但它只是用来快速演示的,并不是要你拿去修改,开发还是要对本地的 Swoft 项目开发。我们应该做的是将本地的 Swoft 框架 挂载到镜像的工作目录 /var/www/swoft 从而替换掉镜像自带的,这样启动 Swoft服务 就会启动映射到本地的 Swoft 项目了镜像的容器启动时默认会启动 Swoft 服务 作为前置进程,这就要求我们在挂载了本地 Swoft 项目时需要保证已完全安装了各项依赖(github 拉取下来的 Swoft 源码 并没有安装库依赖,需要使用 Composer install 一下)好像咬到尾巴了,为了开发需要挂载本地 Swoft 项目到镜像工作目录,因为容器启动时还会一并启动 Swoft 服务,所以要求挂载的本地 Swoft项目 必须使用 Composer 安装好依赖,嗯?这不还是得在本地装 PHP + Composer 嘛,镜像不是都提供了嘛,重复劳动了。修改 Swoft 镜像的 entrypoint 使得 Swoft 容器启动时不同时启动 Swoft 服务,这就不需要要求我们挂载的本地 Swoft 项目必须完全安装好依赖了。容器创建好后,登入容器 sh,使用镜像内置的 Composer 安装依赖启动 Swoft 服务这样就能充分利用镜像内置的环境和工具,快乐的开始 Swoft 的开发了工作了,下面给出具体的实例。Swoft 镜像的使用前面夸赞了那么多镜像的便利之处,下面如果不完全把镜像用到极致那就不太好了 O(∩_∩)O哈哈1、首先我们从 github 上拉取最新的 Swoft 源码到本地cd ~ && git clone git@github.com:swoft-cloud/swoft.git && cd swoft2、查看 swoft 镜像的 Dockerfile# 在文件尾设定了 entrypoint 命令为 启动 swoft服务ENTRYPOINT [“php”, “/var/www/swoft/bin/swoft”, “start”]entrypoint 就是我们后面需要改掉的参数3、直接使用镜像创建容器docker run -p 8081:80 \ #映射宿主机808-v $(pwd):/var/www/swoft #挂载本地 Swoft 项目到镜像工作目录-it -d \ #重要 开启 stdin tty 并以daemon模式运行–entrypoint="" #重要 覆盖掉镜像内设定的 entrypoint 参数–name my_swoft #容器命令–privileges=true #赋予权限swoft/swoft bash4、使用 docker-compose 更为简洁#编辑 docker-compose 编排文件vim docker-compose.yml#内容修改如下version: ‘3’services: swoft: image: swoft/swoft:latest container_name: my_swoft # 给容器自定义个名称便于管理 #build: ./ ports: - “8081:80” #端口映射 volumes: - ./:/var/www/swoft # 挂载本地swoft项目到镜像工作目录 stdin_open: true #打开标准输出 -i tty: true # 打开 tty 会话 -t privileged: true # 给与权限 比如创建文件夹之类的 #entrypoint: [“php”, “/var/www/swoft/bin/swoft”, “start”] # 入口启动命令 即启动 swoft 服务 entrypoint: [“bash”] 创建容器docker-compose up -d swoft ./5、登入容器,安装依赖,开启 Swoft 服务使用3或4创建的Swoft容器,便以 bash 作为启动的前置进程,而非启动 Swoft 服务,我们登入容器使用内置的 Composer 安装依赖后,启动Swoft服务即可。docker exec -it my_swoft bash# 安装框架依赖composer install# 启动/停止/重启 Swoft 服务php bin/swoft start|stop|restar6、开启热重载,关闭 daemon,让框架调试信息输出到 stderr 方便开发调试编辑本地的 Swoft 项目 .env 文件# ApplicationAPP_DEBUG=true# Server…AUTO_RELOAD=true…# Swoole Settings…DAEMONIZE=0…保存并重新启动 Swoft服务小提示:可以使用 PHPStorm IDE 配置 FTP/SFTP 文件改动自动上传的方式,开发起飞 ...

February 21, 2019 · 2 min · jiezi

还为重复安装开发环境而烦吗? 这或许是更好的解决方案 —— docker

工欲善其事必先利其器开始进行web开发之前,都需要搭建好基本的开发环境.个人用到的有nginx、redis、mysql、node.js.搭建环境不同的方法使用apt(ubuntu)、brew(mac os)一个个安装脚本: LNMP一键安装包源码编译上面的解决方案都有一个共同的缺点一旦系统重装,需要重新安装、配置(有多台电脑时,开发环境版本容易不一致)没有版本控制系统,软件配置维护麻烦更好的解决方案 —— docker基于docker(18.03以上)搭建nginx、 redis 、mysql 服务。项目结构.├── .env # 默认为dev的环境变量├── .gitignore├── README.md├── container # 不同容器的配置文件│ ├── mysql│ │ └── docker-compose.yml│ ├── nginx│ │ ├── conf│ │ ├── docker-compose.prod.yml│ │ └── docker-compose.yml│ └── redis│ └── docker-compose.yml└── prod # prod的环境变量 └── .envdocker-compose 在运行时会使用当前目录下的.env文件,并且不支持指定env文件,所以需要多个不同环境时,只能在对应文件夹下建立.env文件项目内容通过.env文件配置整个项目所需要的环境变量# file .env# 项目名称COMPOSE_PROJECT_NAME=site# compose文件COMPOSE_FILE=container/nginx/docker-compose.yml:container/mysql/docker-compose.yml:container/redis/docker-compose.yml# mysql configMYSQL_ROOT_PASSWORD=123456MYSQL_DATABASE=demo# redis configREDIS_PASSWORD=123456# 自定义环境变量 本地服务器 IPSITE_IP=host.docker.internal # host.docker.internal需要18.03以上版本 以nginx的 docker-compose.yml 文件为例: ${SITE_IP}将被替换成host.docker.internal, $${SITE_IP}将不会被替换version: “3"services: nginx: image: nginx volumes: - ./conf/dev.template:/etc/nginx/conf.d/dev.template ports: - “80:80” environment: - SITE_IP=${SITE_IP} command: /bin/bash -c “envsubst ‘$${SITE_IP}’< /etc/nginx/conf.d/dev.template > /etc/nginx/conf.d/dev.conf && exec nginx -g ‘daemon off;’” networks: - default - network_sitenetworks: network_site: driver: bridge其他镜像的配置可以从dockerhub查看redis、mysql启动全部// dev模式docker-compose up// prod模式,使用 prod下的.env文件cd ./prod && docker-compose up单独启动docker-compose up nginxdocker-compose up mysqldocker-compose up redis停止# 停止某个服务docker-compose stop nginx # 停止全部docker-compose stop具体配置请从github仓库查看通过使用docker,我们只需要一个repository存放配置, 便可以在多台电脑上迅速安装环境. ...

February 15, 2019 · 1 min · jiezi

Kafka 集群 Golang 应用实例

项目见:???? kafka cluster example这个实例做了些什么?搭建了拥有 3 节点 kafka、 3 节点 zookeeper 的 docker 集群服务;分别创建了 1 个消息发布者和 2 个相同消费组的消息订阅者的 docker 应用;使用 ab 进行并发测试,验证该实例消息的订阅 / 发布功能;通过这个实例,能够了解些什么?使用 Docker Compose 构建 Kafka 集群使用 Golang 创建 Kafka Pub/Sub 实例使用 ApacheBench 进行并发测试使用 Makefile 简化构建操作命令如果这个实例,对你了解 kakfa 有所帮助,请为项目添加 star ,非常感谢!

February 15, 2019 · 1 min · jiezi

docker搭建lnmp环境

<!– TOC –>docker搭建lnmp环境一、Dockerfile定制镜像二、docker-compose三、docker-compose编排lnmp环境1、mysql2、redis3、mongo4、nginx5、php6、完整版四、参考<!– /TOC –>有收获的话请加颗小星星,没有收获的话可以 反对 没有帮助 举报三连代码仓库docker搭建lnmp环境一、Dockerfile定制镜像# FROM 指定基础镜像FROM 镜像FROM php:7.2-fpm# RUN 执行RUN <命令>orRUN [“可执行文件”, “参数1”, “参数2”]RUN echo ‘<h1>Hello, Docker!</h1>’ > /usr/share/nginx/html/index.htmlRUN [“php”, “-S”, “0.0.0.0:8080”]# COPY 复制文件COPY <源路径>… <目标路径>COPY swoole-4.2.10.tgz /homeCOPY 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 <key> <value>ENV MYSQL_ROOT_PASSWORD root# ARG与ENV差不多ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的ENV MYSQL_ROOT_PASSWORD root# VOLUME 匿名卷VOLUME ["<路径1>", “<路径2>”…]VOLUME ["/data"]# EXPOSE 暴露端口EXPOSE <端口1> [<端口2>…]EXPOSE 80 443# WOEKDIR 指定工作目录,进入容器后的落地目录WORKDIR <工作目录路径>WORKDIR /var/www# USER 指定当前用户USER <用户名>USER root二、docker-compose详细请查看 https://docker_practice.gitee…服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。三、docker-compose编排lnmp环境1、mysql这里我们使用了mysql5.5版本,没其它用意,相比5.7以上版本,占内存和硬盘最小的一个版本我们准备了一个my.cnf作为额外配置,这里我修改了数据库的时区[mysqld]default-time-zone = ‘+8:00’FROM mysql:5.5COPY my.cnf /etc/mysql/conf.dEXPOSE 33062、redis我们使用准备的配置文件redis.conf覆盖容器默认启动的配置文件,修改了ip绑定和密码bind 0.0.0.0requirepass rootFROM redis:latestCOPY redis.conf /usr/local/etc/redis/redis.confCMD [ “redis-server”, “/usr/local/etc/redis/redis.conf” ]EXPOSE 63793、mongomongodb我们没有特殊处理FROM mongo:latestEXPOSE 270174、nginx我们准备了一份nginx.conf和虚拟目录conf.d,为了以后可以动态的配置网站的代理和负载均衡还有一个日志目录,放在外层logs目录里面,记录nginx的访问日志特别注意的是fastcgi_pass php:9000;而不是fastcgi_pass 127.0.0.1:9000;,目前自己也没明白FROM nginx:alpineCOPY nginx.conf /etc/nginx/nginx.confEXPOSE 805、phpphp算是这里面最难搞定的,因为我们需要额外的添加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会解压缩# swooleCOPY swoole-4.2.10.tgz /homeRUN pecl install /home/swoole-4.2.10.tgz && \ docker-php-ext-enable swoole && \ rm /home/swoole-4.2.10.tgz6、完整版version: ‘3’networks: frontend: driver: bridge backend: driver: bridgevolumes: mysql: driver: local mongo: driver: local redis: driver: localservices: 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四、参考Docker — 从入门到实践laradockDocker在PHP项目开发环境中的应用 ...

January 20, 2019 · 2 min · jiezi

简明docker教程

<!– TOC –>简明docker教程一、什么是docker二、docker与虚拟机比较三、安装docker四、基本概念1、镜像2、容器3、数据卷4、挂载五、参考资料<!– /TOC –>有收获的话请加颗小星星,没有收获的话可以 反对 没有帮助 举报三连代码仓库简明docker教程一、什么是dockerDocker是一个开放源代码软件项目,让应用程序布署在软件货柜下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制。Docker利用Linux核心中的资源分离机制,例如cgroups,以及Linux核心名字空间(namespaces),来创建独立的容器(containers)。这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担。Linux核心对名字空间的支持完全隔离了工作环境中应用程序的视野,包括进程树、网络、用户ID与挂载文件系统,而核心的cgroup提供资源隔离,包括CPU、存储器、block I/O与网络。从0.9版本起,Dockers在使用抽象虚拟是经由libvirt的LXC与systemd - nspawn提供界面的基础上,开始包括libcontainer库做为以自己的方式开始直接使用由Linux核心提供的虚拟化的设施,上面都是废话,简言之Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。二、docker与虚拟机比较特性容器虚拟机启动秒级分钟级硬盘使用一般为 MB一般为 GB性能接近原生弱于系统支持量单机支持上千个容器一般几十个三、安装docker我自己用的是Docker for Mac其它系统可以参考 http://docker_practice.gitee….四、基本概念镜像(Image)Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。容器(Container)镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。仓库(Repository)镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。1、镜像# 获取镜像docker pull ubuntu:14.04# 以ubuntu:14.04镜像为基础启动并运行一个容器docker run -it –rm \ ubuntu:14.04 \ bash-it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。–rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 –rm 可以避免浪费空间。ubuntu:14.04:这是指用 ubuntu:14.04 镜像为基础来启动容器。bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。# 列出镜像docker image lsdocker images# 镜像占用docker system df# 清楚悬挂镜像docker image prune# 删除镜像docker image rmdocker rmi2、容器# 启动以守护模式创建的名字为demo-u的容器,并以交互模式进入容器docker run –name demo-u -t -i -d ubuntu:14.04 bash# 运行后就可以通过ID或名字进入容器,并输出hello worlddocker exec -it demo-u /bin/sh -c “echo hello world”# 查看运行中的容器docker container lsdocker ps# 所有容器docker container ls -adocker ps -a# 查看容器日志docker container logs demo-udocker logs demo-u# 终止容器docker container stop demo-udocker stop demo-u# 启动容器docker container start demo-udocker start demo-u# 重启容器docker container restart demo-udocker restart demo-u# 进入容器,退出后容器也停止docker attach demo-u# 导出容器docker export# 导入容器docker import# 删除容器docker container rmdocker rm# 清除所有容器docker container prune3、数据卷# 创建数据卷docker volume create# 列出数据卷docker volume ls# 删除数据卷docker volume rm# 清除没用的数据卷docker volume prune4、挂载也就是目录共享,两种方式:-v–mount 推荐# 使用php本地服务器查看php环境,加载主机的 ~/web 目录到容器的 /var/www/web目录mkdir -p ~/web && cd ~/web && echo “<?php phpinfo();” > index.phpdocker run -d \ –name web \ -p 8080:8080 \ –mount type=bind,source=pwd,target=/var/www/web \ php:7.2-fpm \ /bin/sh -c “cd /var/www/web && php -S 0.0.0.0:8080"或者docker run -d \ –name web \ -p 8080:8080 \ -v pwd:/var/www/web \ php:7.2-fpm \ /bin/sh -c “cd /var/www/web && php -S 0.0.0.0:8080"打开浏览器 0.0.0.0:8080# 查看数据卷docker volume inspect web五、参考资料Docker — 从入门到实践 ...

January 20, 2019 · 2 min · jiezi

Dockerfile、Docker-Compose基本命令与介绍

一、Dockerfile基本命名指令说明备注FROM指定所创建镜像的基础镜像第一条指令必须为 FROM 指令。格式为 FROM <image> 或FROM <image>:<tag> 。MAINTAINER指定维护者信息格式为 MAINTAINER <name>RUN运行命令在镜像中要执行的命令,格式为 RUN <command> 或 RUN [“executable”, “param1”, “param2”]。前者默认将在 shell 终端中运行命令,即 /bin/bash -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN [“/bin/bash”, “-c”,”echo hello”] 。每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用换行。例如:RUN apt-get update &amp;& apt-get install -ylibsnappy-dev zliblg-dev libbz2-dev &amp;& rm -rf /var/cache/aptCMD指定启动容器时默认执行的命令支持三种格式:1. CMD[“executable”,“param1”,“param2”] 使用 exec 执行,推荐方式;2. CMD command param1 param2 在 /bin/bash 中执行,提供给需要交互的应用;3. CMD [“param1”,“param2”] 提供给 ENTRYPOINT 的默认参数;LABEL指定生成镜像的元数据标签信息 EXPOSE声明镜像内服务所监听的端口指定容器要打开的端口ENV指定环境变量格式为 ENV <key> <value> 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。ADD赋值指定的路径下的内容到容器中的路径下,可以为URL;如果为tar文件,会自动解压到路径下相当于 COPY,但是比 COPY 功能更强大COPY赋值本地主机的路径下的内容到容器中的路径下;一般情况下推荐使用COPY而不是ADD复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中的ENTRYPOINT指定镜像的默认入口 VOLUME创建数据挂载点挂载目录,格式为VOLUME ["/data"]USER指定运行容器时的用户名或UID WORKDIR配置工作目录指定当前工作目录,相当于 cdARG指定镜像内使用的参数(例如版本号信息等) ONBUILD配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作的命令 STOPSIGNAL容器退出的信号 HEALTHCHECK如何进行健康检查 SHELL指定使用SHELL时的默认SHELL类型 二、Dockerfile 基本结构 一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。’#’ 为 Dockerfile 中的注释。先看下面一个小例子:# This my first nginx Dockerfile# Version 1.0# Base images 基础镜像FROM centos#MAINTAINER 维护者信息MAINTAINER tianfeiyu #ENV 设置环境变量ENV PATH /usr/local/nginx/sbin:$PATH#ADD 文件放在当前目录下,拷过去会自动解压ADD nginx-1.8.0.tar.gz /usr/local/ ADD epel-release-latest-7.noarch.rpm /usr/local/ #RUN 执行以下命令 RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpmRUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean allRUN useradd -s /sbin/nologin -M www#WORKDIR 相当于cdWORKDIR /usr/local/nginx-1.8.0 RUN ./configure –prefix=/usr/local/nginx –user=www –group=www –with-http_ssl_module –with-pcre && make && make installRUN echo “daemon off;” >> /etc/nginx.conf#EXPOSE 映射端口EXPOSE 80#CMD 运行以下命令CMD [“nginx”]三、构建镜像3.1 编写Dockerfile文件vim DockerfileFROM alpine:latestMAINTAINER troyCMD echo “Hello Workd!“3.2 构建镜像docker build -t hello_world .3.3 运行镜像docker run hello_world记:1.表示当前用户使用的shell是/bin/bash,所谓的shell你可以理解为操作系统和人之间交互的平台。例如windows系统的桌面环境就是一个shell。bin目录中基本上都是可执行的命令。启动容器并启动bash(交互方式):$docker run -i -t <image_name/continar_id> /bin/bash2.保存对容器的修改(commit) 当你对某一个容器做了修改之后(通过在容器中运行某一个命令),可以把对容器的修改保存下来,这样下次可以从保存后的最新状态运行该容器。$docker commit ID new_image_name 当然如果在保存成新镜像的时候想添加新的 dockerfile命令,比如,启动进入新的目录。docker commit -c “WORKDIR /usr/bin” 07c5f9ed32b0 test-images当然你也可以在旧镜像的基础上写一个新的dockerfile,用dockerfile生成新的镜像。Note: image相当于类,container相当于实例,不过可以动态给实例安装新软件,然后把这个container用commit命令固化成一个image。四、Docker-Compose 一句话:docker-compose 是用来做docker 的多容器控制,是一个用来把 docker 自动化的东西。有了 docker-compose 你可以把所有繁复的 docker 操作全都一条命令,自动化的完成。4.1 常用命令docker-compose up -d nginx 构建建启动nignx容器docker-compose exec nginx bash 登录到nginx容器中docker-compose down 删除所有nginx容器,镜像docker-compose ps 显示所有容器docker-compose restart nginx 重新启动nginx容器docker-compose run –no-deps –rm php-fpm php -v 在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器docker-compose build nginx 构建镜像 。 docker-compose build –no-cache nginx 不带缓存的构建。docker-compose logs nginx 查看nginx的日志 docker-compose logs -f nginx 查看nginx的实时日志docker-compose config -q 验证(docker-compose.yml)文件配置,当配置正确时,不输出任何内容,当文件配置错误,输出错误信息。 docker-compose events –json nginx 以json的形式输出nginx的docker日志docker-compose pause nginx 暂停nignx容器docker-compose unpause nginx 恢复ningx容器docker-compose rm nginx 删除容器(删除前必须关闭容器)docker-compose stop nginx 停止nignx容器docker-compose start nginx 启动nignx容器4.2 docker-compose.ymldepends_on在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务:version: ‘2’services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。links还记得上面的depends_on吧,那个标签解决的是启动顺序问题,这个标签解决的是容器连接问题,与Docker client的–link一样效果,会连接到其它服务中的容器。格式如下:links: - db - db:database - redis使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:172.12.2.186 db172.12.2.186 database172.12.2.187 redis相应的环境变量也将被创建。volumes挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER] 这样的格式,或者使用 [HOST:CONTAINER:ro] 这样的格式,后者对于容器来说,数据卷是只读的,这样可以有效保护宿主机的文件系统。Compose的数据卷指定路径可以是相对路径,使用 . 或者 .. 来指定相对目录。数据卷的格式可以是下面多种形式:volumes: // 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。 - /var/lib/mysql // 使用绝对路径挂载数据卷 - /opt/data:/var/lib/mysql // 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。 - ./cache:/tmp/cache // 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。 - ~/configs:/etc/configs/:ro // 已经存在的命名的数据卷。 - datavolume:/var/lib/mysql如果你不使用宿主机的路径,你可以指定一个volume_driver。volume_driver: mydrivervolumes_from从其它容器或者服务挂载数据卷,可选的参数是 :ro或者 :rw,前者表示容器只读,后者表示容器对数据卷是可读可写的。默认情况下是可读可写的。volumes_from: - service_name - service_name:ro - container:container_name - container:container_name:rw参考文档:1. docker与dockerfile教程 2. Docker系列教程22-docker-compose.yml常用命令 ...

January 16, 2019 · 2 min · jiezi

微服务实战 - docker-compose实现mysql+springboot+angular

前言这是一次完整的项目实践,Angular页面+Springboot接口+MySQL都通过Dockerfile打包成docker镜像,通过docker-compose做统一编排。目的是实现整个项目产品的轻量级和灵活性,在将各个模块的镜像都上传公共镜像仓库后,任何人都可以通过 “docker-compose up -d” 一行命令,将整个项目的前端、后端、数据库以及文件服务器等,运行在自己的服务器上。本项目是开发一个类似于segmentfault的文章共享社区,我的设想是当部署在个人服务器上时就是个人的文章库,部署在项目组的服务器上就是项目内部的文章库,部署在公司的服务器上就是所有职工的文章共享社区。突出的特点就是,项目相关的所有应用和文件资源都是灵活的,用户可以傻瓜式地部署并使用,对宿主机没有任何依赖。目前一共有三个docker镜像,考虑以后打在一个镜像中,但目前只能通过docker-compose来编排这三个镜像。MySQL镜像:以MySQL为基础,将项目所用到的数据库、表结构以及一些基础表的数据库,通过SQL脚本打包在镜像中。用户在启动镜像后就自动创建了项目所有的数据库、表和基础表数据。SpringBoot镜像:后台接口通过SpringBoot开发,开发完成后直接可以打成镜像,由于其内置tomcat,可以直接运行,数据库指向启动好的MySQL容器中的数据库。Nginx(Angular)镜像:Nginx镜像中打包了Angular项目的dist目录资源,以及default.conf文件。主要的作用有:部署Angular项目页面;挂载宿主机目录作为文件服务器;以及反向代理SpringBoot接口,解决跨域问题等等。最后三个docker容器的编排通过docker-compose来实现,三个容器之间的相互访问都通过容器内部的别名,避免了宿主机迁移时ip无法对应的问题。为了方便开发,顺便配了个自动部署。MySQL镜像初始化脚本在项目完成后,需要生成项目所需数据库、表结构以及基础表数据的脚本,保证在运行该docker容器中,启动MySQL数据库时,自动构建数据库和表结构,并初始化基础表数据。Navicat for MySQL的客户端支持导出数据库的表结构和表数据的SQL脚本。如果没有安装Navicat,可以在连接上容器中开发用的MySQL数据库,通过mysqldump 命令导出数据库表结构和数据的SQL脚本。下文中就是将数据库的SQL脚本导出到宿主机的/bees/sql 目录:docker exec -it mysql mysqldump -uroot -pPASSWORD 数据库名称 > /bees/sql/数据库名称.sql以上只是导出 表结构和表数据的脚本,还要在SQL脚本最上方加上 生成数据库的SQL:drop database if exists 数据库名称;create database 数据库名称;use 数据库名称;通过以上两个步骤,数据库、表结构和表数据三者的初始化SQL脚本就生成好了。Dockerfile构建镜像我们生成的SQL脚本叫 bees.sql,在MySQL官方镜像中提供了容器启动时自动执行/docker-entrypoint-initdb.d文件夹下的脚本的功能(包括shell脚本和sql脚本),我们在后续生成镜像的时候,将上述生成的SQL脚本COPY到MySQL的/docker-entrypoint-initdb.d目录下就可以了。现在我们写Dockerfile,很简单:FROM mysqlMAINTAINER kerry(kerry.wu@definesys.com)COPY bees.sql /docker-entrypoint-initdb.d将 bees.sql 和 Dockerfile 两个文件放在同一目录,执行构建镜像的命令就可以了:docker build -t bees-mysql .现在通过 docker images,就能看到本地的镜像库中就已经新建了一个 bees-mysql的镜像啦。SpringBoot镜像springboot构建镜像的方式很多,有通过代码生成镜像的,也有通过jar包生成镜像的。我不想对代码有任何污染,就选择后者,通过生成的jar包构建镜像。创建一个目录,上传已经准备好的springboot的jar包,这里名为bees-0.0.1-SNAPSHOT.jar,然后同样编写Dockerfile文件:FROM java:8VOLUME /tmpADD bees-0.0.1-SNAPSHOT.jar /bees-springboot.jarEXPOSE 8010ENTRYPOINT [“java”,"-Djava.security.egd=file:/dev/./urandom","-jar","-Denv=DEV","/bees-springboot.jar"]将bees-0.0.1-SNAPSHOT.jar和Dockerfile放在同一目录执行命令开始构建镜像,同样在本地镜像库中就生成了bees-springboot的镜像:docker build -t bees-springboot .Nginx(Angular)镜像Nginx的配置该镜像主要在于nginx上conf.d/default.conf文件的配置,主要实现三个需求:1、Angualr部署Angular的部署很简单,只要将Angular项目通过 ng build –prod 命令生成dist目录,将dist目录作为静态资源文件放在服务器上访问就行。我们这里就把dist目录打包在nginx容器中,在default.conf上配置访问。2、文件服务器项目为文章共享社区,少不了的就是一个存储文章的文件服务器,包括存储一些图片之类的静态资源。需要在容器中创建一个文件目录,通过default.conf上的配置将该目录代理出来,可以直接访问目录中的文件。当然为了不丢失,这些文件最好是保存在宿主机上,在启动容器时可以将宿主机本地的目录挂载到容器中的文件目录。3、接口跨域问题在前后端分离开发的项目中,“跨域问题”是较为常见的,SpringBoot的容器和Angular所在的容器不在同一个ip和端口,我们同样可以在default.conf上配置反向代理,将后台接口代理成同一个ip和端口的地址。话不多说,结合上面三个问题,我们最终的default.conf为:server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://beesSpringboot:8010/; } location /file { alias /home/file; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; }}location / :代理的是Angular项目,dist目录内通过Dockerfile COPY在容器内的/usr/share/nginx/html目录;location /file :代理/home/file 目录,作为文件服务器;location /api/ :是为了解决跨域而做的反向代理,为了脱离宿主机的限制,接口所在容器的ip通过别名beesSpringboot来代替。别名的设置是在docker-compose.yml中设置的,后续再讲。Dockerfile构建镜像同样创建一个目录,包含Angualr的dist目录、Dockerfile和nginx的default.conf文件,目录结构如下:[root@Kerry angular]# tree.├── dist│ └── Bees│ ├── 0.cb202cb30edaa3c93602.js│ ├── 1.3ac3c111a5945a7fdac6.js│ ├── 2.99bfc194c4daea8390b3.js│ ├── 3.50547336e0234937eb51.js│ ├── 3rdpartylicenses.txt│ ├── 4.53141e3db614f9aa6fe0.js│ ├── assets│ │ └── images│ │ ├── login_background.jpg│ │ └── logo.png│ ├── favicon.ico│ ├── index.html│ ├── login_background.7eaf4f9ce82855adb045.jpg│ ├── main.894e80999bf907c5627b.js│ ├── polyfills.6960d5ea49e64403a1af.js│ ├── runtime.37fed2633286b6e47576.js│ └── styles.9e4729a9c6b60618a6c6.css├── Dockerfile└── nginx └── default.confDockerfile文件如下:FROM nginxCOPY nginx/default.conf /etc/nginx/conf.d/RUN rm -rf /usr/share/nginx/html/*COPY /dist/Bees /usr/share/nginx/htmlCMD [“nginx”, “-g”, “daemon off;"]以上,通过下列命令,构建bees-nginx-angular的镜像完成:docker build -t bees-nginx-angular . docker-compose容器服务编排上述,我们已经构建了三个镜像,相对应的至少要启动三个容器来完成项目的运行。那要执行三个docker run?太麻烦了,而且这三个容器之间还需要相互通信,如果只使用docker来做的话,不光启动容器的命令会很长,而且为了容器之间的通信,docker –link 都会十分复杂,这里我们需要一个服务编排。docker的编排名气最大的当然是kubernetes,但我的初衷是让这个项目轻量级,不太希望用户安装偏重量级的kubernetes才能运行,而我暂时又没能解决将三个镜像构建成一个镜像的技术问题,就选择了适中的一个产品–docker-compse。安装docker-compose很简单,这里就不赘言了。安装完之后,随便找个目录,写一个docker-compose.yml文件,然后在该文件所在地方执行一行命令就能将三个容器启动了:#启动docker-compose up -d#关闭docker-compose down这里直接上我写的docker-compose.yml文件version: “2"services: beesMysql: restart: always image: bees-mysql ports: - 3306:3306 volumes: - /bees/docker_volume/mysql/conf:/etc/mysql/conf.d - /bees/docker_volume/mysql/logs:/logs - /bees/docker_volume/mysql/data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: kerry beesSpringboot: restart: always image: bees-springboot ports: - 8010:8010 depends_on: - beesMysql beesNginxAngular: restart: always image: bees-nginx-angular ports: - 8000:80 depends_on: - beesSpringboot volumes: - /bees/docker_volume/nginx/nginx.conf:/etc/nginx/nginx.conf - /bees/docker_volume/nginx/conf.d:/etc/nginx/conf.d - /bees/docker_volume/nginx/file:/home/fileimage:镜像名称ports:容器的端口和宿主机的端口的映射services:文中三个service,在各自容器启动后就会自动生成别名,例如:在springboot中访问数据库,只需要通过“beesMysql:3306”就能访问。depends_on:会设置被依赖的容器启动之后,才会启动自己。例如:mysql数据库容器启动后,再启动springboot接口的容器。volumes:挂载卷,一些需要长久保存的文件,可通过宿主机中的目录,挂载到容器中,否则容器重启后会丢失。例如:数据库的数据文件;nginx的配置文件和文件服务器目录。其他自动部署为了提高开发效率,简单写了一个自动部署的脚本,直接贴脚本了:#!/bin/bashv_springboot_jar=find /bees/devops/upload/ -name "*.jar"echo “找到jar:"$v_springboot_jarv_angular_zip=find /bees/devops/upload/ -name "dist.zip"echo “找到dist:"$v_angular_zipcd /bees/conf/docker-compose downecho “关闭容器"docker rmi -f $(docker images | grep “bees-springboot” | awk ‘{print $1}’)docker rmi -f $(docker images | grep “bees-nginx-angular” | awk ‘{print $1}’)echo “删除镜像"cd /bees/devops/dockerfiles/springboot/rm -f *.jarcp $v_springboot_jar ./bees-0.0.1-SNAPSHOT.jardocker build -t bees-springboot .echo “生成springboot镜像"cd /bees/devops/dockerfiles/angular/rm -rf dist/cp $v_angular_zip ./dist.zipunzip dist.ziprm -f dist.zipdocker build -t bees-nginx-angular .echo “生成angular镜像"cd /bees/conf/docker-compose up -decho “启动容器"docker ps遇到的坑一开始在docker-compose.yml文件中写services时,每个service不是驼峰式命名,而是下划线连接,例如:bees_springboot、bees_mysql、bees_nginx_angular 。在springboot中访问数据库的别名可以,但是在nginx中,反向代理springboot接口地址时死活代理不了 bees_springboot的别名。能在bees_nginx_angular的容器中ping通bees_springboot,但是代理不了bees_springboot地址的接口,通过curl -v 查看原因,是丢失了host。最后发现,nginx默认request的header中包含“_”下划线时,会自动忽略掉。我因此把docker-compose.yml中service名称,从下划线命名都改成了驼峰式。当然也可以通过在nginx里的nginx.conf配置文件中的http部分中添加如下配置解决:underscores_in_headers on; ...

January 6, 2019 · 2 min · jiezi

Kubernetes pod里一个特殊的容器:pause-amd64

大家在使用Docker容器或者Kubernetes时,遇到过这个容器么?gcr.io/google_containers/pause-amd64docker ps的命令返回的结果:[root@k8s-minion1 kubernetes]# docker ps |grep pausec3026adee957 gcr.io/google_containers/pause-amd64:3.0 “/pause” 22 minutes ago Up 22 minutes k8s_POD.d8dbe16c_redis-master-343230949-04glm_default_ce3f60a9-095d-11e7-914b-0a77ecd65f3e_66c108d5202df18d636e gcr.io/google_containers/pause-amd64:3.0 “/pause” 24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-proxy-js0z0_kube-system_2866cfc2-0891-11e7-914b-0a77ecd65f3e_c8e1a667072d3414d33a gcr.io/google_containers/pause-amd64:3.0 “/pause” 24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-flannel-ds-tsps5_default_2866e3fb-0891-11e7-914b-0a77ecd65f3e_be4b719e[root@k8s-minion1 kubernetes]#Kubernetes的官网解释:it’s part of the infrastructure. This container is started first in all Pods to setup the network for the Pod.意思是:pause-amd64是Kubernetes基础设施的一部分,Kubernetes管理的所有pod里,pause-amd64容器是第一个启动的,用于实现Kubernetes集群里pod之间的网络通讯。对这个特殊容器感兴趣的朋友,可以阅读其源代码:https://github.com/kubernetes…我们查看这个pause-amd64镜像的dockerfile,发现实现很简单,基于一个空白镜像开始:FROM scratchARG ARCHADD bin/pause-${ARCH} /pauseENTRYPOINT ["/pause"]ARG指令用于指定在执行docker build命令时传递进去的参数。这个pause container是用C语言写的:https://www.ianlewis.org/en/a…在运行的Kubernetes node上运行docker ps,能发现这些pause container:pause container作为pod里其他所有container的parent container,主要有两个职责:是pod里其他容器共享Linux namespace的基础扮演PID 1的角色,负责处理僵尸进程这两点我会逐一细说。在Linux里,当父进程fork一个新进程时,子进程会从父进程继承namespace。目前Linux实现了六种类型的namespace,每一个namespace是包装了一些全局系统资源的抽象集合,这一抽象集合使得在进程的命名空间中可以看到全局系统资源。命名空间的一个总体目标是支持轻量级虚拟化工具container的实现,container机制本身对外提供一组进程,这组进程自己会认为它们就是系统唯一存在的进程。在Linux里,父进程fork的子进程会继承父进程的命名空间。与这种行为相反的一个系统命令就是unshare:再来聊聊pause容器如何处理僵尸进程的。Pause容器内其实就运行了一个非常简单的进程,其逻辑可以从前面提到的Pause github仓库上找到:static void sigdown(int signo) { psignal(signo, “Shutting down, got signal”); exit(0);}static void sigreap(int signo) { while (waitpid(-1, NULL, WNOHANG) > 0);}int main() { if (getpid() != 1) /* Not an error because pause sees use outside of infra containers. */ fprintf(stderr, “Warning: pause should be the first process\n”); if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) return 1; if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) return 2; if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap, .sa_flags = SA_NOCLDSTOP}, NULL) < 0) return 3; for (;;) pause(); fprintf(stderr, “Error: infinite loop terminated\n”); return 42;}这个c语言实现的进程,核心代码就28行:其中第24行里一个无限循环for(;;), 至此大家能看出来pause容器名称的由来了吧?这个无限循环里执行的是一个系统调用pause,因此pause容器大部分时间都在沉睡,等待有信号将其唤醒。接收什么信号呢?一旦收到SIGCHLD信号,pause进程就执行注册的sigreap函数。看下SIGCHLD信号的帮助:SIGCHLD,在一个进程正常终止或者停止时,将SIGCHLD信号发送给其父进程,按系统默认将忽略此信号,如果父进程希望被告知其子系统的这种状态,则应捕捉此信号。pause进程注册的信号处理函数sigreap里,调用另一个系统调用waitpid来获得子进程终止的原因。希望这篇文章对大家理解Kubernetes里的pause容器有所帮助。感谢阅读。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

December 21, 2018 · 1 min · jiezi

容器和容器镜像的区别,您真的了解吗

很多刚刚接触容器技术的朋友,不容易弄清楚容器,容器镜像和Docker这几个词的区别和联系。我们首先来看容器和容器镜像。举个例子,执行命令行docker search nginx,搜索结果的一条条记录就是一个个容器镜像。所谓镜像,就是一个静态概念,一个镜像由若干只读层(read-only layer)构成。上图左边是Docker镜像的内部实现细节,我们能看到多个只读层叠加在一起,层与层之间通过指针关联,这些层能够在运行Docker的宿主机的文件系统上访问到。Linux的统一文件系统(union file system)技术将这些叠加的只读层合并成一个文件系统,该系统为这些只读层提供了一个统一的视角,从而为Docker的用户隐藏了多层的存在。从Docker用户的视角出发,一个Docker镜像只存在一个文件系统,即上图右边所示。这些文件系统的设计是Docker实现细节,一般情况下我们不用去深究。但如果您足够好奇,使用命令sudo tree浏览目录 /var/lib/docker即可:比如我用命令docker images浏览下载到本地的docker镜像:其中一个叫jerry-nginx的镜像,是一个web应用,它的所有内容能在/var/lib/docker目录下的这个目录查到:讲完了容器镜像,我们再来看容器。容器和容器镜像一样,也是若干层的叠加,唯一区别是所有只读层的最上面一层,是一层可读可写层,如上图绿色图例所示。初学者可以记住这个简单的公式:容器 = 容器镜像 + 可读可写层我们如果用命令docker ps –all查看本机所有容器列表,会发现有的容器处于运行状态,有的处于退出状态。因此,一个处于运行状态的容器(running container)包含一个可读写的文件系统加上隔离的进程空间。容器里的进程可以对这个可读写文件系统内的文件进行修改、删除、创建等操作。镜像里每一层其实都能在docker文件夹的containers子目录下找到:上图每一个红色文件夹代表镜像里的一层,蓝色文件包含了该层运行时的日志文件,或者网络相关配置等。做个实验:ubuntu这个容器执行结束后,使用find / -name i042416.txt文件,这说明docker运行时能对宿主机的文件系统进行写操作。下面分析几个常用的易混淆的命令。docker create <image-id>先看它的帮助文档:试着执行以下:产生一个输出id:7ee10851c3f1e53bbd35e5f196f34de560afa1a20d9bf1ced587630dbcda877bcreate创建的容器,状态变为created:docker create命令给通过命令行传入的容器镜像创建了一个新的可读可写层,从而生成了一个新的容器实例:然后再执行docker start,输入docker create创建的容器实例ID,就可以启动这个容器实例了。而docker run其实就是docker create和docker start这两个命令合二为一的版本。希望这篇文章能帮助大家理解容器和容器镜像的区别。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

December 21, 2018 · 1 min · jiezi

Docker技术三大要点:cgroup, namespace和unionFS的理解

www.docker.com的网页有这样一张有意思的动画:从这张gif图片,我们不难看出Docker网站想传达这样一条信息, 使用Docker加速了build,ship和run的过程。Docker最早问世是2013年,以一个开源项目的方式被大家熟知。Docker的奠基者是dotcloud,一家开发PaaS平台的技术公司。不过可惜的是,这家公司把Docker开源之后,于2016年倒闭了,因为其主业务PaaS无法和微软,亚马逊等PaaS业界巨头竞争,不禁让人唏嘘。Docker其实是容器化技术的具体技术实现之一,采用go语言开发。很多朋友刚接触Docker时,认为它就是一种更轻量级的虚拟机,这种认识其实是错误的,Docker和虚拟机有本质的区别。容器本质上讲就是运行在操作系统上的一个进程,只不过加入了对资源的隔离和限制。而Docker是基于容器的这个设计思想,基于Linux Container技术实现的核心管理引擎。为什么资源的隔离和限制在云时代更加重要?在默认情况下,一个操作系统里所有运行的进程共享CPU和内存资源,如果程序设计不当,最极端的情况,某进程出现死循环可能会耗尽CPU资源,或者由于内存泄漏消耗掉大部分系统资源,这在企业级产品场景下是不可接受的,所以进程的资源隔离技术是非常必要的。我当初刚接触Docker时,以为这是一项新的技术发明,后来才知道,Linux操作系统本身从操作系统层面就支持虚拟化技术,叫做Linux container,也就是大家到处能看到的LXC的全称。LXC的三大特色:cgroup,namespace和unionFS。cgroup:CGroups 全称control group,用来限定一个进程的资源使用,由Linux 内核支持,可以限制和隔离Linux进程组 (process groups) 所使用的物理资源 ,比如cpu,内存,磁盘和网络IO,是Linux container技术的物理基础。namespace:另一个维度的资源隔离技术,大家可以把这个概念和我们熟悉的C++和Java里的namespace相对照。如果CGroup设计出来的目的是为了隔离上面描述的物理资源,那么namespace则用来隔离PID(进程ID),IPC,Network等系统资源。我们现在可以将它们分配给特定的Namespace,每个Namespace里面的资源对其他Namespace都是透明的。不同container内的进程属于不同的Namespace,彼此透明,互不干扰。我们用一个例子来理解namespace的必要。假设多个用户购买了一台Linux服务器的Nginx服务,每个用户在该服务器上被分配了一个Linux系统的账号。我们希望每个用户只能访问分配给其的文件夹,这当然可以通过Linux文件系统本身的权限控制来实现,即一个用户只能访问属于他本身的那些文件夹。但是有些操作仍然需要系统级别的权限,比如root,但我们肯定不可能给每个用户都分配root权限。因此我们就可以使用namespace技术:我们能够为UID = n的用户,虚拟化一个namespace出来,在这个namespace里面,该用户具备root权限,但是在宿主机上,该UID =n的用户还是一个普通用户,也感知不到自己其实不是一个真的root用户这件事。同样的方式可以通过namespace虚拟化进程树。在每一个namespace内部,每一个用户都拥有一个属于自己的init进程,pid = 1,对于该用户来说,仿佛他独占一台物理的Linux服务器。对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为1),其他进程的PID依次递增,A和B空间都有PID为1的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。从图中我们可以看到,进程3在父命名空间里面PID 为3,但是在子命名空间内,他就是1.也就是说用户从子命名空间 A 内看进程3就像 init 进程一样,以为这个进程是自己的初始化进程,但是从整个 host 来看,他其实只是3号进程虚拟化出来的一个空间而已。看下面的图加深理解。父容器有两个子容器,父容器的命名空间里有两个进程,id分别为3和4, 映射到两个子命名空间后,分别成为其init进程,这样命名空间A和B的用户都认为自己独占整台服务器。Linux操作系统到目前为止支持的六种namespace:unionFS:顾名思义,unionFS可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。要理解unionFS,我们首先要认识bootfs和rootfs。1. boot file system (bootfs):包含操作系统boot loader 和 kernel。用户不会修改这个文件系统。一旦启动完成后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放出内存。同样内核版本的不同的 Linux 发行版,其bootfs都是一致的。2. root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp就是我下面这张图里的这些文件夹:等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。Linux 系统在启动时,roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了。不同的Linux版本,实现unionFS的技术可能不一样,使用命令docker info查看,比如我的机器上实现技术是overlay2:看个实际的例子。新建两个文件夹abap和java,在里面用touch命名分别创建两个空文件:新建一个mnt文件夹,用mount命令把abap和java文件夹merge到mnt文件夹下,-t执行文件系统类型为aufs:sudo mount -t aufs -o dirs=./abap:./java none ./mntmount完成后,到mnt文件夹下查看,发现了来自abap和java文件夹里总共4个文件:现在我到java文件夹里修改spring,比如加上一行spring is awesome, 然后到mnt文件夹下查看,发现mnt下面的文件内容也自动被更新了。那么反过来会如何呢?比如我修改mnt文件夹下的aop文件:而java文件夹下的原始文件没有受到影响:实际上这就是Docker容器镜像分层实现的技术基础。如果我们浏览Docker hub,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如debian基础镜像。而新镜像就是从基础镜像上一层层叠加新的逻辑构成的。这种分层设计,一个优点就是资源共享。想象这样一个场景,一台宿主机上运行了100个基于debian base镜像的容器,难道每个容器里都有一份重复的debian拷贝呢?这显然不合理;借助Linux的unionFS,宿主机只需要在磁盘上保存一份base镜像,内存中也只需要加载一份,就能被所有基于这个镜像的容器共享。当某个容器修改了基础镜像的内容,比如 /bin文件夹下的文件,这时其他容器的/bin文件夹是否会发生变化呢?根据容器镜像的写时拷贝技术,某个容器对基础镜像的修改会被限制在单个容器内。这就是我们接下来要学习的容器 Copy-on-Write 特性。容器镜像由多个镜像层组成,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /text,上层的 /text 会覆盖下层的 /text,也就是说用户只能访问到上层中的文件 /text。假设我有如下这个dockerfile:FROM debianRUN apt-get install emacsRUN apt-get install apache2CMD ["/bin/bash"]执行docker build .看看发生了什么。生成的容器镜像如下:当用docker run启动这个容器时,实际上在镜像的顶部添加了一个新的可写层。这个可写层也叫容器层。容器启动后,其内的应用所有对容器的改动,文件的增删改操作都只会发生在容器层中,对容器层下面的所有只读镜像层没有影响。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

December 21, 2018 · 1 min · jiezi

Liunx docker-compose 实战

Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。容器技术是继大数据和云计算之后又一炙手可热的技术,而且未来相当一段时间内都会非常流行。本文介绍在Liunx下docker-compose编排PHP基本环境基本步骤,废话少说直奔主题。安装docker本文选用 Centos7.3系统确保系统中无残留dockersudo yum remove docker \docker-common \docker-selinux \docker-engine-selinux \docker-engine \docker-ce安装前准备sudo yum install -y yum-utils device-mapper-persistent-data lvm2更换yum 软件源sudo yum-config-manager \ –add-repo \ https://download.docker.com/linux/centos/docker-ce.repo设置使用最新Docker CEsudo yum-config-manager –enable docker-ce-edgesudo yum-config-manager –enable docker-ce-test安装dockersudo yum install docker-ce如果非root用户配置非root运行dockersudo usermod -aG docker 用户名启动service docker start查看是否安装成功docker info配置加速https://www.daocloud.io/ (加速器申请地址#回到服务器将你或得到的命令直接运行curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://你的编号.m.daocloud.io#重启dockerservice docker restart安装docker-composehttps://github.com/docker/com… github下载地址执行conpose下载curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s-uname -m` -o /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-compose实验docker-compose -version环境搭建成功后可观看 docker编排PHP开发坏境 部署属于你的环境致谢谢谢各位观看,欢迎讨论~

November 2, 2018 · 1 min · jiezi

Rails Docker开发环境配置

rails mysql redis 的开发环境首先构建自己的镜像Dockerfile.developmentFROM ruby:2.3.4-slimRUN apt-get update && apt-get install -y \ build-essential \ nodejs \ libmysqlclient-devRUN mkdir -p /appWORKDIR /appCOPY Gemfile Gemfile.lock /app/RUN gem install bundler && bundle install –jobs 20 –retry 5COPY . /appEXPOSE 4000ENTRYPOINT [“bundle”, “exec”]CMD [“rails”, “server”, “-b”, “0.0.0.0”, “-p”, “4000”]docker-compose.yml 配置version: ‘3’services: mysql: image: mysql:5.7.17 command: –sql-mode="" restart: always volumes: - ./mysql_data/:/var/lib/mysql ports: - “3306:3306” environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: shiji_development redis: image: redis command: redis-server volumes: - ./redis_data:/data ports: - 6379:6379 web: build: context: . dockerfile: Dockerfile.development command: bash -c “rm -f tmp/pids/server.pid && bundle exec rails s -p 4000 -b ‘0.0.0.0’” stdin_open: true tty: true volumes: - .:/app ports: - “4000:4000” depends_on: - mysql - redis ...

October 26, 2018 · 1 min · jiezi

使用Docker部署Spring-Boot+Vue博客系统

在今年年初的时候,完成了自己的个Fame博客系统的实现,当时也做了一篇博文Spring-boot+Vue = Fame 写blog的一次小结作为记录和介绍。从完成实现到现在,也断断续续的根据实际的使用情况进行更新。只不过每次上线部署的时候都觉得有些麻烦,因为我的服务器内存太小,每次即使只更新了前台部分(fame-front)的代码,在执行npm build的时候都还必须把我的后端服务(fame-server)的进程关掉,不然会造成服务器卡死(惨啊)。而且这个项目是前后端分离的,博客前台页面还为了SEO用了Nuxt框架,假如是第一次部署或者要服务器迁移的话,麻烦的要死啊,部署一次的话要以下步骤安装mysql,修改相关配置文件,设置编码时区等,然后重启下载安装java,配置java环境下载安装maven,配置maven环境下载安装nginx,修改配置文件,设计反向代理等启动spring-boot项目打包vue项目,npm install,npm run build等启动nuxt项目,npm install,npm run start等如果能够顺利的完成这七个步骤算是幸运儿了,假如中间哪个步骤报错出了问题,可能还要回头查找哪个步骤出了问题,然后又重新部署。在这些需求面前,Docker就是解决这些问题的大杀器。无论是其虚拟化技术隔离各个容器使其资源互不影响,还是一致的运行环境,以及docker-compose的一键部署,都完美的解决了上述问题。项目地址:FameDocker和Docker-compose安装Docker和Docker-compose的功能和使用可以看线上的一个中文文档Docker — 从入门到实践下面是Centos7安装和配置Docker以及Docker-compose的shell脚本,其他操作系统可以参考修改来安装。其中Docker版本为docker-ce,Docker-compose版本为1.22.0#!/bin/sh### 更新 ###yum -y update### 安装docker #### 安装一些必要的系统工具sudo yum install -y yum-utils device-mapper-persistent-data lvm2# 添加软件源信息sudo yum-config-manager –add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 更新 yum 缓存sudo yum makecache fast# 安装 Docker-cesudo yum -y install docker-ce# 启动docker并设置为开机启动(centos7)systemctl start docker.servicesystemctl enable docker.service# 替换docker为国内源echo ‘{“registry-mirrors”: [“https://registry.docker-cn.com”],“live-restore”: true}’ > /etc/docker/daemon.jsonsystemctl restart docker# 安装dokcer-composesudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s-uname -m` -o /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-compose# 安装命令补全工具yum -y install bash-completioncurl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version –short)/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose### 安装docker结束 ###Docker化改造改造后目录结构先看一下改造后的项目的结构├─Fame│ │ .env // docker-compose环境参数配置文件│ │ docker-compose.yml // docker-compose文件│ ├─fame-docker│ │ │ fame-front-Dockerfile // fame-front的Dockerfile文件│ │ │ fame-server-Dockerfile // fame-server的Dockerfile文件│ │ │ │ │ ├─fame-admin│ │ │ fame-admin-Dockerfile // fame-admin的Dockerfile文件│ │ │ nginx.conf // fame-admin的nginx服务器配置文件│ │ │ │ │ ├─fame-mysql│ │ │ fame-mysql-Dockerfile // mysql的Dockerfile文件│ │ │ mysqld.cnf // mysql的配置文件mysqld.cnf│ │ │ │ │ └─fame-nginx│ │ nginx-Dockerfile // 整个项目的nginx服务器的Dockerfile文件│ │ nginx.conf // 整个项目的nginx的配置文件│ │ │ ├─fame-admin // 博客管理后台,基于Vue+elementui│ ├─fame-front // 博客前端,基于Nuxt│ └─fame-server // 博客服务端,基于spring-boot为了不破坏原有项目的结构,无论前端还是后端的docker的相关配置文件全部提取出来,单独放在了fame-docker文件夹中。docker-compose.yml放在项目根目录下,直接在根目录运行命令:docker-compose up -d[root@localhost Fame]# docker-compose up -dStarting fame-front … Starting fame-admin … Starting fame-front … doneStarting fame-admin … doneStarting fame-nginx … done就启动项目了,再也不用重复繁琐的步骤!改造后的docker项目结构改造后的docker-compose.yaml文件version: ‘3’services: fame-nginx: container_name: fame-nginx build: context: ./ dockerfile: ./fame-docker/fame-nginx/nginx-Dockerfile ports: - “80:80” volumes: - ./logs/nginx:/var/log/nginx depends_on: - fame-server - fame-admin - fame-front fame-mysql: container_name: fame-mysql build: context: ./ dockerfile: ./fame-docker/fame-mysql/fame-mysql-Dockerfile environment: MYSQL_DATABASE: fame MYSQL_ROOT_PASSWORD: root MYSQL_ROOT_HOST: ‘%’ TZ: Asia/Shanghai expose: - “3306” volumes: - ./mysql/mysql_data:/var/lib/mysql restart: always fame-server: container_name: fame-server restart: always build: context: ./ dockerfile: ./fame-docker/fame-server-Dockerfile working_dir: /app volumes: - ./fame-server:/app - ~/.m2:/root/.m2 - ./logs/fame:/app/log expose: - “9090” command: mvn clean spring-boot:run -Dspring-boot.run.profiles=docker -Dmaven.test.skip=true depends_on: - fame-mysql fame-admin: container_name: fame-admin build: context: ./ dockerfile: ./fame-docker/fame-admin/fame-admin-Dockerfile args: BASE_URL: ${BASE_URL} expose: - “3001” fame-front: container_name: fame-front build: context: ./ dockerfile: ./fame-docker/fame-front-Dockerfile environment: BASE_URL: ${BASE_URL} PROXY_HOST: ${PROXY_HOST} PROXY_PORT: ${PROXY_PORT} expose: - “3000"docker-compose.yml的结构和刚才目录结构大体类似,也是分以下几个部分fame-nginxfame-mysqlfame-serverfame-adminfame-front这个docker-compose.yml中有几个要点fame-mysql和fame-server的restart要设置为always,因为目前Docker-compose是没有一个方案可以解决容器启动的先后的问题的。即使设置了depends_on,那也只是控制容器开始启动的时间,不能控制容器启动完成的时间,所以让fame-mysql和fame-server这两个容器设置restart,防止spring-boot在mysql启动完成之前启动而报错启动失败fame-server,fame-mysql,fame-nginx这三个容器都设置了volumes,把容器里的logs日志文件挂载到宿主机的项目目录里,方便随时看日志文件fame-mysql容器的mysql存储文件也设置了volumes挂载在项目目录里(./mysql/mysql_data:/var/lib/mysql),这个建议大家可以根据实际的情况设置到宿主机的其他目录里,不然不小心删除项目的话那么容器里的数据库数据也都没了几个镜像的Dockerfile大部分都比较简单,这部分就不全部详细介绍了,可以直接去我项目中了解。Docker化过程的困难和解决方法spring-boot双配置切换为了能够让spring-boot能够在开发环境和Docker环境下快速切换,需要将spring-boot的配置文件进行修改└─fame-server … │ └─resources │ │ application-dev.properties │ │ application-docker.properties │ │ application.properties在原有的application.properties基础上增加application-dev.properties和application-docker.properties配置文件,把application.properties里的数据库日志等信息分别放到application-dev.properties和application-docker.properties这两个文件中,实现开发环境和Docker环境的快速切换。# application.properties文件#端口号server.port=9090#mybatismybatis.type-aliases-package=com.zbw.fame.Model#mappermapper.mappers=com.zbw.fame.util.MyMappermapper.not-empty=falsemapper.identity=MYSQL#mailspring.mail.properties.mail.smtp.auth=truespring.mail.properties.mail.smtp.starttls.enable=truespring.mail.properties.mail.smtp.starttls.required=true#默认propertiesspring.profiles.active=dev# application-docker.properties文件#datasourcespring.datasource.driverClassName=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://fame-mysql:3306/fame?useUnicode=true&characterEncoding=utf-8&useSSL=falsespring.datasource.username=rootspring.datasource.password=root#loglogging.level.root=INFOlogging.level.org.springframework.web=INFOlogging.file=log/fame.logapplication-dev.properties的内容和application-docker.properties文件类似,只是根据自己开发环境的情况修改mysql和log配置。动态配置axios的baseUrl地址在fame-admin和fame-front中用了axios插件,用于发起和获取fame-server服务器的请求。在axios要配置服务器url地址baseUrl,那么通常开发环境和Docker环境以及生产环境的url可能都不一样,每次都去修改有点麻烦。(虽然只需要配置两处,但是代码洁癖不允许我硬编码这个配置)。先修改fame-admin(Vue)使其兼容手动部署模式和Docker模式fame-admin是基于Vue CLI 3搭建的,相对于cli 2.0官方把webpack的一些配置文件都封装起来了,所以没有config和build文件夹。不过对应的官网也给了一些设置更加方便的配置参数。在官方文档中提到:只有以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中。你可以在应用的代码中这样访问它们:console.log(process.env.VUE_APP_SECRET)在构建过程中,process.env.VUE_APP_SECRET 将会被相应的值所取代。在 VUE_APP_SECRET=secret 的情况下,它会被替换为 “sercet”。利用这个特性来设置环境变量来动态的设置Docker模式和手动部署模式的baseUrl的值在fame-admin目录下创建文件server-config.js,编写以下内容const isProd = process.env.NODE_ENV === ‘production’const localhost = ‘http://127.0.0.1:9090/‘const baseUrl = process.env.VUE_APP_API_URL || localhostconst api = isProd ? baseUrl : localhostexport default { isProd, api}那么只要在环境变量中有VUE_APP_API_URL的值,且NODE_ENV === ‘production’,baseUrl就等于VUE_APP_API_URL的值,否则就是localhost的值。接着在axios配置文件中引用该文件设置// fame-admin/src/plugins/http.js…import serverConfig from ‘../../server-config’const Axios = axios.create({ baseURL: serverConfig.api + ‘api/’, …}) …现在只要将docker的环境变量设置一个VUE_APP_API_URL的值就行了,只要在对应的Dockerfile中增加一个步骤就可以了。ENV VUE_APP_API_URL http://xx.xxx.xxx.xxx再修改fame-front(Nuxt)使其兼容手动部署模式和Docker模式同样的,对于用Nuxt搭建fame-front博客前台修改也是类似的思路。在Nuxt的官方文档中写到:Nuxt.js 让你可以配置在客户端和服务端共享的环境变量。例如 (nuxt.config.js):module.exports = { env: { baseUrl: process.env.BASE_URL || ‘http://localhost:3000’ }}以上配置我们创建了一个 baseUrl 环境变量,如果应用设定了 BASE_URL 环境变量,那么 baseUrl 的值等于 BASE_URL 的值,否则其值为 http://localhost:3000。所以我们只要和官方文档说的一样,在nuxt.config.js文件中增加代码就可以了module.exports = { env: { baseUrl: process.env.BASE_URL || ‘http://localhost:3000’ }}接着在server-config.js文件和axios的配置文件fame-front/plugins/http.js以及对应的Dockerfile文件中编写和上面fame-admin部分一样的代码就可以了现在已经把baseUrl的设置从代码的硬编码中解放出来了,但事实上我们只是把这个参数的编码从代码从转移到Dockerfile文件里了,要是想要修改的话也要去这两个文件里查找然后修改,这样也不方便。后面会解决这个问题把所有环境配置统一起来。Nuxt在Docker中无法访问到宿主机ip问题先要说明一点,为什么博客前端要单独去使用的Nuxt而不是和博客后台一样用Vue呢,因为博客前端有SEO的需求的,像Vue这样的对搜索引擎很不友好。所以Nuxt的页面是服务器端渲染(SSR)的这样就产生了问题fame-front的页面在渲染之前必须获取到fame-server服务器中的数据,但是每个docker容器都是互相独立的,其内部想要互相访问只能通过容器名访问。例如容器fame-front想要访问容器fame-server,就设置baseURL = fame-server (fame-server是服务器的容器的container_name)。这样设置之后打开浏览器输入网址:http://xx.xxx.xxx.xx可以成功…,但是随便点击一个链接,就会看到浏览器提示错误无法访问到地址http://fame-server/…vendor.e2feb665ef91f298be86.js:2 GET http://fame-server/api/article/1 net::ERR_CONNECTION_REFUSED这是必然的结果,在容器里http://fame-server/就是服务器…,但是你本地的浏览器当然是不知道http://fame-server/是个什么鬼…,所以就浏览器就报出无法访问的错误。什么?可是刚才不是说Nuxt是服务器渲染的页面吗,怎么又让本地浏览器报这个错误了。原来是因为当通过浏览器链接直接访问的时候,Nuxt的确是从后端渲染了页面再传过来,但是在页面中点击链接的时候是通过Vue-Router跳转的,这时候不在Nuxt的控制范围,而是和Vue一样在浏览器渲染的,这时候就要从浏览器里向服务端获取数据来渲染,浏览器就会报错。如何解决呢这个问题开始的时候一直想要尝试配置Docker容器的网络模式来解决,可是都没有解决。直到后面我看axios文档的时候才注意到axios的代理功能,其本质是解决跨域的问题的,因为只要在axios设置了代理,在服务端渲染的时候就会使用代理的地址,同时在浏览器访问的时候会用baseUrl 的地址,这个特点完美解决我的问题啊。在server-config.js文件里增加以下代码(在nuxt.config.js里获取环境变量里的proxyHost和proxyPort)…const localProxy = { host: ‘127.0.0.1’, port: 9090}const baseProxy = { host: process.env.proxyHost || localProxy.host, port: process.env.proxyPort || localProxy.port}exports.baseProxy = isProd ? baseProxy : localProxy…然后在axios配置文件里增加代码// fame-front/plugins/http.jsconst Axios = axios.create({ proxy: serverConfig.baseProxy …}) …就可以完美的解决问题了。Dockerfile的环境参数统一设置在上文解决动态配置axios地址的部分把baseUrl的设置放在了Dockerfile中,现在就再把Dockerfile中的硬编码提取出来,放到统一的配置文件中。首先在docker-compose.yml文件目录下(即项目跟目录)创建环境文件.env并编写一下内容BASE_URL=http://xx.xxx.xxx.xxxPROXY_HOST=fame-nginxPROXY_PORT=80这个是docker-compose的env_file参数,从文件中获取环境变量,可以为单独的文件路径或列表,如果同目录下有.env文件则会默认读取,也可以自己在docker-compose里设置路径。已经在.env设置了环境变量BASE_URL的值,就能在docker-compose.yml里直接使用了。修改docker-compose.yml的fame-front部分:fame-front: … environment: BASE_URL: ${BASE_URL} PROXY_HOST: ${PROXY_HOST} PROXY_PORT: ${PROXY_PORT} …这样在fame-front的容器里就有对应的BASE_URL,PROXY_HOST,PROXY_PORT环境变量,Nuxt也能够成功获取并设置。不过对于fame-admin容器来说就要稍微复杂一点点了。先来看一下fame-admin容器的Dockerfile文件fame-admin-Dockerfile# build stageFROM node:10.10.0-alpine as build-stage#中间一些操作省略…RUN npm run build# production stageFROM nginx:1.15.3-alpine as production-stageCOPY ./fame-docker/fame-admin/nginx.conf /etc/nginx/conf.d/default.confCOPY –from=build-stage /app/dist /usr/share/nginx/htmlEXPOSE 80CMD [“nginx”, “-g”, “daemon off;"]这里用了多阶段构建容器,如果直接通过docker-compose设置环境变量只会在后面一个阶段生效,但是npm run build是在第一个阶段执行的,所以环境变量不能应用到Vue当中。为了让环境变量在第一阶段就应用,必须要在构建的时候就把变量从docker-compose传到fame-admin-Dockerfile中,然后在Dockerfile中的第一阶段把这个环境变量应用到容器里。下面修改docker-compose.yml的fame-admin部分: fame-admin: … build: context: ./ dockerfile: ./fame-docker/fame-admin/fame-admin-Dockerfile args: BASE_URL: ${BASE_URL} # 这里把环境变量当做ARG传给Dockerfile …然后在fame-admin-Dockerfile的第一阶段增加步骤# build stageFROM node:10.10.0-alpine as build-stageARG BASE_URL # 必须申明这个ARG才能从docker-compose里获取ENV VUE_APP_API_URL $BASE_URL# 以下省略…这样就可以在构建阶段一镜像的时候就把环境变量传入到阶段一的镜像里,让Vue里的变量生效了。总结现在网上很多复杂一点的项目即使用了docker-compose部署,也多少依赖shell脚本来操作,比如复制文件设置环境等,我觉得这样会降低docker-compose的意义。如果都使用了shell脚本,那不如直接不用docker-compose而全用shell来构建和启动镜像。所以在Docker化的过程中虽然遇到一些坎坷,但坚持实现了只用docker-compose部署,以后上线和下线就及其方便了。也希望我的Docker化思路可以给其他项目做一些参考。对比以前恐怖的步骤,现在Fame博客的上线和下线只需要两行命令,真的十分的便捷。docker-compose updocker-compose down源码地址:doodle原文地址:使用Docker部署Spring-Boot+Vue博客系统 ...

September 29, 2018 · 3 min · jiezi