เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เด’เดฐเต เดซเต€เดšเตเดšเตผ เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เด•เดŸเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เดฎเตเดฎเตเดชเต, เดธเด™เตเด•เต€เตผเดฃเตเดฃเดฎเดพเดฏ เด“เตผเด•เตเด•เดธเตโ€ŒเดŸเตเดฐเต‡เดฑเตเดฑเตผเดฎเดพเดฐเตเดŸเต†เดฏเตเด‚ CI/CD เดฏเตเดŸเต†เดฏเตเด‚ เด‡เด•เตเด•เดพเดฒเดคเตเดคเต, เดชเตเดฐเดคเดฟเดฌเดฆเตเดงเดคเดฏเดฟเตฝ เดจเดฟเดจเตเดจเต เดŸเต†เดธเตเดฑเตเดฑเตเด•เดณเดฟเดฒเต‡เด•เตเด•เตเด‚ เดกเต†เดฒเดฟเดตเดฑเดฟเดฏเดฟเดฒเต‡เด•เตเด•เตเด‚ เด’เดฐเตเดชเดพเดŸเต เดฆเต‚เดฐเด‚ เดชเต‹เด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต. เดฎเตเดฎเตเดชเต, เดจเดฟเด™เตเด™เตพเด•เตเด•เต FTP เดตเดดเดฟ เดชเตเดคเดฟเดฏ เดซเดฏเดฒเตเด•เตพ เด…เดชเตโ€Œเดฒเต‹เดกเต เดšเต†เดฏเตเดฏเดพเดฎเดพเดฏเดฟเดฐเตเดจเตเดจเต (เด‡เดจเดฟ เด†เดฐเตเด‚ เด…เดคเต เดšเต†เดฏเตเดฏเดฟเดฒเตเดฒ, เดถเดฐเดฟเดฏเดฒเตเดฒเต‡?), เด•เต‚เดŸเดพเดคเต† "เดตเดฟเดจเตเดฏเดพเดธเด‚" เดชเตเดฐเด•เตเดฐเดฟเดฏเดฏเตเด•เตเด•เต เดจเดฟเดฎเดฟเดทเด™เตเด™เตพ เดŽเดŸเตเดคเตเดคเต. เด‡เดชเตเดชเต‹เตพ เดจเดฟเด™เตเด™เตพ เด’เดฐเต เดฒเดฏเดจ เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดธเตƒเดทเตโ€ŒเดŸเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดซเต€เดšเตเดšเตผ เด‰เดชเดฏเต‹เด•เตเดคเดพเด•เตเด•เดณเดฟเตฝ เดŽเดคเตเดคเตเดจเตเดจเดคเดฟเดจเดพเดฏเดฟ เดฆเต€เตผเด˜เดจเต‡เดฐเด‚ เด•เดพเดคเตเดคเดฟเดฐเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดตเต‡เดฃเด‚.

เดˆ เดชเดพเดคเดฏเตเดŸเต† เดญเดพเด—เดฎเดพเดฃเต เด’เดฐเต เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเต เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเดคเต. เดšเดฟเดฒเดชเตเดชเต‹เตพ เด…เดธเด‚เดฌเตเดฒเดฟ เดฎเดฟเดจเดฟเดฑเตเดฑเตเด•เตพ เดจเต€เดฃเตเดŸเตเดจเดฟเตฝเด•เตเด•เตเด‚, เดšเดฟเดฒเดชเตเดชเต‹เตพ เดชเดคเดฟเดจเดพเดฏเดฟเดฐเด•เตเด•เดฃเด•เตเด•เดฟเดจเต เดฎเดฟเดจเดฟเดฑเตเดฑเต เดจเต€เดฃเตเดŸเตเดจเดฟเตฝเด•เตเด•เตเด‚, เด…เดคเดฟเดจเต† เดธเดพเดงเดพเดฐเดฃเดฎเต†เดจเตเดจเต เดตเดฟเดณเดฟเด•เตเด•เดพเดจเดพเดตเดฟเดฒเตเดฒ. เดˆ เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ, เดžเด™เตเด™เตพ เด’เดฐเต เด‡เดฎเต‡เดœเดฟเดฒเต‡เด•เตเด•เต เดชเดพเด•เตเด•เต‡เดœเต เดšเต†เดฏเตเดฏเตเดจเตเดจ เด’เดฐเต เดฒเดณเดฟเดคเดฎเดพเดฏ เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดŽเดŸเตเด•เตเด•เตเด‚, เดฌเดฟเตฝเดกเต เดตเต‡เด—เดคเตเดคเดฟเดฒเดพเด•เตเด•เดพเตป เดจเดฟเดฐเดตเดงเดฟ เดฐเต€เดคเดฟเด•เตพ เดชเตเดฐเดฏเต‹เด—เดฟเด•เตเด•เตเด•, เดˆ เดฐเต€เดคเดฟเด•เตพ เดŽเด™เตเด™เดจเต† เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต เดŽเดจเตเดจเดคเดฟเดจเตเดฑเต† เดธเต‚เด•เตเดทเตเดฎเดคเด•เตพ เดจเต‹เด•เตเด•เตเด•.

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เดฎเต€เดกเดฟเดฏ เดตเต†เดฌเตเดธเตˆเดฑเตเดฑเตเด•เตพ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดฒเตเด‚ เดชเดฟเดจเตเดคเตเดฃเดฏเตเด•เตเด•เตเดจเตเดจเดคเดฟเดฒเตเด‚ เดžเด™เตเด™เตพเด•เตเด•เต เดจเดฒเตเดฒ เด…เดจเตเดญเดตเดฎเตเดฃเตเดŸเต: เดŸเดพเดธเต, เดฆเดฟ เดฌเต†เตฝ, "เดชเตเดคเดฟเดฏ เดชเดคเตเดฐเด‚", เดœเดจเดพเดงเดฟเดชเดคเดญเดฐเดฃเด‚... เด…เดงเดฟเด•เด‚ เดคเดพเดฎเดธเดฟเดฏเดพเดคเต† เดžเด™เตเด™เตพ เด’เดฐเต เด‰เตฝเดชเตเดชเดจเตเดจ เดตเต†เดฌเตเดธเตˆเดฑเตเดฑเต เดชเตเดฑเดคเตเดคเดฟเดฑเด•เตเด•เดฟ เดžเด™เตเด™เดณเตเดŸเต† เดชเต‹เตผเดŸเตเดŸเตเดซเต‹เดณเดฟเดฏเต‹ เดตเดฟเดชเตเดฒเต€เด•เดฐเดฟเดšเตเดšเต เด“เตผเดฎเตเดฎเดชเตเดชเต†เดŸเตเดคเตเดคเตฝ. เดชเตเดคเดฟเดฏ เดซเต€เดšเตเดšเดฑเตเด•เตพ เดชเต†เดŸเตเดŸเต†เดจเตเดจเต เด•เต‚เดŸเตเดŸเดฟเดšเตเดšเต‡เตผเด•เตเด•เตเด•เดฏเตเด‚ เดชเดดเดฏ เดฌเด—เตเด•เตพ เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดฎเตเดชเต‹เตพ, เดฎเดจเตเดฆเด—เดคเดฟเดฏเดฟเดฒเตเดณเตเดณ เดตเดฟเดจเตเดฏเดพเดธเด‚ เด’เดฐเต เดตเดฒเดฟเดฏ เดชเตเดฐเดถเตเดจเดฎเดพเดฏเดฟ เดฎเดพเดฑเดฟ.

เดžเด™เตเด™เตพ GitLab-เดฒเต‡เด•เตเด•เต เดตเดฟเดจเตเดฏเดธเดฟเด•เตเด•เตเดจเตเดจเต. เดžเด™เตเด™เตพ เดšเดฟเดคเตเดฐเด™เตเด™เตพ เดถเต‡เด–เดฐเดฟเด•เตเด•เตเด•เดฏเตเด‚ เด…เดตเดฏเต† GitLab เดฐเดœเดฟเดธเตเดŸเตเดฐเดฟเดฏเดฟเดฒเต‡เด•เตเด•เต เดคเดณเตเดณเตเด•เดฏเตเด‚ เด…เดต เดชเตเดฐเตŠเดกเด•เตเดทเดจเดฟเดฒเต‡เด•เตเด•เต เดฎเดพเดฑเตเดฑเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต. เดˆ เดฒเดฟเดธเตเดฑเตเดฑเดฟเดฒเต† เดเดฑเตเดฑเดตเตเด‚ เดฆเตˆเตผเด˜เตเดฏเดฎเต‡เดฑเดฟเดฏ เด•เดพเดฐเตเดฏเด‚ เดšเดฟเดคเตเดฐเด™เตเด™เตพ เด•เต‚เดŸเตเดŸเดฟเดšเตเดšเต‡เตผเด•เตเด•เตเด• เดŽเดจเตเดจเดคเดพเดฃเต. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต: เด’เดชเตเดฑเตเดฑเดฟเดฎเตˆเดธเต‡เดทเตป เด‡เดฒเตเดฒเดพเดคเต†, เด“เดฐเต‹ เดฌเดพเด•เตเด•เต†เตปเดกเต เดฌเดฟเตฝเดกเตเด‚ 14 เดฎเดฟเดจเดฟเดฑเตเดฑเต เดŽเดŸเตเดคเตเดคเต.

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เด…เดตเดธเดพเดจเด‚, เดจเดฎเตเด•เตเด•เต เด‡เดจเดฟ เด‡เด™เตเด™เดจเต† เดœเต€เดตเดฟเด•เตเด•เดพเตป เด•เดดเดฟเดฏเดฟเดฒเตเดฒเต†เดจเตเดจเต เดตเตเดฏเด•เตเดคเดฎเดพเดฏเดฟ, เดŽเดจเตเดคเตเด•เตŠเดฃเตเดŸเดพเดฃเต เดšเดฟเดคเตเดฐเด™เตเด™เตพ เดถเต‡เด–เดฐเดฟเด•เตเด•เดพเตป เด‡เดคเตเดฐเดฏเดงเดฟเด•เด‚ เดธเดฎเดฏเด‚ เดŽเดŸเตเด•เตเด•เตเดจเตเดจเดคเต†เดจเตเดจเต เดฎเดจเดธเดฟเดฒเดพเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เด‡เดฐเตเดจเตเดจเต. เดคเตฝเดซเดฒเดฎเดพเดฏเดฟ, เด…เดธเด‚เดฌเตเดฒเดฟ เดธเดฎเดฏเด‚ 30 เดธเต†เด•เตเด•เตปเดกเดพเดฏเดฟ เด•เตเดฑเดฏเตเด•เตเด•เดพเตป เดžเด™เตเด™เตพเด•เตเด•เต เด•เดดเดฟเดžเตเดžเต!

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เดˆ เดฒเต‡เด–เดจเดคเตเดคเดฟเดจเดพเดฏเดฟ, เดฑเดฟเดฎเตˆเตปเดกเดฑเดฟเดจเตเดฑเต† เดชเดฐเดฟเดคเดธเตเดฅเดฟเดคเดฟเดฏเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเด•เตเด•เดชเตเดชเต†เดŸเดพเดคเดฟเดฐเดฟเด•เตเด•เดพเตป, เด’เดฐเต เดถเต‚เดจเตเดฏเดฎเดพเดฏ เด•เต‹เดฃเต€เดฏ เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เด•เต‚เดŸเตเดŸเดฟเดšเตเดšเต‡เตผเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด’เดฐเต เด‰เดฆเดพเดนเดฐเดฃเด‚ เดจเต‹เด•เตเด•เดพเด‚. เด…เดคเดฟเดจเดพเตฝ, เดจเดฎเตเด•เตเด•เต เดžเด™เตเด™เดณเตเดŸเต† เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดธเตƒเดทเตเดŸเดฟเด•เตเด•เดพเด‚:

ng n app

เด‡เดคเดฟเดฒเต‡เด•เตเด•เต PWA เดšเต‡เตผเด•เตเด•เตเด• (เดžเด™เตเด™เตพ เดชเตเดฐเต‹เด—เดฎเดจเดชเดฐเดฎเดพเดฃเต):

ng add @angular/pwa --project app

เด’เดฐเต เดฆเดถเดฒเด•เตเดทเด‚ npm เดชเดพเด•เตเด•เต‡เดœเตเด•เตพ เดกเต—เตบเดฒเต‹เดกเต เดšเต†เดฏเตเดฏเดชเตเดชเต†เดŸเตเดฎเตเดชเต‹เตพ, เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเต เดŽเด™เตเด™เดจเต† เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเตเดตเต†เดจเตเดจเต เดจเดฎเตเด•เตเด•เต เดจเต‹เด•เตเด•เดพเด‚. เด’เดฐเต เด•เดฃเตเดŸเต†เดฏเตโ€Œเดจเตผ เดŽเดจเตเดจ เด’เดฑเตเดฑเดชเตเดชเต†เดŸเตเดŸ เดชเดฐเดฟเดคเดธเตเดฅเดฟเดคเดฟเดฏเดฟเตฝ เด…เดชเตเดฒเดฟเด•เตเด•เต‡เดทเดจเตเด•เตพ เดชเดพเด•เตเด•เต‡เดœเตเดšเต†เดฏเตเดฏเดพเดจเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เดพเดจเตเดฎเตเดณเตเดณ เด•เดดเดฟเดตเต เดกเต‹เด•เตเด•เตผ เดจเตฝเด•เตเดจเตเดจเต. เด’เดฑเตเดฑเดชเตเดชเต†เดŸเดฒเดฟเดจเต เดจเดจเตเดฆเดฟ, เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด’เดฐเต เดธเต†เตผเดตเดฑเดฟเตฝ เด’เดฐเต‡เดธเดฎเดฏเด‚ เดจเดฟเดฐเดตเดงเดฟ เด•เดฃเตเดŸเต†เดฏเตโ€Œเดจเดฑเตเด•เตพ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเด‚. เด•เดฃเตเดŸเต†เดฏเตโ€Œเดจเดฑเตเด•เตพ เดตเต†เตผเดšเตเดตเตฝ เดฎเต†เดทเต€เดจเตเด•เดณเต‡เด•เตเด•เดพเตพ เดตเดณเดฐเต† เดญเดพเดฐเด‚ เด•เตเดฑเดžเตเดžเดคเดพเดฃเต, เด•เดพเดฐเดฃเด‚ เด…เดต เดธเดฟเดธเตเดฑเตเดฑเด‚ เด•เต‡เตผเดฃเดฒเดฟเตฝ เดจเต‡เดฐเดฟเดŸเตเดŸเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต. เดžเด™เตเด™เดณเตเดŸเต† เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด’เดฐเต เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต, เดžเด™เตเด™เตพ เด†เดฆเตเดฏเด‚ เด’เดฐเต เด‡เดฎเต‡เดœเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต, เด…เดคเดฟเตฝ เดžเด™เตเด™เดณเตเดŸเต† เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เด†เดตเดถเตเดฏเดฎเดพเดฏ เดŽเดฒเตเดฒเดพเด‚ เดžเด™เตเด™เตพ เดชเดพเด•เตเด•เต‡เดœเต เดšเต†เดฏเตเดฏเตเด‚. เด…เดŸเดฟเดธเตเดฅเดพเดจเดชเดฐเดฎเดพเดฏเดฟ, เด’เดฐเต เดšเดฟเดคเตเดฐเด‚ เดซเดฏเตฝ เดธเดฟเดธเตเดฑเตเดฑเดคเตเดคเดฟเดจเตเดฑเต† เดชเด•เตผเดชเตเดชเดพเดฃเต. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, Dockerfile เดŽเดŸเตเด•เตเด•เตเด•:

FROM node:12.16.2
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

เด’เดฐเต เดกเต‹เด•เตเด•เตผเดซเดฏเตฝ เดจเดฟเตผเดฆเตเดฆเต‡เดถเด™เตเด™เดณเตเดŸเต† เด’เดฐเต เด•เต‚เดŸเตเดŸเดฎเดพเดฃเต; เด…เดต เด“เดฐเต‹เดจเตเดจเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต†, เดกเต‹เด•เตเด•เตผ เดซเดฏเตฝ เดธเดฟเดธเตเดฑเตเดฑเดคเตเดคเดฟเดฒเต† เดฎเดพเดฑเตเดฑเด™เตเด™เตพ เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดฎเตเดฎเตเดชเดคเตเดคเต†เดตเดฏเดฟเตฝ เด…เดตเดฏเต† เด“เดตเตผเดฒเต‡ เดšเต†เดฏเตเดฏเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเด‚. เด“เดฐเต‹ เดŸเต€เดฎเตเด‚ เดธเตเดตเดจเตเดคเด‚ เดชเดพเดณเดฟ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจเต. เดชเต‚เตผเดคเตเดคเดฟเดฏเดพเด•เตเด•เดฟเดฏ เดšเดฟเดคเตเดฐเด‚ เดฒเต†เดฏเดฑเตเด•เตพ เด’เดฐเตเดฎเดฟเดšเตเดšเต เดšเต‡เตผเด•เตเด•เตเดจเตเดจเต.

เด…เดฑเดฟเดฏเต‡เดฃเตเดŸ เดชเตเดฐเดงเดพเดจ เด•เดพเดฐเตเดฏเด‚: เด“เดฐเต‹ เดกเต‹เด•เตเด•เตผ เดฒเต†เดฏเดฑเตเด‚ เด•เดพเดทเต† เดšเต†เดฏเตเดฏเดพเตป เด•เดดเดฟเดฏเตเด‚. เด…เดตเดธเดพเดจ เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเดจเต เดถเต‡เดทเด‚ เด’เดจเตเดจเตเด‚ เดฎเดพเดฑเดฟเดฏเดฟเดŸเตเดŸเดฟเดฒเตเดฒเต†เด™เตเด•เดฟเตฝ, เด•เดฎเดพเตปเดกเต เดŽเด•เตเดธเดฟเด•เตเดฏเต‚เดŸเตเดŸเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดชเด•เดฐเด‚, เดกเต‹เด•เตเด•เตผ เด’เดฐเต เดฑเต†เดกเดฟเดฎเต†เดฏเตเดกเต เดฒเต†เดฏเตผ เดŽเดŸเตเด•เตเด•เตเด‚. เดฌเดฟเตฝเดกเต เดธเตเดชเต€เดกเดฟเดฒเต† เดชเตเดฐเดงเดพเดจ เดตเตผเดฆเตเดงเดจเดตเต เด•เดพเดทเต†เดฏเตเดŸเต† เด‰เดชเดฏเต‹เด—เด‚ เดฎเต‚เดฒเดฎเดพเด•เตเดฎเต†เดจเตเดจเดคเดฟเดจเดพเตฝ, เดฌเดฟเตฝเดกเต เดธเตเดชเต€เดกเต เด…เดณเด•เตเด•เตเดฎเตเดชเต‹เตพ, เด’เดฐเต เดฑเต†เดกเดฟเดฎเต†เดฏเตเดกเต เด•เดพเดทเต† เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด’เดฐเต เด‡เดฎเต‡เดœเต เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เดžเด™เตเด™เตพ เดชเตเดฐเดคเตเดฏเต‡เด•เด‚ เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เตเด‚. เด…เดคเดฟเดจเดพเตฝ, เด˜เดŸเตเดŸเด‚ เด˜เดŸเตเดŸเดฎเดพเดฏเดฟ:

  1. เดฎเตเดฎเตเดชเดคเตเดคเต† เดฑเดฃเตเดฃเตเด•เตพ เดชเดฐเดฟเดถเต‹เดงเดจเดฏเต† เดฌเดพเดงเดฟเด•เตเด•เดพเดคเดฟเดฐเดฟเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดšเดฟเดคเตเดฐเด™เตเด™เตพ เดชเตเดฐเดพเดฆเต‡เดถเดฟเด•เดฎเดพเดฏเดฟ เด‡เดฒเตเดฒเดพเดคเดพเด•เตเด•เตเดจเตเดจเต.
    docker rmi $(docker images -q)
  2. เดžเด™เตเด™เตพ เด†เดฆเตเดฏเดฎเดพเดฏเดฟ เดฌเดฟเตฝเดกเต เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเต.
    time docker build -t app .
  3. เดžเด™เตเด™เตพ src/index.html เดซเดฏเตฝ เดฎเดพเดฑเตเดฑเตเดจเตเดจเต - เด’เดฐเต เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเดฑเตเดŸเต† เดœเต‹เดฒเดฟ เดžเด™เตเด™เตพ เด…เดจเตเด•เดฐเดฟเด•เตเด•เตเดจเตเดจเต.
  4. เดžเด™เตเด™เตพ เดฌเดฟเตฝเดกเต เดฐเดฃเตเดŸเดพเด‚ เดคเดตเดฃ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเต.
    time docker build -t app .

เด‡เดฎเต‡เดœเตเด•เตพ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดชเดฐเดฟเดธเตเดฅเดฟเดคเดฟ เดถเดฐเดฟเดฏเดพเดฏเดฟ เด•เต‹เตบเดซเดฟเด—เตผ เดšเต†เดฏเตโ€ŒเดคเดฟเดŸเตเดŸเตเดฃเตเดŸเต†เด™เตเด•เดฟเตฝ (เดคเดพเดดเต†เดฏเตเดณเตเดณเดคเดฟเตฝ เด•เต‚เดŸเตเดคเตฝ), เดฌเดฟเตฝเดกเต เด†เดฐเด‚เดญเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เดกเต‹เด•เตเด•เดฑเดฟเดจเต เด‡เดคเดฟเดจเด•เด‚ เดคเดจเตเดจเต† เด’เดฐเต เด•เต‚เดŸเตเดŸเด‚ เด•เดพเดทเต†เด•เตพ เด‰เดฃเตเดŸเดพเดฏเดฟเดฐเดฟเด•เตเด•เตเด‚. เด•เดพเดทเต† เดŽเด™เตเด™เดจเต† เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดฎเต†เดจเตเดจเต เดฎเดจเดธเดฟเดฒเดพเด•เตเด•เตเด• เดŽเดจเตเดจเดคเดพเดฃเต เดžเด™เตเด™เดณเตเดŸเต† เดšเตเดฎเดคเดฒ, เด…เดคเตเดตเดดเดฟ เดฌเดฟเตฝเดกเต เด•เดดเดฟเดฏเตเดจเตเดจเดคเตเดฐ เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดŸเด•เตเด•เตเดจเตเดจเต. เด’เดฐเต เด•เดพเดทเต† เด‡เดฒเตเดฒเดพเดคเต† เด’เดฐเต เดฌเดฟเตฝเดกเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเต เด’เดฐเต เดคเดตเดฃ เดฎเดพเดคเตเดฐเดฎเต‡ เดธเด‚เดญเดตเดฟเด•เตเด•เตเด•เดฏเตเดณเตเดณเต‚ เดŽเดจเตเดจเต เดžเด™เตเด™เตพ เด…เดจเตเดฎเดพเดจเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเดพเตฝ-เด†เดฆเตเดฏ เดคเดตเดฃ-เด†เดฆเตเดฏเดคเตเดคเต† เดชเตเดฐเดพเดตเดถเตเดฏเด‚ เดŽเดคเตเดฐเดฎเดพเดคเตเดฐเด‚ เดฎเดจเตเดฆเด—เดคเดฟเดฏเดฟเดฒเดพเดฏเดฟเดฐเตเดจเตเดจเตเดตเต†เดจเตเดจเต เดจเดฎเตเด•เตเด•เต เด…เดตเด—เดฃเดฟเด•เตเด•เดพเด‚. เดŸเต†เดธเตเดฑเตเดฑเตเด•เดณเดฟเตฝ, เดฌเดฟเตฝเดกเดฟเดจเตเดฑเต† เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต† เดฑเตบ เดžเด™เตเด™เตพเด•เตเด•เต เดชเตเดฐเดงเดพเดจเดฎเดพเดฃเต, เด•เดพเดทเต†เด•เตพ เด‡เดคเดฟเดจเด•เด‚ เดšเต‚เดŸเดพเด•เตเดฎเตเดชเต‹เตพ เดžเด™เตเด™เตพ เด•เต‡เด•เตเด•เต เดšเตเดŸเดพเตป เดคเดฏเตเดฏเดพเดฑเดพเดฃเต. เดŽเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด‚, เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ เด†เดฆเตเดฏ เดฌเดฟเตฝเดกเดฟเดจเต† เดฌเดพเดงเดฟเด•เตเด•เตเด‚.

เดฎเตเด•เดณเดฟเตฝ เดตเดฟเดตเดฐเดฟเดšเตเดš Dockerfile เดชเตเดฐเตŠเดœเด•เตเดฑเตเดฑเต เดซเต‹เตพเดกเดฑเดฟเตฝ เด‡เดŸเตเดŸเต เดฌเดฟเตฝเดกเต เด†เดฐเด‚เดญเดฟเด•เตเด•เดพเด‚. เดตเดพเดฏเดจเดฏเตเดŸเต† เดŽเดณเตเดชเตเดชเดคเตเดคเดฟเดจเดพเดฏเดฟ เดŽเดฒเตเดฒเดพ เดฒเดฟเดธเตเดฑเตเดฑเดฟเด‚เด—เตเด•เดณเตเด‚ เดšเตเดฐเตเด•เตเด•เดฟเดฏเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต.

$ time docker build -t app .
Sending build context to Docker daemon 409MB
Step 1/5 : FROM node:12.16.2
Status: Downloaded newer image for node:12.16.2
Step 2/5 : WORKDIR /app
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:20:09.664Z - Hash: fffa0fddaa3425c55dd3 - Time: 37581ms
Successfully built c8c279335f46
Successfully tagged app:latest

real 5m4.541s
user 0m0.000s
sys 0m0.000s

เดžเด™เตเด™เตพ src/index.html-เดจเตเดฑเต† เด‰เดณเตเดณเดŸเด•เตเด•เด‚ เดฎเดพเดฑเตเดฑเตเด•เดฏเตเด‚ เด…เดคเต เดฐเดฃเตเดŸเดพเด‚ เดคเดตเดฃ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต.

$ time docker build -t app .
Sending build context to Docker daemon 409MB
Step 1/5 : FROM node:12.16.2
Step 2/5 : WORKDIR /app
 ---> Using cache
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:26:26.587Z - Hash: fffa0fddaa3425c55dd3 - Time: 37902ms
Successfully built 79f335df92d3
Successfully tagged app:latest

real 3m33.262s
user 0m0.000s
sys 0m0.000s

เดจเดฎเตเด•เตเด•เต เด‡เดฎเต‡เดœเต เด‰เดฃเตเดŸเต‹ เดŽเดจเตเดจเดฑเดฟเดฏเดพเตป, เด•เดฎเดพเตปเดกเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเด• docker images:

REPOSITORY   TAG      IMAGE ID       CREATED              SIZE
app          latest   79f335df92d3   About a minute ago   1.74GB

เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เดฎเตเดฎเตเดชเต, เดกเต‹เด•เตเด•เตผ เดจเดฟเดฒเดตเดฟเดฒเต† เดธเดจเตเดฆเตผเดญเดคเตเดคเดฟเตฝ เดŽเดฒเตเดฒเดพ เดซเดฏเดฒเตเด•เดณเตเด‚ เดŽเดŸเตเดคเตเดคเต เด…เดคเดฟเดจเตเดฑเต† เดกเต†เดฎเดจเดฟเดฒเต‡เด•เตเด•เต เด…เดฏเดฏเตเด•เตเด•เตเดจเตเดจเต Sending build context to Docker daemon 409MB. เดฌเดฟเตฝเดกเต เด•เดฎเดพเตปเดกเดฟเดจเตเดฑเต† เด…เดตเดธเดพเดจ เด†เตผเด—เตเดฏเตเดฎเต†เดจเตเดฑเดพเดฏเดฟ เดฌเดฟเตฝเดกเต เดธเดจเตเดฆเตผเดญเด‚ เดตเตเดฏเด•เตเดคเดฎเดพเด•เตเด•เดฟเดฏเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต. เดžเด™เตเด™เดณเตเดŸเต† เด•เดพเดฐเตเดฏเดคเตเดคเดฟเตฝ, เด‡เดคเดพเดฃเต เดจเดฟเดฒเดตเดฟเดฒเต† เดกเดฏเดฑเด•เตโ€ŒเดŸเดฑเดฟ - โ€œ.โ€, - เด•เต‚เดŸเดพเดคเต† เดˆ เดซเต‹เตพเดกเดฑเดฟเตฝ เด‰เดณเตเดณเดคเต†เดฒเตเดฒเดพเด‚ เดกเต‹เด•เตเด•เตผ เดตเดฒเดฟเดšเตเดšเดฟเดŸเตเดจเตเดจเต. 409 MB เด’เดฐเตเดชเดพเดŸเต เด†เดฃเต: เด…เดคเต เดŽเด™เตเด™เดจเต† เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เดพเดฎเต†เดจเตเดจเต เดจเดฎเตเด•เตเด•เต เดšเดฟเดจเตเดคเดฟเด•เตเด•เดพเด‚.

เดธเดจเตเดฆเตผเดญเด‚ เด•เตเดฑเดฏเตเด•เตเด•เตเดจเตเดจเต

เดธเดจเตเดฆเตผเดญเด‚ เด•เตเดฑเดฏเตเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต, เดฐเดฃเตเดŸเต เด“เดชเตเดทเดจเตเด•เตพ เด‰เดฃเตเดŸเต. เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เด…เดธเด‚เดฌเตเดฒเดฟเด•เตเด•เต เด†เดตเดถเตเดฏเดฎเดพเดฏ เดŽเดฒเตเดฒเดพ เดซเดฏเดฒเตเด•เดณเตเด‚ เด’เดฐเต เดชเตเดฐเดคเตเดฏเต‡เด• เดซเต‹เตพเดกเดฑเดฟเตฝ เด‡เดŸเตเด•, เดกเต‹เด•เตเด•เตผ เดธเดจเตเดฆเตผเดญเด‚ เดˆ เดซเต‹เตพเดกเดฑเดฟเดฒเต‡เด•เตเด•เต เดชเต‹เดฏเดฟเดจเตเดฑเต เดšเต†เดฏเตเดฏเตเด•. เด‡เดคเต เดŽเดฒเตเดฒเดพเดฏเตเดชเตเดชเต‹เดดเตเด‚ เดธเต—เด•เดฐเตเดฏเดชเตเดฐเดฆเดฎเดพเดฏเดฟเดฐเดฟเด•เตเด•เดฟเดฒเตเดฒ, เด…เดคเดฟเดจเดพเตฝ เด’เดดเดฟเดตเดพเด•เตเด•เดฒเตเด•เตพ เดตเตเดฏเด•เตเดคเดฎเดพเด•เตเด•เดพเตป เดธเดพเดงเดฟเด•เตเด•เตเด‚: เดธเดจเตเดฆเตผเดญเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เดตเดฒเดฟเดšเตเดšเดฟเดŸเดพเตป เดชเดพเดŸเดฟเดฒเตเดฒเดพเดคเตเดคเดคเต. เด‡เดคเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต, เดชเตเดฐเต‹เดœเด•เตเดฑเตเดฑเดฟเตฝ .dockerignore เดซเดฏเตฝ เด‡เดŸเตเด•เดฏเตเด‚ เดฌเดฟเตฝเดกเดฟเดจเต เด†เดตเดถเตเดฏเดฎเดฟเดฒเตเดฒเดพเดคเตเดคเดคเต เดธเต‚เดšเดฟเดชเตเดชเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเด•:

.git
/node_modules

เดฌเดฟเตฝเดกเต เดตเต€เดฃเตเดŸเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเด•:

$ time docker build -t app .
Sending build context to Docker daemon 607.2kB
Step 1/5 : FROM node:12.16.2
Step 2/5 : WORKDIR /app
 ---> Using cache
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:33:54.338Z - Hash: fffa0fddaa3425c55dd3 - Time: 37313ms
Successfully built 4942f010792a
Successfully tagged app:latest

real 1m47.763s
user 0m0.000s
sys 0m0.000s

607.2 เด•เต†เดฌเดฟ 409 เดŽเด‚เดฌเดฟเดฏเต‡เด•เตเด•เดพเตพ เดฎเดฟเด•เดšเตเดšเดคเดพเดฃเต. เดžเด™เตเด™เตพ เดšเดฟเดคเตเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดตเดฒเตเดชเตเดชเด‚ 1.74 เตฝ เดจเดฟเดจเตเดจเต 1.38 GB เด†เดฏเดฟ เด•เตเดฑเดšเตเดšเต:

REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
app          latest   4942f010792a   3 minutes ago   1.38GB

เดšเดฟเดคเตเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดตเดฒเดฟเดชเตเดชเด‚ เด‡เดจเดฟเดฏเตเด‚ เด•เตเดฑเดฏเตเด•เตเด•เดพเตป เดถเตเดฐเดฎเดฟเด•เตเด•เดพเด‚.

เดžเด™เตเด™เตพ เด†เตฝเดชเตˆเตป เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต

เด‡เดฎเต‡เดœเต เดธเตˆเดธเต เดฒเดพเดญเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดฎเดฑเตเดฑเตŠเดฐเต เดฎเดพเตผเด—เด‚ เด’เดฐเต เดšเต†เดฑเดฟเดฏ เดชเดพเดฐเดจเตเดฑเต เด‡เดฎเต‡เดœเต เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด• เดŽเดจเตเดจเดคเดพเดฃเต. เดฐเด•เตเดทเดพเด•เตผเดคเตƒ เดšเดฟเดคเตเดฐเด‚ เดŽเดจเตเดจเดคเต เดจเดฎเตเดฎเตเดŸเต† เดšเดฟเดคเตเดฐเด‚ เดคเดฏเตเดฏเดพเดฑเดพเด•เตเด•เตเดจเตเดจ เดšเดฟเดคเตเดฐเดฎเดพเดฃเต. เดคเดพเดดเต†เดฏเตเดณเตเดณ เดฒเต†เดฏเตผ เด•เดฎเดพเตปเดกเต เดชเตเดฐเด•เดพเดฐเด‚ เดตเตเดฏเด•เตเดคเดฎเดพเด•เตเด•เดฟเดฏเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต FROM เดกเต‹เด•เตเด•เตผเดซเดฏเดฒเดฟเตฝ. เดžเด™เตเด™เดณเตเดŸเต† เด•เดพเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดžเด™เตเด™เตพ เด‡เดคเดฟเดจเด•เด‚ เดจเต‹เดกเต‡เดœเตเด•เตพ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดคเดฟเดŸเตเดŸเตเดณเตเดณ เด’เดฐเต เด‰เดฌเตเดฃเตเดŸเต เด…เดงเดฟเดทเตเด เดฟเดค เด‡เดฎเต‡เดœเดพเดฃเต เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเต. เด’เดชเตเดชเด‚ เดญเดพเดฐเดตเตเด‚...

$ docker images -a | grep node
node 12.16.2 406aa3abbc6c 17 minutes ago 916MB

... เดเดคเดพเดฃเตเดŸเต เด’เดฐเต เดœเดฟเด—เดพเดฌเตˆเดฑเตเดฑเต. Alpine Linux เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเด•เตเด•เดฟเดฏเตเดณเตเดณ เด’เดฐเต เด‡เดฎเต‡เดœเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดตเต‹เดณเดฟเดฏเด‚ เด—เดฃเตเดฏเดฎเดพเดฏเดฟ เด•เตเดฑเดฏเตเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเด‚. เด†เตฝเดชเตˆเตป เดตเดณเดฐเต† เดšเต†เดฑเดฟเดฏ เดฒเดฟเดจเด•เตเดธเดพเดฃเต. เด†เตฝเดชเตˆเตป เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเด•เตเด•เดฟเดฏเตเดณเตเดณ เดจเต‹เดกเต‡เดœเตเด•เตพเด•เตเด•เตเดณเตเดณ เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเดฟเดจเตเดฑเต† เดญเดพเดฐเด‚ 88.5 MB เดฎเดพเดคเตเดฐเดฎเดพเดฃเต. เด…เดคเดฟเดจเดพเตฝ, เดตเต€เดŸเตเด•เดณเดฟเตฝ เดจเดฎเตเดฎเตเดŸเต† เดธเดœเต€เดตเดฎเดพเดฏ เดšเดฟเดคเตเดฐเด‚ เดฎเดพเดฑเตเดฑเดฟเดธเตเดฅเดพเดชเดฟเด•เตเด•เดพเด‚:

FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เด†เดตเดถเตเดฏเดฎเดพเดฏ เดšเดฟเดฒ เด•เดพเดฐเตเดฏเด™เตเด™เตพ เดžเด™เตเด™เตพ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต. เด…เดคเต†, เดชเตˆเดคเตเดคเตบ ยฏ(ยฐ_o)/ยฏ เด‡เดฒเตเดฒเดพเดคเต† Angular เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒ

เดŽเดจเตเดจเดพเตฝ เดšเดฟเดคเตเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดตเดฒเตเดชเตเดชเด‚ 150 MB เด†เดฏเดฟ เด•เตเดฑเดžเตเดžเต:

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
app          latest   aa031edc315a   22 minutes ago   761MB

เด‡เดจเดฟเดฏเตเด‚ เดฎเตเดจเตเดจเต‹เดŸเตเดŸเต เดชเต‹เด•เดพเด‚.

เดฎเตพเดŸเตเดŸเดฟเดธเตเดฑเตเดฑเต‡เดœเต เด…เดธเด‚เดฌเตเดฒเดฟ

เดšเดฟเดคเตเดฐเดคเตเดคเดฟเตฝ เด‰เดณเตเดณเดคเต†เดฒเตเดฒเดพเด‚ เดจเดฎเตเด•เตเด•เต เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเตฝ เด†เดตเดถเตเดฏเดฎเตเดณเตเดณเดตเดฏเดฒเตเดฒ.

$ docker run app ls -lah
total 576K
drwxr-xr-x 1 root root 4.0K Apr 16 19:54 .
drwxr-xr-x 1 root root 4.0K Apr 16 20:00 ..
-rwxr-xr-x 1 root root 19 Apr 17 2020 .dockerignore
-rwxr-xr-x 1 root root 246 Apr 17 2020 .editorconfig
-rwxr-xr-x 1 root root 631 Apr 17 2020 .gitignore
-rwxr-xr-x 1 root root 181 Apr 17 2020 Dockerfile
-rwxr-xr-x 1 root root 1020 Apr 17 2020 README.md
-rwxr-xr-x 1 root root 3.6K Apr 17 2020 angular.json
-rwxr-xr-x 1 root root 429 Apr 17 2020 browserslist
drwxr-xr-x 3 root root 4.0K Apr 16 19:54 dist
drwxr-xr-x 3 root root 4.0K Apr 17 2020 e2e
-rwxr-xr-x 1 root root 1015 Apr 17 2020 karma.conf.js
-rwxr-xr-x 1 root root 620 Apr 17 2020 ngsw-config.json
drwxr-xr-x 1 root root 4.0K Apr 16 19:54 node_modules
-rwxr-xr-x 1 root root 494.9K Apr 17 2020 package-lock.json
-rwxr-xr-x 1 root root 1.3K Apr 17 2020 package.json
drwxr-xr-x 5 root root 4.0K Apr 17 2020 src
-rwxr-xr-x 1 root root 210 Apr 17 2020 tsconfig.app.json
-rwxr-xr-x 1 root root 489 Apr 17 2020 tsconfig.json
-rwxr-xr-x 1 root root 270 Apr 17 2020 tsconfig.spec.json
-rwxr-xr-x 1 root root 1.9K Apr 17 2020 tslint.json

เดธเดนเดพเดฏเดคเตเดคเต‹เดŸเต† docker run app ls -lah เดžเด™เตเด™เดณเตเดŸเต† เด‡เดฎเต‡เดœเดฟเดจเต† เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเด•เตเด•เดฟ เดžเด™เตเด™เตพ เด’เดฐเต เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เดชเตเดฑเดคเตเดคเดฟเดฑเด•เตเด•เดฟ app เด…เดคเดฟเดฒเต† เด•เดฎเดพเตปเดกเต เดŽเด•เตเดธเดฟเด•เตเดฏเต‚เดŸเตเดŸเต เดšเต†เดฏเตเดฏเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดคเต ls -lah, เด…เดคเดฟเดจเตเดถเต‡เดทเด‚ เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เด…เดคเดฟเดจเตเดฑเต† เดœเต‹เดฒเดฟ เดชเต‚เตผเดคเตเดคเดฟเดฏเดพเด•เตเด•เดฟ.

เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเตฝ เดจเดฎเตเด•เตเด•เต เด’เดฐเต เดซเต‹เตพเดกเตผ เดฎเดพเดคเตเดฐเดฎเต‡ เด†เดตเดถเตเดฏเดฎเตเดณเตเดณเต‚ dist. เดˆ เดธเดพเดนเดšเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดซเดฏเดฒเตเด•เตพ เดŽเด™เตเด™เดจเต†เดฏเต†เด™เตเด•เดฟเดฒเตเด‚ เดชเตเดฑเดคเตเดคเต เดจเตฝเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต. เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดจเต‹เดกเต‡เดœเตเด•เดณเดฟเตฝ เดšเดฟเดฒ HTTP เดธเต†เตผเดตเตผ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เดพเด‚. เดŽเดจเตเดจเดพเตฝ เดžเด™เตเด™เตพ เด…เดคเต เดŽเดณเตเดชเตเดชเดฎเดพเด•เตเด•เตเด‚. "y" เดŽเดจเตเดจ เดจเดพเดฒเต เด…เด•เตเดทเดฐเด™เตเด™เดณเตเดณเตเดณ เด’เดฐเต เดฑเดทเตเดฏเตป เดตเดพเด•เตเด•เต เดŠเดนเดฟเด•เตเด•เตเด•. เดถเดฐเดฟเดฏเดพเดฃเต! Ynzhynyksy. เดจเดฎเตเด•เตเด•เต nginx เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด’เดฐเต เดšเดฟเดคเตเดฐเด‚ เดŽเดŸเตเด•เตเด•เดพเด‚, เด…เดคเดฟเตฝ เด’เดฐเต เดซเต‹เตพเดกเตผ เด‡เดŸเตเด• dist เด’เดฐเต เดšเต†เดฑเดฟเดฏ เด•เต‹เตบเดซเดฟเด—เดฑเต‡เดทเดจเตเด‚:

server {
    listen 80 default_server;
    server_name localhost;
    charset utf-8;
    root /app/dist;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

เดฎเตพเดŸเตเดŸเดฟ-เดธเตเดฑเตเดฑเต‡เดœเต เดฌเดฟเตฝเดกเต เด‡เดคเต†เดฒเตเดฒเดพเด‚ เดšเต†เดฏเตเดฏเดพเตป เดžเด™เตเด™เดณเต† เดธเดนเดพเดฏเดฟเด•เตเด•เตเด‚. เดจเดฎเตเด•เตเด•เต เดจเดฎเตเดฎเตเดŸเต† Dockerfile เดฎเดพเดฑเตเดฑเดพเด‚:

FROM node:12.16.2-alpine3.11 as builder
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

FROM nginx:1.17.10-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/static.conf /etc/nginx/conf.d
COPY --from=builder /app/dist/app .

เด‡เดชเตเดชเต‹เตพ เดจเดฎเตเด•เตเด•เต เดฐเดฃเตเดŸเต เดจเดฟเตผเดฆเตเดฆเต‡เดถเด™เตเด™เดณเตเดฃเตเดŸเต FROM เดกเต‹เด•เตเด•เตผเดซเดฏเดฒเดฟเตฝ, เด…เดต เด“เดฐเต‹เดจเตเดจเตเด‚ เดตเตเดฏเดคเตเดฏเดธเตเดค เดฌเดฟเตฝเดกเต เดธเตเดฑเตเดฑเต†เดชเตเดชเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเต. เดžเด™เตเด™เตพ เด†เดฆเตเดฏเดคเตเดคเต†เดฏเดพเดณเต† เดตเดฟเดณเดฟเดšเตเดšเต builder, เดŽเดจเตเดจเดพเตฝ เด…เดตเดธเดพเดจเดคเตเดคเต† FROM เดฎเตเดคเตฝ, เดžเด™เตเด™เดณเตเดŸเต† เด…เดจเตเดคเดฟเดฎ เดšเดฟเดคเตเดฐเด‚ เดคเดฏเตเดฏเดพเดฑเดพเด•เตเด•เดชเตเดชเต†เดŸเตเด‚. เดฎเตเดฎเตเดชเดคเตเดคเต† เด˜เดŸเตเดŸเดคเตเดคเดฟเดฒเต† เดžเด™เตเด™เดณเตเดŸเต† เด…เดธเด‚เดฌเตเดฒเดฟเดฏเตเดŸเต† เด†เตผเดŸเตเดŸเดฟเดซเดพเด•เตเดฑเตเดฑเต nginx เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด…เดจเตเดคเดฟเดฎ เดšเดฟเดคเตเดฐเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เดชเด•เตผเดคเตเดคเตเด• เดŽเดจเตเดจเดคเดพเดฃเต เด…เดตเดธเดพเดจ เด˜เดŸเตเดŸเด‚. เดšเดฟเดคเตเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดตเดฒเตเดชเตเดชเด‚ เด—เดฃเตเดฏเดฎเดพเดฏเดฟ เด•เตเดฑเดžเตเดžเต:

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
app          latest   2c6c5da07802   29 minutes ago   36MB

เดจเดฎเตเด•เตเด•เต เดจเดฎเตเดฎเตเดŸเต† เดšเดฟเดคเตเดฐเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เดพเด‚, เดŽเดฒเตเดฒเดพเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเตเดตเต†เดจเตเดจเต เด‰เดฑเดชเตเดชเดพเด•เตเด•เตเด•:

docker run -p8080:80 app

-p8080:80 เด“เดชเตเดทเตป เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต, nginx เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจ เด•เดฃเตเดŸเต†เดฏเตโ€Œเดจเดฑเดฟเดจเตเดณเตเดณเดฟเดฒเต† เดชเต‹เตผเดŸเตเดŸเต 8080-เดฒเต‡เด•เตเด•เต เดžเด™เตเด™เดณเตเดŸเต† เดนเต‹เดธเตเดฑเตเดฑเต เดฎเต†เดทเต€เดจเดฟเดฒเต† เดชเต‹เตผเดŸเตเดŸเต 80 เดซเต‹เตผเดตเต‡เดกเต เดšเต†เดฏเตเดคเต. เดฌเตเดฐเต—เดธเดฑเดฟเตฝ เดคเตเดฑเด•เตเด•เตเด• http://localhost:8080/ เดžเด™เตเด™เตพ เดžเด™เตเด™เดณเตเดŸเต† เด…เดชเต‡เด•เตเดท เด•เดพเดฃเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต. เดŽเดฒเตเดฒเดพเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต!

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เด‡เดฎเต‡เดœเต เดตเดฒเตเดชเตเดชเด‚ 1.74 GB-เดฏเดฟเตฝ เดจเดฟเดจเตเดจเต 36 MB-เดฒเต‡เด•เตเด•เต เด•เตเดฑเดฏเตเด•เตเด•เตเดจเตเดจเดคเต เดจเดฟเด™เตเด™เดณเตเดŸเต† เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดชเตเดฐเตŠเดกเด•เตเดทเดจเดฟเตฝ เดŽเดคเตเดคเดฟเด•เตเด•เดพเตป เดŽเดŸเตเด•เตเด•เตเดจเตเดจ เดธเดฎเดฏเด‚ เด—เดฃเตเดฏเดฎเดพเดฏเดฟ เด•เตเดฑเดฏเตเด•เตเด•เตเดจเตเดจเต. เดŽเดจเตเดจเดพเตฝ เดจเดฎเตเด•เตเด•เต เด…เดธเด‚เดฌเตเดฒเดฟ เดธเดฎเดฏเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เดฎเดŸเด™เตเด™เดพเด‚.

$ time docker build -t app .
Sending build context to Docker daemon 608.8kB
Step 1/11 : FROM node:12.16.2-alpine3.11 as builder
Step 2/11 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
 ---> Using cache
Step 3/11 : WORKDIR /app
 ---> Using cache
Step 4/11 : COPY . .
Step 5/11 : RUN npm ci
added 1357 packages in 47.338s
Step 6/11 : RUN npm run build --prod
Date: 2020-04-16T21:16:03.899Z - Hash: fffa0fddaa3425c55dd3 - Time: 39948ms
 ---> 27f1479221e4
Step 7/11 : FROM nginx:stable-alpine
Step 8/11 : WORKDIR /app
 ---> Using cache
Step 9/11 : RUN rm /etc/nginx/conf.d/default.conf
 ---> Using cache
Step 10/11 : COPY nginx/static.conf /etc/nginx/conf.d
 ---> Using cache
Step 11/11 : COPY --from=builder /app/dist/app .
Successfully built d201471c91ad
Successfully tagged app:latest

real 2m17.700s
user 0m0.000s
sys 0m0.000s

เดชเดพเดณเดฟเด•เดณเตเดŸเต† เด•เตเดฐเดฎเด‚ เดฎเดพเดฑเตเดฑเตเดจเตเดจเต

เดžเด™เตเด™เดณเตเดŸเต† เด†เดฆเตเดฏ เดฎเต‚เดจเตเดจเต เด˜เดŸเตเดŸเด™เตเด™เตพ เด•เดพเดทเต† เดšเต†เดฏเตเดคเต (เดธเต‚เดšเดจ Using cache). เดจเดพเดฒเดพเดฎเดคเตเดคเต† เด˜เดŸเตเดŸเดคเตเดคเดฟเตฝ, เดŽเดฒเตเดฒเดพ เดชเตเดฐเต‹เดœเด•เตเดฑเตเดฑเต เดซเดฏเดฒเตเด•เดณเตเด‚ เดชเด•เตผเดคเตเดคเตเด•เดฏเตเด‚ เด…เดžเตเดšเดพเด‚ เด˜เดŸเตเดŸเดคเตเดคเดฟเตฝ เดกเดฟเดชเตปเดกเตปเดธเดฟเด•เตพ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต RUN npm ci - 47.338 เดธเต†. เดกเดฟเดชเตปเดกเตปเดธเดฟเด•เตพ เดตเดณเดฐเต† เด…เดชเต‚เตผเดตเตเดตเดฎเดพเดฏเดฟ เดฎเดพเดฑเตเด•เดฏเดพเดฃเต†เด™เตเด•เดฟเตฝ เดŽเดจเตเดคเดฟเดจเดพเดฃเต เด“เดฐเต‹ เดคเดตเดฃเดฏเตเด‚ เดตเต€เดฃเตเดŸเตเด‚ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเต? เดŽเดจเตเดคเตเด•เตŠเดฃเตเดŸเดพเดฃเต เด…เดต เด•เดพเดทเต† เดšเต†เดฏเตเดฏเดพเดคเตเดคเดคเต†เดจเตเดจเต เดจเดฎเตเด•เตเด•เต เด•เดฃเตเดŸเต†เดคเตเดคเดพเด‚. เด•เดฎเดพเตปเดกเตเด‚ เด…เดคเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเต†เดŸเตเดŸ เดซเดฏเดฒเตเด•เดณเตเด‚ เดฎเดพเดฑเดฟเดฏเดฟเดŸเตเดŸเตเดฃเตเดŸเต‹ เดŽเดจเตเดจเดฑเดฟเดฏเดพเตป เดกเต‹เด•เตเด•เตผ เดฒเต†เดฏเตผ เดฌเตˆ เดฒเต†เดฏเตผ เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เตเด‚ เดŽเดจเตเดจเดคเดพเดฃเต เด•เดพเดฐเตเดฏเด‚. เดจเดพเดฒเดพเดฎเดคเตเดคเต† เด˜เดŸเตเดŸเดคเตเดคเดฟเตฝ, เดžเด™เตเด™เดณเตเดŸเต† เดชเตเดฐเต‹เดœเด•เตเดฑเตเดฑเดฟเดจเตเดฑเต† เดŽเดฒเตเดฒเดพ เดซเดฏเดฒเตเด•เดณเตเด‚ เดžเด™เตเด™เตพ เดชเด•เตผเดคเตเดคเตเดจเตเดจเต, เด…เดตเดฏเดฟเตฝ เดคเต€เตผเดšเตเดšเดฏเดพเดฏเตเด‚ เดฎเดพเดฑเตเดฑเด™เตเด™เดณเตเดฃเตเดŸเต, เด…เดคเดฟเดจเดพเตฝ เดกเต‹เด•เตเด•เตผ เดˆ เดฒเต†เดฏเตผ เด•เดพเดทเต†เดฏเดฟเตฝ เดจเดฟเดจเตเดจเต เดŽเดŸเตเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒ, เดฎเดพเดคเตเดฐเดฎเดฒเตเดฒ เดคเตเดŸเตผเดจเตเดจเตเดณเตเดณเดตเดฏเตเด‚! เดกเต‹เด•เตเด•เตผเดซเดฏเดฒเดฟเตฝ เดšเต†เดฑเดฟเดฏ เดšเดฟเดฒ เดฎเดพเดฑเตเดฑเด™เตเด™เตพ เดตเดฐเตเดคเตเดคเดพเด‚.

FROM node:12.16.2-alpine3.11 as builder
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build --prod

FROM nginx:1.17.10-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/static.conf /etc/nginx/conf.d
COPY --from=builder /app/dist/app .

เด†เดฆเตเดฏเด‚, package.json, pack-lock.json เดŽเดจเตเดจเดฟเดต เดชเด•เตผเดคเตเดคเดฟ, เดคเตเดŸเตผเดจเตเดจเต เดกเดฟเดชเตปเดกเตปเดธเดฟเด•เตพ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต, เด…เดคเดฟเดจเตเดถเต‡เดทเด‚ เดฎเดพเดคเตเดฐเดฎเต‡ เดฎเตเดดเตเดตเตป เดชเตเดฐเต‹เดœเด•เตเดฑเตเดฑเตเด‚ เดชเด•เตผเดคเตเดคเตเด•เดฏเตเดณเตเดณเต‚. เดคเตฝเดซเดฒเดฎเดพเดฏเดฟ:

$ time docker build -t app .
Sending build context to Docker daemon 608.8kB
Step 1/12 : FROM node:12.16.2-alpine3.11 as builder
Step 2/12 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
 ---> Using cache
Step 3/12 : WORKDIR /app
 ---> Using cache
Step 4/12 : COPY package*.json ./
 ---> Using cache
Step 5/12 : RUN npm ci
 ---> Using cache
Step 6/12 : COPY . .
Step 7/12 : RUN npm run build --prod
Date: 2020-04-16T21:29:44.770Z - Hash: fffa0fddaa3425c55dd3 - Time: 38287ms
 ---> 1b9448c73558
Step 8/12 : FROM nginx:stable-alpine
Step 9/12 : WORKDIR /app
 ---> Using cache
Step 10/12 : RUN rm /etc/nginx/conf.d/default.conf
 ---> Using cache
Step 11/12 : COPY nginx/static.conf /etc/nginx/conf.d
 ---> Using cache
Step 12/12 : COPY --from=builder /app/dist/app .
Successfully built a44dd7c217c3
Successfully tagged app:latest

real 0m46.497s
user 0m0.000s
sys 0m0.000s

46 เดฎเดฟเดจเดฟเดฑเตเดฑเดฟเดจเต เดชเด•เดฐเด‚ 3 เดธเต†เด•เตเด•เตปเดกเต - เดตเดณเดฐเต† เดจเดฒเตเดฒเดคเต! เดฒเต†เดฏเดฑเตเด•เดณเตเดŸเต† เดถเดฐเดฟเดฏเดพเดฏ เด•เตเดฐเดฎเด‚ เดชเตเดฐเดงเดพเดจเดฎเดพเดฃเต: เด†เดฆเตเดฏเด‚ เดจเดฎเตเดฎเตพ เดฎเดพเดฑเดพเดคเตเดคเดต เดชเด•เตผเดคเตเดคเตเดจเตเดจเต, เดชเดฟเดจเตเดจเต€เดŸเต เด…เดชเต‚เตผเดตเตเดตเดฎเดพเดฏเดฟ เดฎเดพเดฑเตเดจเตเดจเดต, เด’เดŸเตเดตเดฟเตฝ เดชเดฒเดชเตเดชเต‹เดดเตเด‚ เดฎเดพเดฑเตเดจเตเดจเดต.

เด…เดŸเตเดคเตเดคเดคเดพเดฏเดฟ, CI/CD เดธเดฟเดธเตเดฑเตเดฑเด™เตเด™เดณเดฟเตฝ เด‡เดฎเต‡เดœเตเด•เตพ เด•เต‚เดŸเตเดŸเดฟเดšเตเดšเต‡เตผเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เด•เตเดฑเดšเตเดšเต เดตเดพเด•เตเด•เตเด•เตพ.

เด•เดพเดทเต†เด•เตเด•เดพเดฏเดฟ เดฎเตเดฎเตเดชเดคเตเดคเต† เดšเดฟเดคเตเดฐเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต

เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเดจเดพเดฏเดฟ เดžเด™เตเด™เตพ เดเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เดคเดฐเดคเตเดคเดฟเดฒเตเดณเตเดณ SaaS เดธเตŠเดฒเตเดฏเต‚เดทเตป เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด•เดฏเดพเดฃเต†เด™เตเด•เดฟเตฝ, เดชเตเดฐเดพเดฆเต‡เดถเดฟเด• เดกเต‹เด•เตเด•เตผ เด•เดพเดทเต† เดถเตเดฆเตเดงเดตเตเด‚ เดชเตเดคเตเดฎเดฏเตเดณเตเดณเดคเตเดฎเดพเดฏเดฟเดฐเดฟเด•เตเด•เตเด‚. เดšเตเดŸเตเดŸเตเดชเดดเตเดคเตเดค เดชเดพเดณเดฟเด•เตพ เดฒเดญเดฟเด•เตเด•เดพเตป เดกเต‹เด•เตเด•เดฑเดฟเดจเต เด’เดฐเต เดธเตเดฅเดฒเด‚ เดจเตฝเด•เตเดจเตเดจเดคเดฟเดจเต, เดฎเตเดฎเตเดชเต เดจเดฟเตผเดฎเตเดฎเดฟเดšเตเดš เดšเดฟเดคเตเดฐเด‚ เดจเตฝเด•เตเด•.

GitHub เดชเตเดฐเดตเตผเดคเตเดคเดจเด™เตเด™เดณเดฟเตฝ เดžเด™เตเด™เดณเตเดŸเต† เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด’เดฐเต เด‰เดฆเดพเดนเดฐเดฃเด‚ เดจเต‹เด•เตเด•เดพเด‚. เดžเด™เตเด™เตพ เดˆ เด•เต‹เตบเดซเดฟเด—เดฑเต‡เดทเตป เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต

on:
  push:
    branches:
      - master

name: Test docker build

jobs:
  deploy:
    name: Build
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Login to GitHub Packages
      env:
        TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN

    - name: Build
      run: |
        docker build 
          -t $IMAGE_NAME:$IMAGE_TAG 
          -t $IMAGE_NAME:latest 
          .

    - name: Push image to GitHub Packages
      run: |
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - name: Logout
      run: |
        docker logout docker.pkg.github.com

เดฐเดฃเตเดŸเต เดฎเดฟเดจเดฟเดฑเตเดฑเตเด‚ 20 เดธเต†เด•เตเด•เตปเดกเตเด‚ เด•เตŠเดฃเตเดŸเต เดšเดฟเดคเตเดฐเด‚ เด•เต‚เดŸเตเดŸเดฟเดšเตเดšเต‡เตผเด•เตเด•เตเด•เดฏเตเด‚ GitHub เดชเดพเด•เตเด•เต‡เดœเตเด•เดณเดฟเดฒเต‡เด•เตเด•เต เดคเดณเตเดณเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต:

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เด‡เดชเตเดชเต‹เตพ เดจเดฎเตเด•เตเด•เต เดฌเดฟเตฝเดกเต เดฎเดพเดฑเตเดฑเดพเด‚, เด…เดคเตเดตเดดเดฟ เดฎเตเดฎเตเดชเดคเตเดคเต† เดจเดฟเตผเดฎเตเดฎเดฟเดšเตเดš เดšเดฟเดคเตเดฐเด™เตเด™เดณเต† เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเด•เตเด•เดฟ เด’เดฐเต เด•เดพเดทเต† เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต:

on:
  push:
    branches:
      - master

name: Test docker build

jobs:
  deploy:
    name: Build
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Login to GitHub Packages
      env:
        TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN

    - name: Pull latest images
      run: |
        docker pull $IMAGE_NAME:latest || true
        docker pull $IMAGE_NAME-builder-stage:latest || true

    - name: Images list
      run: |
        docker images

    - name: Build
      run: |
        docker build 
          --target builder 
          --cache-from $IMAGE_NAME-builder-stage:latest 
          -t $IMAGE_NAME-builder-stage 
          .
        docker build 
          --cache-from $IMAGE_NAME-builder-stage:latest 
          --cache-from $IMAGE_NAME:latest 
          -t $IMAGE_NAME:$IMAGE_TAG 
          -t $IMAGE_NAME:latest 
          .

    - name: Push image to GitHub Packages
      run: |
        docker push $IMAGE_NAME-builder-stage:latest
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - name: Logout
      run: |
        docker logout docker.pkg.github.com

เดŽเดจเตเดคเตเด•เตŠเดฃเตเดŸเดพเดฃเต เดฐเดฃเตเดŸเต เด•เดฎเดพเตปเดกเตเด•เตพ เดธเดฎเดพเดฐเด‚เดญเดฟเดšเตเดšเดคเต†เดจเตเดจเต เด†เดฆเตเดฏเด‚ เดžเด™เตเด™เตพ เดจเดฟเด™เตเด™เดณเต‹เดŸเต เดชเดฑเดฏเต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต build. เด’เดฐเต เดฎเตพเดŸเตเดŸเดฟเดธเตเดฑเตเดฑเต‡เดœเต เด…เดธเด‚เดฌเตเดฒเดฟเดฏเดฟเตฝ เดคเดคเตเดซเดฒเดฎเดพเดฏเตเดฃเตเดŸเดพเด•เตเดจเตเดจ เดšเดฟเดคเตเดฐเด‚ เด…เดตเดธเดพเดจ เด˜เดŸเตเดŸเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เด’เดฐเต เด•เต‚เดŸเตเดŸเด‚ เดชเดพเดณเดฟเด•เดณเดพเดฏเดฟเดฐเดฟเด•เตเด•เตเด‚ เดŽเดจเตเดจเดคเดพเดฃเต เดตเดธเตเดคเตเดค. เดˆ เดธเดพเดนเดšเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดฎเตเตป เดชเดพเดณเดฟเด•เดณเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดฒเต†เดฏเดฑเตเด•เตพ เดšเดฟเดคเตเดฐเดคเตเดคเดฟเตฝ เด‰เตพเดชเตเดชเต†เดŸเตเดคเตเดคเดฟเดฒเตเดฒ. เด…เดคเดฟเดจเดพเตฝ, เดฎเตเตป เดฌเดฟเตฝเดกเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เด…เดจเตเดคเดฟเดฎ เดšเดฟเดคเตเดฐเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เดจเต‹เดกเต‡เดœเตเด•เตพ (เดฌเดฟเตฝเดกเตผ เด˜เดŸเตเดŸเด‚) เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดšเดฟเดคเตเดฐเด‚ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเตป เดกเต‹เด•เตเด•เดฑเดฟเดจเต เดคเดฏเตเดฏเดพเดฑเดพเดฏ เดชเดพเดณเดฟเด•เตพ เด•เดฃเตเดŸเต†เดคเตเดคเดพเตป เด•เดดเดฟเดฏเดฟเดฒเตเดฒ. เดˆ เดชเตเดฐเดถเตเดจเด‚ เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเดพเดฏเดฟ, เด’เดฐเต เด‡เดจเตเดฑเตผเดฎเต€เดกเดฟเดฏเดฑเตเดฑเต เด‡เดฎเต‡เดœเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดจเตเดจเต $IMAGE_NAME-builder-stage เด•เต‚เดŸเดพเดคเต† GitHub เดชเดพเด•เตเด•เต‡เดœเตเด•เดณเดฟเดฒเต‡เด•เตเด•เต เดคเดณเตเดณเดชเตเดชเต†เดŸเตเด•เดฏเตเด‚, เด…เดคเตเดตเดดเดฟ เดคเตเดŸเตผเดจเตเดจเตเดณเตเดณ เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเตฝ เด’เดฐเต เด•เดพเดทเต† เด‰เดฑเดตเดฟเดŸเดฎเดพเดฏเดฟ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดจเตเด‚ เด•เดดเดฟเดฏเตเด‚.

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เดฎเตŠเดคเตเดคเด‚ เด…เดธเด‚เดฌเตเดฒเดฟ เดธเดฎเดฏเด‚ เด’เดจเตเดจเดฐ เดฎเดฟเดจเดฟเดฑเตเดฑเดพเดฏเดฟ เด•เตเดฑเดšเตเดšเต. เดฎเตเดฎเตเดชเดคเตเดคเต† เดšเดฟเดคเตเดฐเด™เตเด™เตพ เดตเดฒเดฟเดšเตเดšเต†เดŸเตเด•เตเด•เดพเตป เด…เดฐ เดฎเดฟเดจเดฟเดฑเตเดฑเต เดšเต†เดฒเดตเดดเดฟเด•เตเด•เตเดจเตเดจเต.

เดชเตเดฐเต€ เด‡เดฎเต‡เดœเดฟเด‚เด—เต

เด’เดฐเต เด•เตเดฒเต€เตป เดกเต‹เด•เตเด•เตผ เด•เดพเดทเต†เดฏเตเดŸเต† เดชเตเดฐเดถเตเดจเด‚ เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เดพเดจเตเดณเตเดณ เดฎเดฑเตเดฑเตŠเดฐเต เดฎเดพเตผเด—เตเด—เด‚, เดšเดฟเดฒ เดฒเต†เดฏเดฑเตเด•เตพ เดฎเดฑเตเดฑเตŠเดฐเต เดกเต‹เด•เตเด•เตผเดซเดฏเดฒเดฟเดฒเต‡เด•เตเด•เต เดจเต€เด•เตเด•เตเด•, เด…เดคเต เดชเตเดฐเดคเตเดฏเต‡เด•เด‚ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเด•, เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เดฐเดœเดฟเดธเตเดŸเตเดฐเดฟเดฏเดฟเดฒเต‡เด•เตเด•เต เดชเตเดทเต เดšเต†เดฏเตเดคเต เด’เดฐเต เดฐเด•เตเดทเดฟเดคเดพเดตเดพเดฏเดฟ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด• เดŽเดจเตเดจเดคเดพเดฃเต.

เด’เดฐเต เด•เต‹เดฃเต€เดฏ เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดžเด™เตเด™เดณเตเดŸเต† เดธเตเดตเดจเตเดคเด‚ เดจเต‹เดกเต‡เดœเต เด‡เดฎเต‡เดœเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจเต. เดชเตเดฐเต‹เดœเด•เตเดฑเตเดฑเดฟเตฝ Dockerfile.node เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเด•

FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++

เดกเต‹เด•เตเด•เตผ เดนเดฌเดฟเตฝ เดžเด™เตเด™เตพ เด’เดฐเต เดชเตŠเดคเต เดšเดฟเดคเตเดฐเด‚ เดถเต‡เด–เดฐเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดคเดณเตเดณเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต:

docker build -t exsmund/node-for-angular -f Dockerfile.node .
docker push exsmund/node-for-angular:latest

เด‡เดชเตเดชเต‹เตพ เดžเด™เตเด™เดณเตเดŸเต† เดชเตเดฐเดงเดพเดจ เดกเต‹เด•เตเด•เตผเดซเดฏเดฒเดฟเตฝ เดžเด™เตเด™เตพ เดชเต‚เตผเดคเตเดคเดฟเดฏเดพเด•เตเด•เดฟเดฏ เดšเดฟเดคเตเดฐเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต:

FROM exsmund/node-for-angular:latest as builder
...

เดžเด™เตเด™เดณเตเดŸเต† เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเตฝ, เดฌเดฟเตฝเดกเต เดธเดฎเดฏเด‚ เด•เตเดฑเดฏเตเดจเตเดจเดฟเดฒเตเดฒ, เดŽเดจเตเดจเดพเตฝ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดจเดฟเดฐเดตเดงเดฟ เดชเตเดฐเต‹เดœเด•เตเดŸเตเด•เตพ เด‰เดฃเตเดŸเต†เด™เตเด•เดฟเตฝ เด…เดตเดฏเดฟเตฝ เด“เดฐเต‹เดจเตเดจเดฟเดฒเตเด‚ เด’เดฐเต‡ เดกเดฟเดชเตปเดกเตปเดธเดฟเด•เตพ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต†เด™เตเด•เดฟเตฝ เดฎเตเตปเด•เต‚เดŸเตเดŸเดฟ เดจเดฟเตผเดฎเตเดฎเดฟเดšเตเดš เดšเดฟเดคเตเดฐเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดฎเดพเด•เตเด‚.

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เตพ เดŽเด™เตเด™เดจเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚ เดŽเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดจเตเดฑเตเด™เตเด™เตเด•เตพ. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 30 เดธเต†เด•เตเด•เตปเดกเต เดตเดฐเต†

เดกเต‹เด•เตเด•เตผ เด‡เดฎเต‡เดœเตเด•เดณเตเดŸเต† เดจเดฟเตผเดฎเตเดฎเดพเดฃเด‚ เดตเต‡เด—เดคเตเดคเดฟเดฒเดพเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดจเดฟเดฐเดตเดงเดฟ เดฐเต€เดคเดฟเด•เตพ เดชเดฐเดฟเดถเต‹เดงเดฟเดšเตเดšเต. เดตเดฟเดจเตเดฏเดพเดธเด‚ เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดŸเด•เตเด•เดฃเดฎเต†เด™เตเด•เดฟเตฝ, เดจเดฟเด™เตเด™เดณเตเดŸเต† เดชเตเดฐเต‹เดœเด•เตเดฑเตเดฑเดฟเตฝ เด‡เดคเต เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเตป เดถเตเดฐเดฎเดฟเด•เตเด•เตเด•:

  • เดธเดจเตเดฆเตผเดญเด‚ เด•เตเดฑเดฏเตเด•เตเด•เตเดจเตเดจเต;
  • เดšเต†เดฑเดฟเดฏ เดชเดพเดฐเดจเตเดฑเต เด‡เดฎเต‡เดœเตเด•เดณเตเดŸเต† เด‰เดชเดฏเต‹เด—เด‚;
  • เดฎเตพเดŸเตเดŸเดฟเดธเตเดฑเตเดฑเต‡เดœเต เด…เดธเด‚เดฌเตเดฒเดฟ;
  • เด•เดพเดทเต† เด•เดพเดฐเตเดฏเด•เตเดทเดฎเดฎเดพเดฏเดฟ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เดกเต‹เด•เตเด•เตผเดซเดฏเดฒเดฟเดฒเต† เดจเดฟเตผเดฆเตเดฆเต‡เดถเด™เตเด™เดณเตเดŸเต† เด•เตเดฐเดฎเด‚ เดฎเดพเดฑเตเดฑเตเดจเตเดจเต;
  • CI/CD เดธเดฟเดธเตเดฑเตเดฑเด™เตเด™เดณเดฟเตฝ เด’เดฐเต เด•เดพเดทเต† เดธเดœเตเดœเต€เด•เดฐเดฟเด•เตเด•เตเดจเตเดจเต;
  • เดšเดฟเดคเตเดฐเด™เตเด™เดณเตเดŸเต† เดชเตเดฐเดพเดฅเดฎเดฟเด• เดธเตƒเดทเตเดŸเดฟ.

เดกเต‹เด•เตเด•เตผ เดŽเด™เตเด™เดจเต† เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเตเดตเต†เดจเตเดจเต เด‰เดฆเดพเดนเดฐเดฃเด‚ เดตเตเดฏเด•เตเดคเดฎเดพเด•เตเด•เตเดฎเต†เดจเตเดจเต เดžเดพเตป เดชเตเดฐเดคเต€เด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเต, เด•เต‚เดŸเดพเดคเต† เดจเดฟเด™เตเด™เดณเตเดŸเต† เดตเดฟเดจเตเดฏเดพเดธเด‚ เด’เดชเตเดฑเตเดฑเดฟเดฎเตฝ เด•เต‹เตบเดซเดฟเด—เตผ เดšเต†เดฏเตเดฏเดพเตป เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด•เดดเดฟเดฏเตเด‚. เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เด‰เดฆเดพเดนเดฐเดฃเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด•เดณเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต, เด’เดฐเต เดถเต‡เด–เดฐเด‚ เดธเตƒเดทเตเดŸเดฟเดšเตเดšเต https://github.com/devopsprodigy/test-docker-build.

เด…เดตเดฒเด‚เดฌเด‚: www.habr.com

เด’เดฐเต เด…เดญเดฟเดชเตเดฐเดพเดฏเด‚ เดšเต‡เตผเด•เตเด•เตเด•