Rocky Linux 8.7 Flask应用docker容器化

本文为Flask应用进行容器化的笔记

上传代码至RockyLinux

将代码文件IPA_VIEW_v0.2.zip上传至/opt路径下(可选择其他路径)

解压在当前目录

1
unzip IPA_VIEW_v0.2.zip 

或解压到指定目录

1
unzip IPA_VIEW_v0.2.zip  -d /IPA_VIEW

在项目根目录下创建Dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 使用官方的 Python 镜像作为基础镜像
FROM python:3.10-slim

# 设置工作目录
WORKDIR /app

# 将当前目录的内容复制到容器的工作目录中
COPY . .

# 设置时区为 Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone

# 安装所需的依赖
# RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

# 有时上面这个清华源不好使,可替换阿里云,网络畅通可以直接连接官方源
RUN pip install --no-cache-dir -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt

# 运行数据库初始化脚本
RUN flask init

# 运行generate_secret_key.py随机生成32 字节的 SECRET_KEY,然后自动写入configs.py文件

RUN python generate_secret_key.py

# 暴露应用使用的端口
# 只是一个标记指示,实际操作中使用其他端口并不影响
# 规范使用的话与实际使用的端口一致
EXPOSE 8080

# 运行 Flask 应用
CMD ["waitress-serve", "--call", "pear_admin:create_app"]

构建镜像

1
docker build -t ipa-view:v0.2 .

说明:ipa-view:v0.2 ,{镜像名称}:{TAG}

创建并运行 Docker 容器

以下创建容器的方式,根据需要选择其中之一即可

方式一:简易启动

1
docker run -d --restart always -p 5666:8080 ipa-view:v0.2

方式二:指定name和network

1
2
# 创建network,用于隔离,属于不同network的容器之间互相隔离不能互访
docker network create ipa-view-net
1
docker run -d --name ipa-view-container --network ipa-view-net --restart always -p 5666:8080 ipa-view:v0.2

参数说明:

  • -d,后台运行
  • –name ipa-view-container, 设置容器名称,不设置会随机生成
  • –network ipa-view-net, 设置network,使用该参数前需要手动创建ipa-view-net,否则提示错误docker: Error response from daemon: network ipa-view-net not found.
  • –restart always ,无论何种原因导致容器退出,都重启容器
  • -p 5666:8080,宿主机端口:容器内flask应用端口
  • ipa-view:v0.2,上一步构建的镜像

方式三:Docker Volumes(持久化)

在默认情况下,Docker Volumes 会被创建在 /var/lib/docker/volumes 目录下

将容器内日志目录和数据库目录保存至宿主机,便于数据库备份和查看日志

1、创建目录:在宿主机上,建一个目录作为Volumes的保存位置

1
2
mkdir -p /opt/ipa_view_data/sqlite_db
mkdir -p /opt/ipa_view_data/log

2、创建 Docker Volumes:使用 docker volume create 命令创建 Docker Volumes,并指定自定义的位置

1
2
docker volume create --driver local --opt o=bind --opt type=none --opt device=/opt/ipa_view_data/sqlite_db sqlite_db
docker volume create --driver local --opt o=bind --opt type=none --opt device=/opt/ipa_view_data/log log

3、创建容器

1
docker run -d -v sqlite_db:/app/instance -v log:/app/log --name ipa-view-container --network ipa-view-net --restart always -p 5666:8080 ipa-view:v0.2

查看容器

1
2
3
[root@localhost IPA_VIEW_v0.2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a72fd1a21a30 ipa-view:v0.2 "waitress-serve --ca…" 21 seconds ago Up 19 seconds 0.0.0.0:5666->8080/tcp, :::5666->8080/tcp ipa-view-container

进入容器

1
2
3
4
5
docker exec -it  a72fd1a21a30  /bin/bash

or

docker exec -it ipa-view-container /bin/bash

访问应用

浏览器输入http://your_ip_address:5666

image-20241010225328437


常见问题记录

容器内flask应用访问网络

最简单的方法是直接使用宿主机的 IP 地址来访问宿主机所在的网络中的其他主机

通常情况下,容器可以通过宿主机的 IP 地址来访问外部网络

容器内IP地址访问外部设备会经过宿主机的NAT转发出去

外部网络访问flask应用

防火墙放行端口

1
2
firewall-cmd --permanent --add-port=5666/tcp
firewall-cmd --reload

日志查看

直接docker命令查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost IPA_VIEW_v0.2]# docker logs ipa-view-container
[INFO][2024-09-30 06:39:08,049][base.py:181]Scheduler started
[DEBUG][2024-09-30 06:39:08,051][base.py:954]Looking for jobs to run
[DEBUG][2024-09-30 06:39:08,095][base.py:1030]No jobs; waiting until a job is added
[INFO][2024-09-30 06:39:08,169][wasyncore.py:485]Serving on http://0.0.0.0:8080
[INFO][2024-09-30 06:41:14,489][__init__.py:76]172.31.100.2 - - [30/Sep/2024 06:41:14] "GET / HTTP/1.1" 200 -
[INFO][2024-09-30 06:41:14,588][__init__.py:76]172.31.100.2 - - [30/Sep/2024 06:41:14] "GET /static/component/pear/css/pear.css HTTP/1.1" 200 -
[INFO][2024-09-30 06:41:14,592][__init__.py:76]172.31.100.2 - - [30/Sep/2024 06:41:14] "GET /static/admin/css/admin.css HTTP/1.1" 200 -
[INFO][2024-09-30 06:41:14,596][__init__.py:76]172.31.100.2 - - [30/Sep/2024 06:41:14] "GET /static/admin/css/admin.dark.css HTTP/1.1" 200 -
[INFO][2024-09-30 06:41:14,603][__init__.py:76]172.31.100.2 - - [30/Sep/2024 06:41:14] "GET /static/admin/css/variables.css HTTP/1.1" 200 -
[WARNING][2024-09-30 06:41:14,608][task.py:114]Task queue depth is 1
[WARNING][2024-09-30 06:41:14,613][task.py:114]Task queue depth is 2
[INFO][2024-09-30 06:41:14,634][__init__.py:76]172.31.100.2 - - [30/Sep/2024 06:41:14] "GET /static/admin/css/reset.css HTTP/1.1" 200 -
[WARNING][2024-09-30 06:41:14,637][task.py:114]Task queue depth is 2

进入Docker Volumes(持久化)的目录查看

1
2
3
4
5
6
7
8
9
10
11
 cd /opt/ipa_view_data/log/

[root@localhost log]# pwd
/opt/ipa_view_data/log
[root@localhost log]# cat log.log | more
[2024-10-09 15:43:55,150][MainThread:140080137403264][task_id:apscheduler.scheduler][base.py:181][INFO][Scheduler started]
[2024-10-09 15:43:55,152][APScheduler:140080083592896][task_id:apscheduler.scheduler][base.py:954][DEBUG][Looking for jobs to run]
[2024-10-09 15:43:55,193][APScheduler:140080083592896][task_id:apscheduler.scheduler][base.py:1030][DEBUG][No jobs; waiting until a job is added]
[2024-10-09 15:43:55,286][MainThread:140080137403264][task_id:waitress][wasyncore.py:485][INFO][Serving on http://0.0.0.0:8080]
[2024-10-09 15:43:55,292][waitress-0:140080074151616][task_id:access_log][__init__.py:76][INFO][172.31.100.2 - - [09/Oct/2024 15:43:55] "GET /api/v1/scheduler/jobs HTTP/
1.1" 200 -]

设置容器自动重启

前面docker run命令已设置,跳过

Docker 容器的重启策略如下:
–restart具体参数值详细信息:
no        // 默认策略,容器退出时不重启容器;
on-failure   // 在容器非正常退出时(退出状态非0)才重新启动容器;
on-failure:3 // 在容器非正常退出时重启容器,最多重启3次;
always     // 无论退出状态是如何,都重启容器;

修改已有容器restart参数

1
docker update --restart=always a72fd1a21a30

容器时间与宿主机时间问题

前面dockerfile已设置,跳过

经过测试,容器内的时间能与宿主机同步,但是时区不能

解决方式一:

在 Dockerfile 中设置时区。确保在容器构建阶段就设置好时区
在Dockerfile文件内添加如下代码

1
2
3
# 设置时区为 Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone

解决方式二:

通过环境变量设置时区,在启动容器时设置环境变量

1
docker run -e TZ=Asia/Shanghai -d --name ipa-view-container-v2.2 --network ipa-view-net --restart always -p 5667:8080 ipa-view:v0.2
配置Gogs和Github免密git push
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×