用 Docker 无脑备份数据库

每次有一个新的数据库,都要琢磨着配置一个备份。当然你可能有一个祖传的 shell 脚本,重新配置一下放到 crontab 里就可以了。但是无论是查看和修改配置,还是查看 crontab 都不是那么方便。 今天介绍一个 Docker 镜像,只需要简单的配置启动,就可以。地址在这里:https://hub.docker.com/r/deitch/mysql-backup/ 但你也许不需要点开链接,先看完我的例子吧。 version: '3.7' services: backup: image: databack/mysql-backup volumes: - /root/dbbackup:/db environment: - DB_DUMP_TARGET=/db - DB_USER=root - DB_PASS=root - DB_SERVER=xxx.xxx.xxx.xxx user: root deploy: placement: constraints: - node.id == YOURDOCKERSWARMNODEID 讲要点 Version 我用了最新版的 docker-compose 格式,优点就是不用在装 docker-compose … 使用新版 Docker 自带的 docker stack -c backup.yml backup 这样子启动 stack 就好。这样机器就只用装 docker 一个包。 如果你想用旧版的 docker-compose 点开上边作者的 readme 里有例子。 ...

2019年2月26日 · 1 分钟 · Hyacinthus

使用 Caddy 制作前端 Docker 镜像

简介 今年夏天又开始新的创业项目,忙得没日没夜,好久没写博客了。 但是也许 Docker 越来越火,知乎的专栏每天都有新的人关注,不抽空写点太对不起大家。 之前写过 API 镜像,今天来说说前端镜像。 本文适用于任何一个需要编译的前端框架,我们利用 Docker 的两段构建,用一个 Dockerfile 一气呵成的产出不含源码的生产镜像。 镜像内用了 Caddy 当作服务器,又经过了半年的发展,虽然版本还没到1,但 Caddy 已经足够强大和健壮了。 Caddyfile 为了能让项目在 Caddy 镜像中被访问,我们在项目根目录建一个叫 Caddyfile 的文件,供后续镜像内启动服务时使用。 0.0.0.0:80 root /www gzip log stdout errors stdout 解释一下,我们未来会把编译好的项目放在容器的 /www 目录。 服务器在容器的80端口。启用gzip,并且将日志输出在stdout–这是 Docker 的推荐做法。 Dockerfile 然后就开始我们的二段构建了: # build FROM node:8 as builder ADD . /src WORKDIR /src RUN npm i && npm run build # product FROM abiosoft/caddy COPY --from=builder /src/dist /www COPY Caddyfile /etc/Caddyfile 我们首先使用 node 的官方镜像对项目进行编译,工作目录为 /src ,编译结果为 /src/dist 。 然后我们再将 dist 文件夹复制为 caddy 镜像的 /www 目录。 最后我们将我们的 Caddyfile 覆盖镜像原版的。 ...

2017年10月15日 · 1 分钟 · Hyacinthus

Docker 重要更新: 原生支持多阶段构建(multi-stage build)

Docker 的口号是 Build, Ship, and Run Any App, Anywhere. 但是我们在应用过程中会遇到一个问题,我们在 build 的时候,把源码也 build 进去了。 然后就继续把源码 Ship 出去吗?这可不行。所有的编译型语言都面临这个困扰。 即使是脚本型语言,build 的时候也会使用很多上线时用不到的构建工具, 而我们希望减小生产镜像的体积,这样我们的小鲸鱼才能多拉一点集装箱嘛。 传统做法 我们最终的目的是要将编译好的可执行文件复制到 alpine 这样的迷你镜像里, 那么该怎么弄到编译好的文件呢?基于 Docker 的思想,我们肯定需要在一个标准容器中编译, 这样这个过程才是标准化的,再说,你在 Ubuntu 编译出一个二进制文件在 alpine 也运行不了。 于是我们先需要准备一个编译用的自定义镜像。一般是用相应语言的 alpine 基础镜像, 把编译项目额外需要的各种工具打包进去,比如 golang 目前没有官方的包管理, 你就需要把你用的包管理工具装进去。 然后我们需要在运行 container 时把主机的一个目录通过 -v 挂载到 container上, 让它把编译的结果输出到这个挂载的目录,这样我们就在主机上拿到这个文件了。 最后,我们用一个最小的 alpine 镜像,把二进制文件复制进去。 可能你还需要设置一下时区之类的。 持续集成 上面的流程,在用持续集成工具时又变成了一个问题。你会发现每一家 CI 提供商都不太一样。 你未必有权限控制 CI 时的宿主机。 比如 Docker Cloud,你需要定义 pre-build 的 hook 去完成这个工作, 在 SEMAPHORE,你发现你有了一台宿主机,这下和我们在本地的做法可以一样了。 在更多的提供商,你会发现他们只是能根据 git 仓库和 Dockerfile 构建镜像, 你用他们的系统甚至没办法做出一个最小镜像…… 中国的 DaoCloud 其实挺先进的,很早就推出了安全镜像的概念,让你的构建通过两步完成。 但是,那个配置的内容太多让不太懂的人看了直接晕掉。 ...

2017年4月14日 · 1 分钟 · Hyacinthus

在 Docker 中使用 mysql 的一些技巧

今天我写一点在 Docker 容器中使用 MYSQL 的 tips. 要不要在生产环境使用 Docker 运行数据库这么深奥的问题,等我踩足够的坑再来写吧。 但是至少在开发和测试环境你可以用 docker 管理数据库啊。 Compose file 先贴一个我常用的 docker-compose 片段,后边进行详细的解释。这是日常使用的状态,此处省略了别的服务。 version: '2' services: mysql: image: mysql:5.7.16 ports: - ${DB_PORT}:3306 environment: - TZ=Asia/Shanghai command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - ./mysql_data:/var/lib/mysql restart: unless-stopped 版本 一定要锁定镜像到最小的版本,因为mysql镜像升级后需要你手动在容器中执行命令去 mysql-upgrade,否则很久之后,你才发现有的数据已经损坏了。 实在想升级,升级步骤如下: 如果是用 docker run 启动的,那么停掉再启动个新的。如果是用 docker-compose 启动的,直接改版本号 pull 镜像重新 up。 在新的版本启动后执行 docker exec -it 你的容器名称或id mysql-upgrade 端口 如果想在外部通过工具访问,需要将3306端口映射到host上的一个端口,不准备外部访问的环境则不必。 一般来说开发和测试环境还是经常需要登到数据库上查看的。 时区 添加环境变量 TZ 让mysql用你的默认时区启动。 这是因为 mysql 的基础镜像是 debian, 这个环境变量可以声明 debian 的时区,然后被 mysql 继承。 ...

2017年3月28日 · 1 分钟 · Hyacinthus

为 Docker 设置代理

因为众所周知的原因,Docker在国内的使用举步维艰。于是,很多组织在国内提供了mirror或者叫加速器。 甚至在1.13的release note中提到微软提供了官方的中国镜像,然后我并没有找到怎么启用,找到了再写。 使用这些镜像或者加速器,拉取各种官方镜像是ok了,自有的镜像也可以放在国内的registry。 但是官方镜像只是沧海一粟,大量的组织或个人的镜像都在docker hub,这一部分并没有被镜像同步。 于是,你还是需要一个代理。 本文假设: 你已经有一个http代理了 Linux发行版的服务管理器使用的是systemd 本文写于 Version 17.03.0-ce , 在 Docker 1.13 和 17.03 上是可以的,不排除将来有所改变 顺带说一句,Windows版的在 Settings 的图形界面上直接可以设置代理。 关于systemd 很多人可能对systemd还不熟悉,但主流发行版已经全都切换成systemd了,还是很有必要了解一下。 # 重启docker $ sudo systemctl restart docker # 对应的旧的命令,其实现在还是支持,效果和上一句一样。 $ sudo service docker restart # 设置开机启动 $ sudo systemctl enable docker systemd是由文件夹/lib/systemd/system中的docker.service文件定义的。 我们随便搜索一下systemd教程,就知道怎么样自己编写一个service文件了。 于是你可能跃跃欲试,把这个文件改一改,代理加进去就好了嘛。 等等,不要着急,如果你自己在做一个自己的服务,当然是要自己直接写这个文件了。但是,我们的docker是从官方源安装的。 这意味着你现在改了这个文件虽然会生效,但是docker一升级,这个文件又被覆盖了呢。针对这个问题,systemd当然也有解决方案。 你其实只需要创造一个叫 <something>.conf 的配置文件,名字随便起,放在 /etc/systemd/system/docker.service.d 目录。你就覆盖了默认的启动配置,并且它会作为你的用户配置一直存在。 HTTP proxy 好了,现在我们可以开始加代理配置了。 默认情况下这个配置文件夹并不存在,我们要创建它。 $ mkdir -p /etc/systemd/system/docker.service.d 创建一个文件 /etc/systemd/system/docker.service.d/http-proxy.conf 包含 HTTP_PROXY 环境变量: [Service] Environment="HTTP_PROXY=http://proxy.example.com:80/" 如果有局域网或者国内的registry,我们还需要使用 NO_PROXY 变量声明一下,比如你可以能国内的daocloud.io放有镜像: ...

2017年3月10日 · 1 分钟 · Hyacinthus