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

使用Docker部署nextjs应用

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

最近使用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

相关推荐

每天一个编程技巧!掌握这7个神技,代码效率飙升200%

“同事6点下班,你却为改BUG加班到凌晨?不是你不努力,而是没掌握‘偷懒’的艺术!本文揭秘谷歌工程师私藏的7个编程神技,每天1分钟,让你的代码从‘能用’变‘逆天’。文末附《Python高效代码模板》,...

Git重置到某个历史节点(Sourcetree工具)

前言Sourcetree回滚提交和重置当前分支到此次提交的区别?回滚提交是指将改动的代码提交到本地仓库,但未推送到远端仓库的时候。...

git工作区、暂存区、本地仓库、远程仓库的区别和联系

很多程序员天天写代码,提交代码,拉取代码,对git操作非常熟练,但是对git的原理并不甚了解,借助豆包AI,写个文章总结一下。Git的四个核心区域(工作区、暂存区、本地仓库、远程仓库)是版本控制的核...

解锁人生新剧本的密钥:学会让往事退场

开篇:敦煌莫高窟的千年启示在莫高窟321窟的《降魔变》壁画前,讲解员指着斑驳色彩说:"画师刻意保留了历代修补痕迹,因为真正的传承不是定格,而是流动。"就像我们的人生剧本,精彩章节永远...

Reset local repository branch to be just like remote repository HEAD

技术背景在使用Git进行版本控制时,有时会遇到本地分支与远程分支不一致的情况。可能是因为误操作、多人协作时远程分支被更新等原因。这时就需要将本地分支重置为与远程分支的...

Git恢复至之前版本(git恢复到pull之前的版本)

让程序回到提交前的样子:两种解决方法:回退(reset)、反做(revert)方法一:gitreset...

如何将文件重置或回退到特定版本(怎么让文件回到初始状态)

技术背景在使用Git进行版本控制时,经常会遇到需要将文件回退到特定版本的情况。可能是因为当前版本出现了错误,或者想要恢复到之前某个稳定的版本。Git提供了多种方式来实现这一需求。...

git如何正确回滚代码(git命令回滚代码)

方法一,删除远程分支再提交①首先两步保证当前工作区是干净的,并且和远程分支代码一致$gitcocurrentBranch$gitpullorigincurrentBranch$gi...

[git]撤销的相关命令:reset、revert、checkout

基本概念如果不清晰上面的四个概念,请查看廖老师的git教程这里我多说几句:最开始我使用git的时候,我并不明白我为什么写完代码要用git的一些列指令把我的修改存起来。后来用多了,也就明白了为什么。gi...

利用shell脚本将Mysql错误日志保存到数据库中

说明:利用shell脚本将MYSQL的错误日志提取并保存到数据库中步骤:1)创建数据库,创建表CreatedatabaseMysqlCenter;UseMysqlCenter;CREATET...

MySQL 9.3 引入增强的JavaScript支持

MySQL,这一广泛采用的开源关系型数据库管理系统(RDBMS),发布了其9.x系列的第三个更新版本——9.3版,带来了多项新功能。...

python 连接 mysql 数据库(python连接MySQL数据库案例)

用PyMySQL包来连接Python和MySQL。在使用前需要先通过pip来安装PyMySQL包:在windows系统中打开cmd,输入pipinstallPyMySQL ...

mysql导入导出命令(mysql 导入命令)

mysql导入导出命令mysqldump命令的输入是在bin目录下.1.导出整个数据库  mysqldump-u用户名-p数据库名>导出的文件名  mysqldump-uw...

MySQL-SQL介绍(mysql sqlyog)

介绍结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统,可以使用相同...

MySQL 误删除数据恢复全攻略:基于 Binlog 的实战指南

在MySQL的世界里,二进制日志(Binlog)就是我们的"时光机"。它默默记录着数据库的每一个重要变更,就像一位忠实的史官,为我们在数据灾难中提供最后的救命稻草。本文将带您深入掌握如...