Docker学习笔记 - 创建自己的image
目录
- 基本概念
- 常用命令
- 使用docker compose启动脚本
- 创建自己的image
使用Docker是现在最为流行的软件发布方式, 本系列将阐述Docker的基本概念,常用命令,启动脚本和如何生产自己的docker image。
在我们发布软件时,往往需要把我们开发的app打包成image。下面就要介绍如何build自己的image。
这里,我们以一个Flask+Postgres项目为例,来讲解如何构建build image。
先介绍一下这个项目的架构。项目有两部分,web界面部分和数据库部分,分别封装在两个container里,并运行在同一台服务器上。Web界面部分是用flask架构开发,发布在port 5000端口,映射到服务器80 port,这样就可以直接用http形式访问。而数据的端口是将container的5432 port映射到服务器的port 15432。web程序通过服务器的15432端口访问数据库。
第一部分 Web界面部分
flask项目的目录结构 app目录位于项目根目录下,也就是说项目根目录下仅一个app目录,没有任何文件。init.py, config.py, db_model.py, db_utils.py 都是位于app目录下。 我们的当前目录是项目的根目录(这点很重要)。
1. 准备工作
执行以下命令,使用pip生成requirements.txt.
pip freeze > requirements.txt
在requirements.txt最后,加上gunicorn,添加以下这行代码。
gunicorn==20.1.0
gunicorn是基于Python的WSGI Server, 它能够接受HTTP请求并交给Flask的app去处理后返回。在生产环境中使用gunicorn比flask自带的web service更为稳定。
2. 编写Dockerfile
我们要编写一个Dockerfile来描述如何构造这个image。
Dockerfile作为默认文件名,不建议修改。但是,编译时也可以通过-f参数来指定文件作为image的构造描述文件。
Dockerfile必须在项目根目录下,这点很重要,因为在build image时会默认搜索当前目录下的Dockerfile文件。
- python开发环境配置
在hub.docker.com 选择一个python的image作为起始点, 我选的是基于Alpine Linux的Python3.11的版本。
# start by pulling the python image
FROM python:3.11-alpine
将之前生成的requirements.txt文件复制到image里
# copy the requirements file into the image
COPY requirements.txt /app/requirements.txt
接下来,安装pip和postgressql-client。pip是为了后续安装python包,而postgresql-client是要用来测试数据连通性的。Alpine Linux下面安装软件需要用apk。Ubuntu Linux 下安装软件则用apt-get。
pip 等常用工具在python的image中都已经包括,不需要单独安装。
RUN apk add postgresql-client
用pip install来安装需要的python库
# install the dependencies and packages in the requirements file
RUN pip install -r requirements.txt
- 工作目录设定
WORKDIR /app
- 复制文件和目录
复制目录的书写方式如下:
COPY ./app/*.py /app/app/
特别注意: “/app/app/” 表示的是目录, 如果最后不加”/" 则表示文件。使用COPY命令时,会自动生成新的目录。
为了将本地的目录结构复制到image里,需要对每个目录下的文件分别使用COPY命令,具体如下:
# copy every content from the local file to the image
COPY ./app/*.py /app/app/
COPY ./app/.env /app/app/
COPY ./app/admin/*.py /app/app/admin/
COPY ./app/browse/*.py /app/app/browse/
COPY ./app/login/*.py /app/app/login/
COPY ./app/templates/*.html /app/app/templates/
- 最后使用CMD命令启动gunicorn
我们就用gunicorn来启动flask程式,并且指定端口5000。如果不指定端口的话,gunicorn的默认端口是8000。
# run the app
CMD ["gunicorn","app:create_app()", "-b :5000"]
3. Build Image:
确保你的当前目录项目的根目录,且Dockerfile在你的当前目录下。运行如下命令:
docker build -t examapp:1.0 .
examapp是你要build的image名字,1.0是版本号,这个版本号不是必须的。如果你build image时不指定版本号,则编译生成的image会是latest。
最后,”.“ 是 表示生成的image保存在当前目录下。 请确保始终使用**”.“** 作为生成image保存的位置,因为你在Dockerfile里COPY使用的相对目录是基于这个位置而言的。
比如,你的image保存在项目根目录下,那么在Dockerfile里admin目录的相对位置就是 ./app/admin/ , 即当前目录下的app目录下的admin目录。
如果,你把你生成image的位置改到项目根目录下的dockerimage目录:
docker build -t examapp:1.0 ./dockerimage/
那么,那么在Dockerfile里admin目录的相对位置就是 …/app/admin/ , 即当前目录dockerimage的上级目录(即项目根目录)下的app目录下的admin。
docker build 还可以通过 -f参数来指定Dockerfile。比如,你使用Dockerfile-20240527作为文件名, 并存放在根目录下的dockerimage目录下。那么你的docker build命令可以如下:
docker build -f ./dockerimage/Dockerfile-20240527 -t examapp:1.0 .
4. 查看并启动image
成功生成image后,在linux下可以使用命令行查看该image。
docker images
在Windows下以上命令一样有效,但还可以使用docker desktop的图形界面来查看。
使用docker run来启动image:
docker run -d \-p 80:5000 \-e FLASK_APP="app:create_app('production')" \--name examapp
examapp:1.0
也可有使用yaml脚本来启动,脚本如下。
service:web:image: examapp:1.0ports:- 80:5000expose:-5000links:-db
第二部分. 数据库部分
1. 使用docker build来初始化数据库
我们有了web app的docker image,但是数据库部分,也可以打包成docker image来发布。这里,我们以posgresql为例。
我们首先要准备一个数据库初始化的脚本,create_db_schema.sql.
--CREATE DATABASE examapp_db;
GRANT ALL PRIVILEGES ON DATABASE examapp_db TO postgres;CREATE SCHEMA examapp AUTHORIZATION postgres;-- examapp.tb_exam_list definition
CREATE TABLE examapp.tb_exam_list (exam_id varchar NOT NULL,exam_desc varchar DEFAULT 'Description of the exam'::character varying NOT NULL,CONSTRAINT tb_exam_list_pk PRIMARY KEY (exam_id)
);
-- examapp.tb_exam_questions definition
CREATE TABLE examapp.tb_exam_questions (id uuid NOT NULL,question varchar NOT NULL,"index" int NULL,optiona varchar NULL,optionb varchar NULL,optionc varchar NULL,optiond varchar NULL,optione varchar NULL,optionf varchar NULL,correct_ans varchar NULL,explanation varchar NULL,exam_id varchar NULL,ansnum int not null default 1,CONSTRAINT exam_questions_pk PRIMARY KEY (id),CONSTRAINT exam_questions_tb_exam_list_fk FOREIGN KEY (exam_id) REFERENCES examapp.tb_exam_list(exam_id)
);
-- examapp.tb_user definition
CREATE TABLE examapp.tb_user (id bigserial NOT NULL,email varchar NOT NULL,"password" varchar NOT NULL,"admin" bool DEFAULT false,username varchar NOT NULL,active bool DEFAULT true NOT NULL,confirmed_at date NULL,CONSTRAINT tb_user_pk PRIMARY KEY (id),CONSTRAINT tb_user_unique UNIQUE (email),CONSTRAINT tb_user_unique_1 UNIQUE (username)
);
-- examapp.tb_usernotes definition
CREATE TABLE examapp.tb_usernotes (note_id uuid NOT NULL,question_id uuid NOT NULL,category varchar NULL,notes varchar NULL,user_id int8 NOT NULL,my_ans varchar NULL,CONSTRAINT tb_usernotes_pk PRIMARY KEY (note_id),CONSTRAINT tb_usernotes_unique UNIQUE (question_id, user_id)
);
-- examapp.tb_highlightnotes definition
CREATE TABLE examapp.tb_highlightnotes (note_id uuid NOT NULL,usernote_id uuid NOT NULL,column_name varchar NOT NULL,start_pos int4 NOT NULL,"length" int4 NOT NULL,highlight_color varchar DEFAULT 'yellow'::character varying NOT NULL,highlight_notes varchar NULL,CONSTRAINT tb_highlightnotes_pk PRIMARY KEY (note_id)
);
INSERT INTO examapp.tb_exam_list(exam_id, exam_desc)
VALUES('AWS-CLF-C01', 'AWS Certified Cloud Practitioner Certification'),
('AWS-SAA-C03','AWS Certified Solutions Architect – Associate Certification'),
('AWS-DVA-C02','AWS Certified Developer - Associate Certification');INSERT INTO examapp.tb_user(email, "password", "admin", username, active, confirmed_at)
VALUES('example@email.com', '$2b$12$1/3.r0NKjI1mXjM8oa/cyuryjVM3zhjMShWjC1HKCWgVhOSZtm2Aq', TRUE, 'admin', TRUE, '2024-05-21');
我们把这数据库脚本放到目录/examapp_db/下,然后开始编写Dockerfile。
2. 编写Dockerfile
# start by pulling the posgres image
FROM posgres:alpine3.19#set environment
ENV POSTGRES_USER posgres
ENV POSTGRES_PASSWORD Password1
ENV POSTGRES_DB examapp_db# copy the sql script into the init location
COPY create_db_schema.sql /docker-entrypoint-initdb.d/create_db_schema.sql
环境变量POSTGRES_DB定义了初始数据库名。
数据库初始化脚本必须复制到/docker-entrypoint-initdb.d/目录下,这样在image初始化时会被执行一次。
在和Dockerfile,create_db_schema.sql的同一目录下执行以下命令来创建image。
docker build -t examapp_db:1.0 .
第三部分 项目启动脚本
我们最后要把数据库的image和web app的image放到一个examapp-docker-launch.yaml里,这样确保他们会被一起创建。
service:db:image: examapp_db:1.0restart: alwaysshm_size: 128mbports: - 5432:5432expose - 5432volumes:- postgre_data: /var/lib/postgresql/dataenvironment:POSTGRES_PASSWORD: Password1 web:image: examapp:1.0ports:- 80:5000expose:-5000links:-db
volumes:postgre_data:
运行如下命令启动image
docker-compose -f examapp-docker-launch.yaml up
6. 附录
完整Dockerfile
# start by pulling the python image
FROM python:3.11-alpine# copy the requirements file into the image
COPY requirements.txt /app/requirements.txt# switch working directory
WORKDIR /app# upgrade pip
RUN apk add py3-pip# install postgre client
RUN apk add postgresql-client# install the dependencies and packages in the requirements file
RUN pip install -r requirements.txt# copy every content from the local file to the image
COPY ./app/*.py /app/app/
COPY ./app/.env /app/app/
COPY ./app/admin/*.py /app/app/admin/
COPY ./app/browse/*.py /app/app/browse/
COPY ./app/login/*.py /app/app/login/
COPY ./app/templates/*.html /app/app/templates/# run the app
CMD ["gunicorn","app:create_app()", "-b :5000"]
我在文中用到的项目实例在github上的地址:
https://github.com/deechean/ExamApp_Flask
相关文章:

Docker学习笔记 - 创建自己的image
目录 基本概念常用命令使用docker compose启动脚本创建自己的image 使用Docker是现在最为流行的软件发布方式, 本系列将阐述Docker的基本概念,常用命令,启动脚本和如何生产自己的docker image。 在我们发布软件时,往往需要把我…...

java web爬虫
目录 读取本地文件 从网站读取文件 java爬虫 总结 读取本地文件 import java.io.File; import java.io.PrintWriter; import java.util.Scanner;public class ReplaceText {public static void main() throws Exception{File file new File("basic\\test.txt"…...
MySQL开发教程和具体应用案例
一、MySQL开发教程 初识数据库 定义:数据仓库,安装在操作系统之上,用于存储和管理数据。 分类:关系型数据库(如MySQL、Oracle、SQL Server)和非关系型数据库(如Redis、MongoDB)。 SQL:结构化查询语言,用于管理和操作关系型数据库。 操作数据库 创建、修改、删除…...

QT C++ 模型视图结构 QTableView 简单例子
在Qt中,MVC模式被广泛使用于各种用户界面框架中,包括Qt的模型视图结构。Qt的模型视图结构是基于MVC模式设计的,其中包括了Model、View和Delegate三个部分。 QTableView是Qt模型视图结构中的一种视图,它用于以表格形式显示数据。 …...
2024年3月电子学会Python编程等级考试(四级)真题题库
2024年3月青少年软件编程Python等级考试(四级)真题试卷 题目总数:38 总分数:100 选择题 第 1 题 单选题 运行如下Python代码,若输入整数3,则最终输出的结果为?( ÿ…...

深入分析 Android BroadcastReceiver (一)
文章目录 深入分析 Android BroadcastReceiver (一)1. Android BroadcastReceiver 设计说明1.1 BroadcastReceiver 的主要用途 2. BroadcastReceiver 的工作机制2.1 注册 BroadcastReceiver2.1.1 静态注册2.1.2 动态注册 3. BroadcastReceiver 的生命周期4. 实现和使用 Broadca…...

2024医美如何做抖音医美抖音号,本地团购、短视频直播双ip爆品引流,实操落地课
课程下载:https://download.csdn.net/download/m0_66047725/89307619 更多资源下载:关注我。 课程内容: 01-0-序.mp4 02-01-账号定位.mp4 03-02-误区.mp4 04-03-五件套.mp4 05-04-文案怎么来.mp4 06-05-对标怎么弄.mp4 07-06-人设怎…...
Debian常用指令指南:高效管理你的Linux系统
Debian作为Linux发行版中的佼佼者,以其稳定性和安全性而闻名。掌握Debian的常用指令对于系统管理员和开发人员来说至关重要。本文将介绍一系列Debian系统中的常用指令,帮助你高效地管理和维护你的系统。喜欢的话记得一键三连哦,方便找到它。 …...
什么是DELINS交货指示?
DELINS 是指 Delivery Instruction(交货指示)报文,用于在供应链管理中传递交货指令和相关信息。该报文用于在供应链中的不同合作伙伴之间交换关于交货的详细信息。 DELINS 报文的主要功能 交货指示:传达具体的交货指令ÿ…...
基于Open3D的点云处理24-ICP匹配cuda加速
参考:docs/jupyter/t_pipelines/t_icp_registration.ipynb 完整测试用例: import open3d as o3d import open3d.core as o3cif o3d.__DEVICE_API__ == cuda:import open3d.cuda.pybind.t.pipelines.registration as treg else:...

UE_地编教程_创建地形洞材质
个人学习笔记,不喜勿喷。侵权立删! 使用地形洞材质来遮罩地形上特定位置的可视性和碰撞。如要在山脉侧面创建进入洞穴的入口,此操作将非常有用。可使用地形材质和地形洞材质的相同材质,但注意:对比不使用不透明蒙版的…...
「C系列」C 基本语法
文章目录 一、C 基本语法1. **程序结构**2. **数据类型**3. **变量声明**4. **运算符**6. **函数**7. **指针**8. **数组**9. **结构体和联合体**10. **预处理指令**11. **内存管理** 二、C 关键字1. 整体概览2. 具体关键字数据类型关键字控制流关键字其他关键字C11新增关键字总…...

java期末细节知识整理(一)
1.java程序的执行过程:先编译后解释。也就是我们在idea写的文件叫做java源文件(.java结尾的文件),经过编译器会生成字节码文件(.class结尾的文件),再通过解释器进行实现 2.栈用来存储引用类型的…...

GIt快速入门(一文学会使用Git)
GIt快速入门 文章目录 GIt快速入门一、为什么要学习Git二、Git的安装1.安装Git2.下载GUI 三、Git的概念1、版本控制2、集中式控制3、分布式控制4、多人协作开发1.并行开发2.分支管理3.冲突解决4.代码审查5.分布式特性 四、Git客户端操作1.界面介绍2.提交操作3.创建分支4.合并分…...

电机测试方法的介绍与功能实现(T测试方法)
目录 概述 1 理论介绍 2 实现原理 2.1 旋转式编码器原理 2.2 系统实现框图 2.3 测速原理 2.4 计算速度值 3 STM32Cube配置项目 3.1 软件版本信息 3.2 配置项目 4 代码实现 4.1 电机速度控制 4.2 速度计算函数 4.3 功能实现 5 测试 概述 本文主要介绍测试电机速…...
多线程和多进程的快速入门
多线程和多进程的快速入门 学习自:莫烦Python www.mofanpy.com Threading - 多线程运算python程序 多线程的简单理解:把数据分成很多段,将每一段数据放入一个线程,将所有的线程同时开始,大大的节省了运算时间。相…...
【TensorFlow深度学习】经典卷积网络架构回顾与分析
经典卷积网络架构回顾与分析 经典卷积网络架构回顾与分析:从AlexNet到ResNet、VGGLeNet、ResNet、DenseNet的深度探索AlexNet ——深度学习的破冰点火VGGNet — 简洁的美ResNet — 深持续深度的秘钥DenseNet — 密集大成塔实战代码示例:ResNet-50模型结语…...

Salesforce推出Einstein 1 Studio:用于自定义Einstein Copilot并将人工智能嵌入任何CRM应用程序的低代码人工智能工具
一、关键要点 1. Salesforce管理员和开发人员现在可以在每个Salesforce应用程序和工作流程中构建、定制和嵌入人工智能,包括Einstein Copilot。 2. Einstein 1 Studio与数据云深度集成,通过对客户数据和元数据的全面理解,解锁并统一被捕获的…...

点赋科技:建设智能饮品高地,打造数字化产业先锋
在当今数字化时代的浪潮中,点赋科技以其敏锐的洞察力和卓越的创新能力,致力于建设智能饮品高地,打造数字化产业先锋。 点赋深知智能饮品机对于推动社会进步和满足人们日益增长的需求的重要性。因此,他们投入大量资源和精力&#x…...
ORACLE RAC的一些基本理论知识
一 . Oracle RAC 的发展历程 1. Oracle Parallel Server (OPS) 早期阶段:Oracle 6 和 7 Oracle Parallel Server(OPS)是 Oracle RAC 的前身。 通过多个实例并行访问同一个数据库来提高性能。 共享磁盘架构,利用分布式锁管理&am…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...