简体   繁体   English

Docker 容器在 Visual Studio 中运行,但在命令行中不执行任何操作

[英]Azure Function in Docker Container runs in Visual Studio, but does nothing from command line

My goal is to have a timer azure function (leveraging Selenium Chromedriver) run inside a docker container.我的目标是让计时器 azure function(利用 Selenium Chromedriver)在 Z040AF6ZFC3 容器内运行。 it works in Visual Studio when i click this VS Docker Button ;当我单击此VS Docker 按钮时,它在 Visual Studio 中工作; however, when i execute the same docker command from VS in the command line, nothing happens.但是,当我在命令行中从 VS 执行相同的 docker 命令时,什么也没有发生。 here's the command VS executes这是VS执行的命令

docker run -dt -v "C:\Users\rlin\vsdbg\vs2017u5:/remote_debugger:rw" -e "ASPNETCORE_ENVIRONMENT=Development" -p 34480:80 --name Retriever --entrypoint tail retriever -f /dev/null

here's my dockerfile for your reference这是我的 dockerfile 供您参考

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/azure-functions/dotnet:3.0 AS base
WORKDIR /home/site/wwwroot
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /home/site/wwwroot
COPY . Retriever/
WORKDIR /home/site/wwwroot/Retriever
RUN dotnet build -c Release -o /home/site/wwwroot

FROM build AS publish
RUN dotnet publish -c Release -o /home/site/wwwroot

FROM base AS final
WORKDIR /home/site/wwwroot
COPY --from=publish /home/site/wwwroot .
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true \
    AzureWebJobsStorage="StorageConnectionString"
    URL="url" \
    USERNAME="username" \
    PASSWORD="password" \
    SFTP="sftp" \
    CONTAINER="container"

WORKDIR /home/site/wwwroot
RUN apt-get update && \
    apt-get install -y gnupg wget curl unzip --no-install-recommends && \
    wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
    echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list && \
    apt-get update -y && \
    apt-get install -y google-chrome-stable && \
    CHROMEVER=$(google-chrome --product-version | grep -o "[^\.]*\.[^\.]*\.[^\.]*") && \
    DRIVERVER=$(curl -s "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROMEVER") && \
    wget -q --continue -P /chromedriver "http://chromedriver.storage.googleapis.com/$DRIVERVER/chromedriver_linux64.zip" && \
    unzip /chromedriver/chromedriver* -d /chromedriver

WORKDIR /
CMD ["/home/site/wwwroot/bin/Retriever.dll"]

been stuck on this for days, so any help is much appreciated.几天来一直坚持这一点,所以非常感谢任何帮助。

EDIT: here's the code for ref编辑:这是 ref 的代码

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using OpenQA.Selenium.Chrome;
using Microsoft.Extensions.Configuration;
using OpenQA.Selenium;
using System.Collections.Generic;
using Azure.Storage.Blobs;
using System.IO.Compression;

namespace Retriever
{
    public class Retriever
    {
        private IConfigurationRoot config;

        [FunctionName("Retriever")]
        public void Run(
            [TimerTrigger("0 */1 * * * *", RunOnStartup = true)] TimerInfo myTimer,
            //[HttpTrigger(AuthorizationLevel.System, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            config = new ConfigurationBuilder()
                .SetBasePath(Environment.CurrentDirectory)
                .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

            Retrieve(log);
            log.LogInformation("Uploaded attachments");
            //return new OkResult();
        }
        public void Retrieve(ILogger log)
        {
            log.LogInformation("Retrieving attachments");

            ChromeOptions options = new ChromeOptions();
            options.AddArgument("--headless");
            options.AddArgument("--no-sandbox"); // Bypass OS security model
            options.AddArgument("start-maximized"); // open Browser in maximized mode
            options.AddArgument("disable-infobars"); // disabling infobars
            options.AddArgument("--disable-extensions"); // disabling extensions
            options.AddArgument("--disable-gpu"); // applicable to windows os only
            options.AddArgument("--disable-dev-shm-usage"); // overcome limited resource problems
            options.AddArgument("--whitelisted-ips");
            options.AddArgument("--proxy-server=direct://");
            options.AddArgument("--proxy-bypass-list=*");
            options.BinaryLocation = "/opt/google/chrome/google-chrome"; //Google Chrome path
            options.AddUserProfilePreference("download.prompt_for_download", false); // DO NOT prompt for download
            options.AddUserProfilePreference("download.default_directory", Path.GetTempPath()); // saves to Temp directory

            ChromeDriverService service = ChromeDriverService.CreateDefaultService("/chromedriver/", "chromedriver"); // use "/usr/bin/" and "chromedriver" in deployment

            ChromeDriver driver = new ChromeDriver(service, options, TimeSpan.FromMinutes(3));
            driver.Manage().Timeouts().ImplicitWait = new TimeSpan(5, 0, 0);

            // Login and Download Steps //
            driver.Navigate().GoToUrl(config.GetValue<string>("URL"));

            IWebElement username = driver.FindElement(By.XPath("//*[@id=\"username\"]"));
            username.SendKeys(config.GetValue<string>("USERNAME"));

            IWebElement next = driver.FindElement(By.CssSelector("body > mc-login > div > div.container > div > div > div.panel.panel-default.panel-shadow.login-panel > div > div > div > form > button"));
            next.Click();

            IWebElement password = driver.FindElement(By.CssSelector("#password"));
            password.SendKeys(config.GetValue<string>("PASSWORD"));

            IWebElement login = driver.FindElement(By.CssSelector("body > mc-login > div > div.container > div > div > div.panel.panel-default.panel-shadow.login-panel > div > div > div > form > button"));
            login.Click();

            IWebElement inbox = driver.FindElement(By.LinkText("Inbox"));
            inbox.Click();
            
            ICollection<IWebElement> emails = driver.FindElements(By.CssSelector("tr"));
            System.Threading.Thread.Sleep(new TimeSpan(0, 0, 2));
            foreach(IWebElement email in emails)
            {
                if (email.Displayed)
                {
                    email.Click();

                    IWebElement view = driver.FindElement(By.LinkText("View"));
                    view.Click();

                    string filename = driver.FindElement(By.CssSelector("body > div.page-container.with-sidebar.full-height.snap-content > div.main-content.full-height > div.ng-isolate-scope > div > div > div.container-fluid.full-height.fill-container.mainarea.ng-scope.mc-tab-unique-main > mc-list-detail > div > div.col-xs-12.col-sm-7.col-md-8.col-lg-8.hidden-xs.full-height.animate-active.no-padding > div > div.dynamic-full-height.horizontal-scroll.vertical-scroll.panel-half-margin-top-negative.ng-scope > div.pull-left.full-width.ng-scope > detail > div:nth-child(4) > div > mc-thumbnail > div > div:nth-child(2) > ul > li > span > span:nth-child(2)")).GetAttribute("innerHTML");
                    string filepath = Path.Combine(Path.GetTempPath(), filename);

                    IWebElement download = driver.FindElement(By.LinkText("Download"));
                    download.Click();
                    System.Threading.Thread.Sleep(new TimeSpan(0, 0, 2));
                    UploadToBlobStorage(log, filepath, filename);
                }
            }
            driver.Close();
            driver.Quit();
            driver.Dispose();
            service.Dispose();
        }
        public void UploadToBlobStorage(ILogger log, string filepath, string filename)
        {
            BlobServiceClient serviceClient = new BlobServiceClient(config.GetValue<string>("SFTP"));
            BlobContainerClient containerClient = serviceClient.GetBlobContainerClient(config.GetValue<string>("CONTAINER"));
            BlobClient client = containerClient.GetBlobClient("uploads/" + filename + ".txt");

            ZipArchive z = ZipFile.Open(filepath, ZipArchiveMode.Update);
            foreach(ZipArchiveEntry e in z.Entries)
            {
                client.Upload(e.Open(), overwrite: true);
            }
            z.Dispose();
            if(File.Exists(filepath)) { File.Delete(filepath); }
        }
    }
}

The command you posted is only used for Visual Studios debugging functionality.您发布的命令仅用于 Visual Studios 调试功能。 It overwites the entrypoint with tail -f /dev/null which is basically "loop forever".它用tail -f /dev/null覆盖入口点,这基本上是“永远循环”。

You will need to run docker build <path to dir where Dockerfile is located> -t retriever to build the image and then docker run -p 80:80 retriever to run it.您将需要运行docker build <path to dir where Dockerfile is located> -t retriever来构建图像,然后docker run -p 80:80 retriever This should make the app available on port 80 of your system.这应该使应用程序在系统的端口 80 上可用。 If you want the app on another port, you can use -p <another port>:80如果您希望应用程序在另一个端口上,您可以使用-p <another port>:80

The last line ( CMD ["/home/site/wwwroot/bin/Retriever.dll"] ) in your Dockerfile overwrites the preset CMD of azure-functions/dotnet ( /azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost ) and will lead to the error "exec: \"dotnet\": executable file not found in $PATH" . The last line ( CMD ["/home/site/wwwroot/bin/Retriever.dll"] ) in your Dockerfile overwrites the preset CMD of azure-functions/dotnet ( /azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost ) 并且会导致错误"exec: \"dotnet\": executable file not found in $PATH" Your function is supposed to be run by WebHost , not by invoking the dll directly.您的 function 应该由WebHost运行,而不是通过直接调用 dll 来运行。 Remove this line .删除此行 The one above it is also unnecessary.上面的那一个也是不必要的。

Your Dockerfile also has another issue (it will possibly still work without adressing them): You are copying your sources, building and publishing all to the same directory /home/site/wwwroot .您的Dockerfile还存在另一个问题(它可能仍然可以在不解决它们的情况下工作):您正在复制源代码,构建并发布所有内容到同一目录/home/site/wwwroot I would suggest changing it like this for the build stage:我建议在构建阶段像这样更改它:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY . .
RUN dotnet build -c Release -o /app/build

For the publish stage:对于发布阶段:

FROM build AS publish
RUN dotnet publish -c Release -o /app/publish

And for final:最后:

FROM base AS final
WORKDIR /home/site/wwwroot
COPY --from=publish /app/publish .
[...]

暂无
暂无

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

相关问题 将命令行参数传递给Visual Studio容器工具中.NET Core控制台应用程序的Docker调试运行 - Pass command line args to a Docker debugging run of a .NET Core console application in Visual Studio Container Tools 如何从Visual Studio或通过命令行部署到Azure信号器服务 - How to deploy to azure signalr service from visual studio or via command line 从Visual Studio将Azure函数发布到Azure不会生成绑定 - Publishing a azure function from Visual Studio to Azure does not generate out bindings 将Azure功能从门户导入Visual Studio - Import Azure Function from portal into Visual Studio 从Visual Studio 2015在Azure上发布到Docker时出错 - Error while publising to docker on Azure from Visual Studio 2015 如何从命令行运行 Visual Studio 生成的 ASP.NET Core 示例 Web 应用 Docker 映像? - How to run Visual Studio generated ASP.NET Core Sample Web App Docker image from command line? SSIS 脚本任务 (c#) 在 Visual Studio 中运行良好。 但是当我在 SSMS 中运行它时,它运行成功但什么也没做 - SSIS script task (c#) works in Visual Studio well. But when I run it in SSMS it runs succesfully but does nothing 根据输入从 Azure 函数启动和停止 Docker 容器 - Start and stop Docker container from Azure function based on input Azure Function running from Docker 容器里面有不同的文件 - Azure Function running from Docker Container has different files inside 使用Visual Studio可以很好地构建项目,但是从命令行失败 - Project builds fine with Visual Studio but fails from the command line
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM