LinuxGod

LinuxGod.net
Linux大神网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

docker-compose用镜像解决PaaS标准化的问题,你还能调试吗?

2023年7月7日 182点热度

搭建开发环境步骤_linux设置环境变量env_怎么搭开发环境

现况

现今的开发模式基本是微服务开发模式,一个服务依赖N个其它服务,一个后端依赖N个前端,倘若本地要debug的话,将会是一件十分头痛的事,常见的debug模式有以下几种:

1. 叫相关开发人员将服务运行起来,然后连接调试
2. 自己将所有代码clone下来,自己在本地运行相关服务
复制代码

似乎也没哪些问题,也可以调试,然而弊病也很显著

先说方案1的弊病

假如开发某日事假了,你没调试环境了,你就能调试吗?假如开发又加了新功能,由于功能是个半成品,不稳定,造成你依赖的插口访问不了,你就能调试吗?

方案2的弊病

这个要求所有开发要熟悉整个技术栈的环境创建、编译建立相关的知识,例如:后端用的是vue,前端开发要安装nodejs,要懂一些npm,vue啥的,前端用的是go,后端要安装go,要懂go的依赖安装,go编译啥的由于有多个服务,服务间若果用了相同端口,才会有端口冲突,改了端口后,相关依赖的服务都要更改,这就要求相关开发要对整个构架、服务依赖特别了解,不然肯定十分折腾

上述方案都只是用一些成本比较大的形式提供了一个不太稳定的开发环境

几个工具docker

要保证开发环境的稳定,就须要一个不可变的基础设施,说到不可变基础设施,肯定就要说一下docker了linux删除命令,docker用镜像解决了PaaS标准化的问题,将PaaS弄成了一个不可变基础设施,这样无论我们在哪些操作系统上,创建下来的实例都可以运行上去,配置一样的情况下,提供的服务也是一样的,但docker只保证单实例的一致性,我们的服务有N多个,怎么将它们构建关联关系并运行上去呢

docker-compose

docker-compose可以申明一组服务,指定启动镜像、启动命令、暴露服务端口,可以挺好的解决服务编排的问题

我们用以下这些服务构架为反例,为每位应用创建一个开发环境

搭建开发环境步骤_怎么搭开发环境_linux设置环境变量env

用docker镜像来解决服务运行环境问题,每位项目有一个Dockerfile、build-dev-image.sh文件,用build-dev-image.sh来建立当前分支下的代码linux设置环境变量env,并push到dockerregistry,依赖项目只须要引用相关版本的镜像就好了

搭建开发环境步骤_linux设置环境变量env_怎么搭开发环境

用docker-compose来解决服务依赖问题,每位项目都要有一个docker-compose.yml文件,申明依赖服务的镜像版本,服务的端口

搭建开发环境步骤_linux设置环境变量env_怎么搭开发环境

建立开发环境docker镜像后端

怎么搭开发环境_linux设置环境变量env_搭建开发环境步骤

Dockerfile如下:

FROM nginx:1.19.2-alpine
COPY ./dist /usr/share/nginx/html
复制代码

build-dev-image.sh如下:

#!/bin/bash
pwdStr=`pwd`
dirName=${pwdStr##*/}
buildTime=`date '+%Y%m%d%H%M'`
harborHost="docker registry domain"
latestTag=$harborHost/dev/${dirName}:latest
buildTimeTag=$harborHost/dev/${dirName}:${buildTime}
harborUser="dev"
harborPasswd="xxxx"
npm run build
docker build -t $latestTag -t $buildTimeTag .
docker login $harborHost -u"$harborUser" -p"$harborPasswd"
docker push $latestTag
docker push $buildTimeTag
echo "docker镜像名称: $latestTag"
echo "docker镜像名称: $buildTimeTag"
复制代码

build-dev-image.sh主要做了:

建立docker镜像push到dockerregistry

功能开发完了,要联调了,执行一下build-dev-image.sh,镜像就建立好了,并push到镜像库房了,须要的项目按需取

这儿输出了两个tag,一个是latest,一个是用年月日的linux设置环境变量env,具体用那个,看变更频繁度,若果很频繁就用年月日的,否则就用latest的,这样就不用老是更改docker-compose.yml了

前端

搭建开发环境步骤_linux设置环境变量env_怎么搭开发环境

Dockerfile

FROM alpine:3.11.6
COPY main /app/
EXPOSE 8000
WORKDIR /app
CMD ["/app/main"]
复制代码

build-dev-image.sh

#!/bin/bash
pwdStr=$(pwd)
dirName=${pwdStr##*/}
buildTime=$(date '+%Y%m%d%H%M')
harborHost="docker registry domain"
latestTag=$harborHost/dev/${dirName}:latest
buildTimeTag=$harborHost/dev/${dirName}:${buildTime}
harborUser="dev"
harborPasswd="xxxx"
GOOS=linux CGO_ENABLED=0 go build -o main main.go
docker build -t $latestTag -t $buildTimeTag .
docker login $harborHost -u"$harborUser" -p"$harborPasswd"
docker push $latestTag
docker push $buildTimeTag
echo "docker镜像名称: $latestTag"
echo "docker镜像名称: $buildTimeTag"
rm -f main
复制代码

服务信息

先看下项目信息

example-front

examplea

exampleb

exampleb

只是简单的输出一个字符串

package main
import (
 "log"
 "net/http"
)
func main() {
 http.HandleFunc("/b/api", func(writer http.ResponseWriter, request *http.Request) {
  log.Println(request.URL.Path)
  writer.Write([]byte("project b"))
 })
 http.ListenAndServe(":8000", nil)
}
复制代码

examplea

调用examplab,并输出一个字符串

const (
 // 从配置服务中取
 PROJECT_B_DOMAIN = "http://exampleb:8000"
)
func main() {
 http.HandleFunc("/a/api", func(writer http.ResponseWriter, request *http.Request) {
  log.Println(request.URL.Path)
  resp, _ := http.Get(PROJECT_B_DOMAIN + "/b/api")
  defer resp.Body.Close()
  result, _ := io.ReadAll(resp.Body)
  writer.Header().Set("Access-Control-Allow-Origin", "*")
  
  writer.Write([]byte("project a
")) writer.Write(result) }) http.ListenAndServe(":8000", nil) } 复制代码

example-front

调用examplea


  

Server Response:

import axios from "axios"; export default { name: "App", data() { return { resp: "", }; }, mounted() { axios.get("http://localhost:8000/a/api").then((resp) => { this.resp = resp.data; }); }, }; 复制代码

创建开发环境example-front

example-front依赖examplea,examplea又依赖exampleb,所以我们须要两个服务,并曝露examplea的端口到宿主机上,供后端调用

docker-compose.yml如下:

version: '3'
services:
  examplea:
    image: {{docker registry domain}}/dev/examplea:latest
    ports:
      - 8000:8000
      
  exampleb:
    image: {{docker registry domain}}/dev/exampleb:latest
复制代码

之后运行docker-composeup,再执行npmrunserve,之后打开浏览器就可以看见

怎么搭开发环境_linux设置环境变量env_搭建开发环境步骤

为了便捷一些,我们可以直接更改package.json的scripts,将docker-composeup-d加到serve上,这样我们直接npmrunserve也可以有一个开发环境

"scripts": {
    "serve": "docker-compose up -d && vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }
复制代码

examplea

docker-compose.yml如下:

version: '3'
services:
  exampleb:
    image: {{docker registry domain}}/dev/exampleb:latest
  example-front:
    image: {{docker registry domain}}/dev/example-front:latest
    ports:
      - "8080:80"
  examplea:
    image: golang:1.19.5
    working_dir: "/go/src/examplea"
    # 调试模式,请制作一个包含go和delve的镜像
#    command: [ "dlv", "debug", "--headless", "--listen=:2345", "--api-version=2", "--accept-multiclient", "main.go" ]
    command: [ "go","run","main.go" ]
    volumes:
      - .:/go/src/examplea
    depends_on:
      - exampleb
      - example-front
    ports:
      - "8000:8000"
      - "2345:2345"
复制代码

这儿为了有点区别,输出改成了debugprojecta

直接docker-composeup,example-front将80映射成8080了,打开浏览器输入:8080,

怎么搭开发环境_搭建开发环境步骤_linux设置环境变量env

exampleb

docker-compose.yml如下:

version: '3'
services:
  examplea:
    image: {{docker registry domain}}/dev/examplea:latest
    ports:
      - "8000:8000"
  example-front:
    image: {{docker registry domain}}/dev/example-front:latest
    ports:
      - "8080:80"
  exampleb:
    image: golang:1.19.5
    working_dir: "/go/src/exampleb"
    # 调试模式,请制作一个包含go和delve的镜像
#    command: [ "dlv", "debug", "--headless", "--listen=:2345", "--api-version=2", "--accept-multiclient", "main.go" ]
    command: [ "go","run","main.go" ]
    volumes:
      - .:/go/src/exampleb
    depends_on:
      - examplea
      - example-front
    ports:
      - "2345:2345"
复制代码

这儿为了有点区别,输出改成了debugprojectb

linux设置环境变量env_搭建开发环境步骤_怎么搭开发环境

总结

现今各项目只须要执行一下docker-composeup或则npmrunserve就可以有一个稳定的开发环境了,再也不用由于环境的问题,折腾大半天,结果还不一定能折腾下来

go项目也是可以启用debug模式,只须要找一个或则自己制做一下包含go和delve的镜像,之后把command改成["dlv","debug","--headless","--listen=:2345","--api-version=2","--accept-multiclient","main.go"],并将端口用ports映射一下就好了

goland用GoRemote

见到APIserverlisteningat:[::]:2345,点击dubug就OK了

搭建开发环境步骤_linux设置环境变量env_怎么搭开发环境

docker-compose.yml配置解读

每位docker-compose.yml必须定义image或则build中的一个,其它的是可选的。

image

指定镜像tag或则ID。示例:

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
复制代码

ps:在version1里同时使用image和build是不容许的,version2则可以,假如同时指定了二者,会将build下来的镜像打上名为image标签

build

拿来指定一个包含Dockerfile文件的路径。通常是当前目录.。Fig将build并生成一个随机命名的镜像。

ps:在version1里bulid仅支持值为字符串。version2里支持对象格式。

build: ./dir
build:
  context: ./dir
  dockerfile: Dockerfile-alternate
  args:
    buildno: 1
复制代码

command

拿来覆盖缺省命令。示例:

command:bundleexecthin-p3000

也支持链表方式:

command:[bundle,exec,thin,-p,3000]

env_file

从文件中获取环境变量,可以为单独的文件路径或列表。假如通过docker-compose-fFILE指定了模板文件,则env_file中路径会基于模板文件路径。假如有变量名称与environment指令冲突,则以前者为准。

env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
复制代码

环境变量文件中每一行必须符合格式,支持#开头的注释行。

# common.env: Set Rails/Rack environment
RACK_ENV=development
复制代码

links

用于链接另一容器服务,如须要使用到另一容器的mysql服务。可以给出服务名和别称;也可以仅给出服务名,这样别称将和服务名相同。同dockerrun--link。示例:

links:
 - db
 - db:mysql
 - redis
复制代码

ports

用于曝露端口。同dockerrun-p。示例:

ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"
复制代码

ps:逗号后面是主机上的端口,逗号旁边是容器内部的端口。

expose

expose提供container之间的端口访问,不会曝露给主机使用。同dockerrun--expose。

expose:
 - "3000"
 - "8000"
复制代码

volumes

挂载数据卷。同dockerrun-v。示例:

volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro
复制代码

volumes_from

挂载数据卷容器,挂载是容器。同dockerrun--volumes-from。示例:

volumes_from:
 - service_name
 - service_name:ro
 - container:container_name
 - container:container_name:rw
复制代码

linux设置环境变量env_怎么搭开发环境_搭建开发环境步骤

ps:container:container_name格式仅支持version2。

environment

添加环境变量。同dockerrun-e。可以是链表或则字典格式:

environment:
  RACK_ENV: development
  SESSION_SECRET:
environment:
  - RACK_ENV=development
  - SESSION_SECRET
复制代码

depends_on

用于指定服务依赖,通常是mysql、redis等。指定了依赖,将会优先于服务创建并启动依赖。

links也可以指定依赖。

external_links

链接搭配docker-compose.yml文件或则Compose之外定义的服务,一般是提供共享或公共服务。格式与links相像:

external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql
复制代码

ps:external_links链接的服务与当前服务必须是同一个网路环境。

extra_hosts

添加主机名映射。

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"
复制代码

将会在/etc/hosts创建记录:

162.242.195.82  somehost
50.31.209.229   otherhost
复制代码

extends

承继自当前yml文件或则其它文件中定义的服务,可以选择性的覆盖原有配置。

extends:
  file: common.yml
  service: webapp
复制代码

service必须有免费linux主机,file可选。service是须要承继的服务,比如web、database。

net

设置网路模式。同docker的--net参数。

net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"
复制代码

dns

自定义dns服务器。

dns: 8.8.8.8
dns:
  - 8.8.8.8
  - 9.9.9.9
复制代码

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 前端 容器 示例 端口 镜像
最后更新:2023年7月7日

Linux大神网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

Linux大神网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
Linux文件系统种类 如何卸载用源码包安装的软件?在线视频教程推荐 「职位」ASP.、PHP、Linux服务器集群开发 Torvalds:Linux内核开发的创新前景充满了热情 Linux文件系统的结构从终端窗口探索Linux目录树结构 卸载软件命令Linux.You linux软件开发如何入门?学习Linux步骤及学习方法介绍 14年Linux发行版的有趣历史观点 Linux中不像Windows可以直接在控制面板中卸载? 2018年波及众多Linux发行版的性能对比会更加深入 如何用源码包安装的软件?name的方法总结 Linux之父李纳斯托瓦兹开发的Linux只是一个内核 Linux系统中的apt和apt-get的区别及解决办法! Linux系统发行版的一种方法,除此以外 MacM1上安装Docker和CentOS,您需要遵循的步骤 linux光驱启动怎么设置 常见的几种设置方法,你知道几个? 关于ESXi主机磁盘空间回收的具体操作步骤及步骤 Linux设置显示中文和设置字体设置中文一个都不能少 如何在Linux系统中使用命令查看Linux发行版版本信息 电脑的系统出现问题需要修复时光驱,两种设置方法
嵌入式Linux操作系统学习规划+LINUX路线,主攻江苏电信天翼校园客户端故障指引及解决办法(101)英特尔GMAGMA950显卡驱动程序/WIN8/8.1电信校园网宽带用USB数据线共享给电脑无线上网国防科大开源操作系统:它只是一个吉祥的象征10个常用Linux文本查看命令及其详细说明和使用示例Linux嵌入式系统内核裁剪与定制方法的介绍情况淘宝教育热卖C语言编程开发C++程序设计零基础入门课程从CPU、内存、硬盘、显卡等这些方面安装Linux系统的最低配置Linux通过chkconfig设置开机启动服务创建的几种常见方式(技术分析)Linux多线程的使用与操作系统的区别通常rar命令由一个主命令加若干选项(可选)构成RedHatLinux中自动运行程序中的应用linux 读写文件 关于Linux内核的神秘面纱,你知道几个?使用wget实用程序的有用命令行工具的使用怎么设置linux开机项自启动?方式是怎样的?嵌入式Linux应用层与驱动层要想学习关于Linux内核的交叉编译步骤和方法:步骤、方法STM32嵌入式linux开发流程及应用程序分析-STMlinux下有哪些文件在介绍lsof命令实用用法介绍?
【Linux基础知识】Linux内核版本命令(两种方法) (Linux基础知识)删除7天前修改的示例命令和命令 Linux生态系统开发工具总结环境开发的工具介绍 10.5内核定时器编程TIMER_SOFTIRQ软中断,运行当前处理器CPU上到期的所有定时器 关闭虚拟机的防火墙:验证进程(上) Linux常见的安装为tar,zip.version.Brpm卸载 linux虚拟机的安装步骤是什么?虚拟机和服务器的区别 使用脚本安装脚本是什么?可能的误区误区! 手机上可以安装完整的Linux系统吗?/VNC 成为一名合格的嵌入式Linux开发工程师需要学习哪些知识? Linux内核源代码的结构分布图-子目录模块 英特尔9月启动Linux补丁征集活动:采用大小核设计 Linux上安装和卸载软件的几种方法,你知道吗? 我准备开始吓人了!C++Linux服务器后台开发学习篇 (知识点)Linux文件权限详解:执行权限 u盘无密码移动版livepersistencepersistence制作u盘有密码 Android官方网站:OpenHandsetAlliance源码模式:开发源码内核 直接设置硬件时间和硬件时钟同步的解决方式有哪些 嵌入式Linux应用层与驱动层要想学习 home/ftproot/scb添加权限,你的第一个要求是什么?
标签聚合
虚拟机 应用 命令 操作 软件 linux服务器 linux系统 文件 内核 文件目录
书籍
课程
技术群
技术干货大合集↓
  • 2023年9月 / 69篇
  • 2023年8月 / 93篇
  • 2023年7月 / 94篇
  • 2023年6月 / 90篇
  • 2023年5月 / 93篇
  • 2023年4月 / 90篇
  • 2023年3月 / 129篇
  • 2023年2月 / 84篇
  • 2023年1月 / 161篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.