github 上已经有人搞了一个deno 的docker 镜像,是基于源码编译的,挺好的
所以结合官方的http server demo 使用docker 运行

环境准备

  • docker-compose 文件
 
  1. version: "3"
  1. services:
  1.  app:
  1.    image: maxmcd/deno:slim
  1.    volumes:
  1.    - "./app:/opt"
  1.    command: deno /opt/app.ts
  1.  file-server:
  1.    image: maxmcd/deno:slim
  1.    ports:
  1.    - "4500:4500"
  1.    volumes:
  1.    - "./server:/opt/server"
  1.    command: deno /opt/server/app.ts --allow-net
 
  • http server 内容
    http 模块的我修改为了使用http,就不用管下载的问题了
 
  1. // This program serves files in the current directory over HTTP.
  1. // TODO Stream responses instead of reading them into memory.
  1. // TODO Add tests like these:
  1. // https://github.com/indexzero/http-server/blob/master/test/http-server-test.js
  1. import {
  1.    listenAndServe,
  1.    ServerRequest,
  1.    setContentLength,
  1.    Response
  1. } from "https://deno.land/x/net/http.ts";
  1.  import { cwd, DenoError, ErrorKind, args, stat, readDir, open } from "deno";
  1.  const dirViewerTemplate = `
  1.  <!DOCTYPE html>
  1.  <html lang="en">
  1.  <head>
  1.    <meta charset="UTF-8">
  1.    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  1.    <meta http-equiv="X-UA-Compatible" content="ie=edge">
  1.    <title>Deno File Server</title>
  1.    <style>
  1.      td {
  1.        padding: 0 1rem;
  1.      }
  1.      td.mode {
  1.        font-family: Courier;
  1.      }
  1.    </style>
  1.  </head>
  1.  <body>
  1.    <h1>Index of <%DIRNAME%></h1>
  1.    <table>
  1.      <tr><th>Mode</th><th>Size</th><th>Name</th></tr>
  1.      <%CONTENTS%>
  1.    </table>
  1.  </body>
  1.  </html>
  1.  `;
  1.  const serverArgs = args.slice();
  1.  let CORSEnabled = false;
  1.  // TODO: switch to flags if we later want to add more options
  1.  for (let i = 0; i < serverArgs.length; i++) {
  1.    if (serverArgs[i] === "--cors") {
  1.      CORSEnabled = true;
  1.      serverArgs.splice(i, 1);
  1.      break;
  1.   }
  1. }
  1.  let currentDir = cwd();
  1.  const target = serverArgs[1];
  1.  if (target) {
  1.    currentDir = `${currentDir}/${target}`;
  1. }
  1.  const addr = `0.0.0.0:${serverArgs[2] || 4500}`;
  1.  const encoder = new TextEncoder();
  1.  function modeToString(isDir: boolean, maybeMode: number | null) {
  1.    const modeMap = ["---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"];
  1.    if (maybeMode === null) {
  1.      return "(unknown mode)";
  1.   }
  1.    const mode = maybeMode!.toString(8);
  1.    if (mode.length < 3) {
  1.      return "(unknown mode)";
  1.   }
  1.    let output = "";
  1.    mode
  1.     .split("")
  1.     .reverse()
  1.     .slice(0, 3)
  1.     .forEach(v => {
  1.        output = modeMap[+v] + output;
  1.     });
  1.    output = `(${isDir ? "d" : "-"}${output})`;
  1.    return output;
  1. }
  1.  function fileLenToString(len: number) {
  1.    const multipler = 1024;
  1.    let base = 1;
  1.    const suffix = ["B", "K", "M", "G", "T"];
  1.    let suffixIndex = 0;
  1.    while (base * multipler < len) {
  1.      if (suffixIndex >= suffix.length - 1) {
  1.        break;
  1.     }
  1.      base *= multipler;
  1.      suffixIndex++;
  1.   }
  1.    return `${(len / base).toFixed(2)}${suffix[suffixIndex]}`;
  1. }
  1.  function createDirEntryDisplay(
  1.    name: string,
  1.    path: string,
  1.    size: number | null,
  1.    mode: number | null,
  1.    isDir: boolean
  1. ) {
  1.    const sizeStr = size === null ? "" : "" + fileLenToString(size!);
  1.    return `
  1.    <tr><td class="mode">${modeToString(
  1.      isDir,
  1.      mode
  1.   )}</td><td>${sizeStr}</td><td><a href="${path}">${name}${
  1.      isDir ? "/" : ""
  1.   }</a></td>
  1.    </tr>
  1.    `;
  1.  }
  1.  // TODO: simplify this after deno.stat and deno.readDir are fixed
  1.  async function serveDir(req: ServerRequest, dirPath: string, dirName: string) {
  1.    // dirname has no prefix
  1.    const listEntry: string[] = [];
  1.    const fileInfos = await readDir(dirPath);
  1.    for (const info of fileInfos) {
  1.      if (info.name === "index.html" && info.isFile()) {
  1.        // in case index.html as dir...
  1.        return await serveFile(req, info.path);
  1.      }
  1.      // Yuck!
  1.      let mode = null;
  1.      try {
  1.        mode = (await stat(info.path)).mode;
  1.      } catch (e) {}
  1.      listEntry.push(
  1.        createDirEntryDisplay(
  1.          info.name,
  1.          dirName + "/" + info.name,
  1.          info.isFile() ? info.len : null,
  1.          mode,
  1.          info.isDirectory()
  1.        )
  1.      );
  1.    }
  1.    const page = new TextEncoder().encode(
  1.      dirViewerTemplate
  1.        .replace("<%DIRNAME%>", dirName + "/")
  1.        .replace("<%CONTENTS%>", listEntry.join(""))
  1.    );
  1.    const headers = new Headers();
  1.    headers.set("content-type", "text/html");
  1.    const res = {
  1.      status: 200,
  1.      body: page,
  1.      headers
  1.    };
  1.    setContentLength(res);
  1.    return res;
  1.  }
  1.  async function serveFile(req: ServerRequest, filename: string) {
  1.    const file = await open(filename);
  1.    const fileInfo = await stat(filename);
  1.    const headers = new Headers();
  1.    headers.set("content-length", fileInfo.len.toString());
  1.    const res = {
  1.      status: 200,
  1.      body: file,
  1.      headers
  1.    };
  1.    return res;
  1.  }
  1.  async function serveFallback(req: ServerRequest, e: Error) {
  1.    if (
  1.      e instanceof DenoError &&
  1.      (e as DenoError<any>).kind === ErrorKind.NotFound
  1.    ) {
  1.      return {
  1.        status: 404,
  1.        body: encoder.encode("Not found")
  1.      };
  1.    } else {
  1.      return {
  1.        status: 500,
  1.        body: encoder.encode("Internal server error")
  1.      };
  1.    }
  1.  }
  1.  function serverLog(req: ServerRequest, res: Response) {
  1.    const d = new Date().toISOString();
  1.    const dateFmt = `[${d.slice(0, 10)} ${d.slice(11, 19)}]`;
  1.    const s = `${dateFmt} "${req.method} ${req.url} ${req.proto}" ${res.status}`;
  1.    console.log(s);
  1.  }
  1.  function setCORS(res: Response) {
  1.    if (!res.headers) {
  1.      res.headers = new Headers();
  1.    }
  1.    res.headers!.append("access-control-allow-origin", "*");
  1.    res.headers!.append(
  1.      "access-control-allow-headers",
  1.      "Origin, X-Requested-With, Content-Type, Accept, Range"
  1.    );
  1.  }
  1.  listenAndServe(addr, async req => {
  1.    const fileName = req.url.replace(/\/$/, "");
  1.    const filePath = currentDir + fileName;
  1.    let response: Response;
  1.    try {
  1.      const fileInfo = await stat(filePath);
  1.      if (fileInfo.isDirectory()) {
  1.        // Bug with deno.stat: name and path not populated
  1.        // Yuck!
  1.        response = await serveDir(req, filePath, fileName);
  1.      } else {
  1.        response = await serveFile(req, filePath);
  1.      }
  1.    } catch (e) {
  1.      response = await serveFallback(req, e);
  1.    } finally {
  1.      if (CORSEnabled) {
  1.        setCORS(response);
  1.      }
  1.      serverLog(req, response);
  1.      req.respond(response);
  1.    }
  1.  });
  1.  console.log(`HTTP server listening on http://${addr}/`);
 
 

运行&&效果

  • 运行
  1. docker-compose up -d
  • 效果

说明

deno 的安全控制上做的挺不错,因为使用了net ,所以需要在运行的时候指定 --allow-net

参考资料

https://github.com/rongfengliang/deno-docker-compose
https://deno.land/

deno学习四 docker 运行官方的一个http file server的更多相关文章

  1. docker 运行jenkins及vue项目与springboot项目(四.docker运行nginx)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

  2. Singer 学习五 docker 运行说明

    介绍过一个工具knots ,方便Singer 可视化开发的工具,但是默认这个工具包含的tap 以及target 比较少(可以自己扩展) 同时这个工具就是基于docker 运行的 docker 运行的几 ...

  3. ICE学习笔记一----运行官方的java版demo程序

    建议新手和我一样,从官网下载英文文档,开个有道词典,慢慢啃. 官方文档下载: http://download.csdn.net/detail/xiong_mao_1/6300631 程序代码就不说了, ...

  4. OpenGL学习——搭建OpenGL运行环境——生成一个空白视口——基于GLFW&GLEW

    最近学习OpenGL,读OpenGL宝典一头蒙,各种gl函数不知所云.逐决定先搭OpenGL运行环境,详细如下. 1.首先OpenGL是什么?是一个标准规范,是一个巨大的状态机,并无具体实现,大多数实 ...

  5. docker学习(四) - docker构建redis主从结构

    此文章假设你已经安装了docker,如果没有安装请查询本博客docker安装章节 容器网络 docker network ls  查看默认的网络 Docker安装后,默认会创建下面三种网络类型 在启动 ...

  6. JBPM学习(四):运行流程实例

    概念: ProcessInstance,流程实例:代表流程定义的一次执行.如:张三昨天按请假流程请了一次假.一个流程实例包含了全部执行阶段,当中最典型的属性就是跟踪当前节点的指针,例如以下图. Exe ...

  7. docker 运行jenkins及vue项目与springboot项目(三.jenkins的使用及自动打包vue项目)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

  8. benchmarkdotnet docker 运行

    使用docker 运行基准测试是一个不错的选择,可以减少我们环境搭建的时间,同时也可以加速ci/cd 环境准备 docker-compose 文件 version: "3" ser ...

  9. docker 运行jenkins及vue项目与springboot项目(一.安装docker)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

随机推荐

  1. 项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved 解决方法

    Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...

  2. TypeError: write() argument must be str, not bytes报错原因及Python3写入二进制文件方法

    Python2随机写入二进制文件: with open('/python2/random.bin','w') as f: f.write(os.urandom(10)) 但使用Python3会报错: ...

  3. Invalid MEX-file: caffe.mexa64 的解决方案

    http://blog.csdn.net/iamzhangzhuping/article/details/53105708

  4. 深入理解java虚拟机---jdk8新特性(二)

    1.jdk8新特性 1.新特性 2.lambda函数表达式的作用 A: 替换内部类 B:对集合的操作并行化

  5. spring源码研究2 自定义标签实现及使用

    1.自定义标签实现及使用参考: http://blog.csdn.net/fighterandknight/article/details/50112701 1)创建一个需要扩展的组件 User.ja ...

  6. SharePoint Framework 配置你的SharePoint客户端web部件开发环境

    博客地址:http://blog.csdn.net/FoxDave 你可以使用Visual Studio或者是你自己的开发环境来构建SharePoint客户端web部件.你可以使用Mac.PC或是 ...

  7. 基于.NET Core 框架搭建WebApi项目

    一 什么是.NET Core? 随着2014年 Xamarin和微软发起.NET基金会,微软在2014年11月份开放.NET框架源代码.在.NET开源基金会的统一规划下诞生了.NET Core .也就 ...

  8. Oracle 一些注意点

    number精度问题 Number(p,s): p和s都是可选的. p指精度(precision),即总位数.默认情况下精度为38.精度的取值范围为1~38. s指小数位(scale),小数点右边的位 ...

  9. <Maven><Dependency><Conflict><Could not resolve>

    maven conflict solution: scenerio: Runtime Error: ``` java.lang.SecurityException: class "javax ...

  10. L314 单音节词读音规则(二)-元音字母发音规则

    1 单个元音发音尽量拖音一下(2S),发音会饱满一些. 2开音节: 辅音(辅组)(没有)+元音+辅音+e 的单词其中:元音发字母本身音,辅音字母不为r , 字母e不发音. 相对开音节:第一个元音都发字 ...