如何将MEAN栈应用打包为集成Nginx的Docker容器
解决方案:Angular+NestJS+MongoDB一体化Docker打包
一、预制模板结构(直接复用)
可以用以下目录结构的模板,克隆后替换对应代码即可快速运行:
your-app/ ├── docker-compose.yml ├── frontend/ # 放入你的Angular项目代码 ├── backend/ # 放入你的NestJS项目代码 ├── nginx/ │ ├── nginx.conf │ └── ssl/ # Let's Encrypt证书自动生成存放目录 └── mongo/ └── init.js # MongoDB初始化脚本(可选,比如创建默认用户)
替换规则:
- 将Angular代码完整移入
frontend/目录 - 将NestJS代码完整移入
backend/目录 - 根据你的后端接口前缀,调整
nginx/nginx.conf里的反向代理路径(比如接口前缀是/api就对应配置里的location /api)
二、核心配置文件编写
1. 前端Dockerfile(frontend/Dockerfile)
# 构建Angular生产包 FROM node:18-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build --prod # 部署到Nginx FROM nginx:alpine COPY --from=build /app/dist/your-angular-app /usr/share/nginx/html COPY ../nginx/nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 443
注意:把your-angular-app替换成你Angular项目打包后dist目录下的实际子目录名
2. 后端Dockerfile(backend/Dockerfile)
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install --production COPY . . EXPOSE 3000 CMD ["npm", "start"]
3. Nginx配置文件(nginx/nginx.conf)
server { listen 80; server_name your-domain.com; # 替换为你的域名,用于Let's Encrypt验证 # HTTP重定向到HTTPS location / { return 301 https://$host$request_uri; } # Let's Encrypt ACME挑战验证路径 location /.well-known/acme-challenge/ { root /usr/share/nginx/html; allow all; } } server { listen 443 ssl; server_name your-domain.com; ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; # 前端静态文件路由 location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } # 反向代理后端接口 location /api { proxy_pass http://backend:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
4. Docker Compose编排文件(docker-compose.yml)
version: '3.8' services: frontend: build: ./frontend ports: - "80:80" - "443:443" volumes: - ./nginx/ssl:/etc/nginx/ssl - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf depends_on: - backend - mongo backend: build: ./backend environment: - MONGO_URI=mongodb://mongo:27017/your-db-name # 替换为你的MongoDB数据库名 depends_on: - mongo mongo: image: mongo:6 volumes: - mongo-data:/data/db - ./mongo/init.js:/docker-entrypoint-initdb.d/init.js # 可选,初始化数据库 ports: - "27017:27017" certbot: image: certbot/certbot volumes: - ./nginx/ssl:/etc/letsencrypt - ./frontend/dist/your-angular-app:/usr/share/nginx/html command: certonly --webroot -w /usr/share/nginx/html --email your-email@example.com --agree-tos --no-eff-email -d your-domain.com depends_on: - frontend volumes: mongo-data:
替换项:your-domain.com、your-db-name、your-email@example.com、your-angular-app
三、一键运行与证书续期
- 完成代码替换和配置修改后,在项目根目录执行:
docker-compose up -d
- Let's Encrypt证书自动续期:添加系统定时任务(例如每天凌晨1点)执行:
docker-compose run --rm certbot renew --webroot -w /usr/share/nginx/html && docker-compose restart frontend
四、单容器模式说明
如果必须要求单容器运行(类似docker run -p 80:80 image),不推荐这种方式(单容器多进程维护成本高),但可以通过supervisord管理Nginx、Node、MongoDB三个进程,构建一个包含所有依赖的镜像。不过从可维护性和Docker最佳实践来看,上面的Docker Compose多容器方案更优。
内容的提问来源于stack exchange,提问作者Xienius
相关产品推荐
相关产品推荐

