Docker中使用MySQL踩坑

需要使用到 MySQL ,打算使用 Docker 来部署,compose 来管理。原以为很简单,没想到还是有些坑的。 version: "3.7" services: mysql: image: mysql:8.0-oracle container_name: mysql ports: - "3306:3306" restart: always environment: # 密码 MYSQL_ROOT_PASSWORD: "root" # 创建默认数据库名 MYSQL_DATABASE: "test" 上面的写法就可以启动一个 MySQL 服务了,很简单。但是如果重新构建的话,数据就会丢失了,解决办法也很简单,挂载一下数据目录。 version: "3.7" services: mysql: image: mysql:8.0-oracle container_name: mysql ports: - "3306:3306" volumes: - ./data/mysql:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: "root" MYSQL_DATABASE: "test" 很好,MySQL 的数据已经挂载出来了,但是当重启 MySQL 容器的时候发现重启不了了,报错如下。 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1.el8 started. chown: cannot dereference '/var/lib/mysql/mysql.sock': No such file or directory 根据报错信息是找不到挂载目录下的文件,猜测是权限原因引起的,加个权限试一试。...

2022-04-08 · 2 分钟

Go标准库time.Parse方法的时区问题

time.Parse方法解析时间字符串得到的 time 的时区为UTC,并不会自动使用系统的默认时区。 parse, _ := time.Parse("2006-01-02 15:04:05", "2022-03-30 13:37:03") //UTC 0 fmt.Println(parse.Zone()) //CST 28800 fmt.Println(time.Now().Zone()) 如果我们不想要UTC时区,需要别的时区。可以使用time.ParseInLocation方法自行设置时区。 loc, _ := time.LoadLocation("Asia/Shanghai") parse, _ := time.ParseInLocation("2006-01-02 15:04:05", "2022-03-30 13:37:03", loc) //CST 28800 fmt.Println(parse.Zone()) //CST 28800 fmt.Println(time.Now().Zone())

2022-03-30 · 1 分钟

alpine镜像设置时区

FROM alpine ENV TZ=Asia/Shanghai RUN echo 'http://mirrors.aliyun.com/alpine/v3.4/main/' > /etc/apk/repositories \ && apk --no-cache add tzdata zeromq \ && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ && echo '$TZ' > /etc/timezone

2022-03-29 · 1 分钟

构建自己的go-gin-api脚手架(三)

Viper 地址:https://github.com/spf13/viper Viper 是适用于 Go 应用程序的完整配置解决方案。它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式。 文档 英文:可查看 Github 仓库的 README 文件 中文:可查看这篇文章的翻译 安装 go get github.com/spf13/viper 使用 新建配置文件/config/config.toml aaa = "111" bbb = "222" Viper 只需简单设置就可以读取到配置信息。 //设置文件路径 viper.AddConfigPath("/config") //设置文件名 viper.SetConfigName("config") //设置文件类型 viper.SetConfigType("toml") //读取配置文件 _ = viper.ReadInConfig() //监控配置文件变动 viper.WatchConfig() for { //输出所有配置 fmt.Println(viper.AllSettings()) time.Sleep(time.Second) } 多配置文件 随着项目开发,配置文件中的信息可能会越来越多,全部集中到一个文件中会变的难以管理。按功能分为不同的配置文件更易于管理,我们来自己实现一个多配置文件的方法。 方法一 使用MergeInConfig()方法将多个配置文件内容合并到一起。 在新建一个/config/router.toml配置文件 port = 8000 //设置文件路径 viper.AddConfigPath("/config") //设置文件名 viper.SetConfigName("config") //设置文件类型 viper.SetConfigType("toml") //读取配置文件 _ = viper.ReadInConfig() //设置第二个配置文件名称 viper.SetConfigName("router") //读取并合并已有配置 _ = viper.MergeInConfig() //输出所有配置 fmt....

2022-02-27 · 2 分钟

Dockerfile编写注意事项与技巧

1、多条指令应换行 ... RUN apt-get clean apt-get update ... 多条指令写在一行会当做一条指令执行,有可能后面的指令不执行或者报错。 应改为: ... RUN apt-get clean \ && apt-get update ... 2、忽略错误继续运行 我们在使用apt-get安装一个包时,常常会因为缺少依赖而安装失败,我们可以使用apt-get install -y -f --fix-missing命令来安装上一次安装失败所需要的依赖包,可以很方便的管理所以依赖,而不用我们手动按照依赖顺序把所有依赖包安装一遍,但是必须在安装失败后执行。Dockerfile 在构建过程中如果出现报错会立即退出构建,我们可以使用逻辑或||来忽略错误继续执行后面的语句。 ... # 下载Chrome安装包 RUN wget -P /tmp https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \ # 安装Chrome失败 && dpkg -i /tmp/google-chrome-stable_current_amd64.deb \ # 安装Chrome的依赖 && apt-get install -y -f --fix-missing \ # 再次安装Chrome && dpkg -i /tmp/google-chrome-stable_current_amd64.deb ... 上面的写法在 Chrome 安装失败时构建会退出,改为下面的写法就可以成功构建了。 ... # 下载Chrome安装包 RUN wget -P /tmp https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \ # 安装Chrome失败之后安装Chrome的依赖 && dpkg -i /tmp/google-chrome-stable_current_amd64....

2022-01-26 · 1 分钟

IDE进入Docker容器输出中文乱码

如下图所示,中文字符输出为乱码。 解决 如下图所示编辑 VM Options ,添加一行 -Dfile.encoding=UTF-8并重启 IDE 。

2022-01-22 · 1 分钟

从零完成一个带滑动验证的自动登陆

前言 最近帮女朋友写了一个监控九价订阅的小程序,对方接口需要登陆,Token 有效时间只有大概 2 个小时,每次都要手动去更新登陆状态,太过麻烦了。所以就想要解决一下自动登陆的问题,登陆有滑动验证码,查找了一些资料决定使用 Python + Selenium 来解决,可惜我也不会 Python ,只能一点点摸索了,顺便记录下来。 了解 Python 因为以前没有使用过 Python ,所以先了解一下 Python 的基本语法。 菜鸟教程 廖雪峰的 Python 教程 配置环境 了解完基础之后先安装一个环境吧,不想在电脑上在安装 Python ,而且完成之后肯定要部署服务器,所以还是使用 Docker 来统一环境。 安装 Python 先简单写一个 docker-compose.yml 的文件,拉取一个 Python 镜像并创建容器。 docker-compose.yml version: "3.7" services: Python: image: Python volumes: - .:/home working_dir: /home tty: true 使用 PyCharm 可以很方便的管理 Docker ,运行 docker-compose.yml 并进入容器。 安装 Chrome 打开 Chrome 官网,滑动到最下面,点击其他平台,然后在弹出窗口选择 Linux,选择适用系统的安装包,获取下载链接,然后进入容器执行以下命令安装 Chrome 。 # 更换apt源 $ sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources....

2022-01-21 · 3 分钟

构建自己的go-gin-api脚手架(二)

在前文中我们已经成功的使用 Gin 框架搭建了一个简易的 API 服务,但是在一个项目中,所有的业务逻辑都写在 main.go 一个文件中显然是不合理的。所以接下来我们会对其进行重构,在整个搭建 go-gin-api 脚手架的过程中,会经常对其重构。 每当我要进行重构的时候,第一个步骤永远相同:我得确保即将修改的代码拥有一组可靠的测试。这些测试必不可少,因为尽管遵循重构手法可以使我避免绝大多数引入 bug 的情形,但我毕竟是人,毕竟有可能犯错。程序越大,我的修改不小心破坏其他代码的可能性就越大——在数字时代,软件的名字就是脆弱。 —— 《重构:改善既有代码的设计》 所以在此之前我们需要编写一套可靠的单元测试,来确保代码重构之后还能良好的运行。 Go 单元测试框架 testing testing 是 Go 标准库中提供的自动化测试支持,通过 go test 命令,能够自动执行如下形式的任何函数: func TestXxx(*testing.T) 注意:Xxx 可以是任何字母数字字符串,但是第一个字母不能是小写字母。 在这些函数中,使用 Error、Fail 或相关方法来发出失败信号。 要编写一个新的测试套件,需要创建一个名称以 _test.go 结尾的文件,该文件包含 TestXxx 函数,如上所述。 将该文件放在与被测试文件相同的包中。该文件将被排除在正常的程序包之外,但在运行 go test 命令时将被包含。 有关详细信息,请运行 go help test 和 go help testflag 了解。 标准库的 testing 实现比较简单,并不支持断言,需要写 if 判断。所以不考虑使用。 Testify 地址:https://github.com/stretchr/testify Testify 是基于 testing 编写的,所以测试文件与执行方式与其完全相同,并且支持断言方法。 编写测试 首先创建一个 main_test.go 的文件,写入以下代码并执行 go mod tidy更新依赖。 main_test.go package main import ( "github....

2022-01-11 · 3 分钟

构建自己的go-gin-api脚手架(一)

目标 学习并掌握 Go 语言 学习并熟练使用 Gin 框架 学习并熟练使用 Go 热门常用的组件 搭建一个自己开箱即用的 api 框架 锻炼自己的封装抽象能力 初始化 使用 Goland 创建一个新项目go-gin-api。 可以看到项目中有一个 go.mod 的文件。 module go-gin-api go 1.17 Gin 安装 下载并安装 Gin : $ go get -u github.com/gin-gonic/gin go get: added github.com/gin-contrib/sse v0.1.0 go get: added github.com/gin-gonic/gin v1.7.7 go get: added github.com/go-playground/locales v0.13.0 ... 可以看到项目中又多了一个 go.sum 的文件,go.sum 文件详细罗列了当前项目直接或间接依赖的所有模块版本,并写明了那些模块版本的 SHA-256 哈希值以备 Go 在今后的操作中保证项目所依赖的那些模块版本不会被篡改。 go.mod 文件也发生了改变: module go-gin-api go 1.17 require ( github.com/gin-contrib/sse v0.1.0 // indirect github....

2022-01-10 · 1 分钟

给Git历史提交添加GPG签名

今天给 commit 添加了 GPG 签名,但是以前的提交记录却没有签名。 使用以下命令 注意:以下命令会修改历史,变更 commit id ,其他人会不同步,慎用。 对历史所有提交增加签名: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD 对最后 X 次提交增加签名: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD~X..HEAD 对指定提交者 Email 增加签名: git filter-branch -f --commit-filter ' if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ] then git commit-tree -S "$@" fi ' 推送到远程 git push -f

2022-01-06 · 1 分钟