前言
上一篇已经说过如何制作镜像(juejin.cn/post/684490…),下面我们以一个基于koa的图片上传服务为例。
准备图片上传代码
const Koa = require('koa')
const fs = require('fs')
const app = new Koa()
const koaBody = require('koa-body') //解析上传文件的插件
// 这两个变量从环境变量中读取
const { MAX_SIZE, FILE_TYPE } = require('./config')
const Path = require('path')
const serve = require('koa-static')
app.use(serve(Path.join(__dirname, '/pic/')))
app.use(koaBody({
multipart: true,
formidable: {
maxFileSize: MAX_SIZE * 1024 * 1024 // 设置上传文件大小最大限制,默认2M
}
}))
// 响应处理
app.use(async ctx => {
let { files, method, path } = ctx.request; // 获取上传文件
if (method !== 'POST' || path !== '/upload') return ctx.throw(404, 'Not found')
if (!files) return ctx.throw(400, '请传人图片')
// 验证图片类型
if (!FILE_TYPE.split(',').includes(files['image'].type)) return ctx.throw(400, '图片类型错误')
// 创建可读流
const reader = fs.createReadStream(files['image']['path'])
let filePath = Path.join(__dirname, `./pic/${files['image']['name']}`)
let remotefilePath = `/${files['image']['name']}`
// 创建可写流
const upStream = fs.createWriteStream(filePath);
// 可读流通过管道写入可写流
reader.pipe(upStream);
return ctx.body = {
url: remotefilePath,
message: "文件上传成功",
cc: 0
}
})
app.listen(3000)
配置文件(config.js):
// 两个参数都从环境变量中读取
// 图片大小限制
const MAX_SIZE = process.env.MAX_SIZE || 2
// 图片类型限制
const FILE_TYPE = process.env.FILE_TYPE || 'image/jpeg,image/png'
module.exports = {
MAX_SIZE,
FILE_TYPE
}
项目地址:github.com/Vongolatt/i….
Dockfile
# koa图片上传
# Version 1.0
# 基础镜像
FROM node:current-alpine
# 维护者信息
LABEL name="vongola"
#ENV 设置环境变量
ENV MAX_SIZE=4 FILE_TYPE='image/jpeg,image/png'
#WORKDIR 相当于cd,当指定后,下面的run命令会在当前文件路径下执行
WORKDIR /home
#RUN 执行以下命令
RUN wget https://github.com/Vongolatt/image-upload/archive/master.zip
RUN unzip master.zip \
&& cd image-upload-master/ \
&& mkdir pic \
&& npm install --production
ENTRYPOINT [ "node", "/home/image-upload-master/app.js" ]
#EXPOSE 暴露端口
EXPOSE 3000
这里我们基于node的alpine版本,这个版本的node会比其他版本小非常多,但是功能受限,可能会有bug,使用的时候需要注意。
然后设置图片大小和图片类型的默认值,拉取项目(这里用的wget命令,就不需要安装git了,是个取巧的办法),最后在入口处启动命令,并暴露3000端口。
构建Dockerfile
在Dockerfile所在目录执行以下命令(注意最后的小点):
docker build --no-cache -t image_upload:v1 .

查看镜像:

启动容器
docker run -itd -p 3000:3000 --rm --name upload -v /Users/vongola/Documents/Image/:/home/image-upload-master/pic image_upload:v1
这里容器启动并且映射了图片保存路径,请把红色部分替换成你的路径,并且没有传递环境变量,所以默认为构建镜像时的环境变量。
测试容器



这里可以看到png、jpeg图片都上传成功,并显示正常。
传递环境变量
前面我们没有传递环境变量启动了容器,现在测试一下环境变量的传递。首先关闭容器(由于启动容器时使用了--rm参数,所以关闭容器后会直接删除容器):
docker stop upload
传递环境变量
docker run -itd -p 3000:3000 --rm --name upload -e FILE_TYPE=image/jpeg -v /Users/vongola/Documents/Image/:/home/image-upload-master/pic image_upload:v1
这里我们让FILE_TYPE=image/jpeg,测试图片上传,可以jpeg正常,png报错:

总结
到这里就完成了一个非常简单的应用docker封装,但是还有很多问题没有考虑到。比如说:
- 代码层面,没有考虑图片上传重名的问题。
- 在拉取git项目时,也没有使用git命令,这对于一般的项目足够了,但是对于私有项目,还需要考虑git的配置。