百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

使用Docker部署nextjs应用

wptr33 2024-12-11 17:29 14 浏览

最近使用nextjs网站开发,希望使用docker进行生产环境的部署,减少环境的依赖可重复部署操作。我采用的是Dockerfile编写应用镜像方式+ docker-compose实现容器部署的功能。

Docker

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。我们可以通过将开发代码打包到docker 镜像中,上传到docker hub中,待发布时通过拉取docker hub镜像启动docker 容器,实现代码运行环境的高度一致,并提高部署效率。

安装

docker 提供了各种不同系统的安装方式,,因为我们常用的正式部署环境使用linux的缘故,我这里只介绍linux里如何安装docker以及如何配置docker国内镜像加速。

1、脚本安装

$ curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

2、手动命令安装

# 先卸载旧版本的docker安装包,后安装新版
$  sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
$ sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

镜像加速

docker在国内网络环境使用会出现镜像下载过慢,甚至无法下载的问题,这里提供几个配置国内加速镜像源头地址, 在/etc/docker/daemon.json文件中写入如下内容:


{
  "registry-mirrors": [
         "https://<your-mirror-id>.mirror.aliyuncs.com", // 阿里云的加速地址,每个人都不一样
         "https://docker.mirrors.sjtug.sjtu.edu.cn", // 上海交大
         "https://docker.nju.edu.cn", // 南京大学
         "https://docker.m.daocloud.io",// DaoCloud
         "https://mirror.baidubce.com", // 百度云
         "https://dockerproxy.com"// DockerProxy 代理
         
  ]
}

配置的时候需要将后面的备注信息删除,配置后需要重启docker服务:

 sudo systemctl restart docker

重启完成后可以通过拉取一个docker镜像来验证镜像源是否可用,如:

$ docker pull node:18

常用命令

docker中又几个命令是需要我们记住的,因为需要经常使用到,如下简单介绍下几个常见的docker命令:

$ docker pull nginx:latest # 从镜像仓库拉取nginx:latest镜像
$ docker search nginx  # 搜索镜像库的nginx相关镜像
$ docker push nginx:0.0.1 # 提交本地镜像nginx:0.0.1到当前登录的镜像仓库
$ docker ps -a # 列出当前主机中所有的docker容器
$ docker run -it nginx /bin/bash  # 基于nginx镜像启动一个docker容器
$ docker pause containername # 暂停docker 容器
$ docker start containername # 启动docker容器
$ docker stop containername # 停止docker容器
$ docker restart containername # 重启docker容器
$ docker attach -it containername /bin/bash # 进入docker 容器,此种方式进入退出后会使得docker容器停止
$ docker exec -it containername /bin/bash # 进入docker 容器,此种方式进入退出后不会使得docker容器停止
$ docker export containername > containername.tar  # 导出docker容器快照
$ docker rm containername # 删除docker 容器
$ docker logs -f containername # 持续输出docker容器的日志信息
$ docker cp containerID:container_path host_path # 复制主机文件到对应docker容器的地址

Dockerfile

Docker可以通过从Dockerfile中读取指令来自动构建图像。Dockerfile是一个文本文档,其中包含用户可以在命令行上调用以组装图像的所有命令。本文介绍了可以在Dockerfile中使用的命令。

编写DockerFile

1、在项目根目录创建Dockerfile文件

构建应用镜像的基础是创建对应的dockerfile文件,常规的我们会选择将dockerfile文件创建在项目的根目录,当然也可以自定义指定位置,只要在之后的构建过程指定路径就可以了

2、dockerfile编写依赖

我这里为了减少容器的大小,所以dockerfile使用了多阶段构建的方式实现,首先是依赖阶段实现依赖库的下载,具体如下:

FROM node:18-alpine AS deps
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
RUN apk update
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn config set registry https://registry.npm.taobao.org
RUN yarn install --frozen-lockfile

需要注意:

  • nodejs对应版本,查看package.json中的版本要求
  "engines": {
    "node": ">=18.17.0"
  }
  • 我这里将软件源修改为国内镜像,默认的国外镜像可能导致软件无法更新下载
  • 更新前端库镜像为淘宝镜像

3、构建阶段

由于已经完成依赖的下载,构建阶段只需要进行编译打包即可:

FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN yarn config set registry https://registry.npm.taobao.org
RUN yarn build && yarn install --production 

4、运行阶段

完成构建后,就需要我们配置容器的基础配置,如环境变量、工作目录、监听端口、应用启动命令等:

FROM node:18-alpine AS runner

WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED 1
ENV NODE_ENV production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
RUN yarn config set registry https://registry.npm.taobao.org

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

USER nextjs

EXPOSE 3000

ENV PORT 3000



CMD ["node_modules/.bin/next", "start"]

Docker-Compose

新的 Compose V2 支持将 compose 命令作为 Docker CLI 的一部分,现已推出。Compose V2 将 compose 功能集成到 Docker 平台中,继续支持之前的大部分 docker-compose 功能和标志。您可以通过使用 docker compose 而不是 docker-compose 将连字符 (-) 替换为空格来运行 Compose V2。

Compose是Docker官方提供一个负责实现Docker 容器集群的快速编排,实现定义和运行多个Docker容器的应用。通过编写docker-compose文件可对多个服务同时进行启动/停止/更新(可定义依赖,按顺序启动服务)。

相关概念

  • 项目(project):一个docker-compose.yml 组成一个project
  • 服务(service):定义容器,配置需要运行的容器实例。一个project中由多个service组成,每个service定义了容器运行的镜像

命令

我们可以通过docker compose来查看帮助命令。


[root@VM_0_16_centos ~]# docker compose --help

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default "/root/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  builder     Manage builds
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  engine      Manage the docker engine
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

常用命令

$docker-compose up #启动docker-compose.yml中的所有容器,命令退出时,所有容器都将停止
$docker-compose up -d   #启动docker-compose.yml中的所有容器,在后台启动容器并使它们保持运行
$docker-compose logs -f #查看该容器的日志打印
$docker logs -f contianer_id #查看某一个容器的启动日志打印
$docker-compose stop #停止compose服务
$docker-compose restart #重启compose服务
$docker-compose rm  #删除compose服务
$docker-compose ps #查看compose 服务
$docker-compose kill #杀死compose服务

编写docker-compse.yml文件

完成dockerfile文件编写后,我们就需要通过编写docker-compose.yml配置文件来启动容器了。我这里是使用nginx来部署,配置如下:

version: "3.1"

services:
  db:
    image: mysql:8
    command:
      --default-authentication-plugin=mysql_native_password
      --sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
      --group_concat_max_len=102400
    restart: unless-stopped
    volumes:
      - ./data/mysql/:/var/lib/mysql/
    environment:
      TZ: Asia/Shanghai # 指定时区
      MYSQL_ROOT_PASSWORD: "nextjs" # 配置root用户密码
      MYSQL_DATABASE: "nextjs" # 业务库名
      MYSQL_USER: "nextjs" # 业务库用户名
      MYSQL_PASSWORD: "nextjs" # 业务库密码
    ports:
      - 3306:3306

  nextjs:
    build: .
    ports:
      - "3000:3000"
    environment:
      TZ: Asia/Shanghai # 指定时区
    container_name: nextjs
    volumes:
      - ./:/app/
    depends_on:
      - db
    restart: unless-stopped

  nginx:
    image: nginx:mainline-alpine
    container_name: nginxserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - ./.next:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d


networks:
  nodeapp-network:
    driver: bridge

Nginx配置

如上可以看出,我一共创建了三个容器,一个数据容器db,一个nextjs容器是我们的应用还有一个nginx容器是web服务,nginx里还需要将我们的配置文件映射到容器内,nginx-conf内容如下:

server {
    listen 80;
    listen [::]:80;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name patientplatypus.com www.patientplatypus.com localhost;

    # location /back {
    #   proxy_set_header X-Real-IP $remote_addr;
    #   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #   proxy_set_header Host $http_host;
    #   proxy_set_header X-NginX-Proxy true;

    #   proxy_http_version 1.1;
    #   proxy_set_header Upgrade $http_upgrade;
    #   proxy_set_header Connection "upgrade";

    #   proxy_pass http://nodejs:8000;
    # }

    location / {
      proxy_pass http://nextjs:3000;
    }

    location ~ /.well-known/acme-challenge {
      allow all;
      root /var/www/html;
    }
}

启动容器

通过如下的学习,只需要我们的宿主机器安装了docker-compse即可直接使用如下命令:

$docker-compose up -d




文章转自:https://juejin.cn/post/7381348874466705458

相关推荐

「网络安全」JAVA代码审计——XXE外部实体注入

一、WEB安全部分想要了解XXE,在那之前需要了解XML的相关基础二、XML基础...

Web前端面试题目及答案汇总(web前端面试题最新)

Web前端面试题目及答案汇总来源:极客头条以下是收集一些面试中经常会遇到的经典面试题以及自己面试过程中无法解决的问题,通过对知识的整理以及经验的总结,重新巩固自身的前端基础知识,如有错误或更好的答案,...

什么是脚本文件?与可执行文件有什么不同?

今天的内容是脚本文件和可执行文件是两种不同类型的计算机文件,它们在结构和执行方式上有显著区别。脚本文件:定义与特性...

20个实用Python运维脚本(收藏级)(python 运维工具)

系统环境:支持Linux(Ubuntu/CentOS/Debian)和Windows...

2026年前每个开发者都应该学习的技能

优秀开发者...

Linux 如何每 5、10、15 或 30 分钟运行一次 Cron 作业?

在Linux系统中,Cron是一个强大的工具,用于自动化重复性任务。通过合理配置...

Shell脚本编程进阶实战:从入门到高效自动化

Shell脚本编程进阶实战:从入门到高效自动化一、参数处理进阶:打造专业级CLI工具1.高级参数解析示例...

在Bash中按分隔符拆分字符串的方法

技术背景在Bash脚本编程中,经常会遇到需要按特定分隔符拆分字符串的需求,例如处理CSV文件、解析日志等。掌握字符串拆分的方法对于数据处理和脚本自动化非常重要。...

程序员用5分钟,把一个400多MB的苹果安装包削掉了187MB

丰色发自凹非寺量子位|公众号QbitAI前些日子,一个...

如何在 Windows 上编写批处理脚本

你知道如何使用命令提示符吗?如果这样做,您可以编写一个批处理文件。在最简单的形式中,批处理文件(或批处理脚本)是双击文件时执行的几个命令的列表。批处理文件一直回到DOS,但仍然适用于现代版本的Win...

一文搞懂shell脚本(shell脚本应用实战)

一文搞懂shell脚本1、shell脚本介绍什么是shell脚本...

一文讲清ShellScript脚本编程知识

摘要:本文详尽地讲述了ShellScript的基础内容,还有它在Linux系统里的运用情况,涵盖了它的基本语法、常用的命令以及高级的功能。ShellScript可是一种简单又非常实用的编...

在Bash脚本中获取自身所在目录的方法

技术背景在使用Bash脚本时,有时需要获取脚本自身所在的目录。比如,当脚本作为另一个应用程序的启动器时,需要将工作目录更改为脚本所在的目录,以便对该目录中的文件进行操作。然而,由于脚本的调用方式多样(...

shell中如何确定脚本的位置?这篇文章告诉你

我想从同一个位置读取一些配置文件,如何确定脚本的位置?。这个问题的出现主要是由两个原因引发的:一是您希望将脚本的数据或配置进行外部化,因此需要一种方式来寻找这些外部资源;二是您的脚本需要对某些捆绑资源...

bash shell 语法(bash命令用法)

下面是**Shell(Bash)语法的常用知识点总结**,适合初学者和日常脚本编写参考。内容涵盖变量、判断、循环、函数、重定向、正则、数组等常见用法。---#Shell(Bash)语法速查总结...