为了账号安全,请及时绑定邮箱和手机立即绑定

基于ubuntu的docker容器中的python argparse

基于ubuntu的docker容器中的python argparse

泛舟湖上清波郎朗 2023-05-16 15:00:27
我正在努力寻找一种方法将参数传递给docker container基于ubuntu. 我正在与docker-compose.yml.请在下面找到示例!docker-compose.ymlversion: "3"services:   bcp:      image: ubuntu:18.04      restart: always      tty: true      entrypoint: ["/bin/bash", "/ingestion/bcp-entrypoint.sh"]      volumes:          - ./services/bcp:/ingestion/services/bcp          - ./bcp-entrypoint.sh:/ingestion/bcp-entrypoint.shbcp-entrypoint.shapt-get updateapt-get upgrade -yapt-get clean -yapt-get install -y python3-pip...蟒蛇脚本required_args.add_argument("--database", metavar="str", type=str, help="database from where to extract", required=True)我调用脚本的方式 - 在容器和主机上 - 是python3 -m services.bcp --database foo并且它工作得非常完美。问题是,我怎样才能在 docker 容器上从主机实现相同的目标?基本上,我正在寻找类似的东西docker-compose exec services.bcp --database foo。我不想用dockerfile!理想情况下,一切都基于docker-compose.
查看完整描述

2 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

这是 docker 和 docker compose 如何在 docker 容器中解析参数的解决方案:


蟒蛇脚本


#!/usr/bin/env python

import argparse


parser = argparse.ArgumentParser()

parser.add_argument("name", help="Name of person to greet")


args = parser.parse_args()


print(f"Hello there, {args.name}!")

使用自定义 dockerfile(对于这种情况似乎是最直接的):


FROM python:3.8


COPY main.py .


ENTRYPOINT ["./main.py"]

然后构建并运行容器化的 cli:


# Should make the script executable to invoke directly

$ chmod +x main.py


$ docker build -t dockerized-cli .

$ docker run -it --rm dockerized-cli -h

usage: main.py [-h] name


positional arguments:

  name        Name of person to greet


optional arguments:

  -h, --help  show this help message and exit

$ docker run -it --rm dockerized-cli Jeff

Hello there, Jeff!

仅使用 docker-compose(原始问题)


version: "3"

services:

  app:

    image: python:3.8

    volumes:

      - .:/opt/app

    entrypoint: ["/opt/app/main.py"]

然后运行,


$ docker-compose run app Jeff

Hello there, Jeff!

如果您需要使用 ubuntu:18.04 图像,但仍然无法从中构建您自己的图像(在入口点之外安装 python),那么您需要做您已经拥有的事情,即首先创建一个入口点脚本安装 python 然后调用你的脚本。需要注意的是,现在您的入口点是入口点脚本本身,而不是您的 python CLI,因此您需要将任何参数从 shell 脚本传播到您的 python 脚本。下面是一个如何操作的简单示例 - 注意 bash 变量“$@”:


entrypoint.sh


#!/bin/bash


# install python here...


python print_args.py $@

print_args.py


import sys

print(sys.argv)


查看完整回答
反对 回复 2023-05-16
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

我找到的唯一解决方案如下:您可以通过 ARG 关键字将启动参数(在构建时传递参数更容易)从 docker-compose 传递到 Dockerfile。这里的问题是 ARG 有一个非常奇怪的范围,所以 ENTRYPOINT 看不到定义的 ARG,但可以看到 ENV。所以你必须将 ARG 复制到 ENV。


ingest_data.py


#!/usr/bin/env python

import argparse


if __name__ == '__main__':    

    

    parser = argparse.ArgumentParser(description='Ingest CSV data to Postgres')


    parser.add_argument('--host', required=True, help='host for postgres')

    parser.add_argument('--port', required=True, help='port for postgres')

    parser.add_argument('--db', required=True, help='database name for postgres')

    parser.add_argument('--table_name', required=True, help='name of the table where we will write the results to')


    args = parser.parse_args()

在 Dockerfile 中。注意:要将参数传递给 ENTRYPOINT,您应该以 shell 形式运行它,而不是以 exec 形式运行它!:


FROM python:3.9.1


RUN pip install pandas sqlalchemy psycopg2 pyarrow


WORKDIR /app

COPY ingest_data.py ingest_data.py


ARG host

ARG port

ARG db

ARG table_name


ENV host=${host} port=${port} db=${db} table_name=${table_name}

RUN echo "Host: ${host}, Port: ${port}, DB: $db"


ENTRYPOINT python ingest_data.py -host=$host --port=$port --db=$db --table_name=$table_name

在 docker-compose.yaml


version: "3"

services:

  app:

    build: 

      context: .

      args: 

        - host=pgdatabase

        - port=5432

        - db=ny_taxi

        - table_name=yellow_taxi_trips_n

最后运行它,


$ docker-compose up -d 


查看完整回答
反对 回复 2023-05-16
  • 2 回答
  • 0 关注
  • 123 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信