i'm trying to run docker on heroku so i tried "git add heroku.yml" "git commit m "Add yml" "git heroku push"
but as you can see here, heroku log shows me this logs
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 [email protected]
2022-01-24T04:10:15.729676 00:00 app[api]: Release v37 created by user [email protected]
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 [email protected]
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 [email protected]
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
i don't know what is wrong with it cause this docker file is working on local but when i run it in heroku, alway shows me this log so it completely freak me out
my 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
my server file<index.js> with 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");
});
pakage.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
CodePudding user response:
You appear to have copied the sample config.yml from Heroku's documentation but not modified it for Node.js.
The run section tells Heroku how to run your application by defining process types (e.g. web) and commands to run for each one. Instead of using bundle exec puma, which might be appropriate for a Rails application, put in whatever command you use to start your production application.
Based on your package.json, something like this would be more appropriate:
run:
web: node index.js
