docker及py程序中时区设置

1 docker中时区设置

写dockerfile时添加以下代码:

ENV DEBIAN_FRONTEND noninteractive
#定义时区参数
ENV TZ=Asia/Shanghai
ENV LANG C.UTF-8

RUN apt-get update \
&& apt-get upgrade -y \
# 安装时区依赖包tzfata,并设置时区为东八区
&& apt-get install -y tzdata \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \

&& rm -rf /var/lib/apt/lists/*

2 python程序中设置时区

python程序中设置时区,一定要系统中/usr/share/zoneinfo文件夹下有时区文件夹及文件,或者设置不能成功,而且设置时区,一定要在入口文件的最顶行设置,否则可能在设置之前的部分代码可能不会生效

import os
import time

os.environ['TZ'] = 'Asia/Shanghai'
time.tzset()

3 使用docker+uwsgi+nginx联合部署项目

3.1 nginx配置

user www-data;
worker_processes auto;
pid /var/log/nginx/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {
    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;
  
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    server {
        listen 10005 default_server;
        listen [::]:10005 default_server;
        root    /home/traffic/app;
        server_name  localhost;
        access_log /home/traffic/app/log/nginx_access.log;
        error_log /home/traffic/app/log/nginx_error.log;

        location / {
            proxy_redirect     off;
            proxy_set_header   Host             $http_host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            include uwsgi_params;
            uwsgi_pass localhost:10000;

            uwsgi_param UWSGI_CHDIR /home/traffic/app;
            uwsgi_param UWSGI_SCRIPT traffic_per_http:app;
            uwsgi_param UWSGI_PYHOME /usr/bin;
            uwsgi_send_timeout 2;        # 指定向uWSGI传送请求的超时时间,完成握手后向uWSGI传送请求的超时时间。
            uwsgi_connect_timeout 2;   # 指定连接到后端uWSGI的超时时间。
            uwsgi_read_timeout 600;        # 指定接收uWSGI应答的超时时间,完成握手后接收uWSGI应答的超时时间。
        }

        location ~ ^\/static\/.*$ {
            expires 30d;
            autoindex on;
            add_header Cache-Control private;
            alias /home/traffic/app/static/;
        }

        location ~ ^\/media\/.*$ {
            alias /home/traffic/app/media/;
        }
    }
}

3.2 uwsgi配置

[uwsgi]
master = true
socket = 127.0.0.1:10000
chdir = /home/traffic/app
pythonpath = /usr/bin/python3
wsgi-file = traffic_per_http.py 
callable = app
logto = /home/traffic/app/log/uwsgi.log
processes = 4     //处理器个数
threads = 2     //线程个数
gevent = 1000
async = 30
stats = 127.0.0.1:9191   //获取uwsgi统计信息的服务地址
vacuum = true #当服务器退出的时候自动删除unix socket文件和pid文件。
listen = 120 #设置socket的监听队列大小
;pidfile = /var/run/uwsgi.pid  #指定pid文件
enable-threads = true  #允许用内嵌的语言启动线程。这将允许你在app程序中产生一个子线程
# daemonize使用需要单独注意,若nginx前台运行,则需要配置daemonize,若nginx后台运行,则不需要配置该句
daemonize = /home/traffic/app/log/traffic_uwsgi.log  # 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器

3.3dockerfile写入内容及权限问题解决办法

nginx启动时报错权限问题,可以通过RUN chown root /usr/sbin/nginx及chmod u+s /usr/sbin/nginx两句予以解决,意为使用root用户启动nginx,如果不使用这两句,则需要通过修改nginx需要写入的日志文件所在的文件夹的权限来达到普通用户启动nginx的目的,用普通用户启动nginx会有警告信息。
如果向root用户管理的文件及文件夹中写入内容而因为没有权限不能启动,可以通过增加权限予以解决,如RUN chmod 777 /usr/sbin/nginx。
容器启动因为权限而不能顺利启动的,需要检查是否向root管理的文件及文件夹中写入过数据(如日志、进程文件等数据),如果写入过,则需要使用RUN来修改,如(RUN chmod -R 777 /var/run),因为没有权限而不能向/var/run文件夹下写入文件,运行了该句,即可使用普通用户身份写入数据到/var/run文件夹中。
dockerfile中谨慎使用root用户启动镜像,因为部署在集群平台会因为安全问题而不能部署成功。

FROM ubuntu:20.04
LABEL description="nginx container based on UBUNTU 20.04"

ENV DEBIAN_FRONTEND noninteractive
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list

#定义时区参数
ENV TZ=Asia/Shanghai LANG=C.UTF-8
ENV redisHost=127.0.0.1 redisPort=6379 redisPassword='**' redisChannel=traffic_channel \
    pgDB=traffic pgHost=127.0.0.1 pgPort=5432 pgPwd=** pgUser=traffic

RUN apt-get update \
    && apt-get upgrade -y \
    # 安装时区依赖包tzfata,并设置时区为东八区
    && apt-get install -y tzdata \
    && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
    && echo $TZ > /etc/timezone \

    && apt-get install -y python3.8 \
    && apt-get install -y python3-pip \
    && apt-get install -y nginx \
    && rm -rf /var/lib/apt/lists/\*

COPY ./requirements.txt requirements.txt

RUN pip3 install --no-cache-dir --default-timeout=1200 -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
#RUN pip3 install numpy==1.20.2 pandas==1.2.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

RUN adduser -u 6789 --disabled-password --gecos '' traffic \
    && adduser traffic sudo

ADD ./ /home/traffic/app
RUN mkdir -p /home/traffic/app/log \
    && chmod -R 777 /home/traffic/app \
    && chmod -R 777 /var/log/nginx \
    && chmod -R 777 /var/lib/nginx \
    && chmod -R 777 /var/run \
    && chmod 777 /usr/sbin/nginx \
    && chmod -R 777 /etc/nginx/ \
    && chown root /usr/sbin/nginx \ # 本句及下一句解决nginx启动警告信息,意为使用root启动nginx
    && chmod u+s /usr/sbin/nginx # 当在集群化平台部署报不能使用root启动时,需要删除本句及上一句

WORKDIR /home/traffic/app
USER traffic
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 10005
# 当使用nginx -g "daemon on;"时,nginx将以后台运行,所以uwsgi必须以前台方式运行,配置文件中不能有daemonize信息
# 当nginx -g "daemon off;",nginx以前台方式运行,所以uwsgi则需以后台方式运行,配置文件中需要有daemonize配置
# 执行多个命令时,必须前面都是后台运行,最后一个在前台运行,daemon off表示nginx关闭后台运行,意即nginx在前台运行
#ENTRYPOINT nginx -g "daemon on;" && uwsgi --ini traffic.ini
ENTRYPOINT uwsgi --ini traffic.ini && nginx -g "daemon off;"

4 supervisor部署项目

4.1修改supervisor.conf配置文件

修改/etc/supervisor/supervisor.conf文件

; supervisor config file

[unix_http_server]
file=/var/run/supervisor.sock   ; (the path to the socket file)
chmod=0700                       ; sockef file mode (default 0700)

[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor            ; ('AUTO' child log dir, default $TEMP)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[inet_http_server]         ; inet (TCP) server disabled by default
port=0.0.0.0:9001          ; (ip_address:port specifier, *:port for all iface)
username=admin              ; (default is no username (open server))
password=123456               ; (default is no password (open server))

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket

; The [include] section can just contain the "files" setting.  This
; setting can list multiple files (separated by whitespace or
; newlines).  It can also contain wildcards.  The filenames are
; interpreted as relative to this file.  Included files *cannot*
; include files themselves.

[include]
files = /etc/supervisor/conf.d/*.conf
 ; 将自定义的文件夹添加到下面一行
files = /etc/supervisor/config.d/*.ini

4.2编写配置文件

vim supervisor_task.ini
chmod -x supervisor_task.ini

[program:traffic-performance-http]
user=main
environment=
    pgDB="traffic",
    pgHost="127.0.0.1",
    pgPort=5432,
    pgPwd="**",
    pgUser="traffic"
command=/bin/bash -c "cd ~/Desktop/traffic&&~/env/traffic/bin/gunicorn -c gun.py traffic_per_http:app"
directory=~/Desktop/traffic/
autorestart=true
startsecs=10
stderr_logfile=~/Desktop/traffic/log/traffic-performance-http.log
stdout_logfile=~/Desktop/traffic/log/traffic-performance-http.log
daemon=true
startretries=100
stopasgroup=true
killasgroup=true

你可能感兴趣的:(docker及py程序中时区设置)