dockerfile构建项目

由 夕空 撰写于  2023年12月3日

多容器通信

创建一个名为mynet的网络:
docker network create mynet

运行 Redis 在 mynet 网络中,容器互相访问默认容器名,可定义别名 --network-alias newname
docker run -d --name redis --network mynet redis:latest
(不添加自定义网络,默认是bridge)

网络联通
docker network connect mynet 容器

拉取node.js镜像
docker pull node:20.10.0-alpine
alpine 生产环境下的多级构建,减少镜像文件

-----------------------------------------------

在含Dockerfile文件目录内制作镜像

docker build -t mynode:1.0 .

运行镜像

docker run -d -p 3000:3000 --name item -v itemdir:/app --restart always mynode:1.0

-d 是在后台执行
-p 是端口映射,这里3000:3000 前面主机的端口 映射到容器内3000端口
--name 是容器的名字
--restart always 重启docker容器跟随启动,镜像必须指明版本,不然就默认 latest
-v 挂载目录

以上具名挂载,将挂载此目录(也可自定义绝对路径)
/var/lib/docker/volumes/itemdir

安装nginx

docker pull nginx

docker run -d --name nginx -m 200m -p 80:80 -p 443:443 -e TZ=Asia/Shanghai -v nginx_conf:/etc/nginx -v nginx_logs:/var/log/nginx -v nginx_html:/usr/share/nginx/html --restart=always --privileged=true nginx:latest

这里是具名挂载,懒得像其它教程那样自定义路径挂载拷贝操作
配置文件将在:
/var/lib/docker/volumes/nginx_conf/_data/

如果nginx及docker项目没有添加共同网络,代理其它容器方法:

proxy_pass http://172.17.0.2:3000;

docker inspect 容器名/id 可查到IP,在"Networks": {"bridge": {"IPAddress": "172.17.0.2"}}}
端口是容器内端口

构建项目容器和nginx容器在同一网络或自定义共同网络,IP可直接填写网络别名

proxy_pass http://item:3000;

不想设置共同网络或查询容器IP,可直接填写主机IP,端口为对外端口

安装mysql

docker pull mysql

docker run -e TZ=Asia/Shanghai --restart=always --privileged=true -d -v /home/mysql/data:/var/lib/mysql -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/my.cnf:/etc/mysql/my.cnf -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 mysql

--restart=always 代表开启启动
--privileged=true 代表进入容器内部为管理员身份
-d 表示后台运行容器 并返回容器Id
-v 把mysql产生的数据同步到本地 防止数据丢失
-e 容器传参 设置mysql的初始密码

--------------------

常用操作

查看容器信息
docker inspect 容器名/id
进入容器
docker exec -it <id_or_name> /bin/bash
如果容器内部没有bash可/bin/sh或sh

镜像添加新标签
docker tag myimage:latest newname:1.1

设置时区(如果前期没配置)
docker cp /usr/share/zoneinfo/Asia/Shanghai mysql:/etc/localtime

拷贝
docker cp /宿主机文件 容器名或ID:/容器目录

清理none镜像(虚悬镜像)
docker image prune

清理未使用的容器、网络、映像和构建缓存(慎用)
docker system prune -a

dockerfile文件制作项目镜像

将node.js项目文件放入item文件夹里,旁边创建【Dockerfile】文件:

# FROM 表示设置要制作的镜像基于哪个镜像,FROM指令必须是整个Dockerfile的第一个指令,如果指定的镜像不存在默认会自动从Docker Hub上下载。
# 如果不指定版本,会默认使用latest,就是最新版本
FROM node:20.10.0-alpine

RUN echo http://mirrors.aliyun.com/alpine/latest-stable/main/ > /etc/apk/repositories \
&& echo http://mirrors.aliyun.com/alpine/latest-stable/community/ >> /etc/apk/repositories
RUN npm config set registry https://registry.npmmirror.com

#安装环境(如果项目无特殊包或已安装了node_modules,可以注释掉,以减小镜像体积)
RUN apk update && apk upgrade && apk add gcc musl-dev g++ make python3
RUN npm install node-pre-gyp -g

# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 创建文件夹 这个文件夹是node环境下的
RUN mkdir -p /app/item
# WORKDIR指令用于设置Dockerfile中的RUN、CMD和ENTRYPOINT指令执行命令的工作目录(默认为/目录),该指令在Dockerfile文件中可以出现多次,如果使用相对路径则为相对于WORKDIR上一次的值,
# 例如WORKDIR /data,WORKDIR logs,RUN pwd最终输出的当前目录是/data/logs。
# cd到 /app/item
WORKDIR /app/item

# 拷贝文件到容器中
COPY ./item/package.json ./

# 安装项目依赖包
RUN npm install --registry=https://registry.npmmirror.com

# WORKDIR /app

COPY . ../


# 容器对外暴露的端口号
EXPOSE 3000
# 容器启动时执行的命令
CMD ["node", "bin/www"]
# 用sh命令替换CMD
# COPY start.sh /app/start.sh
# RUN chmod +x /app/start.sh
# CMD ["/bin/bash", "/app/start.sh"]


# docker network create mynet
# --network mynet 添加共同网络

# docker build -t mynode:1.0 .
# docker run -d -p 3000:3000 --name item -v itemdir:/app/item --network mynet --restart always mynode:1.0

按以上步骤docker build在docker run

这里使用了alpine作为基础构建node.js,要比直接用源node.js有1G小很多,alpine如果不安装上面的额外项仅有200兆

共用node_modules

# FROM 表示设置要制作的镜像基于哪个镜像,FROM指令必须是整个Dockerfile的第一个指令,如果指定的镜像不存在默认会自动从Docker Hub上下载。
# 如果不指定版本,会默认使用latest,就是最新版本
FROM node:20.10.0-alpine
# 设置阿里镜像源
RUN echo http://mirrors.aliyun.com/alpine/latest-stable/main/ > /etc/apk/repositories \
&& echo http://mirrors.aliyun.com/alpine/latest-stable/community/ >> /etc/apk/repositories
RUN npm config set registry https://registry.npmmirror.com

#安装环境(如果项目无特殊包或已安装了node_modules,可以注释掉,以减小镜像体积)
RUN apk update && apk upgrade && apk add gcc musl-dev g++ make python3
RUN npm install node-pre-gyp -g

# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 创建文件夹 这个文件夹是node环境下的
RUN mkdir -p /app/item
# WORKDIR指令用于设置Dockerfile中的RUN、CMD和ENTRYPOINT指令执行命令的工作目录(默认为/目录),该指令在Dockerfile文件中可以出现多次,如果使用相对路径则为相对于WORKDIR上一次的值,
# 例如WORKDIR /data,WORKDIR logs,RUN pwd最终输出的当前目录是/data/logs。

WORKDIR /app

# 拷贝文件到容器中
COPY ./item/package.json ./
COPY ./item ./item

# 安装项目依赖包
RUN npm install --registry=https://registry.npmmirror.com
# 链接 源目录 目标目录
RUN ln -s /app/node_modules /app/item/node_modules
WORKDIR /app/item

# 容器对外暴露的端口号
EXPOSE 3000
# 容器启动时执行的命令
CMD ["node", "bin/www"]
# 用sh命令替换CMD
# COPY start.sh /app/start.sh
# RUN chmod +x /app/start.sh
# CMD ["/bin/bash", "/app/start.sh"]


# docker network create mynet
# --network mynet 添加共同网络

# docker build -t mynode:1.0 .
# docker run -d -p 3000:3000 --name item -v node_modules:/app/node_modules -v itemdir:/app/item --network mynet --restart always mynode:1.0

方法是node_modules包安装至app文件夹内,然后链接至item文件夹里

docker run -d -p 3000:3000 --name item -v node_modules:/app/node_modules -v itemdir:/app/item --network mynet --restart always mynode:1.0

然后构建时具名挂载-v node_modules:/app/node_modules,构建其它项目时也挂载此处(注意挂载/app/item时换掉itemdir),此时所有项目都共用这个具名挂载的node_modules目录了。

后续安装请在/app/目录下npm install,切记不要在项目目录也就是/app/item/里进行npm install,这样会导致链接失效,容器/app/item里会重新出现node_modules文件夹


声明:星耀夕空|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - dockerfile构建项目


欢迎光顾我的小站!