一步步完整搭建一个图纸管理系统(Django+Vue3)

Posted 重拾初心的青年人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一步步完整搭建一个图纸管理系统(Django+Vue3)相关的知识,希望对你有一定的参考价值。

图纸管理系统

一、初步构建后端项目

1、打开已经创建好的虚拟环境:激活activate(推荐使用虚拟环境)并创建项目

2、导入vs code中,项目环境大致如下:

需要将终端改成虚拟环境的解释器后,简单试运行:

3、创建子app(图纸管理系统模块)

由于我们把子项目都放在apps里面了(方便统一管理)所以注册要加入一段配置

4、创建数据库

一定要注意格式

5、设置Django连接数据库

(1)安装pymysql

pip install pymysql

(2)gveInformationSystem/settings中进行相关配置

DATABASES = 
    \'default\': 
        \'ENGINE\': \'django.db.backends.mysql\',
        \'NAME\': \'StudentDB\',
        \'USER\': \'root\',
        \'PASSWORD\': \'123456\',
        \'HOST\': \'localhost\',
        \'PORT\': \'3306\',
    

(3)需要在init.py导入pymysql

6、创建数据库表内容

(在:apps/DrawingManagementSystem/models.py)

from django.db import models


# Create your models here.
# === 图纸管理系统 models
# 传感器分类--sensor, 项目--project, 资料-data, 图纸信息-drawing

# 公有创建时间和修改时间
class TimestampMode(models.Model):
    """
    An abstract base class model that provides selfupdating ``created`` and ``modified`` fields.
    """
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True  # it\'s very important to add this line


# === 传感器类 --- Sensor:Id,name,created,modified
class Sensor(TimestampMode):
    sensor_name = models.CharField(verbose_name="传感器名称", max_length=50, unique=True, null=False, blank=False)

    # create_time = models.DateTimeField(default=timezone.now().replace(microsecond=0))

    class Meta:
        db_table = "Draw_Sensor"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.sensor_name)


# === 项目类 --- project:Id,name,created,modified
class Project(TimestampMode):
    project_name = models.CharField(verbose_name="项目名称", max_length=50, unique=True, null=False, blank=False)
    sensor = models.ForeignKey(verbose_name="所属传感器", to=Sensor, on_delete=models.PROTECT)

    class Meta:
        db_table = "Draw_Project"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.project_name)


# === 资料类 --- data:ID,name,created,modified
class Data(TimestampMode):
    data_name = models.CharField(verbose_name="资料名称", max_length=50, unique=True, null=False, blank=False)
    sensor = models.ForeignKey(verbose_name="所属传感器", to=Sensor, on_delete=models.PROTECT)
    project = models.ForeignKey(verbose_name="所属项目", to=Project, on_delete=models.PROTECT)

    class Meta:
        db_table = "Draw_Data"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.data_name)


# === 图纸信息 --- drawing:ID(Material_code),drawing_name,created,modified,drawing_spec,drawing_page,drawing_client_id,drawing_remark,drawing_version
class Drawing(TimestampMode):
    material_code = models.CharField(verbose_name="物料编号", max_length=50, blank=False)
    sensor = models.ForeignKey(verbose_name="所属传感器", to=Sensor, on_delete=models.PROTECT)
    project = models.ForeignKey(verbose_name="所属项目", to=Project, on_delete=models.PROTECT)
    data = models.ForeignKey(verbose_name="所属资料", to=Data, on_delete=models.PROTECT)
    drawing_name = models.CharField(verbose_name="材料名称", max_length=50, blank=False)
    drawing_spec = models.CharField(verbose_name="规格/图纸号", max_length=50, blank=False)
    drawing_page = models.CharField(verbose_name="图纸页数", max_length=50, blank=False)
    drawing_client_id = models.CharField(verbose_name="客户编号", max_length=50)
    drawing_version = models.CharField(verbose_name="版本号", max_length=50, blank=False)
    drawing_remark = models.CharField(verbose_name="备注", max_length=100)
    drawing_url = models.CharField(verbose_name="地址", max_length=100)
    is_deleted = models.IntegerField(verbose_name="逻辑删除0否1是", max_length=10, blank=False, default=0)

    class Meta:
        db_table = "Draw_Drawing"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.drawing_name)


(1)用指令生成数据库

python manage.py makemigrations
python manage.py migrate

完成后代码如下:

7、DRF接口(初步)

(1)DRF的安装和快速实现

安装DjangoRestFramework包

pip install djangorestframework==3.13.0

在settings中导入

序列化:负责对象和json格式的相互转换

​ a获取数据:对象-->Json返回给前端

​ b添加、修改:json-->对象 存储在数据库中

视图:实现后台功能的核心

​ 早期:视图是基于函数--FBV

​ DRF:视图基于类--CBV

路由:路由的匹配

(2)序列化

创建DrawingManagementSystem\\serializer.py文件

from rest_framework import serializers
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing


# ----Sensor序列化类----
class SensorSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Sensor
        fields = "__all__"

# ____Project序列化类____
class ProjectSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Project
        fields = "__all__"

# ____Data序列化类____
class DataSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Data
        fields = "__all__"

# ____Drawing序列化类____
class DrawingSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Drawing
        fields = "__all__"

(3)编写view.py代码(apps\\DrawingManagementSystem\\views.py)

# ====== 导入模块 ======
from rest_framework.viewsets import ModelViewSet  # 封装完成的ModelViewset视图集
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing  # 具体的类
from DrawingManagementSystem.serializer import SensorSerialzer, ProjectSerialzer, DataSerialzer, DrawingSerialzer # 序列化类

# ---Sensor视图---
class SensorViewSet(ModelViewSet):
    queryset = Sensor.objects.all()
    serializer_class = SensorSerialzer

# ---Project---
class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerialzer

# ---Data视图---
class DataViewSet(ModelViewSet):
    queryset = Data.objects.all()
    serializer_class = DataSerialzer

# ---Sensor视图---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer

(4)编写urls.py代码(apps\\DrawingManagementSystem\\urls.py)

# ======导入模块======
from django.urls import path
from rest_framework.routers import DefaultRouter
from DrawingManagementSystem.views import SensorViewSet, ProjectViewSet, DataViewSet, DrawingViewSet

# ====1.实例化一个 DefaultRouter====
router = DefaultRouter()

# ====2.注册相应的url====
# 注册Sensor对象
router.register(\'Sensors\', SensorViewSet, basename=\'Sensors\') # http://127.0.0.1:8080/DrawingApi/v1/Sensors/
# 注册Sensor对象
router.register(\'Projects\', ProjectViewSet, basename=\'Projects\') # http://127.0.0.1:8080/DrawingApi/v1/Projects/
# 注册Sensor对象
router.register(\'Datas\', DataViewSet, basename=\'Datas\') # http://127.0.0.1:8080/DrawingApi/v1/Datas/
# 注册Sensor对象
router.register(\'Drawings\', DrawingViewSet, basename=\'Drawings\') # http://127.0.0.1:8080/DrawingApi/v1/Drawings/

urlpatterns = [

]

# ====3.附加到urlpatterns集合中====
urlpatterns += router.urls

编写总urls.py代码(gveInformationSystemBE\\urls.py)

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path(\'admin/\', admin.site.urls),
    path(\'DrawingApi/v1/\',include(\'DrawingManagementSystem.urls\')),
]

编写后运行django项目

python manage.py runserver

浏览器输入:http://127.0.0.1:8000/DrawingApi/v1/

可以看到界面如下:

说明简单后端接口已经完成,可以简单测试下:

发现存入的时间是北美市区,将gveInformationSystemBE\\settings.py中的USE_TZ = True改为:USE_TZ = False

发现存入的时间是带毫秒:参考解决方法为

或者直接在数据库软件中

可以避免存入毫秒的问题

8、DRF进阶(增删改接口、筛选、搜索、分页)

其实在网址后面加上id,就可以进行数据的删除修改

(1)DRF的筛选

步骤为:

安装:pip install django-filter

pip install django-filter==21.1

注册到installed_apps中

完成filter的筛选类

在apps\\DrawingManagementSystem新建filter.py

# =====导入模块=====
from django_filters import FilterSet
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing


# ---Sensor的Filter类---
class SensorFilter(FilterSet):
    class Meta:
        model = Sensor
        fields = (\'sensor_name\',) # 传感器名称


# ---Project的Filter类---
class ProjectFilter(FilterSet):
    class Meta:
        model = Project
        fields = (\'project_name\', \'sensor\') # 项目名称 所属传感器


# ---Data的Filter类---
class DataFilter(FilterSet):
    class Meta:
        model = Data
        fields = (\'data_name\', \'sensor\', \'project\') # 资料名称 所属传感器 所属项目


# ---Drawing的Filter类---
class DrawingFilter(FilterSet):
    class Meta:
        model = Drawing
        fields = (\'drawing_name\', \'material_code\', \'drawing_spec\', \'drawing_client_id\')  # 材料名称、物料编号、规格/图纸号、客户编号

在viewset中添加筛选类

# ====== 导入模块 ======
from rest_framework.viewsets import ModelViewSet  # 封装完成的ModelViewset视图集
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing  # 具体的类
from DrawingManagementSystem.serializer import SensorSerialzer, ProjectSerialzer, DataSerialzer, \\
    DrawingSerialzer  # 序列化类
from django_filters.rest_framework import DjangoFilterBackend  # 实现筛选的后台模块
from DrawingManagementSystem.filter import SensorFilter, ProjectFilter, DataFilter, DrawingFilter


# ---Sensor视图---
class SensorViewSet(ModelViewSet):
    queryset = Sensor.objects.all()
    serializer_class = SensorSerialzer
    # 设定筛选的后台
    filter_backends = (DjangoFilterBackend,)
    # 指定筛选的类
    filter_class = SensorFilter

# ---Project---
class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerialzer
    # 设定筛选的后台
    filter_backends = (DjangoFilterBackend,)
    # 指定筛选的类
    filter_class = ProjectFilter


# ---Data视图---
class DataViewSet(ModelViewSet):
    queryset = Data.objects.all()
    serializer_class = DataSerialzer
    # 设定筛选的后台
    filter_backends = (DjangoFilterBackend,)
    # 指定筛选的类
    filter_class = DataFilter


# ---Sensor视图---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer
    # 设定筛选的后台
    filter_backends = (DjangoFilterBackend,)
    # 指定筛选的类
    filter_class = DrawingFilter

效果如下:

(2)筛选优化——模糊匹配

# =====导入模块=====
from django_filters import FilterSet,filters
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing


# ---Sensor的Filter类---
class SensorFilter(FilterSet):
    # 重新需要支持模糊匹配的字段
    sensor_name = filters.CharFilter(field_name=\'sensor_name\',lookup_expr="icontains")
    class Meta:
        model = Sensor
        fields = (\'sensor_name\',) # 传感器名称


# ---Project的Filter类---
class ProjectFilter(FilterSet):
    # 重新需要支持模糊匹配的字段
    project_name = filters.CharFilter(field_name=\'project_name\', lookup_expr="icontains")
    class Meta:
        model = Project
        fields = (\'project_name\', \'sensor\') # 项目名称 所属传感器


# ---Data的Filter类---
class DataFilter(FilterSet):
    # 重新需要支持模糊匹配的字段
    data_name = filters.CharFilter(field_name=\'data_name\', lookup_expr="icontains")
    class Meta:
        model = Data
        fields = (\'data_name\', \'sensor\', \'project\') # 资料名称 所属传感器 所属项目


# ---Drawing的Filter类---
class DrawingFilter(FilterSet):
    # 重新需要支持模糊匹配的字段
    drawing_name = filters.CharFilter(field_name=\'drawing_name\', lookup_expr="icontains")
    material_code = filters.CharFilter(field_name=\'material_code\', lookup_expr="icontains")
    drawing_spec = filters.CharFilter(field_name=\'drawing_spec\', lookup_expr="icontains")
    drawing_client_id = filters.CharFilter(field_name=\'drawing_client_id\', lookup_expr="icontains")
    class Meta:
        model = Drawing
        fields = (\'drawing_name\', \'material_code\', \'drawing_spec\', \'drawing_client_id\')  # 材料名称、物料编号、规格/图纸号、客户编号

(3)全局加入筛选后台

在gveInformationSystemBE\\settings.py中加入

# ======= REST Framework全局设置 ===========
REST_FRAMEWORK = 

    # ==== 设置全局的Filter_Backends ====
    \'DEFAULT_FILTER_BACKENDS\': [
        \'django_filters.rest_framework.DjangoFilterBackend\',
    ],



这样views.py中就不需要加入

# 设定筛选的后台
    filter_backends = (DjangoFilterBackend,)

修改后代码如下:

# ====== 导入模块 ======
from rest_framework.viewsets import ModelViewSet  # 封装完成的ModelViewset视图集
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing  # 具体的类
from DrawingManagementSystem.serializer import SensorSerialzer, ProjectSerialzer, DataSerialzer, \\
    DrawingSerialzer  # 序列化类
from DrawingManagementSystem.filter import SensorFilter, ProjectFilter, DataFilter, DrawingFilter


# ---Sensor视图---
class SensorViewSet(ModelViewSet):
    queryset = Sensor.objects.all()
    serializer_class = SensorSerialzer

    # 指定筛选的类
    filter_class = SensorFilter

# ---Project---
class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerialzer

    # 指定筛选的类
    filter_class = ProjectFilter


# ---Data视图---
class DataViewSet(ModelViewSet):
    queryset = Data.objects.all()
    serializer_class = DataSerialzer

    # 指定筛选的类
    filter_class = DataFilter


# ---Sensor视图---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer

    # 指定筛选的类
    filter_class = DrawingFilter

(4)加入搜索

筛选【filter】:一个值只能对应一个字段,需要django-filter

搜索【search】;一个值能对应多个字段,DRF自带

在gveInformationSystemBE\\settings.py中加入\'rest_framework.filters.SearchFilter\',

# ======= REST Framework全局设置 ===========
REST_FRAMEWORK = 

    # ==== 设置全局的Filter_Backends ====
    \'DEFAULT_FILTER_BACKENDS\': [
        \'django_filters.rest_framework.DjangoFilterBackend\',
        \'rest_framework.filters.SearchFilter\',

    ],



在apps\\DrawingManagementSystem\\views.py中加入需要搜索匹配的字段

# ---Sensor视图---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer

    # 指定筛选的类
    filter_class = DrawingFilter
    # 指定查找匹配的字段
    search_fields = (\'drawing_name\', \'material_code\', \'drawing_spec\', \'drawing_client_id\')

结果如下:

(5)加入分页

有2种,一种为全局

即在在gveInformationSystemBE\\settings.py中加入

# ======= REST Framework全局设置 ===========
REST_FRAMEWORK = 

    # ==== 设置全局的Filter_Backends ====
    \'DEFAULT_FILTER_BACKENDS\': [
        \'django_filters.rest_framework.DjangoFilterBackend\',
        \'rest_framework.filters.SearchFilter\',

    ],
    # ===== 设置分页 ===============
    \'DEFAULT_PAGINATION_CLASS\': \'rest_framework.pagination.PageNumberPagination\',
    \'PAGE_SIZE\': 10



还有一种为:按需分页

apps\\DrawingManagementSystem下新建paginations.py

代码如下:

# ========== 导入 ===========
from rest_framework.pagination import PageNumberPagination


class MyPageNumberPagination(PageNumberPagination):
    page_size = 5
    page_query_param = "page"
    page_size_query_param = \'size\'
    max_page_size = 50

在apps\\DrawingManagementSystem\\views.py中加入:

from DrawingManagementSystem.paginations import MyPageNumberPagination
###
###
###
# ---Sensor视图---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer
    pagination_class = MyPageNumberPagination

    # 指定筛选的类
    filter_class = DrawingFilter
    # 指定查找匹配的字段
    search_fields = (\'drawing_name\', \'material_code\', \'drawing_spec\', \'drawing_client_id\')

效果如下:

9、添加Swagger文档

记得在setting中注册

INSTALLED_APPS = [
    \'django.contrib.admin\',
    \'django.contrib.auth\',
    \'django.contrib.contenttypes\',
    \'django.contrib.sessions\',
    \'django.contrib.messages\',
    \'django.contrib.staticfiles\',
    \'DrawingManagementSystem\',
    \'rest_framework\',
    \'django_filters\',
    \'drf_yasg\',
]

效果如下:

想要中文注释

效果如下:

Dockerfile理论+实战!!!

Dockerfile概述

?Dockerfile是docker中镜像文件的的描述文件,说的直白点就是镜像文件到底是由什么东西一步步构成的。
?例如:你在淘宝上买了一个衣架,但是卖家并没有给你发一个完整的衣架,而是一些组件和一张图纸,你按照这个图纸一步一步将衣架组装起来,就成了你所需要的样子。那么 Dockerfile 就是这张图纸,镜像文件就是你需要的这个衣架,Dockerfile 不建议随便命名,就用 Dockerfile。
?因此,Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

Docker 执行 Dockerfile 的大致流程:

(1)docker从基础镜像运行一个容器;
(2)执行一条指令并对容器作出修改;
(3)执行类似docker commit的操作提交一个新的镜像层;
(4)docker再基于刚提交的镜像运行一个新容器;
(5)执行dockerfile中的下一条指令直到所有指令都执行完成。

不同阶段:

1、Dockerfile :是软件的原材料,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库等等;

2、Docker镜像 :是软件的交付品,用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;

3、Docker容器 :则可以认为是软件的运行态,容器是直接提供服务的。

Dockerfile 各参数详解:

指令 含义
FROM 镜像 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令
MAINTAINER 名字 说明新镜像的维护人信息
RUN 命令 在所基于的镜像上执行命令,并提交到新的镜像中
CMD [“要运行的程序”,”参数1”,”参数2”] 指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能最后一条被执行
EXPOSE 端口号 指定新镜像加载到Docker时要开启的端口
ENV 环境变量 变量值 设置一个环境变量的值,会被后面的RUN使用
ADD 源文件/目录 目标文件/目录 将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中, 或者是一个URL
COPY 源文件/目录 目标文件/目录 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中
VOLUME [“目录”] 在容器中创建一个挂载点
USER 用户名/UID 指定运行容器时的用户
WORKDIR 路径 为后续的RUN、CMD、ENTRYPOINT指定 工作目录
ONBUILD 命令 指定所生成的镜像作为一个基础镜像时所要运行的命令
HEALTHCHECK 健康检查

Dockerfile实战

1、构建sshd镜像

[root@localhost ~]# cd /opt/
[root@localhost opt]# mkdir sshd  ##创建目录
[root@localhost opt]# cd sshd/
[root@localhost sshd]# vim Dockerfile  ##编写dockerfile文件

FROM centos    ##下载镜像
MAINTAINER this is sshd <xu>   ##描述信息
RUN yum -y update
RUN yum -y install openssh* net-tools lsof telnet passwd
RUN echo ‘123456‘ | passwd --stdin root
RUN sed -i ‘s/UsePAM yes/UsePAM no/g‘ /etc/ssh/sshd_config
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -i ‘/^sessions+requireds+pam_loginuid.so/s/^/#/‘ /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
EXPOSE 22  ##端口
CMD ["/usr/sbin/sshd" , "-D"]
[root@localhost sshd]# docker build -t sshd:new .   ##创建镜像
89432272695ab560b18de75a064428e4a7c4a52dfce223afd2e85132ae6c3c72
[root@localhost sshd]# docker run -d -P sshd:new  ##创建映射和容器
[root@localhost sshd]# docker ps -a  ##查看容器状态
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS                   NAMES
89432272695a        sshd:new            "/usr/sbin/sshd -D"   7 seconds ago       Up 6 seconds        0.0.0.0:32768->22/tcp   sad_fermi
[root@localhost sshd]# ssh localhost -p 32768  ##用ssh登录本地

2、构建systemctl镜像

[root@localhost ~]# cd /opt/
[root@localhost opt]# mkdir systemctl   ##创建目录
[root@localhost opt]# cd systemctl/
[root@localhost systemctl]# vim Dockerfile   ##编写dockerfile文件

FROM sshd:new
ENV container docker   ##环境
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); rm -f /lib/systemd/system/multi-user.target.wants/*; rm -f /etc/systemd/system/*.wants/*; rm -f /lib/systemd/system/local-fs.target.wants/*; rm -f /lib/systemd/system/sockets.target.wants/*udev*; rm -f /lib/systemd/system/sockets.target.wants/*initctl*; rm -f /lib/systemd/system/basic.target.wants/*; rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
[root@localhost systemctl]# docker build -t systemd:lasted .   ##创建镜像
[root@localhost systemctl]# docker run --privileged -it -v /sys/fs/cgroup/:/sys/fs/cgroup:ro systemd:lasted /sbin/init
##privateged container 内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
[root@localhost ~]# docker exec -it 23a50d568c75 bash  ##进入容器
[root@23a50d568c75 /]# systemctl status sshd   ##查看状态

3、构建Nginx镜像

[root@localhost ~]# cd /opt/
[root@localhost opt]# mkdir nginx   ##创建Nginx目录
[root@localhost opt]# cd nginx/
[root@localhost nginx]# vim Dockerfile

FROM centos:7
MAINTAINER The is nginx <xu>
RUN yum install -y proc-devel gcc gcc-c++ zlib zlib-devel make openssl-devel wget
ADD nginx-1.12.2.tar.gz /usr/local
WORKDIR /usr/local/nginx-1.12.2/
RUN ./configure --prefix=/usr/local/nginx && make && make install
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
WORKDIR /root/nginx
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
[root@localhost nginx]# vim run.sh

#!/bin/bash
/usr/local/nginx/sbin/nginx   ##开启Nginx服务
[root@localhost nginx]# mount.cifs //192.168.100.3/LNMP-C7 /mnt/  ##挂载镜像
Password for root@//192.168.100.3/LNMP-C7:  
[root@localhost nginx]# cp /mnt/nginx-1.12.2.tar.gz ./   ##复制到当前目录下
[root@localhost nginx]# docker build -t nginx:new .   ##创建镜像
[root@localhost nginx]# docker run -d -P nginx:new    ##创建容器
228c1f5b8070d52c6f19d03159ad93a60d682a586c0b1f944dc651ee40576a3e
[root@localhost nginx]# docker ps -a   ##查看容器
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS                                           NAMES
228c1f5b8070        nginx:new           "/run.sh"                9 seconds ago       Up 8 seconds                  0.0.0.0:32770->80/tcp, 0.0.0.0:32769->443/tcp   busy_booth

用浏览器访问网页

技术图片

4、构建Tomcat镜像

[root@localhost opt]# mkdir tomcat
[root@localhost opt]# cd tomcat
[root@localhost tomcat]# cp /mnt/tomcat/jdk-8u91-linux-x64.tar.gz ./ ##复制到当前目录
[root@localhost tomcat]# cp /mnt/Tomcat1/tomcat/apache-tomcat-9.0.16.tar.gz ./
[root@localhost tomcat]# vim Dockerfile
FROM centos:7
MAINTAINER this is tomcat
ADD jdk-8u91-linux-x64.tar.gz /usr/local
WORKDIR /usr/local
RUN mv jdk1.8.0_91 /usr/local/java
ENV JAVA_HOME /usr/local/java     ##设置环境变量
ENV JAVA_BIN /usr/local/java/bin
ENV JRE_HOME /usr/local/java/jre
ENV PATH $PATH:/usr/local/java/bin:/usr/local/java/jre/bin
ENV CLASSPATH /usr/local/java/jre/bin:/usr/local/java/lib:/usr/local/java/jre/lib/charsets.jar
ADD apache-tomcat-8.5.16.tar.gz /usr/local
WORKDIR /usr/local
RUN mv apache-tomcat-8.5.16 /usr/local/tomcat8
EXPOSE 8080
ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]
[root@localhost tomcat]# docker build -t tomcat:centos .  ##创建镜像
[root@localhost tomcat]# docker run --name tomcat01 -p 1234:8080 -it  tomcat:centos /bin/bash
##创建容器

利用浏览器访问

技术图片

5、构建MySQL镜像

[root@localhost opt]# mkdir mysql
[root@localhost opt]# cd mysql
[root@localhost mysql]# cp /mnt/mysql-boost-5.7.20.tar.gz ./  ##将压缩包复制到当前目录下
[root@localhost mysql]# vim my.cnf  ##在当前目录下创建配置文件模板

[client]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock

[mysql]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock

[mysqld]
user = mysql
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
character_set_server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket = /usr/local/mysql/mysql.sock
server-id = 1

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
[root@localhost mysql]# vim Dockerfile   ##编写dockerfile文件
FROM centos:7
RUN yum -y install ncurses ncurses-devel bison cmake make gcc gcc-c++
RUN useradd -s /sbin/nologin mysql
ADD mysql-boost-5.7.20.tar.gz /usr/local/src
WORKDIR /usr/local/src/mysql-5.7.20/
RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock -DSYSCONFDIR=/etc -DSYSTEMD_PID_DIR=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_BOOST=boost -DWITH_SYSTEMD=1 && make && make install
RUN chown -R mysql:mysql /usr/local/mysql/
RUN rm -rf /etc/my.cnf
ADD my.cnf /etc
RUN chown mysql:mysql /etc/my.cnf
ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
WORKDIR /usr/local/mysql/
RUN bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
RUN cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
EXPOSE 3306
RUN echo -e "#!/bin/sh 
systemctl enable mysqld" > /run.sh
RUN chmod 755 /run.sh
RUN sh /run.sh
CMD ["init"]
[root@localhost mysql]# docker build -t centos:mysql .   ##创建镜像
[root@localhost mysql]# docker run --name=mysql_server -d -P --privileged centos:mysql 
##创建容器
[root@localhost mysql]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                     NAMES
998dc9797102        centos:mysql        "init"              About a minute ago   Up About a minute   0.0.0.0:32768->3306/tcp   mysql_server
[root@localhost mysql]# docker exec -it 998dc9797102 /bin/bash

[root@998dc9797102 mysql]# mysql
mysql> grant all privileges on *.* to ‘root‘@‘%‘ identified by ‘abc123‘;
mysql> grant all privileges on *.* to ‘root‘@‘localhost‘ identified by ‘abc123‘;
[root@localhost ~]# mysql -h 192.168.13.128 -u root -P 32768 -pabc123
Welcome to the MariaDB monitor.  Commands end with ; or g.
Your MySQL connection id is 4
Server version: 5.7.20 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;‘ or ‘h‘ for help. Type ‘c‘ to clear the current input statement.

MySQL [(none)]> 

以上是关于一步步完整搭建一个图纸管理系统(Django+Vue3)的主要内容,如果未能解决你的问题,请参考以下文章

White Hole现场场记(步步实现个人博客社区,Django实战开发一)

Dockerfile构建(sshsystemctlnginxtomcatmysql)

Dockerfile理论+实战!!!

Dockerfile实例——(实践操作!)

用FastDFS一步步搭建文件管理系统

干货零基础30分钟让你拥有一个完整属于自己的短视频APP系统