如何通过 Lambda|API 网关访问 Dockerized R 镜像?

问题描述

这个问题的第一个版本可能没有我想的那么清楚,因为有很多部分,问题出在流程的一个部分。

尽可能简单: 我有一个 dockerized R 应用程序暴露给水管工的 http 访问,我想在 aws lambda 中使用它。

Dockerfile 非常简单:

FROM rstudio/plumber:latest

workdir /opt/ml

# system libraries of general use
RUN apt-get update && apt-get install -y --no-install-recommends \
    autoconf \
    automake \
    wget \
    libcurl4-openssl-dev\
    libsodium-dev \
    ca-certificates

# r pkgs (https://rstudio.github.io/renv/articles/docker.html)
RUN R -e "install.packages('renv',repos = c(CRAN = 'https://cloud.r-project.org'))"

# renv (https://nicd.ncl.ac.uk/blog/posts/deploying-model-predictions-using-plumber-and-docker/)
copY . .
RUN R -e "renv::restore()" # uncomment to create docker image with renv

# plumber
ENTRYPOINT ["Rscript","run_plumber.R"] # uncomment to create docker image with renv
EXPOSE 8080/tcp
docker build -t image-name:0.0.1 .
docker run --name sandBox --restart=always -p 8080:8080 -v C:\Users\User\Downloads\aws_s3:/data image-name:0.0.1

当我运行这个命令时,我得到一个容器,我可以像这样使用 curl 访问它:

curl -X POST "http://127.0.0.1:8080/functionName?param1=/data/archive.json&param2=/data/archive.csv"

或者按照文档的建议,我有这个功能

# plumber.R

#* Echo back the input
#* @param msg The message to echo
#* @get /echo
function(msg="") {
  list(msg = paste0("The message is: '",msg,"'"))
}

我得到了结果(这只是为了确认工作流程有效

curl -X GET"http://127.0.0.1:8080/echo?msg=hi"

到这里一切正常;一旦图像被标记并推送到 ECR 并在其上创建一个 lambda 函数,我就可以通过 API 网关访问它

在API网关中我设置了一个资源和一个方法,资源就是curl和函数指定的“echo”函数的名字;部署后,我知道管道工库暴露在端口 8080

当我通过 API 网关调用我的函数时:我在云观察中得到这个日志:


Error: Failed to create directory at path '/home/sbx_user1051/.local/share/renv'
In addition: Warning message:
In dir.create(rownames(info),recursive = TRUE) :
cannot create dir '/home/sbx_user1051/.local',reason 'No such file or directory'
Traceback (most recent calls last):
19: source("renv/activate.R")
18: withVisible(eval(ei,envir))
17: eval(ei,envir)
16: eval(ei,envir)
15: local(...)
14: eval.parent(substitute(eval(quote(expr),envir)))
13: eval(expr,p)
12: eval(expr,p)
11: eval(quote(...),new.env())
10: eval(quote(...),new.env())
9: renv_bootstrap_load(project,libpath,version)
8: renv::load(project)
7: renv_load_renviron(project)
6: renv_paths_root(".Renviron")
5: Sys.getenv("RENV_PATHS_ROOT",unset = NA) %NA% renv_paths_root_default()
4: renv_paths_root_default()
3: ensure_directory(path)
2: stopf("Failed to create directory at path '%s'",rownames(info))
1: stop(sprintf(fmt,...),call. = call.)
Execution halted

解决方法

这里的问题是 import * as React from 'react'; import { Text,View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'; const Tabs = createMaterialTopTabNavigator(); export default function App() { return ( <NavigationContainer> <Tabs.Navigator tabBarPosition="bottom" tabBarOptions={{ indicatorStyle: { backgroundColor: 'red' } }}> <Tabs.Screen name="screen 1" component={View} /> <Tabs.Screen name="screen 2" component={View} /> </Tabs.Navigator> </NavigationContainer> ); } 不可写​​,另见 docker-lambda #103。在 renv 部分之前的 Dockerfile 中,将 /home/sbx_user1051/.local 设置为默认用户对其具有写入权限的目录以绕过错误,例如。

RENV_PATHS_ROOT

另请参阅 renv docs 以了解有关路径自定义的更多详细信息。此外,请注意,如果 ENV RENV_PATHS_ROOT="/tmp/.local/share/renv" # ENV RENV_PATHS_ROOT="${LAMBDA_TASK_ROOT}/.local/share/renv" # works similarly 中没有禁用 use.cache,您可能会在 AWS Lambda 上遇到 L2 缓存大小问题:

l2_cache_size

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...