Skip to content

Docker 开发环境打包

🕒 发布时间: 🕒 阅读时间: 0 分钟✍︎ 文章字数: 0

在学习Docker时候,就在想怎么去利用这个技术去做点什么。于是乎,我想既然可以把运行环境包装在容器里,那我就把平时的开发环境也放在容器里试试。

Dockerfile

创建一个dockerfile文件 输入以下内容

txt
# 前端开发中,时常需要使用 shell 命令,而有一个较为完整的环境比较重要,因此选择了使用 ubuntu 作为基础,若在意容器大小的话,可自行选择适用的基础镜像

FROM debian

# 镜像作者信息

MAINTAINER Caster "[email protected]"

  

# 设置环境变量

# 在Debian系列的操作系统中,内核支持多个安装参数,DEBIAN_FRONTEND就是其中之一,用以设置安装过程中的用户界面类型。

ENV DEBIAN_FRONTEND noninteractive

  

# 设置时区

ARG TZ=Asia/Shanghai

ENV TZ ${TZ}

  

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

  

# 用 root 用户操作

USER root

  

### 更换成中科大源和更新源

RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \

    && apt-get clean \

    && apt-get update

  

# 安装相应工具

RUN apt-get install -y \

      vim \

      wget \

      curl \

      python \

      git-core

  

SHELL ["/bin/bash", "--login", "-i", "-c"]

# 安装 nvm 和 node pnpm yarn vue和nest.js

ENV NVM_DIR /home/.nvm

ENV NODE_VERSION v16

RUN mkdir -p $NVM_DIR && \

    curl -o- https://gitee.com/mirrors/nvm/raw/master/install.sh | bash \

        && . $NVM_DIR/nvm.sh \

        && nvm install ${NODE_VERSION} \

        && nvm use ${NODE_VERSION} \

        && nvm alias ${NODE_VERSION} \

        && ln -s `npm bin --global` /home/.node-bin \

        && npm install --global nrm \

        && nrm use taobao \

        && npm install -g pnpm \

        && pnpm config set registry http://registry.npm.taobao.org \

        && npm install --global yarn \

        && npm i -g @nestjs/cli \

        && npm i -g @vue/cli

  

# Add PATH for node

ENV PATH $PATH:/home/.node-bin

  

# 删除 apt/lists,可以减少最终镜像大小,详情见:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#general-guidelines-and-recommendations

# USER root

RUN rm -rf /var/lib/apt/lists/*

  

WORKDIR /var/www

Docker Compose

上面虽然创建好了dockerfile,但是有时候开发环境镜像可能还不够,比如当我需要使用Mysql时候,最好是启动一个mysql镜像,更为方便。那么就可以配置一个docker compose文件,让docker帮我们启动一系列容器。

文件内容如下

yaml
version: '3'

services:

  frontend:

    build:

      context: .

      dockerfile: ./Dockerfile

    tty: true

    ports:

      - 30000:3000

    volumes:

      - ./frontend/www:/var/www

    networks:

      - frontend

  mysql:

    image: mysql:5.7

    ports:

      - 33060:3306

    volumes:

      - ./mysql/data:/var/lib/mysql

      - ./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d

    environment:

      - MYSQL_ROOT_PASSWORD=123456

    networks:

      - frontend

  

# 将容器置于同一 networks 即可直接通过容器名访问

networks:

  frontend:

    driver: bridge

注意点

一开始我并没有加入

bash
SHELL ["/bin/bash", "--login", "-i", "-c"]

这导致了一个问题,就是我使用npm指令时候,哪怕安装了也是显示npm no found 我一直不理解,直到看到了stackoverflow的资料后才知道如何解决 就是加入上面这句放在dockerfile里,就能正确获取到npm指令了。

原因:

Dockerfile 中每一个指令都会建立一层layerRUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,commit 这一层的修改,构成新的镜像。

每个 RUN 语句都独立于其他语句运行,因此/bin/sh -c不会获得通常在登录 shell 中获取的任何环境变量。 也就是说,哪怕上面的RUN指令安装了nvm,下面的RUN指令也是获取不到的。 而RUN指令默认运行环境是/bin/sh

docker根据https://docs.docker.com/engine/reference/builder/#run的默认 [Linux] shellRUN/bin/sh -c

而我们可以用shell命令去修改运行环境

bash
SHELL ["executable", "parameters"]

SHELL 指令允许覆盖用于命令的 shell 形式的默认 shell。Linux 上的默认 shell 是 ["/bin/sh", "-c"],而在 Windows 上是 ["cmd", "/S", "/C"]。SHELL 指令必须以 JSON 形式写入 Dockerfile 中。

使用下面这句,就可以将变量环境统一为登录bash环境,也就能获取到正常使用的环境变量。

bash
SHELL ["/bin/bash", "--login", "-i", "-c"]




本文参考
https://juejin.cn/post/6991026939934801951
https://stackoverflow.com/questions/25899912/how-to-install-nvm-in-docker
https://stackoverflow.com/questions/20635472/using-the-run-instruction-in-a-dockerfile-with-source-does-not-work

Last updated: