关于Nodejs环境使用Docker+Nginx打包部署

354 阅读2分钟

Docker镜像 Node+Nginx

  1. 项目中创建文件 Dockerfile:
# node基础镜像
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN cd ./; npm run build
WORKDIR /app

# nginx基础镜像
FROM nginx:alpine
# 将生成文件移至nginx的html目录
COPY ./dist /usr/share/nginx/html/
# 为防止冲突,移除原nginx配置
RUN rm -rf /etc/nginx/conf.d/default.conf
# 将项目中的nginx配置复制到宿主机
COPY nginx/nginx.conf /etc/nginx/
RUN mkdir /etc/nginx/logs
# 启动nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
  1. nginx配置文件nginx.conf
user  nobody;
worker_processes  8;
pid  /etc/nginx/logs/nginx.pid;
events {
    use epoll;
    worker_connections  100000;
}
worker_rlimit_nofile 100000;
http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 8m;
    sendfile           on;
    tcp_nopush        on;
    tcp_nodelay       on;
    keepalive_timeout  0;
    fastcgi_connect_timeout 30;
    fastcgi_send_timeout 30;
    fastcgi_read_timeout 30;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    gzip              on;
    gzip_min_length   1k;
    gzip_buffers      4 16k;
    gzip_http_version 1.0;
    gzip_comp_level   2;
    gzip_types        text/plain application/x-javascript text/css application/xml text/javascript;
    gzip_vary         on;
    charset      utf-8;
    access_log   off;
    log_not_found off;
    error_page   400 403 405 408 /40x.html;
    error_page   500 502 503 504 /50x.html;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$host$request_uri" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    server {
        listen       80 default;
        add_header   Content-Security-Policy upgrade-insecure-requests;
        gzip on;
        access_log /var/log/nginx/afm.access.log;
        location / {
            root /usr/share/nginx/html/;
            index index.html;
            try_files $uri $uri/ /index.html;
        }
        location ~ ^/(api) {
            # 代理后端服务
            proxy_pass https://xxxxxxxx;
            proxy_set_header Host $host;
            proxy_redirect default;
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            add_header Access-Control-Allow-Headers '*';

            if ($request_method = 'OPTIONS') {
                return 204;
            }
        }
    }
}
  1. 执行docker build -t imageName . (注意别把点丢了。。)
  2. 执行docker run -d -p 80:80 --name containerName imageName

实现过程中的几个坑:

  1. docker ps ports 为空,因为在dockerfile少了启动nginx的命令
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
  1. nginx.conf文件中第2行会报user nobody。实际是user变量已经被定义,可以查找下nginx目录里是不是存在多个nginx.con文件,所以导致变量冲突。
[emerg] "user" directive is not allowed here in /etc/nginx/conf.d/nginx.conf:2
  1. nginx.pid找不到,在Dockerfile里添加对应目录可解决。RUN mkdir /etc/nginx/logs
# [[error] open() "/usr/local/var/run/nginx.pid" failed (2: No such file or directory)](https://www.cnblogs.com/fancyLee/p/8931814.html)

几个比较常用docker命令:

  1. 已经启动过的容器,需要使用 docker logs containerName

docker cp containerName:containerPath localPath

  1. docker ps -a(不加-a只显示运行中的容器),需要查看各容器状态
  2. docker stop containerName 停止容器服务docker rm containerName移除容器
  3. docker logs containerName 这个方法很有必要,在头疼排查不到docker问题出在哪儿的时候,通过查看日志定位问题。
  4. docker cp containerName:containerPath localPath将容器内文件下载至本地指纹路径下,方便排查文件情况