简体   繁体   English

在 Docker 容器错误的时区内运行 python 脚本

[英]Running python script inside Docker container wrong timezone

I'm running a script inside a Docker container (python:3.6) and it shows me the wrong time in the logs.我在 Docker 容器 (python:3.6) 中运行一个脚本,它在日志中显示了错误的时间。 When using the following python code in the python console(inside the container) it gives me the correct timezone.在 python 控制台(在容器内)中使用以下 python 代码时,它为我提供了正确的时区。

import datetime
datetime.datetime.now()
datetime.datetime(2019, 8, 3, 17, 26, 25, 662809)

Also, when running the date command inside the container, it gives the correct timezone.此外,在容器内运行date命令时,它会提供正确的时区。

However, I have this print statement in my script:但是,我的脚本中有这个打印语句:

print("Updating....", datetime.datetime.now())

This however, gives me the wrong timezone (2 hours off).然而,这给了我错误的时区(2 小时)。

在此处输入图像描述

This is my docker-compose.yml:这是我的 docker-compose.yml:

version: '3'
services:
  app:
    container_name: app
    build: .
    restart: unless-stopped
    environment:
      TZ: Europe/Amsterdam
    depends_on:
      - db
  db:
    container_name: db
    image: mariadb
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: x
      MYSQL_DATABASE: x
      MYSQL_USER: x
      MYSQL_PASSWORD: x
      TZ: Europe/Amsterdam
    volumes:
      - /volumes/x/db:/var/lib/mysql

This is my crontab file (runs inside the app container)这是我的 crontab 文件(在应用程序容器内运行)

CRON_TZ=Europe/Amsterdam

*/5 * * * * cd /usr/src/app && /usr/local/bin/python3.6 -u -m x > /proc/1/fd/1 2>/proc/1/fd/2
0,30 * * * * cd /usr/src/app && /usr/local/bin/python3.6 -u -m x > /proc/1/fd/1 2>/proc/1/fd/2
5 0 * * * cd /usr/src/app && /usr/local/bin/python3.6 -u -m x > /proc/1/fd/1 2>/proc/1/fd/2

I tried setting the timezone in docker-compose.yml , that worked for date command and the python console.我尝试在docker-compose.yml中设置时区,这适用于date命令和 python 控制台。 I tried setting the timezone inside the crontab file, but it still doesn't show the correct timezone in the script.我尝试在 crontab 文件中设置时区,但它仍然没有在脚本中显示正确的时区。

How do I set the timezone for Python inside a crontab, so that the logs do have the correct timezone?如何在 crontab 中设置 Python 的时区,以便日志具有正确的时区? Also, I need to run a script at 00:05 not 22:05, does that work now?另外,我需要在 00:05 而不是 22:05 运行脚本,现在可以了吗?

If you are trying to sync the timezone in the container with the host machine, you can map the timezone setting from the host.如果您尝试将容器中的时区与主机同步,则可以从主机映射时区设置。 I've done this successfully with the following volume:我已经成功完成了以下卷:

-v /etc/localtime:/etc/localtime

Or in your docker-compose.yml file:或者在你的 docker-compose.yml 文件中:

volumes:
    - /etc/localtime:/etc/localtime

I got burned by this same problem a while back.不久前,我被同样的问题所困扰。 Unfortunately, I don't remember the exact fix that ended up working.不幸的是,我不记得最终起作用的确切修复。 But here are some pointers:但这里有一些提示:

1) The problem is with Docker, not Python or datetime or anything else. 1) 问题出在 Docker 上,而不是 Python 或日期时间或其他任何东西。 Docker containers struggle to know what the time is. Docker 容器很难知道时间是什么时候。 What you want to search for is ways to sync up time inside a container with host.您要搜索的是将容器内的时间与主机同步的方法。

2) There are many suggested ways of handling time in containers, but I remember them all being work-arounds of sorts. 2)在容器中处理时间有很多建议的方法,但我记得它们都是各种变通方法。 Last I checked there was no clear solution.最后我检查了没有明确的解决方案。

3) I would HIGHLY recommend that you do not put cron jobs inside containers. 3)我强烈建议您不要将 cron 作业放入容器中。 If you need things to run at a certain time, put the crons ON THE HOST, and have them spin up the containers when needed.如果您需要在某个时间运行某些东西,请将 cron 放在主机上,并在需要时让它们启动容器。 This is much more reliable.这要可靠得多。

you can try to use time.tzset() in the beginning of your code or you can use :您可以尝试在代码开头使用 time.tzset() 或者您可以使用:

import detetime
import pytz

datetime.now(tz=pytz.timezone('Europe/Amsterdam'))

# or datetime.now(tz=pytz.timezone(os.environ.get('TZ'))

also, check this另外,检查这个

For most users, setting the environment variable as below for your Python container in your docker-compose.yml should be sufficient and effective:对于大多数用户来说,在docker-compose.yml中为 Python 容器设置如下环境变量就足够了:

   environment:
      TZ: America/New_York

This was tested with CPython 3.8.这是用 CPython 3.8 测试的。 Remember to recreate and not merely restart your container after setting it.请记住重新创建,而不仅仅是在设置后重新启动容器。


Credit: comment by Harsh Nagarkar.图片来源:Harsh Nagarkar 的评论。

What is extremely strange, is that I have a python script writing the time to a log (among other things).非常奇怪的是,我有一个 python 脚本将时间写入日志(以及其他内容)。

import time 
print(time.strftime("%c"))

will return 'Tue Mar 15 14:25:31 2022' for example.例如,将返回“2022 年 3 月 15 日星期二 14:25:31”。 If I connect to the container and start python3 and do the commands manually, it returns 'Tue Mar 15 15:25:31 2022'如果我连接到容器并启动 python3 并手动执行命令,它会返回“2022 年 3 月 15 日星期二 15:25:31”

the container has the timezone set as TZ parameter and if I run 'date' from the shell in the container, the time is indeed the intended localtime.容器将时区设置为 TZ 参数,如果我从容器中的 shell 运行“日期”,时间确实是预期的本地时间。 If I omit the TZ, it's reverts to UTC time.如果我省略 TZ,它将恢复为 UTC 时间。

I was forced to pass the TZ as a parameter to the python script and process it.我被迫将 TZ 作为参数传递给 python 脚本并进行处理。

import time
import os
os.environ['TZ'] = a
time.tzset()
print(time.strftime("%c"))

where 'a' is that passed parameter其中“a”是传递的参数

It's quite clear in my github project: https://github.com/TrueOsiris/docker-godaddypy as this only has a Dockerfile, one bash script and one python script.在我的 github 项目中很清楚: https://github.com/TrueOsiris/docker-godaddypy因为它只有一个 Dockerfile、一个 bash 脚本和一个 python 脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM