【问题标题】:heroku docker bundle not found error // i'm trying to deploy dockerfile to heroku but it always says me bundle not foundheroku docker bundle not found 错误 // 我正在尝试将 dockerfile 部署到 heroku 但它总是说我找不到 bundle
【发布时间】:2022-01-27 23:11:39
【问题描述】:

我正在尝试在 heroku 上运行 docker 所以我尝试了 “git 添加heroku.yml” "git commit m "添加 yml" “git heroku 推”

但正如您在此处看到的,heroku 日志向我显示了这些日志

2022-01-24T04:10:12.979291+00:00 heroku[web.1]: Restarting
2022-01-24T04:10:15.729676+00:00 app[api]: Remove PATH config vars by user hanjk13262@gmail.com
2022-01-24T04:10:15.729676+00:00 app[api]: Release v37 created by user hanjk13262@gmail.com
2022-01-24T04:10:15.965096+00:00 heroku[web.1]: Restarting
2022-01-24T04:10:21.029250+00:00 heroku[web.1]: Starting process with command `/bin/sh -c bundle\ exec\ puma\ -C\ config/puma.rb`
2022-01-24T04:10:22.051845+00:00 app[web.1]: /bin/sh: 1: bundle: not found
2022-01-24T04:10:22.172593+00:00 heroku[web.1]: Process exited with status 127
2022-01-24T04:10:39.006056+00:00 heroku[web.1]: Starting process with command `/bin/sh -c bundle\ exec\ puma\ -C\ config/puma.rb`
2022-01-24T04:10:40.617158+00:00 app[web.1]: /bin/sh: 1: bundle: not found
2022-01-24T04:10:40.794603+00:00 heroku[web.1]: Process exited with status 127
2022-01-24T04:10:40.946303+00:00 heroku[web.1]: State changed from starting to crashed
2022-01-24T04:10:41.842541+00:00 heroku[web.1]: Starting process with command `/bin/sh -c bundle\ exec\ puma\ -C\ config/puma.rb`
2022-01-24T04:10:43.098998+00:00 app[web.1]: /bin/sh: 1: bundle: not found
2022-01-24T04:10:43.326072+00:00 heroku[web.1]: Process exited with status 127
2022-01-24T04:11:41.000000+00:00 app[api]: Build started by user hanjk13262@gmail.com
2022-01-24T04:14:11.000000+00:00 app[api]: Build succeeded
2022-01-24T04:14:11.299638+00:00 app[api]: Release v38 created by user hanjk13262@gmail.com
2022-01-24T04:14:12.170626+00:00 heroku[web.1]: State changed from crashed to starting
2022-01-24T04:14:31.949298+00:00 heroku[web.1]: Starting process with command `/bin/sh -c /bin/sh\ -c\ bundle\\\ exec\\\ puma\\\ -C\\\ config/puma.rb`
2022-01-24T04:14:32.978306+00:00 app[web.1]: /bin/sh: 1: bundle: not found
2022-01-24T04:14:33.120489+00:00 heroku[web.1]: Process exited with status 127
2022-01-24T04:14:33.222836+00:00 heroku[web.1]: State changed from starting to crashed

我不知道它有什么问题,因为这个 docker 文件正在本地工作 但是当我在heroku中运行它时,总是给我看这个日志 所以它完全把我吓坏了

我的 Dockerfile

FROM node:14.17.5
RUN apt-get update && \
apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \
xvfb x11vnc x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic x11-apps
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
EXPOSE 3001
CMD xvfb-run --server-args="-screen 0 1024x768x24" npm start



# FROM node:14.17.5
# RUN apt-get update && \
# apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
# libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
# libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
# libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
# ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \
# xvfb x11vnc x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic x11-apps
# WORKDIR /app
# COPY package.json /app
# RUN npm install
# COPY . /app
# EXPOSE 8081
# CMD xvfb-run --server-args="-screen 0 1024x768x24" npm start

我的服务器文件 和 express.js

import express from "express";
import puppeteer from "puppeteer";
import cors from "cors";
import dotenv from "dotenv";

dotenv.config();

const app = express();

const whitelist = [
  "http://localhost:3000",
  "my netlify address",
];

const corsOptions = {
  origin: (origin, callback) => {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error("Not Allowed Origin!"));
    }
  },
  methods: ["GET", "POST", "PUT", "DELETE"],
  credentials: true,
};

app.use(cors());
app.use(express.json());
// 아 맞아 전체 url갖고있으면 굳이 서버 없어도 되잖아
// 그리고 자기 아이디 작성하게 하기

const setIdPw = async (page) => {
  // FIXME: 아이디 비밀번호 입력
  await page.waitForSelector("input[name=userid]");
  await page.waitForSelector("input[name=password]");

  await page.$eval("input[name=userid]", (el) => (el.value = "userid"));
  await page.$eval("input[name=password]", (el) => (el.value = "userpassword"));

  await page.click('input[type="submit"]');
};

const getText = async (page) => {
  // FIXME: 텍스트  크롤링

  await page.waitForSelector(".article p.large");
  const text = await page.evaluate(() => {
    const anchor = document.querySelector(".article p.large");
    return anchor.innerHTML;
  });
  return text;
};

const getImg = async (page) => {
  try {
    await page.waitForSelector(".article .attach img", { timeout: 2000 });

    try {
      const img = await page.evaluate(() => {
        const imgsrc = document
          .querySelector(".article .attach img")
          .getAttribute("src");

        return imgsrc;
      });

      return img;
    } catch (error) {}
  } catch (error) {
    return "꽝";
  }
};

const getProfile = async (page) => {
  await page.waitForSelector(".picture.large");
  await page.waitForSelector(".profile .large");

  const profile = await page.evaluate(() => {
    const Pimg = document.querySelector(".picture.large").getAttribute("src");
    const username = document.querySelectorAll(".profile .large")[0].innerText;
    const date = document.querySelectorAll(".profile .large")[1].innerText;
    const url = window.location.href;

    return { Pimg, username, date, url };
  });
  return profile;
};

// FIXME: 검색
app.post("/gotoEta", (req, res) => {
  const { url } = req.body;
  (async () => {
    const options = {
      args: [
        "--fast-start",
        "--disable-web-security",
        "--disable-features=IsolateOrigins",
        "--disable-site-isolation-trials",
        "--disable-extensions",
        "--disable-setuid-sandbox",
        "--no-sandbox",
      ],
      ignoreHTTPSErrors: true,
      headless: false,
      ignoreDefaultArgs: ["--disable-extensions"],
    };
    try {
      // FIXME: 초기설정
      const browser = await puppeteer.launch(options);

      const page = await browser.newPage();
      await page.setViewport({ width: 640, height: 768 });

      const everytimeUrl = url;
      await page.goto(everytimeUrl, [
        "load",
        "domcontentloaded",
        "networkidle0",
      ]);

      setIdPw(page);
      // FIXME: 텍스트 / 사진 크롤링
      const text = await getText(page);
      const img = await getImg(page);
      const profile = await getProfile(page);
      console.log(profile);

      res.json({ text, img, profile });
      // FIXME: 브라우져 닫기
      await browser.close();
    } catch (error) {
      console.log("Error " + error.toString());
      res.send("오류발생1");
    }
  })();
});

const gotoNextPage = async (page) => {
  try {
    await page.waitForSelector("a.next");
    await page.click("a.next");
    return true;
  } catch (err) {
    return false;
  }
};

const get20Urls = async (page) => {
  await page.waitForSelector("#container .wrap.articles article a");

  const urlList = await page.evaluate(() => {
    const hrefs = document.querySelectorAll(
      "#container .wrap.articles article a"
    );

    let list = [];
    hrefs.forEach((val) => {
      const href = val.getAttribute("href");
      const url = `https://everytime.kr${href}`;
      list.push(url);
    });

    return list;
  });
  // console.log(urlList);

  return urlList;
};

app.get("/getEveryUrls", (req, res) => {
  (async () => {
    try {
      const browser = await puppeteer.launch({
        headless: false,
      });

      const page = await browser.newPage();
      await page.setViewport({ width: 640, height: 500 });
      const everytimeUrl = `https://everytime.kr/409275/p/1`;

      await page.goto(everytimeUrl, [
        "load",
        "domcontentloaded",
        "networkidle0",
      ]);
      setIdPw(page);

      let totalUrls = [];

      let stopWhile = true;
      let i = 0;
      while (true) {
        try {
          const urls = await get20Urls(page);
          totalUrls.push(...urls);
          stopWhile = await gotoNextPage(page);
          i += 1;
          console.log(i);
        } catch (error) {
          break;
        }
      }
      res.json(totalUrls);
      console.log(totalUrls);
    } catch (err) {
      console.log("Error " + error.toString());
      console.log("오류발생");
      res.send("오류발생");
    }
  })();
});

app.get("/hi", (req, res) => {
  console.log("hi there");
  res.send("안녕 반가워");
});

// FIXME: 헤드레스로 만들기

const setIdPwV2 = async (page) => {
  // FIXME: 아이디 비밀번호 입력
  page.waitForNavigation({ waitUntil: "load" });

  // await page.focus("input[name=userid]");
  // await page.keyboard.type("hanjk123");

  await page.$eval("input[name=userid]", (el) => (el.value = "hanjk123"));
  await page.$eval("input[name=password]", (el) => (el.value = "agdsffaith00"));

  page.click('input[type="submit"]');
};

const getTextV2 = async (page) => {
  // FIXME: 텍스트  크롤링
  await page.waitForSelector(".article p.large");

  const text = await page.evaluate(() => {
    const anchor = document.querySelector(".article p.large");
    return anchor.innerHTML;
  });
  return text;
};

app.get("/gotoEtaV2", (req, res) => {
  const url = "https://everytime.kr/409275/v/227352083";
  (async () => {
    const options = {
      args: [
        "--fast-start",
        "--disable-web-security",
        "--disable-features=IsolateOrigins",
        "--disable-site-isolation-trials",
        "--disable-extensions",
        "--disable-setuid-sandbox",
        "--no-sandbox",
      ],
      ignoreHTTPSErrors: true,
      headless: false,
      ignoreDefaultArgs: ["--disable-extensions"],
    };
    try {
      // FIXME: 초기설정
      const browser = await puppeteer.launch(options);

      const page = await browser.newPage();

      const everytimeUrl = url;
      await page.goto(everytimeUrl, [
        "load",
        "domcontentloaded",
        "networkidle0",
      ]);

      setIdPwV2(page);
      // FIXME: 텍스트 / 사진 크롤링
      const text = await getTextV2(page);
      console.log(text);
      // const img = await getImg(page);
      // const profile = await getProfile(page);
      // console.log(profile);

      res.json({ text });
      // FIXME: 브라우져 닫기
      await browser.close();
    } catch (error) {
      console.log("Error " + error.toString());
      res.send("오류발생1");
    }
  })();
});
app.listen(process.env.PORT || 3001, () => {
  console.log("SERVER RUNNING ON PORT 3001");
});

包装.json

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^14.2.0",
    "express": "^4.17.2",
    "nodemon": "^2.0.15",
    "puppeteer": "^13.0.1"
  },
  "type": "module"
}

heroku.yml

build:
  docker:
    web: Dockerfile
run:
  web: bundle exec puma -C config/puma.rb
  # web: /bin/sh -c bundle\ exec\ puma\ -C\ config/puma.rb

【问题讨论】:

    标签: javascript node.js docker express heroku


    【解决方案1】:

    您似乎复制了 the sample config.yml from Heroku's documentation,但没有针对 Node.js 进行修改。

    The run section tells Heroku how to run your application 通过定义进程类型(例如web)和为每个进程运行的命令。不要使用可能适用于 Rails 应用程序的bundle exec puma,而是输入您用来启动生产应用程序的任何命令。

    根据您的package.json,这样的事情会更合适:

    run:
      web: node index.js
    

    【讨论】:

      【解决方案2】:

      我已经用这种部署方式解决了这个问题

      heroku login
      heroku container:login
      docker build -t registry.heroku.com/yourHerokuAppName/web .
      docker push registry.heroku.com/ollunch2/web
      heroku container:release web -a ollunch2
      

      只需将这些命令放在你的 vscode 终端上

      https://www.youtube.com/watch?v=6l55lOyerZk

      【讨论】:

        猜你喜欢
        • 2017-09-13
        • 2018-11-20
        • 1970-01-01
        • 1970-01-01
        • 2017-11-19
        • 1970-01-01
        • 2021-11-30
        • 2020-03-07
        • 2020-03-03
        相关资源
        最近更新 更多