安装docker

https://www.docker.com/

在这里插入图片描述
打开windows功能
在控制面板中打开程序和功能,再打开启动或关闭windows功能,打开这些
1
在这里插入图片描述

2
在这里插入图片描述

3
在这里插入图片描述
安装完毕后打开doc程序,出现以下代表安装运行成功
在这里插入图片描述
额外信息
如果打开出现出现以下
docker engine stopped
在这里插入图片描述
打开PowerShell以管理员方式启动,然后输入以下

wsl --update

或在cmd中输入以下

wsl.exe --update

安装wsl
在这里插入图片描述
等待安装完毕后输入以下,出现类似结果代表成功

wsl -v

在这里插入图片描述
此时再打开docker出现以下,代表docker安装并启动成功
在这里插入图片描述

docker打包和部署项目

项目文件目录结构如下

在这里插入图片描述

Dockerfile文件

# 使用官方的 Python镜像作为基础镜像
FROM python:3.12.6

# 设置工作目录
WORKDIR /app

# 将 requirements.txt 文件复制到工作目录
COPY requirements.txt .

# 安装项目依赖
# 在容器中执行 pip install 命令,安装 requirements.txt 中列出的所有依赖包。
# --no-cache-dir 参数用于避免在安装时缓存包,从而减小镜像体积。
# -i https://pypi.tuna.tsinghua.edu.cn/simple使用清华大学的镜像源
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

# 将项目代码复制到工作目录
# 第一次参数是相对于Dockerfile的路径,第二次参数是相对于WORKDIR的路径
COPY . .

# 声明容器在运行时将使用的端口
EXPOSE 8000

# 启动 FastAPI 应用,使用 uvicorn 作为 ASGI 服务器
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

requirements.txt文件

fastapi==0.115.0
uvicorn==0.30.6

main.py文件

import fastapi
from fastapi.responses import HTMLResponse

app = fastapi.FastAPI()

@app.post("/login")
async def login(request: fastapi.Request):
    request_data = await request.json()
    username = request_data.get("username")
    password = request_data.get("password")
    if username == "xudawu":
        print("测试成功")
        response_content_dict = {
            "username": username,
            "flag": '中文测试'
        }
        return response_content_dict

@app.post("/click")
async def click_handler():
    return {"response": "你点击了div!"}

@app.post("/filter")
async def filter_handler():
    return {"response": "你选择了筛选框选项!"}

# 主页面,嵌入前端代码
@app.get("/", response_class=HTMLResponse)
async def read_root():
    return """
    <html>
        <body>
            <h2>Login</h2>
            <form id="login-form">
                <input type="text" id="username" placeholder="Username" required>
                <input type="password" id="password" placeholder="Password" required>
                <button type="submit">Login</button>
            </form>

            <p id="response"></p>
            <div id="clickable-div" style="width: 200px; height: 100px; background-color: lightblue; text-align: center; line-height: 100px; cursor: pointer;">
                点击这里
            </div>
            <p id="div-response"></p>
            
            <select id="filter-select" style="margin-top: 20px; cursor: pointer;">
                <option value="">选择一个选项</option>
                <option value="option1">选项 1</option>
                <option value="option2">选项 2</option>
            </select>
            <p id="filter-response"></p>

            <iframe src="/iframe" width="100%" height="300" style="border: none;"></iframe>

            <script>
                document.getElementById('login-form').onsubmit = async (e) => {
                    e.preventDefault();
                    const username = document.getElementById('username').value;
                    const password = document.getElementById('password').value;

                    const response = await fetch('/login', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({ username, password })
                    });

                    const result = await response.json();
                    if (result.flag === '中文测试') {
                        alert('前后端通信成功')
                    }
                };

                document.getElementById('clickable-div').onclick = async () => {
                    const response = await fetch('/click', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        }
                    });

                    const result = await response.json();
                    document.getElementById('div-response').innerText = result.response;
                };

                document.getElementById('filter-select').onchange = async (e) => {
                    const response = await fetch('/filter', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        }
                    });

                    const result = await response.json();
                    document.getElementById('filter-response').innerText = result.response;
                };
            </script>
        </body>
    </html>
    """

# iframe页面,嵌入前端代码
@app.get("/iframe", response_class=HTMLResponse)
async def read_iframe():
    return """
    <html>
        <body>
            <h2>Login (Iframe)</h2>
            <form id="iframe-login-form">
                <input type="text" id="iframe-username" placeholder="Username" required>
                <input type="password" id="iframe-password" placeholder="Password" required>
                <button type="submit">Login</button>
            </form>

            <p id="iframe-response"></p>
            <div id="iframe-clickable-div" style="width: 200px; height: 100px; background-color: lightblue; text-align: center; line-height: 100px; cursor: pointer;">
                点击这里 (Iframe)
            </div>
            <p id="iframe-div-response"></p>
            
            <select id="iframe-filter-select" style="margin-top: 20px; cursor: pointer;">
                <option value="">选择一个选项</option>
                <option value="option1">选项 1</option>
                <option value="option2">选项 2</option>
            </select>
            <p id="iframe-filter-response"></p>

            <script>
                document.getElementById('iframe-login-form').onsubmit = async (e) => {
                    e.preventDefault();
                    const username = document.getElementById('iframe-username').value;
                    const password = document.getElementById('iframe-password').value;

                    const response = await fetch('/login', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({ username, password })
                    });

                    const result = await response.json();
                    if (result.flag === '中文测试') {
                        alert('前后端通信成功 (Iframe)')
                    }
                };

                document.getElementById('iframe-clickable-div').onclick = async () => {
                    const response = await fetch('/click', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        }
                    });

                    const result = await response.json();
                    document.getElementById('iframe-div-response').innerText = result.response;
                };

                document.getElementById('iframe-filter-select').onchange = async (e) => {
                    const response = await fetch('/filter', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        }
                    });

                    const result = await response.json();
                    document.getElementById('iframe-filter-response').innerText = result.response;
                };
            </script>
        </body>
    </html>
    """

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

docker打包项目文件

cd到项目所在根目录,也是Dockerfile所在的目录,启动以下命令
hello-docker为要打包成的名字
.表示Dockerfile当前所在的目录

docker build -t hello-docker .

执行过程
在这里插入图片描述

docker手动拉取镜像

当使用Dockerfile里的配置拉取镜像失败,使用以下手动方式拉取镜像

docker pull python:3.12.6

docker项目打包成功

在这里插入图片描述
使用以下命令查看创建好的镜像

docker images

在这里插入图片描述

启动刚刚创建的镜像

使用以下代码启动docker镜像
hello-docker为指定的镜像名

docker run -d -p 8000:8000 your_image_name

在这里插入图片描述
打开docker desktop可以看到镜像创建成功并已经启动
在这里插入图片描述
鼠标点击这里的链接
在这里插入图片描述
正常打开如下页面,代表docker部署成功
在这里插入图片描述

删除镜像

docker rmi image_name

执行成功
在这里插入图片描述

导出docker打包的项目

hello_docker_explore.tar为导出要存储的目标文件名
hello_docker要打包的镜像名
latest要打包的镜像标签

docker save -o hello_docker_explore.tar hello_docker:latest

在这里插入图片描述
然后在启动cmd的当前目录自动生成打包好的镜像文件
在这里插入图片描述

导入打包好的docker镜像

在docker镜像包的当前目录启动终端

docker load -i hello_docker_explore.tar

在这里插入图片描述
使用以下命名查看所有镜像,可以看到导入成功

docker images

在这里插入图片描述

导出镜像

docker save 镜像id > new_imagesname.tar

查看docker镜像的文件结构

使用以下命令进入项目文件根目录

docker run -it scau_jwc_v1 /bin/bash

使用以下命令查看根目录文件目录

ls

使用以下命令进入文件目录

ls /app/database

这里要加app是因为Dockerfile中设置了工作目录为以下
在这里插入图片描述
以下是文件目录的命令结果
在这里插入图片描述

docker官方镜像官网

https://hub.docker.com/

在这里插入图片描述

常用镜像

SQL Server

docker pull mcr.microsoft.com/mssql/server

卸载docker

卸载docker desktop
然后
在以下路径删除本地文件
在这里插入图片描述
还有如下文件
在这里插入图片描述

docker挂载、数据持久化

数据卷

数据卷是 Docker 管理的一种特殊目录,位于 Docker 主机文件系统中,默认在 /var/lib/docker/volumes/ 目录下。数据卷可以在容器之间共享,并且不受容器生命周期的影响,具有高性能和易于管理的特点。/var/lib/docker/volumes/是一个虚拟目录,并不会暴露在Windows或者mac中,属于Linux 系统上的 Docker 默认数据存储路径

创建数据卷

docker volume create my_volume

查看所有数据卷list

docker volume ls 

查看数据卷详细信息

docker volume inspect my_volume

挂载数据卷到容器

docker run -d -v my_volume:/app/data my_image

绑定挂载

绑定挂载是将主机上的一个特定目录或文件直接挂载到容器内部路径中。使用绑定挂载可以将容器的数据直接保存在主机的指定路径中
挂载的主机目录或文件不会随着容器删除而删除。

挂载主机目录到容器

docker run -d -v C:\download:/container/path my_image

区别

数据卷和绑定挂载是两种独立的数据持久化方式,可以选择其一来实现数据持久化

数据卷:

  • 优点:这种方式相当于把挂载全部交给Docker本身处理,方便快捷。
  • 缺点:真实挂载目录由Docker生成,目录较深,不方便查找。
    数据挂载:
  • 优点:目录和文件更好找也更好维护,并且能直接把目录或者文件挂载到容器上。
  • 缺点:目录和文件需要我们自行创建和维护。

常见镜像

阿里云镜像官网

https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

在这里插入图片描述

使用镜像命令

单次使用

比如拉取ollama,默认拉取命名为

docker pull ollama/ollama

在这里插入图片描述
在镜像名前添加镜像地址,如以下,构成单次使用镜像源拉取镜像

docker run -d docker.m.daocloud.io/ollama/ollama

更多可用镜像仓库

https://github.com/DaoCloud/public-image-mirror

中科大镜像官网

https://mirrors.ustc.edu.cn/

在这里插入图片描述

配置镜像

添加以下字段

"registry-mirrors": [
	  "https://dockerhub.icu/",
    "https://docker.chenby.cn/",
    "https://1gyy6d27.mirror.aliyuncs.com/",
    "https://docker.awsl9527.cn/",
    "https://docker.anyhub.us.kg/",
    "https://dhub.kubesre.xyz/",
    "https://docker.1panel.live",
    "https://docker.1ms.run",
    "https://mirror.ccs.tencentyun.com",
    "https://docker-0.unsee.tech",
    "https://docker.xuanyuan.me",
  ]

在这里插入图片描述

MaxKB

docker重新启动后数据丢失,需要将数据挂载到指定的存储位置,如maxkb的挂载

docker run -d --name=maxkb -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages cr2.fit2cloud.com/1panel/maxkb

将以上的这部分替换为自己指定的存储路径,并且设置privileged=true

~/.maxkb

最终的完整启动docker命令

docker run -d --name=maxkb -p 8080:8080 -v C:\xudawu\program\MaxKBData:/var/lib/postgresql/data --privileged=true 1panel/maxkb

MaxkB配置api时提示无效,如果是docker启动maxkb、ollma是宿主机安装的话,输入以下

http://host.docker.internal:11434/

http://host.docker.internal 是一个用于从 Docker 容器访问宿主机的特殊地址。使用这个地址可以让 Docker 容器连接到宿主机上运行的服务

SqlServer

docker run --name sqlserver2022 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=sqlserver123" -p 1434:1433 --restart always -v C:\xudawu\DockerData2024_09_29\SqlServer_2024_10_30:/var/opt/mssql/data -d mcr.microsoft.com/mssql/server
  • docker run: 这是用于运行一个新的 Docker 容器的命令。
  • -e ‘ACCEPT_EULA=Y’: 这个选项设置环境变量 ACCEPT_EULA,表明你接受 Microsoft 的最终用户许可协议 (EULA)。将其设置为 Y(Yes)是必要的,否则容器将无法启动。
  • -e ‘MSSQL_SA_PASSWORD=sqlserver123’: 这个选项设置 SQL Server 的系统管理员(SA)密码。这里密码被设置为 123
  • -p 1434:1433: 这个选项将容器的 1433 端口(SQL Server 的默认端口)映射到主机的 1434 端口。这样,主机上的应用程序可以通过 localhost:1433 访问 SQL Server。
  • –name sqlserver2022: 这个选项给容器指定一个名称(这里是 sqlserver2022),这样在管理容器时可以更容易地引用它。
  • -d: 这个选项表示在后台运行容器(detached mode),即使你关闭终端,容器仍然会在后台运行。
  • mcr.microsoft.com/mssql/server: 这是要使用的 Docker 镜像的名称,指向 Microsoft 的
    SQL Server 官方镜像。
    • –restart always,当容器停止时总是自动重启
    • -v C:\xudawu\DockerData2024_09_29\SqlServer_2024_10_30:/var/opt/mssql/data
      数据持久化存储位置

启动docker的sqlserver服务器后连接

使用navicat连接,出现如下报错,提示没有安装驱动

[IM002][Microsoft][ODBC驱动程序管理器]未发现数据源名称并且未指定默认驱动程序(0

在这里插入图片描述
在navicat安装目录找到msodbcsql_64,然后安装
在这里插入图片描述
安装后再次连接测试,测试成功

在这里插入图片描述

也可以在微软官网下载odbc驱动
https://learn.microsoft.com/zh-cn/sql/connect/odbc/microsoft-odbc-driver-for-sql-server?view=sql-server-ver16
注意navicat17以上要加端口应将英文的冒号:改为英文的逗号,

如将127.0.0.1:1433
改为127.0.0.1,1433

Navicat导入sql文件

在模式上鼠标右键,选择运行sql文件
在这里插入图片描述

修改sa的密码

使用navicat连接数据数据库后,使用以下sql语句修改密码

ALTER LOGIN sa WITH PASSWORD = '新密码' OLD_PASSWORD = '旧密码';

导入bak格式的备份文件

新建数据库,设置单一用户访问模式

在这里插入图片描述

空白处右键从文件还原

在这里插入图片描述

找到本地挂载的备份文件

在这里插入图片描述

设置好文件路径

在这里插入图片描述

postgres

docker run --name hello_postgres -e POSTGRES_PASSWORD=docker_postgres -v C:\xudawu\DockerData2024_09_29\postgres_2024_10_31:/var/lib/postgresql/data -p 5432:5432 -d postgres

默认用户名为postgres

mysql

拉取镜像

docker pull mysql:9.1.0

在这里插入图片描述

启动容器

默认用户名root
默认端口3306
docker.io/mysql:9.1.0
docker.io默认使用docker hub的镜像,未使用-d则表示前台运行,会将运行信息显示在终端

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my_secret_pw -p 3306:3306 docker.io/mysql:9.1.0

使用以上初始化容器后,删除容器,使用以下启动容器

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my_secret_pw -p 3306:3306 -d mysql:9.1.0

使用以下命令进行数据挂载

-v /my/own/datadir:/var/lib/mysql

安装mysql的odbc

先安装微软的mdac依赖
https://www.microsoft.com/en-in/download/details.aspx?id=21995

在这里插入图片描述

安装odbc
https://dev.mysql.com/downloads/connector/odbc/

在这里插入图片描述

安装完毕按win+q打开搜索栏搜索odbc,打开odbc数据源

在这里插入图片描述
在这里显示驱动,代表安装完成
在这里插入图片描述

也可以通过以下方式查看有哪些odbc驱动
import pyodbc

print(pyodbc.drivers())

运行结果
在这里插入图片描述

Ollama

拉取命令

在以下dockerhub仓库找到ollama的拉取命令

https://hub.docker.com/r/ollama/ollama/tags

如以下,也可以在Tags里找到安装指定版本的拉取命令

docker pull ollama/ollama

在这里插入图片描述

在终端输入命令

docker pull ollama/ollama:latest

等待下载完成
在这里插入图片描述

启动ollama

使用以下命令运行镜像为容器
CPU only

docker run --name ollama_container0.4.3 -v C:\xudawu\DockerData2024_09_29\ollama_2024_11_21:/root/.ollama -p 11434:11434 -d ollama/ollama

NVIDIA GPU

docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

来源,我这里的命令修改了容器名字和挂载的路径
在这里插入图片描述

启动成功

在docker中能看到端口号,
在这里插入图片描述
本地通过以下地址访问

http://localhost:11434/

代表ollama正常启动
在这里插入图片描述

使用ollama命令

在ollama命令前,增加

docker exec -it ollama_contain_name

如以下完整的命令

docker exec -it ollama_contain_name ollama run qwen2.5-coder:3b

本地没有模型会先自动下载模型
在这里插入图片描述

aider

镜像仓库链接

https://hub.docker.com/r/paulgauthier/aider/tags

使用以下命令拉取aider
在这里插入图片描述

docker桥接网络

适用于不同容器之间通信

查看所有网络列表

docker network ls

在这里插入图片描述

创建自定义桥接网络

docker network create docker_bridge_network

在这里插入图片描述

删除网络

docker network rm docker_bridge_network

在这里插入图片描述

容器加入自定义网络

增加以下字段

--network docker_bridge_network

容器间通信地址

如以下sqlserver的连接ip地址
在这里插入图片描述

常用命令

查看所有镜像

docker images

查看所有运行的容器

docker ps

查看所有容器

docker ps -a

启动容器

快捷启动

docker run -p 8080:8080 -d your_image_name

增加自定义操作

docker run --restart always --name scau_jwc_container -p 8000:8000 -v C:\xudawu\DockerData2024_09_29\scau_jwc_2024_11_01:/scau_jwc/data -d scau_jwc_image:latest

–restart always指定停止后总是自动重启
–name scau_jwc_container指定容器名
–network docker_bridge_network指定网络环境
-v C:\xudawu\DockerData2024_09_29\scau_jwc_2024_11_01:/scau_jwc/data指定挂载的本地路径
-d scau_jwc_image依赖的本地镜像

导出镜像

docker save -o hello_docker_explore.tar hello_docker:latest

导入镜像

docker load -i hello_docker_explore.tar

一个docker-compose.yml文件

mysql的docker-compose.yml文件

services:

  # 定义服务名,也是容器名
  mysql910:
    image: mysql:9.1.0
    restart: always
    environment:
      #root用户的密码 
      MYSQL_ROOT_PASSWORD: sicau_jwc_mysql123
    # 暴露端口
    ports:
      - "3306:3306"  # 将容器的 8000 端口映射到主机的 8000 端口
    # 挂载数据目录
    volumes:
      - C:\xudawu\DockerData2024_09_29\mysql_2024_11_07:/var/lib/mysql  # 将主机目录挂载到容器内的数据目录
    networks:
      - bridge  # 将服务连接到指定的网络

启动docker-compose.yml服务

cd到文件所在根目录

docker-compose up

停止服务

docker-compose down

进入容器内部

进入后可执行模型启动命令、调试环境等

docker exec -it maxkb /bin/bash

在这里插入图片描述

查看容器内文件目录

docker exec 容器ID或名称 ls

docker exec maxkbtest ls

在这里插入图片描述

ls常用命令

列出当前目录下的可见文件和目录(不包含隐藏文件,即不显示以 . 开头的文件)
ls
-a 选项:显示所有文件,包括以 . 开头的隐藏文件(如 .bashrc、.gitignore 等)
ls -a
显示详细信息(权限、大小、时间等)
ls -l
组合

ls -la:显示所有文件(包括隐藏文件)的详细信息

ls-la

空运行容器

在末尾添加 tail -f /dev/null

docker run --name maxkbtest -d 1panel/maxkb:latest tail -f /dev/null

在这里插入图片描述

拷贝本地文件到容器内部

docker cp 本地文件/目录路径 容器名称或ID:容器内目标路径

先启动一个测试容器

docker run --name=maxkbtest -p 8889:8080 -v C:\Download:/var/lib/postgresql/data -d 1panel/maxkb:latest

在这里插入图片描述

拷贝文件

docker cp C:\xudawu\Ghost1.jpg maxkbtest:/boot

在这里插入图片描述

拷贝文件目录

docker cp C:\Download\temp maxkbtest:/boot

在这里插入图片描述

docker推送镜像到仓库

创建仓库

在这里插入图片描述

在这里看到推送命令

docker tag local-image:tagname new-repo:tagname
docker push new-repo:tagname

在这里插入图片描述

本地登录dockerhub

docker login -u username

在这里插入图片描述

查看本地的镜像

docker images

在这里插入图片描述

标记镜像

docker tag hello_docker:latest rhythmcc/sicau_jwc:latest

此处已建立仓库,所以命令也同步修改
在这里插入图片描述
执行完毕
在这里插入图片描述

推送镜像到仓库

docker push rhythmcc/sicau_jwc:latest

在这里插入图片描述

推送成功

在这里查看仓库推送的镜像,和查看pull命令
在这里插入图片描述

本地拉取命令

在这里插入图片描述

安装odbc

先自行下载,然后复制到docker中

在这里插入图片描述

编写Dockerfile

# 基础镜像(选择适合你需要的镜像)
FROM python:3.12.6

# 复制本地的 .deb 文件到 Docker 容器中的 /tmp/ 目录
COPY ./mysql-connector-odbc_9.1.0-1debian12_amd64.deb /tmp/

# 安装 MySQL ODBC 驱动程序并自动修复依赖
RUN dpkg -i /tmp/mysql-connector-odbc_9.1.0-1debian12_amd64.deb || apt-get install -y -f \
    && rm /tmp/mysql-connector-odbc_9.1.0-1debian12_amd64.deb

# 清理并安装相关依赖项
RUN apt-get update \
    && apt-get install -y \
    unixodbc \
    && apt-get clean

文件目录结构

将安装包复制到此处
在这里插入图片描述

打包镜像

docker build -t mysql_odbc .
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐