Deploying Docker images via SSH
Original URL:https://advancedweb.hu/2015/04/14/deploying-docker-images-via-ssh/
Background
When we began Dockerizing this blog for good, I began to look for ways to automate the build and deployment process. It turned out that although Docker is an excellent container for running applications, there is no standard way to update a server. Luckily with a moderately complex shell script it is indeed doable, and can be fully automated.
Our current architecture is made of several dependent Docker images and a Linux box as a production server. Luckily we have no dynamic data, but the deploy script can easily be modified to handle those too. In that case we would use thedata only containerapproach.
So, let’s build our deployment script!
The script
The basic idea of the build script is simple: Build the images, upload them to the server, then restart the containers with the new versions. These are the building blocks, just need some tricks to mix in order to be able to fully automate the process.
For the sake of example, let’s say we have an apache app in the apache/ subdirectory and a monitoring app residing in monitoring/.
Setting up
Let’s name our script deploy.sh and add some bootstrapping:
#!/bin/bash set -e REMOTE_USERNAME="..."
REMOTE_HOST="..."
IMAGE_REPOSITORY="my_repository"
The last variable will be the repository name for the Docker images. It is important to add one, as we will use it for the up-to-date check later.
Building
The first thing to do is to build the images. It has nothing interesting, just a standard Docker build:
function build_image {
docker build -t $IMAGE_REPOSITORY:$ $
} build_image apache apache/
build_image monitoring monitoring/
It builds the image to the predefined repository and adds a tag for easy retrieval.
Uploading to the remote server
Fortunately Docker can save and load an image to/from the standard input stream, so it makes piping possible. It effectively makes the whole uploading a one-liner.
docker save $IMAGE_REPOSITORY:$ | bzip2 | pv | ssh $REMOTE_USERNAME@$REMOTE_HOST 'bunzip2 | docker load'
What we should implement is to first check whether the image was actually modified or not. As Docker images tends to weight several hundred megabytes, it can save a lot of bandwidth, especially when there are several images and only a few of them are changing. The idea is that we can list the images for a given repository, then extract the image ID, then do the same on the remote machine, and if the IDs are the same, then the images are the same.
The finished part looks like this:
function upload_image_if_needed {
if [[ $(ssh $REMOTE_USERNAME@$REMOTE_HOST "docker images $IMAGE_REPOSITORY | grep $1 | tr -s ' ' | cut -d ' ' -f 3") != $(docker images $IMAGE_REPOSITORY | grep $ | tr -s ' ' | cut -d ' ' -f ) ]]
then
echo "$1 image changed, updating..."
docker save $IMAGE_REPOSITORY:$ | bzip2 | pv | ssh $REMOTE_USERNAME@$REMOTE_HOST 'bunzip2 | docker load'
else
echo "$1 image did not change"
fi
} upload_image_if_needed apache
upload_image_if_needed monitoring
Updating the containers
The last step is to restart the containers using the new images. The good thing is that we can embed remote bash commands in our deploy script and treat them just like the local ones:
ssh -tt $REMOTE_USERNAME@$REMOTE_HOST << EOF ... exit
EOF
The first thing is to kill the current containers if they exist:
docker rm -f ${IMAGE_REPOSITORY}_apache || true
docker rm -f ${IMAGE_REPOSITORY}_monitoring || true
The || true is needed, because if the conta
iner does not exists, then docker rm gives back an error. Since we just want to have the containers killed, in case they did not exist in the first place, doing nothing is perfectly fine.
The second step is to start the containers, the standard way:
docker run -d --name ${IMAGE_REPOSITORY}_apache $IMAGE_REPOSITORY:apache
docker run -d --name ${IMAGE_REPOSITORY}_monitoring $IMAGE_REPOSITORY:monitoring
The final script
For a better overview, here is the complete script:
#!/bin/bash set -e REMOTE_USERNAME="..."
REMOTE_HOST="..."
IMAGE_REPOSITORY="my_repository" function upload_image_if_needed {
if [[ $(ssh $REMOTE_USERNAME@$REMOTE_HOST "docker images $IMAGE_REPOSITORY | grep $1 | tr -s ' ' | cut -d ' ' -f 3") != $(docker images $IMAGE_REPOSITORY | grep $ | tr -s ' ' | cut -d ' ' -f ) ]]
then
echo "$1 image changed, updating..."
docker save $IMAGE_REPOSITORY:$ | bzip2 | pv | ssh $REMOTE_USERNAME@$REMOTE_HOST 'bunzip2 | docker load'
else
echo "$1 image did not change"
fi
} function build_image {
docker build -t $IMAGE_REPOSITORY:$ $
} build_image apache apache/
build_image monitoring monitoring/ upload_image_if_needed apache
upload_image_if_needed monitoring ssh -tt $REMOTE_USERNAME@$REMOTE_HOST << EOF
docker rm -f ${IMAGE_REPOSITORY}_apache || true
docker rm -f ${IMAGE_REPOSITORY}_monitoring || true docker run -d --name ${IMAGE_REPOSITORY}_apache $IMAGE_REPOSITORY:apache
docker run -d --name ${IMAGE_REPOSITORY}_monitoring $IMAGE_REPOSITORY:monitoring exit
EOF
Conclusion
Docker is a fascinating container technology that allows building works-everywhere apps, and it comes with good CLI support. It currently lacks the features to make deploying easy, but with some scripting magic, we can work around these issues. I hope the above script gives some insight and possibly a solution to people facing the same problem.
Deploying Docker images via SSH的更多相关文章
- Docker创建支持ssh服务的容器和镜像
原文链接:Docker创建支持ssh服务的容器和镜像 1. 这里使用的centos作为容器,所以首先下载centos的images # sudo docker pull centos 2. 下载后执行 ...
- 配置docker容器上ssh无密登录
配置docker容器上ssh无密登录 1.修改所有容器中root账户密码 ssh到远程主机时,首次需要密码访问,因此需要修改root账号密码. 密码必须要8位以上字母数字混合. $>passwd ...
- Docker 添加容器SSH服务
很多时候我们需要登陆到容器内部操作,此时我们就需要开启容器的SSH支持了,下面的小例子将具体介绍三种分配IP地址的方法,分别是pipworl分配,commit分配,Docker分配等. 基于commi ...
- docker中安装ssh服务
系统:Debian Docker 目标:在docker(debian系统)中安装ssh服务,实现远程登陆和控制docker 步骤: 初始状态:通过docker pull debian得到的一个debi ...
- Centos7下,简单DOCKER 使用.映射SSH端口到宿主主机.
其实使用docker完全没有必要ssh,初学的时候,可以这样熟悉以下操作. 参考这哥们的文章:http://www.jianshu.com/p/d2dd936863ec 获取镜像 docker pul ...
- Deploying docker registry v2
生成证书 openssl genrsa -out mydomain.key 2048 生成秘钥 openssl req -newkey rsa:4096 -nodes -sha256 -keyout ...
- 配置docker中免密码SSH
更换docker国内镜像,使用DaoCloud,特别快 编写Dockerfile文件 FROM ubuntu MAINTAINER ggzone xxx@live.com ENV REFRESHED_ ...
- 为Docker镜像添加SSH服务
一.基于commit命令创建 1. 首先下载镜像 $ docker run -it ubuntu:16.04 /bin/bash 2. 安装SSH服务 #更新apt缓存 root@5ef1d31632 ...
- stackstorm docker中配置ssh免密码登录方式
在docker中配置st2的ssh登录方式折腾了好久,今天终于彻底搞懂了如何重启容器后也不丢失之前的配置,只要容器起来后就可以正常ssh 执行st2中的remote-shell-script 和rem ...
随机推荐
- noip2018 pre——Dp
Dp专题 1011: KC的瓷器 (porcelain) 题目描述 KC来到了一个盛产瓷器的国度.他来到了一位商人的店铺.在这个店铺中,KC看到了一个有n(1<=n<=100)排的柜子,每 ...
- g2o安装
1.安装依赖项 sudo apt-get install libeigen3-dev libsuitesparse-dev libqt4-dev qt4-qmake 2.安装依赖项 libqglvi ...
- python3的cookielib
http://stackoverflow.com/questions/8405096/python-3-2-cookielib
- 小米监控 open-falcon部署
具体详情请参考官方文档 http://book.open-falcon.org/zh_0_2/quick_install/ centos6.8 建议centos7系统 否则后面按照官方 ...
- 在npm当中发布自己的包的方法
首先需要一个注册一个npm账号,注意,必须验证邮箱,不然是无法发布包的!下面是当时的报错 接着在你需要发布的包的文件夹下面打开你的cmd或者其他的命令行输入工具 输入 npm init 初始化你的 ...
- 分配问题(cogs 740)
«问题描述: 有n件工作要分配给n个人做.第i 个人做第j 件工作产生的效益为c[i][j] .试设计一个将n件工作分配给n个人做的分配方案,使产生的总效益最大. «编程任务: 对于给定的n件工作和 ...
- set与map的区别
STL中:MAP的节点是一对数据. SET的节点是一个数据. Map使用关键值Key来唯一标识每一个成员 map可以重复.set是集合 都属于关联容器 只不过, map的形式 map& ...
- set基本用法-----2
#include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #inclu ...
- TP5 多条件whereOr查询
问题背景:最近在用ThinkPHP 5开发项目的过程中,发现根据筛选条件做or查询的时候,连贯操作不可以使用where进行条件查询了. 首先列出一个user数据表的信息: uid uname grad ...
- HDU 2034 人见人爱A-B【STL/set】
人见人爱A-B Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...