使用 Docker 部署一个 Remix 项目到自己的云服务器

1,430 阅读4分钟

使用 Docker 部署一个 Remix 项目到自己的云服务器.png

本文从 0 开始部署一个 Node.js (Remix) 为例,本文本将镜像放在 ali 云上,备份。

一、技术栈准备

  • 本地 docker
  • 一台服务器(以阿里云云服务为例)
  • Docker 镜像存储库(阿里镜像服务)
  • Node.js 项目(Remix + Prisma + PostreSQL)
  • Dockerfile
  • Nginx
  • cerbot

二、为什么?

  • 在服务器和本地机器之间需要一个 DockerHub, 但是不想想将内容托管了 DockerHub 上开源。
  • 在阿里云上将镜像设为私有比较符合需求。
  • 服务器配置问题。如果我们服务器比较小,但是我们项目比较大,在本地构建的时候没有问题,但是到了服务器上就可能因为机器限制不能构建成功。

三、安装 Docker

首先需要本地服务器 都安装 docker, 根据不同的系统安装即可。

docker-default-meta-image.webp

服务推荐安装社区版本的。

四、注册阿里云并开通个人镜像服务

本文基于阿里云镜像服务,没有阿里云可以考虑开通一个,注册并开通个人镜像服务。

如果找不到,可以 容器镜像服务ACR

个人版.png

如果已经开通了个人版,显示应该是同上面的。但是会有实现使用限制:

  • 仓库:限额 300
  • 命名空间:3

这些空间其实,个人项目也够用了。也可以在 获取凭证 中修改自己的固定密码,这样就可以在终端使用自己固定的 aliyun Registry 进行登录了.

五、终端登录阿里云账号

sudo docker login --username=<your_aliyun_name> registry.<your_region>.aliyuncs.com

本地和服务器都需要使用阿里云账号登录。

六、开始一个 Remix 项目

这里以 Remix 为例,其他的编程语言,或者 Next.js 其实都差不多。

npx create-remix ali-docker-remix-demo

七、编写 Dockrefile

FROM node:20.11.1-alpine3.19 AS dependencies

WORKDIR /app

COPY package.json pnpm-lock.yaml ./

ARG DATABASE_URL

ENV DATABASE_URL=${DATABASE_URL}

RUN npm config set registry https://registry.npmmirror.com \
  && npm install -g pnpm \
  && pnpm install --prod=false

FROM dependencies AS build

COPY . .

RUN npx prisma generate

RUN NODE_OPTIONS=--max-old-space-size=4096 pnpm run build

# RUN pnpm prune --prod

FROM node:20.11.1-alpine3.19 AS runtime

WORKDIR /app

RUN npm config set registry https://registry.npmmirror.com \
  && npm install -g pnpm

COPY --from=build /app/node_modules ./node_modules

COPY --from=build /app/build ./build
COPY --from=build /app/prisma ./prisma
COPY --from=build /app/package.json ./
COPY --from=build /app/pnpm-lock.yaml ./

ARG DATABASE_URL

ENV DATABASE_URL=${DATABASE_URL}

EXPOSE 3000

CMD ["pnpm", "run", "start"]

这是一个优化过后端的 Dockerfile, 这里使用了 Prisma 链接数据库,使用分阶段构建进行,移除了非生产所需的内容,优化构建体积。

如果有更加复杂应用,如使用了数据库,redis, nginx, oss可以考虑使用 docker-compose 组合这里简单就直接使用 Dockerfile 了。

八、构建 docker 镜像

本机构建docker 进行镜像:

docker build --build-arg DATABASE_URL=postgresql://<user_name>:<password>@<host>:<port>/<db_name>?schema=public -t registry.<origin>.aliyuncs.com/<name_space>/<image_name>:<image_version> .

# 找到目标镜像 id
docker images

# 打上 tag
docker tag [ImageId]  registry.<origin>.aliyuncs.com/<name_space>/<image_name>:[镜像版本号]

使用 docker build 指定参数数据地址参数构建。

九、上传 aliyuan 镜像

# 登录
docker login --username=<user_name> registry.<origin_name>.aliyuncs.com

# 按照镜像 tag 上传
docker push  registry.<origin>.aliyuncs.com/<name_space>/<image_name>:[镜像版本号]

查看镜像版本.png

登录并将服务器上传到阿里云。上传之后可以在云服务后台查看自己的上传的进行是否成功。

十、在服务器拉取镜像

进入自己的服务器,这里以阿里云云服务为例:

# 登录
docker login --username=<user_name> registry.<origin_name>.aliyuncs.com

# 拉取镜像
docker pull  registry.<origin>.aliyuncs.com/<name_space>/<image_name>:[镜像版本号]

十一、运行镜像为容器

如果你的老项目还在运行,先停止

docker ps # 找到你的老项目<容器 id>
docker stop <container_id>

# 指定端口运行容器
docker run -p <your_port>:<container_port> -itd <container_id>

# 如果有需要可以删除老容器和镜像
docker ps -a # 找到所有容器和<容器 id>
docker rm <container_id>

docker images # 找到所有的镜像和镜像 id
docker rmi <image_id>

十二、查看镜像 logs

当然可以容器运行了情况如何也可能也需要查看一下:

docker ps # 查看正在运行的容器列表
docker ps -a # 如果运行出错,镜像不会运行

docker logs <container_id> # 输出运行后的输出

如果项目正常输出,就正常运行了

十三、ngnix

如果使用了单独 nginx 进行反向代理,可能还需要配置,并重启一下 nignx 配置。

server {
      server_name <your_server_name>;

      gzip on;
      gzip_min_length 1k;
      gzip_buffers 4 32;
      gzip_comp_level 6;
      gzip_types text/plain application/c-javascript application/javascript text/javascript;
      gzip_vary on;
      gzip_disable  "MSIE [1-6]\.";

      location / {
                      proxy_pass http://localhost:<port>;
                      proxy_set_header X-Real-IP $remote_addr;
                      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                      proxy_set_header Host $host;
            }
      access_log /var/log/nginx/<your_logs_dir>/access.log;
      error_log /var/log/nginx/<your_logs_dir>/error.log;
}

这里给了一些基本的 nginx 配置,包含gzip 压缩、本地服务代理(也就是我们 Node.js 服务),header、host 等,以及 access、error 日志保存。如果需要 ssl 证书可以使用 certbot 的服务,配合定时任务完成续签。

sudo systemctl restart nginx # 重启
sudo systemctl status nginx # 查看 nginx 状态

十四、域名与防火墙

如果有自己的域名,绑定自己域名与服务器,并在服务器打开端口防火墙限制。然后测试服务器是否正常访问。

十五、小结

本文主要探索和实践 Docker 部署 Node.js 项目(Remix 为例),从为什么需要一个私有的 Register 到本地构建到服务端运行容器,一整流程流程。最后希望能够帮助到大家。