【发布时间】: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
我的服务器文件
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