{"id":35043,"date":"2024-10-21T14:04:40","date_gmt":"2024-10-21T07:04:40","guid":{"rendered":"http:\/\/jupitek.maudemo.vip\/index.php\/2024\/10\/21\/how-to-create-a-dagger-pipeline-on-akamai\/"},"modified":"2024-10-21T14:04:40","modified_gmt":"2024-10-21T07:04:40","slug":"how-to-create-a-dagger-pipeline-on-akamai","status":"publish","type":"post","link":"https:\/\/jupitek.maudemo.vip\/index.php\/2024\/10\/21\/how-to-create-a-dagger-pipeline-on-akamai\/","title":{"rendered":"C\u00e1ch t\u1ea1o Dagger Pipeline tr\u00ean Akamai"},"content":{"rendered":"<p><a href=\"https:\/\/dagger.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Dagger<\/a>&nbsp;l\u00e0 m\u1ed9t \u1ee9ng d\u1ee5ng m\u00e3 ngu\u1ed3n m\u1edf v\u00e0 mi\u1ec5n ph\u00ed \u0111\u1ec3 t\u1ef1 \u0111\u1ed9ng h\u00f3a c\u00e1c \u0111\u01b0\u1eddng \u1ed1ng&nbsp;<em>T\u00edch h\u1ee3p li\u00ean t\u1ee5c\/Ph\u00e2n ph\u1ed1i li\u00ean t\u1ee5c<\/em>&nbsp;(CI\/CD). N\u00f3 cho ph\u00e9p c\u00e1c qu\u1ea3n tr\u1ecb vi\u00ean v\u00e0 nh\u00e0 ph\u00e1t tri\u1ec3n t\u1ea1o c\u00e1c t\u1eadp l\u1ec7nh \u0111\u1ec3 l\u1eafp r\u00e1p, th\u1eed nghi\u1ec7m, x\u00e2y d\u1ef1ng v\u00e0 th\u1eadm ch\u00ed xu\u1ea5t b\u1ea3n m\u1ed9t d\u1ef1 \u00e1n v\u00e0o m\u1ed9t s\u1ed5 \u0111\u0103ng k\u00fd container. Dagger bao g\u1ed3m c\u00e1c API cho m\u1ed9t s\u1ed1 ng\u00f4n ng\u1eef l\u1eadp tr\u00ecnh, cung c\u1ea5p th\u00eam s\u1ef1 ti\u1ec7n l\u1ee3i. H\u01b0\u1edbng d\u1eabn n\u00e0y cung c\u1ea5p ph\u1ea7n gi\u1edbi thi\u1ec7u ng\u1eafn g\u1ecdn v\u1ec1 Dagger v\u00e0 tr\u00ecnh b\u00e0y c\u00e1ch t\u1ea1o m\u1ed9t \u0111\u01b0\u1eddng \u1ed1ng Dagger \u0111\u01a1n gi\u1ea3n.<\/p>\n<h2 id=\"what-is-dagger\">Dagger l\u00e0 g\u00ec?<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#what-is-dagger\"><\/a><\/h2>\n<p>Dagger ban \u0111\u1ea7u \u0111\u01b0\u1ee3c t\u1ea1o ra b\u1edfi ng\u01b0\u1eddi s\u00e1ng l\u1eadp Docker. N\u00f3 cho ph\u00e9p ng\u01b0\u1eddi d\u00f9ng t\u1ef1 \u0111\u1ed9ng h\u00f3a c\u00e1c \u0111\u01b0\u1eddng \u1ed1ng s\u1ea3n xu\u1ea5t c\u1ee7a h\u1ecd b\u1eb1ng ng\u00f4n ng\u1eef m\u00e0 h\u1ecd th\u00edch. Giao di\u1ec7n Dagger cho ph\u00e9p ng\u01b0\u1eddi d\u00f9ng t\u1ea1o, x\u00e2y d\u1ef1ng, th\u1eed nghi\u1ec7m v\u00e0 ch\u1ee9a c\u00e1c \u1ee9ng d\u1ee5ng c\u1ee7a h\u1ecd th\u00f4ng qua vi\u1ec7c s\u1eed d\u1ee5ng SDK chi ti\u1ebft. Dagger ch\u1ea1y to\u00e0n b\u1ed9 \u0111\u01b0\u1eddng \u1ed1ng b\u00ean trong m\u1ed9t ho\u1eb7c nhi\u1ec1u v\u00f9ng ch\u1ee9a v\u00e0 y\u00eau c\u1ea7u Docker BuildKit backend \u0111\u1ec3 ho\u1ea1t \u0111\u1ed9ng. N\u00f3 \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf \u0111\u1ec3 s\u1eed d\u1ee5ng nh\u01b0 m\u1ed9t ph\u1ea7n c\u1ee7a \u0111\u01b0\u1eddng \u1ed1ng CI\/CD, t\u1ef1 \u0111\u1ed9ng h\u00f3a to\u00e0n b\u1ed9 v\u00f2ng \u0111\u1eddi ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng. \u0110\u01b0\u1eddng \u1ed1ng CI\/CD tr\u01b0\u1edfng th\u00e0nh cho ph\u00e9p c\u00f3 l\u1ecbch tr\u00ecnh ph\u00e2n ph\u1ed1i nhanh h\u01a1n, hi\u1ec7u qu\u1ea3 h\u01a1n v\u00e0 m\u1ea1nh m\u1ebd h\u01a1n.<\/p>\n<p>\u0110\u1ea7u ti\u00ean, t\u1eadp l\u1ec7nh nh\u1eadp g\u00f3i Dagger v\u00e0 m\u1edf m\u1ed9t phi\u00ean cho c\u00f4ng c\u1ee5 Dagger. Sau \u0111\u00f3, t\u1eadp l\u1ec7nh truy\u1ec1n c\u00e1c y\u00eau c\u1ea7u \u0111\u01b0\u1eddng \u1ed1ng \u0111\u1ebfn c\u00f4ng c\u1ee5 b\u1eb1ng giao th\u1ee9c n\u1ed9i b\u1ed9. \u0110\u1ed1i v\u1edbi m\u1ed7i y\u00eau c\u1ea7u, c\u00f4ng c\u1ee5 Dagger x\u00e1c \u0111\u1ecbnh c\u00e1c ho\u1ea1t \u0111\u1ed9ng c\u1ea7n thi\u1ebft \u0111\u1ec3 t\u00ednh to\u00e1n k\u1ebft qu\u1ea3. C\u00e1c t\u00e1c v\u1ee5 kh\u00e1c nhau \u0111\u01b0\u1ee3c ch\u1ea1y \u0111\u1ed3ng th\u1eddi \u0111\u1ec3 c\u00f3 hi\u1ec7u su\u1ea5t t\u1ed1t h\u01a1n. Sau \u0111\u00f3, c\u00e1c k\u1ebft qu\u1ea3 \u0111\u01b0\u1ee3c x\u1eed l\u00fd kh\u00f4ng \u0111\u1ed3ng b\u1ed9 v\u00e0 g\u1eedi l\u1ea1i cho t\u1eadp l\u1ec7nh khi m\u1ecdi th\u1ee9 \u0111\u00e3 \u0111\u01b0\u1ee3c gi\u1ea3i quy\u1ebft. K\u1ebft qu\u1ea3 c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c g\u00e1n cho m\u1ed9t bi\u1ebfn v\u00e0 \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng l\u00e0m \u0111\u1ea7u v\u00e0o cho c\u00e1c giai \u0111o\u1ea1n ti\u1ebfp theo c\u1ee7a \u0111\u01b0\u1eddng \u1ed1ng.<\/p>\n<p>Ngo\u00e0i vi\u1ec7c h\u1ed7 tr\u1ee3 \u0111a ng\u00f4n ng\u1eef, Dagger c\u00f2n cung c\u1ea5p m\u1ed9t s\u1ed1 l\u1ee3i th\u1ebf sau:<\/p>\n<ul>\n<li>N\u00f3 cho ph\u00e9p c\u00e1c nh\u00e0 ph\u00e1t tri\u1ec3n t\u00edch h\u1ee3p c\u00e1c b\u00e0i ki\u1ec3m tra t\u1ef1 \u0111\u1ed9ng tr\u1ef1c ti\u1ebfp v\u00e0o quy tr\u00ecnh c\u1ee7a h\u1ecd.<\/li>\n<li>V\u00ec \u0111\u01b0\u1ee3c ph\u00e1t tri\u1ec3n b\u1eb1ng ng\u00f4n ng\u1eef l\u1eadp tr\u00ecnh chu\u1ea9n, n\u00ean t\u1eadp l\u1ec7nh Dagger c\u00f3 t\u00ednh di \u0111\u1ed9ng v\u00e0 kh\u00f4ng ph\u1ee5 thu\u1ed9c v\u00e0o h\u1ec7 th\u1ed1ng. N\u00f3 c\u00f3 th\u1ec3 ch\u1ea1y tr\u00ean b\u1ea5t k\u1ef3 ki\u1ebfn \u200b\u200btr\u00fac n\u00e0o.<\/li>\n<li>C\u00e1c t\u1eadp l\u1ec7nh c\u00f3 th\u1ec3 ch\u1ea1y c\u1ee5c b\u1ed9 ho\u1eb7c t\u1eeb xa.<\/li>\n<li>Dagger l\u01b0u tr\u1eef k\u1ebft qu\u1ea3 \u0111\u1ec3 s\u1eed d\u1ee5ng sau nh\u1eb1m t\u1ed1i \u01b0u h\u00f3a hi\u1ec7u su\u1ea5t.<\/li>\n<li>N\u00f3 ho\u00e0n to\u00e0n t\u01b0\u01a1ng th\u00edch v\u00e0 t\u00edch h\u1ee3p ch\u1eb7t ch\u1ebd v\u1edbi Docker. Docker h\u1ed7 tr\u1ee3 Dagger trong vi\u1ec7c qu\u1ea3n l\u00fd s\u1ef1 ph\u1ee5 thu\u1ed9c. C\u00e1c t\u1eadp l\u1ec7nh t\u01b0\u01a1ng th\u00edch ch\u00e9o v\u1edbi nhi\u1ec1u m\u00f4i tr\u01b0\u1eddng CI\/CD kh\u00e1c.<\/li>\n<li>Ch\u1ec9 c\u1ea7n r\u1ea5t \u00edt m\u00e3 \u0111\u1ec3 ph\u00e1t tri\u1ec3n m\u1ed9t quy tr\u00ecnh ph\u1ee9c t\u1ea1p.<\/li>\n<li>T\u00f9y ch\u1ecdn c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng ti\u1ec7n \u00edch m\u1edf r\u1ed9ng Dagger CLI \u0111\u1ec3 t\u01b0\u01a1ng t\u00e1c v\u1edbi Dagger Engine t\u1eeb d\u00f2ng l\u1ec7nh.<\/li>\n<li>Dagger c\u00f3 kh\u1ea3 n\u0103ng m\u1edf r\u1ed9ng v\u00e0 c\u00f3 th\u1ec3 x\u1eed l\u00fd \u0111\u1ed3ng th\u1eddi nhi\u1ec1u \u0111\u01b0\u1eddng \u1ed1ng c\u00f3 \u0111\u1ed9 chi ti\u1ebft cao.<\/li>\n<\/ul>\n<p>V\u00ec Dagger l\u00e0 m\u1ed9t \u1ee9ng d\u1ee5ng t\u01b0\u01a1ng \u0111\u1ed1i m\u1edbi n\u00ean n\u00f3 ch\u01b0a c\u00f3 l\u01b0\u1ee3ng ng\u01b0\u1eddi d\u00f9ng r\u1ed9ng r\u00e3i ho\u1eb7c nhi\u1ec1u ph\u01b0\u01a1ng ti\u1ec7n h\u1ed7 tr\u1ee3. M\u1eb7c d\u00f9 Dagger SDK r\u1ea5t m\u1ea1nh m\u1ebd, nh\u01b0ng n\u00f3 c\u0169ng ph\u1ee9c t\u1ea1p v\u00e0 m\u1ea5t m\u1ed9t th\u1eddi gian \u0111\u1ec3 h\u1ecdc.<\/p>\n<p>Do h\u1ed7 tr\u1ee3 \u0111a ng\u00f4n ng\u1eef c\u1ee7a Dagger, c\u00e1c nh\u00e0 ph\u00e1t tri\u1ec3n c\u00f3 th\u1ec3 m\u00e3 h\u00f3a \u0111\u01b0\u1eddng \u1ed1ng c\u1ee7a h\u1ecd b\u1eb1ng ng\u00f4n ng\u1eef y\u00eau th\u00edch c\u1ee7a h\u1ecd. N\u00f3 c\u00f3 kh\u1ea3 n\u0103ng cung c\u1ea5p c\u01a1 h\u1ed9i s\u1eed d\u1ee5ng c\u00f9ng ng\u00f4n ng\u1eef l\u1eadp tr\u00ecnh v\u1edbi ng\u00f4n ng\u1eef \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng. Dagger SDK\/API c\u00f3 s\u1eb5n b\u1eb1ng c\u00e1c ng\u00f4n ng\u1eef sau:<\/p>\n<ul>\n<li><strong>Tr\u0103n<\/strong><\/li>\n<li><strong>\u0110i<\/strong><\/li>\n<li><strong>Node.js<\/strong><\/li>\n<li><strong>\u0110\u1ed3 th\u1ecb<\/strong><\/li>\n<\/ul>\n<p>Dagger \u0111\u1ec1 xu\u1ea5t Go SDK cho nh\u1eefng ai kh\u00f4ng ch\u1eafc ch\u1eafn n\u00ean s\u1eed d\u1ee5ng SDK n\u00e0o. GraphQL API kh\u00f4ng ph\u1ee5 thu\u1ed9c v\u00e0o ng\u00f4n ng\u1eef. N\u00f3 c\u00f3 th\u1ec3 \u0111\u00f3ng vai tr\u00f2 l\u00e0 m\u1ed9t khu\u00f4n kh\u1ed5 c\u1ea5p th\u1ea5p cho nh\u1eefng ai mu\u1ed1n s\u1eed d\u1ee5ng m\u1ed9t ng\u00f4n ng\u1eef m\u00e0 kh\u00f4ng c\u1ea7n API ri\u00eang.<\/p>\n<p>\u0110\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin c\u01a1 b\u1ea3n v\u1ec1 Dagger, h\u00e3y xem&nbsp;<a href=\"https:\/\/docs.dagger.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">T\u00e0i li\u1ec7u Dagger<\/a>&nbsp;v\u00e0&nbsp;<a href=\"https:\/\/docs.dagger.io\/7442989\/cookbook\/\" target=\"_blank\" rel=\"noreferrer noopener\">S\u00e1ch h\u01b0\u1edbng d\u1eabn Dagger<\/a>&nbsp;.<\/p>\n<h2 id=\"before-you-begin\">Tr\u01b0\u1edbc khi b\u1ea1n b\u1eaft \u0111\u1ea7u<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#before-you-begin\"><\/a><\/h2>\n<ol>\n<li>N\u1ebfu b\u1ea1n ch\u01b0a th\u1ef1c hi\u1ec7n, h\u00e3y t\u1ea1o m\u1ed9t t\u00e0i kho\u1ea3n Linode v\u00e0 Compute Instance. Xem h\u01b0\u1edbng d\u1eabn&nbsp;<a href=\"https:\/\/www.linode.com\/docs\/products\/platform\/get-started\/\">B\u1eaft \u0111\u1ea7u v\u1edbi Linode<\/a>&nbsp;v\u00e0&nbsp;<a href=\"https:\/\/www.linode.com\/docs\/products\/compute\/compute-instances\/guides\/create\/\">T\u1ea1o Compute Instance<\/a>&nbsp;c\u1ee7a ch\u00fang t\u00f4i .<\/li>\n<li>L\u00e0m theo h\u01b0\u1edbng d\u1eabn&nbsp;<a href=\"https:\/\/www.linode.com\/docs\/products\/compute\/compute-instances\/guides\/set-up-and-secure\/\">Thi\u1ebft l\u1eadp v\u00e0 B\u1ea3o m\u1eadt Phi\u00ean b\u1ea3n Compute<\/a>&nbsp;c\u1ee7a ch\u00fang t\u00f4i \u0111\u1ec3 c\u1eadp nh\u1eadt h\u1ec7 th\u1ed1ng c\u1ee7a b\u1ea1n. B\u1ea1n c\u0169ng c\u00f3 th\u1ec3 mu\u1ed1n \u0111\u1eb7t m\u00fai gi\u1edd, c\u1ea5u h\u00ecnh t\u00ean m\u00e1y ch\u1ee7, t\u1ea1o t\u00e0i kho\u1ea3n ng\u01b0\u1eddi d\u00f9ng gi\u1edbi h\u1ea1n v\u00e0 t\u0103ng c\u01b0\u1eddng quy\u1ec1n truy c\u1eadp SSH.<\/li>\n<li>\u0110\u1ec3 xu\u1ea5t b\u1ea3n container, b\u1ea1n ph\u1ea3i c\u00f3 quy\u1ec1n truy c\u1eadp v\u00e0o s\u1ed5 \u0111\u0103ng k\u00fd container. H\u01b0\u1edbng d\u1eabn n\u00e0y s\u1eed d\u1ee5ng s\u1ed5 \u0111\u0103ng k\u00fd&nbsp;<a href=\"https:\/\/goharbor.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Harbor<\/a>&nbsp;ngu\u1ed3n m\u1edf \u0111\u1ec3 xu\u1ea5t b\u1ea3n container. Tuy nhi\u00ean, c\u00f3 th\u1ec3 \u0111\u1ea9y container v\u00e0o b\u1ea5t k\u1ef3 kho l\u01b0u tr\u1eef container n\u00e0o. \u0110\u1ec3 bi\u1ebft th\u00f4ng tin v\u1ec1 c\u00e1ch t\u1ea1o s\u1ed5 \u0111\u0103ng k\u00fd Harbor tr\u00ean m\u1ed9t Compute Instance ri\u00eang bi\u1ec7t, h\u00e3y xem h\u01b0\u1edbng d\u1eabn v\u1ec1&nbsp;<a href=\"https:\/\/www.linode.com\/docs\/marketplace-docs\/guides\/harbor\/\">Tri\u1ec3n khai Harbor th\u00f4ng qua Linode Marketplace<\/a>&nbsp;. Tr\u01b0\u1edbc khi s\u1eed d\u1ee5ng Harbor, c\u1ea7n t\u1ea1o m\u1ed9t d\u1ef1 \u00e1n c\u00f3 t\u00ean l\u00e0&nbsp;<code>dagger<\/code>l\u01b0u tr\u1eef container m\u1eabu.<\/li>\n<\/ol>\n<p>Ghi ch\u00faH\u01b0\u1edbng d\u1eabn n\u00e0y \u0111\u01b0\u1ee3c vi\u1ebft cho ng\u01b0\u1eddi d\u00f9ng kh\u00f4ng ph\u1ea3i root. C\u00e1c l\u1ec7nh y\u00eau c\u1ea7u quy\u1ec1n n\u00e2ng cao \u0111\u01b0\u1ee3c th\u00eam ti\u1ec1n t\u1ed1&nbsp;<\/p>\n<p><code>sudo<\/code>. N\u1ebfu b\u1ea1n kh\u00f4ng quen v\u1edbi&nbsp;<\/p>\n<p><code>sudo<\/code>l\u1ec7nh, h\u00e3y xem h\u01b0\u1edbng d\u1eabn&nbsp;<\/p>\n<p><a href=\"https:\/\/www.linode.com\/docs\/guides\/linux-users-and-groups\/\">Ng\u01b0\u1eddi d\u00f9ng v\u00e0 Nh\u00f3m<\/a>&nbsp;.<\/p>\n<h2 id=\"how-to-install-dagger\">C\u00e1ch c\u00e0i \u0111\u1eb7t Dagger<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#how-to-install-dagger\"><\/a><\/h2>\n<p>Dagger y\u00eau c\u1ea7u s\u1eed d\u1ee5ng Docker. H\u01b0\u1edbng d\u1eabn n\u00e0y s\u1eed d\u1ee5ng Python SDK \u0111\u1ec3 bi\u00ean so\u1ea1n t\u1eadp l\u1ec7nh. M\u00f4-\u0111un Dagger cho Python \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t b\u1eb1ng&nbsp;<code>pip<\/code>, tr\u00ecnh qu\u1ea3n l\u00fd g\u00f3i Python. H\u01b0\u1edbng d\u1eabn n\u00e0y \u0111\u01b0\u1ee3c vi\u1ebft cho ng\u01b0\u1eddi d\u00f9ng Ubuntu 22.04 LTS, nh\u01b0ng th\u01b0\u1eddng \u00e1p d\u1ee5ng cho h\u1ea7u h\u1ebft c\u00e1c b\u1ea3n ph\u00e1t h\u00e0nh g\u1ea7n \u0111\u00e2y v\u00e0 c\u00e1c b\u1ea3n ph\u00e2n ph\u1ed1i Linux kh\u00e1c. \u0110\u1ec3 c\u00e0i \u0111\u1eb7t Dagger, h\u00e3y l\u00e0m theo c\u00e1c b\u01b0\u1edbc sau.<\/p>\n<p>1.C\u00e0i \u0111\u1eb7t m\u1ecdi b\u1ea3n c\u1eadp nh\u1eadt \u0111\u1ec3 \u0111\u1ea3m b\u1ea3o h\u1ec7 th\u1ed1ng \u0111\u01b0\u1ee3c c\u1eadp nh\u1eadt:<\/p>\n<pre class=\"wp-block-code\"><code>sudo apt update -y <strong>&amp;&amp;<\/strong> sudo apt upgrade -y<\/code><\/pre>\n<p>Sau \u0111\u00f3, h\u00e3y kh\u1edfi \u0111\u1ed9ng l\u1ea1i h\u1ec7 th\u1ed1ng n\u1ebfu \u0111\u01b0\u1ee3c y\u00eau c\u1ea7u.<\/p>\n<p>2.\u0110\u1ea3m b\u1ea3o&nbsp;<code>git<\/code>\u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t tr\u00ean h\u1ec7 th\u1ed1ng:<\/p>\n<pre class=\"wp-block-code\"><code>sudo apt install git<\/code><\/pre>\n<p>3.\u0110\u1ec3 chu\u1ea9n b\u1ecb cho vi\u1ec7c c\u00e0i \u0111\u1eb7t Docker v2, h\u00e3y x\u00f3a m\u1ecdi b\u1ea3n ph\u00e1t h\u00e0nh c\u0169 h\u01a1n c\u1ee7a \u1ee9ng d\u1ee5ng r\u1ed3i c\u00e0i \u0111\u1eb7t m\u1ed9t s\u1ed1 th\u00e0nh ph\u1ea7n b\u1ed5 sung:<\/p>\n<pre class=\"wp-block-code\"><code>sudo apt remove docker docker-engine docker.io containerd runc\nsudo apt install ca-certificates curl gnupg lsb-release<\/code><\/pre>\n<p>4.Th\u00eam kh\u00f3a GPG Docker ch\u00ednh th\u1ee9c \u0111\u1ec3 gi\u00fap x\u00e1c th\u1ef1c c\u00e0i \u0111\u1eb7t:<\/p>\n<pre class=\"wp-block-code\"><code>sudo mkdir -m 0755 -p \/etc\/apt\/keyrings\ncurl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg | sudo gpg --dearmor -o \/etc\/apt\/keyrings\/docker.gpg<\/code><\/pre>\n<p>5.Th\u00eam kho l\u01b0u tr\u1eef Docker v\u00e0o&nbsp;<code>apt<\/code>, sau \u0111\u00f3 c\u1eadp nh\u1eadt danh s\u00e1ch g\u00f3i:<\/p>\n<pre class=\"wp-block-code\"><code>echo \"deb &#91;arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/docker.gpg] https:\/\/download.docker.com\/linux\/ubuntu \\\n$(lsb_release -cs) stable\" | sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null\nsudo apt update<\/code><\/pre>\n<p>6.C\u00e0i \u0111\u1eb7t phi\u00ean b\u1ea3n m\u1edbi nh\u1ea5t c\u1ee7a Docker Engine v\u00e0 CLI c\u00f9ng v\u1edbi m\u1ed9t s\u1ed1 g\u00f3i li\u00ean quan:<\/p>\n<pre class=\"wp-block-code\"><code>sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin<\/code><\/pre>\n<p>7.\u0110\u1ec3 \u0111\u1ea3m b\u1ea3o Docker ho\u1ea1t \u0111\u1ed9ng ch\u00ednh x\u00e1c, h\u00e3y ch\u1ea1y&nbsp;<code>hello-world<\/code>container:<\/p>\n<pre class=\"wp-block-code\"><code>sudo docker run hello-world<\/code><\/pre>\n<p>N\u1ebfu m\u1ecdi th\u1ee9 \u0111\u1ec1u ho\u1ea1t \u0111\u1ed9ng, container s\u1ebd hi\u1ec3n th\u1ecb th\u00f4ng b\u00e1o&nbsp;<code>Hello from Docker!<\/code>:<\/p>\n<pre class=\"wp-block-code\"><code>Hello from Docker!\nThis message shows that your installation appears to be working correctly.<\/code><\/pre>\n<p>8.C\u00e0i \u0111\u1eb7t Dagger SDK cho ng\u00f4n ng\u1eef l\u1eadp tr\u00ecnh ph\u00f9 h\u1ee3p. H\u01b0\u1edbng d\u1eabn n\u00e0y s\u1eed d\u1ee5ng Python \u0111\u1ec3 t\u1ea1o \u1ee9ng d\u1ee5ng v\u00ed d\u1ee5, v\u00ec v\u1eady c\u00e1c b\u01b0\u1edbc ti\u1ebfp theo s\u1ebd gi\u1ea3i th\u00edch c\u00e1ch t\u1ea3i xu\u1ed1ng Python SDK. S\u1eed d\u1ee5ng&nbsp;<code>pip<\/code>\u0111\u1ec3 c\u00e0i \u0111\u1eb7t&nbsp;<code>dagger-io<\/code>m\u00f4-\u0111un. N\u1ebfu&nbsp;<code>pip<\/code>ch\u01b0a c\u00e0i \u0111\u1eb7t, c\u00f3 th\u1ec3 th\u00eam b\u1eb1ng l\u1ec7nh&nbsp;<code>sudo apt install python3-pip<\/code>. Y\u00eau c\u1ea7u Python b\u1ea3n ph\u00e1t h\u00e0nh 3.10.<\/p>\n<p>T\u00f9y ch\u1ecdn b\u1eaft bu\u1ed9c<\/p>\n<p>Dagger s\u1eed d\u1ee5ng Docker \u0111\u1ec3 t\u1ea1o m\u1ed9t container, nh\u01b0ng&nbsp;<code>sudo<\/code>th\u00f4ng th\u01b0\u1eddng l\u00e0 b\u1eaft bu\u1ed9c \u0111\u1ec3 ch\u1ea1y Docker. \u0110i\u1ec1u n\u00e0y c\u00f3 ngh\u0129a l\u00e0 g\u00f3i Python&nbsp;<code>dagger-io<\/code>ph\u1ea3i c\u00f3 th\u1ec3 truy c\u1eadp \u0111\u01b0\u1ee3c \u0111\u1ed1i v\u1edbi ng\u01b0\u1eddi d\u00f9ng root. Th\u1eadt kh\u00f4ng may, Python c\u00e0i \u0111\u1eb7t c\u00e1c m\u00f4-\u0111un c\u1ee5c b\u1ed9 theo m\u1eb7c \u0111\u1ecbnh. C\u00f3 m\u1ed9t v\u00e0i c\u00e1ch \u0111\u1ec3 gi\u1ea3i quy\u1ebft v\u1ea5n \u0111\u1ec1 n\u00e0y:<\/p>\n<p>Ph\u01b0\u01a1ng ph\u00e1p nhanh nh\u1ea5t l\u00e0 c\u00e0i \u0111\u1eb7t&nbsp;<code>dagger-io<\/code>g\u00f3i tr\u00ean to\u00e0n c\u1ea7u b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng&nbsp;<code>pip -H<\/code>c\u1edd. \u0110i\u1ec1u n\u00e0y \u0111\u1ea3m b\u1ea3o r\u1eb1ng t\u1ea5t c\u1ea3 ng\u01b0\u1eddi d\u00f9ng \u0111\u1ec1u c\u00f3 th\u1ec3 truy c\u1eadp \u0111\u01b0\u1ee3c. Th\u1eadt kh\u00f4ng may, vi\u1ec7c s\u1eed d\u1ee5ng&nbsp;<code>pip<\/code>tr\u00ean to\u00e0n c\u1ea7u c\u00f3 th\u1ec3 d\u1eabn \u0111\u1ebfn c\u00e1c v\u1ea5n \u0111\u1ec1 ph\u1ee9c t\u1ea1p v\u00e0 kh\u00f3 hi\u1ec3u v\u1ec1 quy\u1ec1n. K\u1ef9 thu\u1eadt n\u00e0y n\u00ean \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng h\u1ebft s\u1ee9c c\u1ea9n th\u1eadn, \u0111\u1eb7c bi\u1ec7t l\u00e0 trong m\u00f4i tr\u01b0\u1eddng nhi\u1ec1u ng\u01b0\u1eddi d\u00f9ng. \u0110\u1ec3 c\u00e0i \u0111\u1eb7t g\u00f3i tr\u00ean to\u00e0n c\u1ea7u, h\u00e3y s\u1eed d\u1ee5ng l\u1ec7nh n\u00e0y thay v\u00ec l\u1ec7nh b\u00ean d\u01b0\u1edbi:<\/p>\n<pre class=\"wp-block-code\"><code>sudo -H pip install dagger-io<\/code><\/pre>\n<p>M\u1ed9t gi\u1ea3i ph\u00e1p thay th\u1ebf t\u1ed1t h\u01a1n l\u00e0 th\u00eam ng\u01b0\u1eddi d\u00f9ng hi\u1ec7n t\u1ea1i v\u00e0o&nbsp;<code>docker<\/code>nh\u00f3m. \u0110i\u1ec1u n\u00e0y cho ph\u00e9p ng\u01b0\u1eddi d\u00f9ng truy c\u1eadp Docker m\u00e0 kh\u00f4ng c\u1ea7n quy\u1ec1n root, nh\u01b0ng \u0111i\u1ec1u n\u00e0y y\u00eau c\u1ea7u ph\u1ea3i kh\u1edfi \u0111\u1ed9ng l\u1ea1i \u0111\u1ec3 c\u00f3 hi\u1ec7u l\u1ef1c. H\u01b0\u1edbng d\u1eabn n\u00e0y ti\u1ebfn h\u00e0nh nh\u01b0 th\u1ec3 ng\u01b0\u1eddi d\u00f9ng \u0111\u00e3 \u0111\u01b0\u1ee3c th\u00eam v\u00e0o&nbsp;<code>docker<\/code>nh\u00f3m v\u00e0 c\u00e0i \u0111\u1eb7t&nbsp;<code>dagger-io<\/code>c\u1ee5c b\u1ed9. \u0110\u1ec3 th\u00eam ng\u01b0\u1eddi d\u00f9ng hi\u1ec7n t\u1ea1i v\u00e0o&nbsp;<code>docker<\/code>nh\u00f3m, h\u00e3y s\u1eed d\u1ee5ng c\u00fa ph\u00e1p l\u1ec7nh sau, thay th\u1ebf&nbsp;<code>example-username<\/code>b\u1eb1ng t\u00ean ng\u01b0\u1eddi d\u00f9ng th\u1ef1c t\u1ebf c\u1ee7a b\u1ea1n:<\/p>\n<pre class=\"wp-block-code\"><code>sudo usermod -aG docker example-username<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>pip install dagger-io<\/code><\/pre>\n<p class=\"has-background\" style=\"background-color:#74f78c33\">Ghi ch\u00fa: SDK c\u0169ng kh\u1ea3 d\u1ee5ng cho Node.js v\u00e0 Go. \u0110\u1ec3 c\u00e0i \u0111\u1eb7t Go SDK, h\u00e3y s\u1eed d\u1ee5ng l\u1ec7nh&nbsp;<code>go mod init main<\/code>v\u00e0&nbsp;<code>go get dagger.io\/dagger<\/code>. \u0110\u1ed1i v\u1edbi Node.js SDK, h\u00e3y s\u1eed d\u1ee5ng&nbsp;<code>npm install @dagger.io\/dagger --save-dev<\/code>.<\/p>\n<h2 id=\"how-to-create-a-sample-dagger-pipeline\">C\u00e1ch t\u1ea1o \u0111\u01b0\u1eddng \u1ed1ng Dagger m\u1eabu<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#how-to-create-a-sample-dagger-pipeline\"><\/a><\/h2>\n<p>H\u01b0\u1edbng d\u1eabn n\u00e0y s\u1eed d\u1ee5ng Python SDK \u0111\u1ec3 t\u1ea1o m\u1ed9t v\u00ed d\u1ee5 v\u1ec1 \u0111\u01b0\u1eddng \u1ed1ng Dagger CI\/CD. \u0110\u1ec3 \u0111\u01a1n gi\u1ea3n h\u00f3a quy tr\u00ecnh, h\u01b0\u1edbng d\u1eabn n\u00e0y s\u1eed d\u1ee5ng&nbsp;<code>hello-dagger<\/code>\u1ee9ng d\u1ee5ng demo \u0111\u1ec3 tr\u00ecnh b\u00e0y c\u00e1c b\u01b0\u1edbc ch\u00ednh. Dagger khuy\u00ean b\u1ea1n n\u00ean s\u1eed d\u1ee5ng \u1ee9ng d\u1ee5ng n\u00e0y khi h\u1ecdc c\u00e1ch t\u1ea1o \u0111\u01b0\u1eddng \u1ed1ng. Tuy nhi\u00ean, b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng b\u1ea5t k\u1ef3 \u1ee9ng d\u1ee5ng n\u00e0o cho b\u1ea3n demo, mi\u1ec5n l\u00e0 c\u00f3 c\u00e1c b\u1ea3n c\u1eadp nh\u1eadt t\u1eadp l\u1ec7nh ph\u00f9 h\u1ee3p.<\/p>\n<p>\u0110\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 Python SDK ho\u1eb7c \u0111\u1ec3 t\u00f9y ch\u1ec9nh th\u00eam \u1ee9ng d\u1ee5ng, h\u00e3y xem&nbsp;<a href=\"https:\/\/docs.dagger.io\/sdk\/python\" target=\"_blank\" rel=\"noreferrer noopener\">t\u00e0i li\u1ec7u Dagger Python SDK<\/a>&nbsp;. Xem&nbsp;<a href=\"https:\/\/docs.dagger.io\/593914\/quickstart-hello\/\" target=\"_blank\" rel=\"noreferrer noopener\">b\u1ea3n demo Dagger Quickstart<\/a>&nbsp;\u0111\u1ec3 bi\u1ebft th\u00f4ng tin v\u1ec1 c\u00e1ch t\u1ea1o \u0111\u01b0\u1eddng \u1ed1ng n\u00e0y b\u1eb1ng Go ho\u1eb7c Node.<\/p>\n<p>\u0110\u1ec3 t\u1ea1o \u0111\u01b0\u1eddng \u1ed1ng Dagger trong Python, h\u00e3y l\u00e0m theo c\u00e1c b\u01b0\u1edbc sau.<\/p>\n<h3 id=\"download-the-example-application\">T\u1ea3i xu\u1ed1ng \u1ee9ng d\u1ee5ng m\u1eabu<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#download-the-example-application\"><\/a><\/h3>\n<p>Dagger \u0111\u00e3 ph\u00e1t tri\u1ec3n m\u1ed9t \u1ee9ng d\u1ee5ng React m\u1eabu c\u00f3 t\u00ean&nbsp;<code>hello-dagger<\/code>l\u00e0 c\u00f4ng c\u1ee5 h\u1ed7 tr\u1ee3 gi\u1ea3ng d\u1ea1y. \u0110\u1ec3 b\u1eaft \u0111\u1ea7u, h\u00e3y t\u1ea3i xu\u1ed1ng \u1ee9ng d\u1ee5ng t\u1eeb GitHub b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng&nbsp;<code>git<\/code>.<\/p>\n<p>1.Sao ch\u00e9p \u1ee9ng d\u1ee5ng t\u1eeb GitHub:<\/p>\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/dagger\/hello-dagger.git<\/code><\/pre>\n<p>2.Chuy\u1ec3n sang th\u01b0 m\u1ee5c m\u1edbi&nbsp;<code>hello-dagger<\/code>v\u00e0 t\u1ea1o m\u1ed9t&nbsp;<code>ci<\/code>th\u01b0 m\u1ee5c m\u1edbi \u0111\u1ec3 ch\u1ee9a c\u00e1c t\u1eadp l\u1ec7nh:<\/p>\n<pre class=\"wp-block-code\"><code>cd hello-dagger\nmkdir ci<\/code><\/pre>\n<h3 id=\"create-and-test-a-dagger-pipeline-for-the-application\">T\u1ea1o v\u00e0 ki\u1ec3m tra \u0111\u01b0\u1eddng \u1ed1ng Dagger cho \u1ee9ng d\u1ee5ng<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#create-and-test-a-dagger-pipeline-for-the-application\"><\/a><\/h3>\n<p>M\u00e1y kh\u00e1ch Dagger cho ph\u00e9p ng\u01b0\u1eddi d\u00f9ng t\u1ea1o ch\u01b0\u01a1ng tr\u00ecnh Python nhi\u1ec1u giai \u0111o\u1ea1n \u0111\u1ec3 x\u00e1c \u0111\u1ecbnh, ki\u1ec3m tra v\u00e0 x\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng. Ph\u1ea7n n\u00e0y c\u1ee7a h\u01b0\u1edbng d\u1eabn ch\u01b0a c\u00f4ng b\u1ed1 \u1ee9ng d\u1ee5ng. \u0110i\u1ec1u quan tr\u1ecdng l\u00e0 ph\u1ea3i ki\u1ec3m tra \u1ee9ng d\u1ee5ng tr\u01b0\u1edbc \u0111\u1ec3 \u0111\u1ea3m b\u1ea3o \u1ee9ng d\u1ee5ng \u0111\u01b0\u1ee3c x\u00e2y d\u1ef1ng \u0111\u00fang c\u00e1ch. \u0110\u1ec3 t\u1ea1o \u0111\u01b0\u1eddng \u1ed1ng m\u1edbi, h\u00e3y l\u00e0m theo c\u00e1c b\u01b0\u1edbc sau.<\/p>\n<p>1.\u0110i\u1ec1u h\u01b0\u1edbng \u0111\u1ebfn&nbsp;<code>hello-dagger\/ci<\/code>th\u01b0 m\u1ee5c, t\u1ea1o m\u1ed9t&nbsp;<code>main.py<\/code>t\u1ec7p d\u1ef1 \u00e1n Python m\u1edbi v\u00e0 m\u1edf t\u1ec7p trong&nbsp;<code>nano<\/code>tr\u00ecnh so\u1ea1n th\u1ea3o v\u0103n b\u1ea3n:<\/p>\n<pre class=\"wp-block-code\"><code>cd ~\/hello-dagger\/ci\nnano main.py<\/code><\/pre>\n<p>2.\u1ede \u0111\u1ea7u t\u1ec7p, th\u00eam&nbsp;<code>import<\/code>c\u00e1c c\u00e2u l\u1ec7nh b\u1eaft bu\u1ed9c, bao g\u1ed3m&nbsp;<code>import dagger<\/code>l\u1ec7nh \u0111\u1ec3 nh\u1eadp Dagger SDK:<\/p>\n<pre class=\"wp-block-code\"><code>import sys\nimport anyio\nimport dagger<\/code><\/pre>\n<p>3.X\u00e1c \u0111\u1ecbnh m\u1ed9t&nbsp;<code>main<\/code>th\u00f3i quen, t\u1ea1o m\u1ed9t \u0111\u1ed1i t\u01b0\u1ee3ng c\u1ea5u h\u00ecnh Dagger v\u00e0 x\u00e1c \u0111\u1ecbnh&nbsp;<code>stdout<\/code>l\u00e0 lu\u1ed3ng \u0111\u1ea7u ra:<\/p>\n<pre class=\"wp-block-code\"><code>async def main():\n    config = dagger.Config(log_output=sys.stdout)<\/code><\/pre>\n<p>T\u1ea1o m\u1ed9t m\u00e1y kh\u00e1ch Dagger b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng&nbsp;<code>dagger.Connection<\/code>, truy\u1ec1n cho n\u00f3&nbsp;<code>config<\/code>\u0111\u1ed1i t\u01b0\u1ee3ng l\u00e0m c\u1ea5u h\u00ecnh m\u1eb7c \u0111\u1ecbnh. T\u1ea1o m\u1ed9t v\u00f9ng ch\u1ee9a m\u00e1y kh\u00e1ch m\u1edbi v\u1edbi c\u00e1c tham s\u1ed1 sau:<\/p>\n<ul>\n<li>\u0110\u1eb7t container d\u1ef1a tr\u00ean&nbsp;<code>node:16-slim<\/code>h\u00ecnh \u1ea3nh b\u1eb1ng&nbsp;<code>from_<\/code>ph\u01b0\u01a1ng ph\u00e1p n\u00e0y. Ph\u01b0\u01a1ng ph\u00e1p n\u00e0y c\u0169ng kh\u1edfi t\u1ea1o container.<\/li>\n<li>S\u1eed d\u1ee5ng&nbsp;<code>with_directory<\/code>ph\u01b0\u01a1ng ph\u00e1p n\u00e0y \u0111\u1ec3 ch\u1ec9 \u0111\u1ecbnh c\u1ea3 th\u01b0 m\u1ee5c d\u00f9ng l\u00e0m ngu\u1ed3n v\u00e0 v\u1ecb tr\u00ed g\u1eafn k\u1ebft b\u00ean trong v\u00f9ng ch\u1ee9a.<\/li>\n<li>Ch\u1ec9 \u0111\u1ecbnh th\u01b0 m\u1ee5c hi\u1ec7n t\u1ea1i l\u00e0m ngu\u1ed3n c\u1ee7a \u1ee9ng d\u1ee5ng b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng chu\u1ed7i&nbsp;<code>client.host().directory(\".\")<\/code>.<\/li>\n<li>G\u1eafn \u1ee9ng d\u1ee5ng v\u00e0o b\u00ean trong&nbsp;<code>\/src<\/code>th\u01b0 m\u1ee5c c\u1ee7a v\u00f9ng ch\u1ee9a.<\/li>\n<li>Lo\u1ea1i tr\u1eeb c\u00e1c th\u01b0 m\u1ee5c&nbsp;<code>node_modules<\/code>v\u00e0&nbsp;<code>ci<\/code>n\u1ed9i dung kh\u00f4ng li\u00ean quan kh\u1ecfi quy tr\u00ecnh n\u00e0y.<\/li>\n<\/ul>\n<p>Th\u00eam c\u00e1c d\u00f2ng sau v\u00e0o t\u1ec7p \u0111\u1ec3 g\u1eafn m\u00e3 ngu\u1ed3n v\u00e0o th\u01b0&nbsp;<code>src<\/code>m\u1ee5c c\u1ee7a&nbsp;<code>node:16-slim<\/code>v\u00f9ng ch\u1ee9a:<\/p>\n<pre class=\"wp-block-code\"><code>async with dagger.Connection(config) as client:\n    source = (\n        client.container()\n        .from_(\"node:16-slim\")\n        .with_directory(\n            \"\/src\",\n            client.host().directory(\".\"),\n            exclude=&#91;\"node_modules\/\", \"ci\/\"],\n        )\n    )<\/code><\/pre>\n<p class=\"has-background\" style=\"background-color:#74f78c33\">Ghi ch\u00fa: Dagger Python SDK s\u1eed d\u1ee5ng r\u1ed9ng r\u00e3i m\u1ed9t k\u1ef9 thu\u1eadt \u0111\u01b0\u1ee3c g\u1ecdi l\u00e0&nbsp;<em>ph\u01b0\u01a1ng th\u1ee9c n\u1ed1i chu\u1ed7i<\/em>&nbsp;. C\u00e1c ph\u01b0\u01a1ng th\u1ee9c \u0111\u01b0\u1ee3c x\u1eed l\u00fd theo th\u1ee9 t\u1ef1 xu\u1ea5t hi\u1ec7n. C\u00e1c ph\u01b0\u01a1ng th\u1ee9c ti\u1ebfp theo t\u00e1c \u0111\u1ed9ng l\u00ean \u0111\u1ed1i t\u01b0\u1ee3ng \u0111\u01b0\u1ee3c tr\u1ea3 v\u1ec1 trong ph\u01b0\u01a1ng th\u1ee9c tr\u01b0\u1edbc \u0111\u00f3.<\/p>\n<p>5.Giai \u0111o\u1ea1n ti\u1ebfp theo c\u1ee7a pipeline s\u1eed d\u1ee5ng&nbsp;<code>npm install<\/code>\u0111\u1ec3 c\u00e0i \u0111\u1eb7t c\u00e1c ph\u1ee5 thu\u1ed9c \u1ee9ng d\u1ee5ng b\u00ean trong container.&nbsp;<code>with_workdir<\/code>Ph\u01b0\u01a1ng ph\u00e1p n\u00e0y cho Dagger bi\u1ebft n\u01a1i b\u00ean trong container \u0111\u1ec3 ch\u1ea1y l\u1ec7nh.&nbsp;<code>with_exec<\/code>Ph\u01b0\u01a1ng ph\u00e1p n\u00e0y cho Dagger bi\u1ebft ch\u1ea1y&nbsp;<code>npm install<\/code>t\u1ea1i v\u1ecb tr\u00ed \u0111\u00f3. Th\u00eam c\u00e1c d\u00f2ng sau v\u00e0o t\u1eadp l\u1ec7nh:<\/p>\n<pre class=\"wp-block-code\"><code>runner = source.with_workdir(\"\/src\").with_exec(&#91;\"npm\", \"install\"])<\/code><\/pre>\n<p>6.Ph\u1ea7n cu\u1ed1i c\u00f9ng c\u1ee7a t\u1eadp l\u1ec7nh Python t\u1ef1 \u0111\u1ed9ng ch\u1ea1y m\u1ed9t b\u1ed9 ki\u1ec3m th\u1eed \u0111\u1ed1i v\u1edbi \u1ee9ng d\u1ee5ng. L\u1ec7nh n\u00e0y s\u1eed d\u1ee5ng&nbsp;<code>with_exec<\/code>l\u1ea1i ph\u01b0\u01a1ng ph\u00e1p n\u00e0y, v\u1edbi&nbsp;<code>npm test --watchAll=false<\/code>t\u01b0 c\u00e1ch l\u00e0 l\u1ec7nh ki\u1ec3m th\u1eed. N\u1ebfu l\u1ed7i x\u1ea3y ra, th\u00f4ng tin chi ti\u1ebft s\u1ebd \u0111\u01b0\u1ee3c in ra b\u1ea3ng \u0111i\u1ec1u khi\u1ec3n th\u00f4ng qua&nbsp;<code>stderr<\/code>lu\u1ed3ng v\u00e0 \u0111\u01b0\u1eddng \u1ed1ng s\u1ebd k\u1ebft th\u00fac. \u1ede cu\u1ed1i t\u1ec7p, h\u00e3y th\u00eam l\u1ec7nh g\u1ecdi v\u00e0o&nbsp;<code>main<\/code>quy tr\u00ecnh:<\/p>\n<pre class=\"wp-block-code\"><code>        out = await runner.with_exec(&#91;\"npm\", \"test\", \"--\", \"--watchAll=false\"]).stderr()\n        print(out)\n\nanyio.run(main)<\/code><\/pre>\n<p>7.To\u00e0n b\u1ed9 t\u1eadp tin s\u1ebd tr\u00f4ng nh\u01b0 th\u1ebf n\u00e0y:<\/p>\n<pre class=\"wp-block-code\"><code>import sys\nimport anyio\nimport dagger\n\nasync def main():\n    config = dagger.Config(log_output=sys.stdout)\n\n    async with dagger.Connection(config) as client:\n        source = (\n            client.container()\n            .from_(\"node:16-slim\")\n            .with_directory(\n                \"\/src\",\n                client.host().directory(\".\"),\n                exclude=&#91;\"node_modules\/\", \"ci\/\"],\n            )\n        )\n\n        runner = source.with_workdir(\"\/src\").with_exec(&#91;\"npm\", \"install\"])\n\n        out = await runner.with_exec(&#91;\"npm\", \"test\", \"--\", \"--watchAll=false\"]).stderr()\n        print(out)\n\nanyio.run(main)<\/code><\/pre>\n<p>\u0110\u1ea3m b\u1ea3o th\u1ee5t l\u1ec1 \u0111\u00fang c\u00e1ch \u1edf m\u1ed7i d\u00f2ng.<\/p>\n<p>Khi ho\u00e0n t\u1ea5t, nh\u1ea5n&nbsp;<kbd>CTRL<\/kbd>+&nbsp;<kbd>X<\/kbd>, ti\u1ebfp theo l\u00e0&nbsp;<kbd>Y<\/kbd>then&nbsp;<kbd>Enter<\/kbd>\u0111\u1ec3 l\u01b0u t\u1ec7p v\u00e0 tho\u00e1t&nbsp;<code>nano<\/code>.<\/p>\n<p>8.Quay l\u1ea1i&nbsp;<code>hello-dagger<\/code>th\u01b0 m\u1ee5c d\u1ef1 \u00e1n ch\u00ednh v\u00e0 ch\u1ea1y t\u1eadp l\u1ec7nh Python b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng&nbsp;<code>python3 ci\/main.py<\/code>:<\/p>\n<pre class=\"wp-block-code\"><code>cd ~\/hello-dagger\npython3 ci\/main.py<\/code><\/pre>\n<p>Kh\u00f4ng c\u00f3 l\u1ed7i n\u00e0o \u0111\u01b0\u1ee3c ph\u00e1t hi\u1ec7n v\u00e0 t\u1ea5t c\u1ea3&nbsp;<code>npm<\/code>c\u00e1c b\u00e0i ki\u1ec3m tra \u0111\u1ec1u ph\u1ea3i v\u01b0\u1ee3t qua:<\/p>\n<pre class=\"wp-block-code\"><code>Test Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        3.896 s\nRan all test suites.<\/code><\/pre>\n<p class=\"has-background\" style=\"background-color:#74f78c33\">Ghi ch\u00fa: V\u00ec Dagger tr\u01b0\u1edbc ti\u00ean ph\u1ea3i y\u00eau c\u1ea7u Docker t\u1ea3i xu\u1ed1ng&nbsp;<code>node:16-slim<\/code>container, n\u00ean c\u00f3 th\u1ec3 m\u1ea5t v\u00e0i ph\u00fat tr\u01b0\u1edbc khi&nbsp;<code>npm install<\/code>l\u1ec7nh ch\u1ea1y. C\u00e1c l\u1ea7n ch\u1ea1y ti\u1ebfp theo c\u1ee7a ch\u01b0\u01a1ng tr\u00ecnh n\u00e0y m\u1ea5t \u00edt th\u1eddi gian h\u01a1n.<\/p>\n<h3 id=\"add-a-build-stage-to-the-pipeline\">Th\u00eam Giai \u0111o\u1ea1n X\u00e2y d\u1ef1ng v\u00e0o \u0110\u01b0\u1eddng \u1ed1ng<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#add-a-build-stage-to-the-pipeline\"><\/a><\/h3>\n<p>Sau khi c\u00e1c th\u00e0nh ph\u1ea7n ch\u00ednh c\u1ee7a pipeline \u0111\u00e3 \u0111\u01b0\u1ee3c t\u1ea1o, nh\u01b0 \u0111\u00e3 m\u00f4 t\u1ea3 trong ph\u1ea7n tr\u01b0\u1edbc, \u0111\u00e3 \u0111\u1ebfn l\u00fac th\u00eam giai \u0111o\u1ea1n build. H\u1ea7u h\u1ebft c\u00e1c&nbsp;<code>main.py<\/code>t\u1ec7p v\u1eabn gi\u1eef nguy\u00ean trong phi\u00ean b\u1ea3n t\u1ec7p n\u00e0y. Tuy nhi\u00ean, \u0111\u1ea7u ra c\u1ee7a giai \u0111o\u1ea1n ki\u1ec3m tra kh\u00f4ng c\u00f2n \u0111\u01b0\u1ee3c g\u1eedi \u0111\u1ebfn \u0111\u1ea7u ra chu\u1ea9n n\u1eefa. Thay v\u00e0o \u0111\u00f3, n\u00f3 \u0111\u01b0a v\u00e0o giai \u0111o\u1ea1n build c\u1ee7a pipeline. \u0110\u1ec3 th\u00eam ch\u1ec9 th\u1ecb build v\u00e0o t\u1ec7p, h\u00e3y l\u00e0m theo c\u00e1c b\u01b0\u1edbc sau.<\/p>\n<p>1.M\u1edf&nbsp;<code>main.py<\/code>t\u1ec7p \u0111\u00e3 s\u1eed d\u1ee5ng \u1edf ph\u1ea7n tr\u01b0\u1edbc:<\/p>\n<pre class=\"wp-block-code\"><code>nano ~\/hello-dagger\/ci\/main.py<\/code><\/pre>\n<p>2.Th\u1ef1c hi\u1ec7n nh\u1eefng thay \u0111\u1ed5i sau:<\/p>\n<ul>\n<li>T\u1ec7p tin v\u1eabn gi\u1eef nguy\u00ean cho \u0111\u1ebfn khi&nbsp;<code>runner.with_exec<\/code>th\u1ef1c hi\u1ec7n l\u1ec7nh.<\/li>\n<li>X\u00f3a l\u1ec7nh&nbsp;<code>out = await runner.with_exec([\"npm\", \"test\", \"--\", \"--watchAll=false\"]).stderr()<\/code>v\u00e0 th\u00eam d\u00f2ng sau. \u0110\u00e2y l\u00e0 l\u1ec7nh t\u01b0\u01a1ng t\u1ef1 ngo\u1ea1i tr\u1eeb k\u1ebft qu\u1ea3 \u0111\u01b0\u1ee3c g\u00e1n cho&nbsp;<code>test<\/code>\u0111\u1ed1i t\u01b0\u1ee3ng.<\/li>\n<li>X\u00f3a&nbsp;<code>print(out)<\/code>l\u1ec7nh v\u00ec c\u00e2u l\u1ec7nh n\u00e0y \u0111\u01b0\u1ee3c \u0111\u01b0a l\u1ea1i v\u00e0o sau trong ch\u01b0\u01a1ng tr\u00ecnh m\u1edbi.<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>test = runner.with_exec(&#91;\"npm\", \"test\", \"--\", \"--watchAll=false\"])<\/code><\/pre>\n<p>3.Th\u00eam h\u01b0\u1edbng d\u1eabn m\u1edbi \u0111\u1ec3 x\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng bao g\u1ed3m c\u00e1c chi ti\u1ebft sau:<\/p>\n<ul>\n<li>S\u1eed d\u1ee5ng&nbsp;<code>with_exec<\/code>ph\u01b0\u01a1ng th\u1ee9c \u0111\u1ec3 x\u00e1c \u0111\u1ecbnh&nbsp;<code>npm run build<\/code>l\u1ec7nh x\u00e2y d\u1ef1ng.<\/li>\n<li>L\u01b0u tr\u1eef k\u1ebft qu\u1ea3 trong&nbsp;<code>\/build<\/code>th\u01b0 m\u1ee5c c\u1ee7a container b\u1eb1ng&nbsp;<code>directory<\/code>ph\u01b0\u01a1ng ph\u00e1p. Th\u01b0 m\u1ee5c m\u1edbi \u0111\u01b0\u1ee3c g\u00e1n cho&nbsp;<code>build_dir<\/code>.<\/li>\n<li>Ph\u01b0\u01a1ng ph\u00e1p n\u00e0y&nbsp;<code>export<\/code>ghi n\u1ed9i dung c\u1ee7a th\u01b0 m\u1ee5c tr\u1edf l\u1ea1i th\u01b0&nbsp;<code>.\/build<\/code>m\u1ee5c tr\u00ean m\u00e1y ch\u1ee7.&nbsp;<code>await<\/code>T\u1eeb kh\u00f3a y\u00eau c\u1ea7u \u0111\u01b0\u1eddng \u1ed1ng ch\u1edd ho\u1ea1t \u0111\u1ed9ng ho\u00e0n t\u1ea5t tr\u01b0\u1edbc khi ti\u1ebfp t\u1ee5c.<\/li>\n<li>Ph\u01b0\u01a1ng ph\u00e1p n\u00e0y&nbsp;<code>entries<\/code>tr\u00edch xu\u1ea5t danh s\u00e1ch \u0111\u1ea7y \u0111\u1ee7 c\u00e1c th\u01b0 m\u1ee5c t\u1eeb&nbsp;<code>build<\/code>th\u01b0 m\u1ee5c v\u00e0 ghi danh s\u00e1ch tr\u1edf l\u1ea1i b\u1ea3ng \u0111i\u1ec1u khi\u1ec3n.<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>        build_dir = (\n            test.with_exec(&#91;\"npm\", \"run\", \"build\"])\n            .directory(\".\/build\")\n        )\n\n        await build_dir.export(\".\/build\")\n        e = await build_dir.entries()\n        print(f\"build dir contents:\\n{e}\")\n\nanyio.run(main)<\/code><\/pre>\n<p>4.Sau khi ph\u1ea7n x\u00e2y d\u1ef1ng m\u1edbi \u0111\u01b0\u1ee3c th\u00eam v\u00e0o, to\u00e0n b\u1ed9 t\u1ec7p s\u1ebd gi\u1ed1ng nh\u01b0 v\u00ed d\u1ee5 sau:<\/p>\n<pre class=\"wp-block-code\"><code>import sys\nimport anyio\nimport dagger\n\nasync def main():\n    config = dagger.Config(log_output=sys.stdout)\n\n    async with dagger.Connection(config) as client:\n        source = (\n            client.container()\n            .from_(\"node:16-slim\")\n            .with_directory(\n                \"\/src\",\n                client.host().directory(\".\"),\n                exclude=&#91;\"node_modules\/\", \"ci\/\"],\n            )\n        )\n\n        runner = source.with_workdir(\"\/src\").with_exec(&#91;\"npm\", \"install\"])\n\n        test = runner.with_exec(&#91;\"npm\", \"test\", \"--\", \"--watchAll=false\"])\n\n        build_dir = (\n            test.with_exec(&#91;\"npm\", \"run\", \"build\"])\n            .directory(\".\/build\")\n        )\n\n        await build_dir.export(\".\/build\")\n        e = await build_dir.entries()\n        print(f\"build dir contents:\\n{e}\")\n\nanyio.run(main)<\/code><\/pre>\n<p>5.Quay l\u1ea1i&nbsp;<code>hello-dagger<\/code>th\u01b0 m\u1ee5c v\u00e0 ch\u1ea1y l\u1ea1i t\u1eadp l\u1ec7nh Python:<\/p>\n<pre class=\"wp-block-code\"><code>cd ~\/hello-dagger\npython3 ci\/main.py<\/code><\/pre>\n<p>T\u1eadp l\u1ec7nh hi\u1ec3n th\u1ecb danh s\u00e1ch c\u00e1c th\u01b0 m\u1ee5c b\u00ean trong th\u01b0 m\u1ee5c build:<\/p>\n<pre class=\"wp-block-code\"><code>build dir contents:\n&#91;'asset-manifest.json', 'favicon.ico', 'index.html', 'logo192.png', 'logo512.png', 'manifest.json', 'robots.txt', 'static']<\/code><\/pre>\n<p class=\"has-background\" style=\"background-color:#74f78c33\">Ghi ch\u00fa: Ph\u1ea7n \u0111\u1ea7u ti\u00ean c\u1ee7a t\u1eadp l\u1ec7nh s\u1ebd ch\u1ea1y nhanh h\u01a1n v\u00ec kh\u00f4ng c\u1ea7n ph\u1ea3i t\u1ea3i xu\u1ed1ng container. Tuy nhi\u00ean, qu\u00e1 tr\u00ecnh x\u00e2y d\u1ef1ng th\u01b0\u1eddng m\u1ea5t kho\u1ea3ng m\u1ed9t ph\u00fat \u0111\u1ec3 ho\u00e0n t\u1ea5t.<\/p>\n<h3 id=\"publish-the-container-to-a-registry\">Xu\u1ea5t b\u1ea3n Container v\u00e0o Registry<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#publish-the-container-to-a-registry\"><\/a><\/h3>\n<p>T\u1ea1i th\u1eddi \u0111i\u1ec3m n\u00e0y, Dagger pipeline t\u1ea1o, ki\u1ec3m tra v\u00e0 x\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng. Pipeline \u0111\u00e3 r\u1ea5t h\u1eefu \u00edch v\u00e0 th\u1eadm ch\u00ed c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c coi l\u00e0 ho\u00e0n ch\u1ec9nh. Tuy nhi\u00ean, Dagger c\u0169ng c\u00f3 th\u1ec3 xu\u1ea5t b\u1ea3n container v\u00e0o s\u1ed5 \u0111\u0103ng k\u00fd \u0111\u1ec3 t\u1ea1o quy tr\u00ecnh l\u00e0m vi\u1ec7c \u0111\u01b0\u1ee3c t\u1ed1i \u01b0u h\u00f3a h\u01a1n n\u1eefa.<\/p>\n<p>Tr\u01b0\u1edbc khi xu\u1ea5t b\u1ea3n container, b\u1ea3n d\u1ef1ng \u1ee9ng d\u1ee5ng \u0111\u01b0\u1ee3c sao ch\u00e9p v\u00e0o&nbsp;<code>nginx<\/code>container. B\u1ea5t k\u1ef3 chi ti\u1ebft x\u00e1c th\u1ef1c n\u00e0o c\u0169ng ph\u1ea3i \u0111\u01b0\u1ee3c x\u00e1c \u0111\u1ecbnh tr\u01b0\u1edbc.<\/p>\n<p>V\u00ed d\u1ee5 n\u00e0y c\u00f4ng b\u1ed1 h\u01b0\u1edbng d\u1eabn v\u1ec1 s\u1ed5 \u0111\u0103ng k\u00fd Harbor. Harbor l\u00e0 m\u1ed9t n\u1ec1n t\u1ea3ng s\u1ed5 \u0111\u0103ng k\u00fd container nh\u1eb9 v\u00e0 d\u1ec5 s\u1eed d\u1ee5ng c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t tr\u00ean m\u1ed9t h\u1ec7 th\u1ed1ng ri\u00eang bi\u1ec7t. N\u00f3 cung c\u1ea5p l\u01b0u tr\u1eef \u0111\u00e1m m\u00e2y, c\u00f4ng c\u1ee5 k\u00fd v\u00e0 qu\u00e9t, b\u1ea3o m\u1eadt, ki\u1ec3m so\u00e1t truy c\u1eadp, c\u01a1 ch\u1ebf ki\u1ec3m to\u00e1n v\u00e0 qu\u1ea3n l\u00fd container. N\u00f3 cho ph\u00e9p qu\u1ea3n tr\u1ecb vi\u00ean ki\u1ec3m so\u00e1t s\u1ed5 \u0111\u0103ng k\u00fd c\u1ee7a ri\u00eang h\u1ecd v\u00e0 gi\u1eef n\u00f3 tr\u00ean c\u00f9ng m\u1ed9t m\u1ea1ng v\u1edbi c\u00e1c h\u1ec7 th\u1ed1ng ph\u00e1t tri\u1ec3n c\u1ee7a h\u1ecd. \u0110\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 c\u00e1ch s\u1eed d\u1ee5ng s\u1ed5 \u0111\u0103ng k\u00fd, h\u00e3y xem&nbsp;<a href=\"https:\/\/goharbor.io\/docs\/2.8.0\/install-config\/\" target=\"_blank\" rel=\"noreferrer noopener\">t\u00e0i li\u1ec7u Harbor<\/a>&nbsp;.<\/p>\n<p>\u0110\u1ec3 xu\u1ea5t b\u1ea3n \u1ee9ng d\u1ee5ng, h\u00e3y l\u00e0m theo c\u00e1c b\u01b0\u1edbc sau.<\/p>\n<p>1.M\u1edf l\u1ea1i t\u1ec7p main.py:<\/p>\n<pre class=\"wp-block-code\"><code>nano ~\/hello-dagger\/ci\/main.py<\/code><\/pre>\n<p>2.Ngay b\u00ean d\u01b0\u1edbi ph\u1ea7n b\u1eaft \u0111\u1ea7u c\u1ee7a&nbsp;<code>async with dagger.Connection(config) as client:<\/code>kh\u1ed1i, th\u00eam chi ti\u1ebft m\u1eadt kh\u1ea9u. S\u1eed d\u1ee5ng&nbsp;<code>set_secret<\/code>ph\u01b0\u01a1ng ph\u00e1p \u0111\u1ec3 cung c\u1ea5p m\u1eadt kh\u1ea9u \u0111\u0103ng k\u00fd. C\u00e1c tham s\u1ed1 ph\u1ea3i l\u00e0 chu\u1ed7i&nbsp;<code>password<\/code>trong d\u1ea5u ngo\u1eb7c k\u00e9p, theo sau l\u00e0 m\u1eadt kh\u1ea9u th\u1ef1c t\u1ebf cho t\u00e0i kho\u1ea3n Harbor. Chu\u1ed7i&nbsp;<code>password<\/code>cho Dagger bi\u1ebft lo\u1ea1i b\u00ed m\u1eadt n\u00e0o \u0111ang \u0111\u01b0\u1ee3c x\u00e1c \u0111\u1ecbnh. G\u00e1n k\u1ebft qu\u1ea3 cho&nbsp;<code>secret<\/code>bi\u1ebfn.<\/p>\n<pre class=\"wp-block-code\"><code>secret = client.set_secret(\"password\", \"HARBORPASSWORD\")<\/code><\/pre>\n<p>3.Thay \u0111\u1ed5i ti\u1ebfp theo \u00e1p d\u1ee5ng cho giai \u0111o\u1ea1n x\u00e2y d\u1ef1ng. Nh\u1eefng thay \u0111\u1ed5i sau \u0111\u00e2y l\u00e0 b\u1eaft bu\u1ed9c \u0111\u1ed1i v\u1edbi ph\u1ea7n n\u00e0y c\u1ee7a \u0111\u01b0\u1eddng \u1ed1ng:<\/p>\n<ul>\n<li>Kh\u00f4ng g\u00e1n k\u1ebft qu\u1ea3 c\u1ee7a b\u1ea3n d\u1ef1ng cho&nbsp;<code>build_dir<\/code>bi\u1ebfn. Thay v\u00e0o \u0111\u00f3, h\u00e3y \u0111\u1ee3i t\u1ea5t c\u1ea3 c\u00e1c ho\u1ea1t \u0111\u1ed9ng x\u00e2y d\u1ef1ng, bao g\u1ed3m c\u1ea3 vi\u1ec7c xu\u1ea5t th\u01b0 m\u1ee5c tr\u1edf l\u1ea1i m\u00e1y ch\u1ee7, ho\u00e0n t\u1ea5t.<\/li>\n<li>Thay th\u1ebf l\u1ec7nh g\u00e1n th\u01b0 m\u1ee5c&nbsp;<code>build_dir<\/code>b\u1eb1ng c\u00e1c d\u00f2ng sau.<\/li>\n<li>X\u00f3a ph\u1ea7n c\u00f2n l\u1ea1i c\u1ee7a&nbsp;<code>main<\/code>h\u00e0m, cho \u0111\u1ebfn l\u1ec7nh&nbsp;<code>anyio.run(main)<\/code>. X\u00f3a hai&nbsp;<code>await<\/code>ch\u1ec9 th\u1ecb kh\u00f4ng \u0111\u1ed3ng b\u1ed9 v\u00e0&nbsp;<code>print<\/code>l\u1ec7nh.<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>await (\n    test.with_exec(&#91;\"npm\", \"run\", \"build\"])\n    .directory(\".\/build\")\n    .export(\".\/build\")\n)<\/code><\/pre>\n<p>4.X\u00e1c \u0111\u1ecbnh m\u1ed9t container m\u1edbi d\u1ef1a tr\u00ean&nbsp;<code>nginx:1.23-alpine<\/code>h\u00ecnh \u1ea3nh v\u00e0 \u0111\u00f3ng g\u00f3i \u1ee9ng d\u1ee5ng v\u00e0o container n\u00e0y. Th\u00eam c\u00e1c chi ti\u1ebft sau:<\/p>\n<ul>\n<li>Ph\u1ea7n n\u00e0y t\u1ea1o m\u1ed9t container m\u1edbi d\u1ef1a tr\u00ean&nbsp;<code>nginx:1.23-alpine<\/code>h\u00ecnh \u1ea3nh. S\u1eed d\u1ee5ng c\u00fa ph\u00e1p&nbsp;<code>client.container().from_(\"nginx:1.23-alpine\")<\/code>\u0111\u1ec3 kh\u1edfi t\u1ea1o container.<\/li>\n<li>S\u1eed d\u1ee5ng&nbsp;<code>.with_directory<\/code>ph\u01b0\u01a1ng ph\u00e1p n\u00e0y \u0111\u1ec3 ghi&nbsp;<code>build<\/code>th\u01b0 m\u1ee5c v\u00e0o th\u01b0 m\u1ee5c g\u1ed1c&nbsp;<code>html<\/code>NGINX b\u00ean trong v\u00f9ng ch\u1ee9a.<\/li>\n<li>G\u00e1n v\u00f9ng ch\u1ee9a cho&nbsp;<code>ctr<\/code>bi\u1ebfn.<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>ctr =  (\n    client.container()\n    .from_(\"nginx:1.23-alpine\")\n    .with_directory(\"\/usr\/share\/nginx\/html\", client.host().directory(\".\/build\"))\n)<\/code><\/pre>\n<p>5.\u0110\u1ec3 xu\u1ea5t b\u1ea3n container l\u00ean s\u1ed5 \u0111\u0103ng k\u00fd, h\u00e3y s\u1eed d\u1ee5ng c\u00e1c ph\u01b0\u01a1ng th\u1ee9c&nbsp;<code>with_registry_auth<\/code>v\u00e0&nbsp;<code>publish<\/code>. V\u00ed d\u1ee5 n\u00e0y s\u1eed d\u1ee5ng Harbor l\u00e0m s\u1ed5 \u0111\u0103ng k\u00fd m\u1ee5c ti\u00eau, nh\u01b0ng container c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c xu\u1ea5t b\u1ea3n l\u00ean b\u1ea5t k\u1ef3 s\u1ed5 \u0111\u0103ng k\u00fd n\u00e0o t\u01b0\u01a1ng th\u00edch v\u1edbi Docker. Th\u00eam ph\u1ea7n sau v\u00e0o t\u1ec7p, t\u00ednh \u0111\u1ebfn c\u00e1c thay \u0111\u1ed5i sau:<\/p>\n<ul>\n<li>\u0110\u00ednh k\u00e8m th\u00f4ng tin chi ti\u1ebft v\u00e0o&nbsp;<code>await<\/code>l\u1ec7nh g\u1ecdi kh\u00f4ng \u0111\u1ed3ng b\u1ed9.<\/li>\n<li>\u0110\u1ed1i v\u1edbi tham s\u1ed1 \u0111\u1ea7u ti\u00ean c\u1ee7a&nbsp;<code>with_registry_auth<\/code>ph\u01b0\u01a1ng ph\u00e1p, h\u00e3y cung c\u1ea5p t\u00ean mi\u1ec1n c\u1ee7a s\u1ed5 \u0111\u0103ng k\u00fd theo \u0111\u1ecbnh d\u1ea1ng&nbsp;<code>registrydomainname\/project\/repository:tag<\/code>. Thay th\u1ebf&nbsp;<code>registrydomainname<\/code>b\u1eb1ng t\u00ean mi\u1ec1n Harbor c\u1ee7a b\u1ea1n,&nbsp;<code>project<\/code>b\u1eb1ng t\u00ean d\u1ef1 \u00e1n v\u00e0&nbsp;<code>repository<\/code>b\u1eb1ng t\u00ean kho l\u01b0u tr\u1eef \u0111\u1ec3 xu\u1ea5t b\u1ea3n.&nbsp;<code>tag<\/code>Tr\u01b0\u1eddng n\u00e0y l\u00e0 t\u00f9y ch\u1ecdn.<\/li>\n<li>\u0110\u1ed1i v\u1edbi c\u00e1c tham s\u1ed1 c\u00f2n l\u1ea1i, h\u00e3y th\u00eam t\u00ean ng\u01b0\u1eddi d\u00f9ng cho t\u00e0i kho\u1ea3n Harbor c\u00f9ng v\u1edbi&nbsp;<code>secret<\/code>bi\u1ebfn. Trong v\u00ed d\u1ee5 n\u00e0y, t\u00ean t\u00e0i kho\u1ea3n l\u00e0&nbsp;<code>admin<\/code>.<\/li>\n<li>Trong v\u00ed d\u1ee5 n\u00e0y,&nbsp;<code>example.com\/dagger\/daggerdemo:main<\/code>c\u00f3 ngh\u0129a l\u00e0 container \u0111\u01b0\u1ee3c xu\u1ea5t b\u1ea3n v\u00e0o&nbsp;<code>daggerdemo<\/code>kho l\u01b0u tr\u1eef b\u00ean trong&nbsp;<code>dagger<\/code>d\u1ef1 \u00e1n trong&nbsp;<code>example.com<\/code>s\u1ed5 \u0111\u0103ng k\u00fd. Container \u0111\u01b0\u1ee3c g\u1eafn th\u1ebb b\u1eb1ng&nbsp;<code>main<\/code>th\u1ebb.<\/li>\n<li>Trong&nbsp;<code>publish<\/code>ph\u01b0\u01a1ng ph\u00e1p n\u00e0y, h\u00e3y ch\u1ec9 ra n\u01a1i xu\u1ea5t b\u1ea3n container. Th\u00f4ng tin n\u00e0y tu\u00e2n theo c\u00f9ng \u0111\u1ecbnh d\u1ea1ng nh\u01b0 th\u00f4ng tin \u0111\u0103ng k\u00fd&nbsp;<code>with_registry_auth<\/code>v\u00e0 ph\u1ea3i l\u1eb7p l\u1ea1i c\u00e1c chi ti\u1ebft gi\u1ed1ng nhau.<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>        addr = await (\n            ctr\n            .with_registry_auth(\"example.com\/dagger\/daggerdemo:main\", \"admin\", secret)\n            .publish(\"example.com\/dagger\/daggerdemo:main\")\n        )\n    print(f\"Published image to: {addr}\")\n\nanyio.run(main)<\/code><\/pre>\n<p class=\"has-background\" style=\"background-color:#74f78c33\">Ghi ch\u00fa: Tr\u01b0\u1edbc khi xu\u1ea5t b\u1ea3n m\u1ed9t container l\u00ean s\u1ed5 \u0111\u0103ng k\u00fd Harbor, b\u1ea1n ph\u1ea3i t\u1ea1o m\u1ed9t d\u1ef1 \u00e1n \u0111\u1ec3 ch\u1ee9a container. V\u00ed d\u1ee5 n\u00e0y xu\u1ea5t b\u1ea3n container l\u00ean&nbsp;<code>daggerdemo<\/code>kho l\u01b0u tr\u1eef b\u00ean trong&nbsp;<code>dagger<\/code>d\u1ef1 \u00e1n. N\u1ebfu&nbsp;<code>dagger<\/code>ch\u01b0a t\u1ed3n t\u1ea1i, y\u00eau c\u1ea7u s\u1ebd kh\u00f4ng th\u00e0nh c\u00f4ng.<\/p>\n<p>6.To\u00e0n b\u1ed9 t\u1ec7p ph\u1ea3i t\u01b0\u01a1ng t\u1ef1 nh\u01b0 v\u00ed d\u1ee5 sau. Thay th\u1ebf&nbsp;<code>example.com<\/code>b\u1eb1ng t\u00ean mi\u1ec1n c\u1ee7a s\u1ed5 \u0111\u0103ng k\u00fd Harbor v\u00e0&nbsp;<code>HARBORPASSWORD<\/code>b\u1eb1ng m\u1eadt kh\u1ea9u th\u1ef1c t\u1ebf c\u1ee7a s\u1ed5 \u0111\u0103ng k\u00fd.<\/p>\n<pre class=\"wp-block-code\"><code>import sys\nimport anyio\nimport dagger\n\nasync def main():\n    config = dagger.Config(log_output=sys.stdout)\n\n    async with dagger.Connection(config) as client:\n        secret = client.set_secret(\"password\", \"HARBORPASSWORD\")\n        source = (\n            client.container()\n            .from_(\"node:16-slim\")\n            .with_directory(\n                \"\/src\",\n                client.host().directory(\".\"),\n                exclude=&#91;\"node_modules\/\", \"ci\/\"],\n            )\n        )\n\n        runner = source.with_workdir(\"\/src\").with_exec(&#91;\"npm\", \"install\"])\n\n        test = runner.with_exec(&#91;\"npm\", \"test\", \"--\", \"--watchAll=false\"])\n\n        await (\n            test.with_exec(&#91;\"npm\", \"run\", \"build\"])\n            .directory(\".\/build\")\n            .export(\".\/build\")\n        )\n\n        ctr =  (\n            client.container()\n            .from_(\"nginx:1.23-alpine\")\n            .with_directory(\"\/usr\/share\/nginx\/html\", client.host().directory(\".\/build\"))\n        )\n\n        addr = await (\n            ctr\n            .with_registry_auth(\"example.com\/dagger\/daggerdemo:main\", \"admin\", secret)\n            .publish(\"example.com\/dagger\/daggerdemo:main\")\n        )\n    print(f\"Published image to: {addr}\")\n\nanyio.run(main)<\/code><\/pre>\n<p>L\u01b0u t\u1ec7p v\u00e0 tho\u00e1t&nbsp;<code>nano<\/code>khi ho\u00e0n t\u1ea5t.<\/p>\n<p>7.T\u1eeb&nbsp;<code>hello-dagger<\/code>th\u01b0 m\u1ee5c, ch\u1ea1y l\u1ea1i t\u1eadp l\u1ec7nh Python. T\u1eadp l\u1ec7nh s\u1ebd x\u00e2y d\u1ef1ng v\u00f9ng ch\u1ee9a v\u00e0 \u0111\u1ea9y n\u00f3 ra s\u1ed5 \u0111\u0103ng k\u00fd. To\u00e0n b\u1ed9 qu\u00e1 tr\u00ecnh c\u00f3 th\u1ec3 m\u1ea5t v\u00e0i ph\u00fat \u0111\u1ec3 ho\u00e0n t\u1ea5t. Khi ho\u00e0n t\u1ea5t, t\u1eadp l\u1ec7nh s\u1ebd hi\u1ec3n th\u1ecb t\u00ean v\u00e0 th\u1ebb \u0111\u01b0\u1ee3c t\u1ea1o cho h\u00ecnh \u1ea3nh. Ghi l\u1ea1i t\u00ean v\u00e0 th\u1ebb v\u00f9ng ch\u1ee9a \u0111\u1ea7y \u0111\u1ee7 \u0111\u1ec3 s\u1eed d\u1ee5ng sau n\u00e0y.<\/p>\n<pre class=\"wp-block-code\"><code>cd ~\/hello-dagger\npython3 ci\/main.py\n\nPublished image to: example.com\/dagger\/daggerdemo:main@sha256:eb8dbf08fb05180ffbf56b<\/code><\/pre>\n<p>8.X\u00e1c nh\u1eadn container \u0111\u00e3 \u0111\u01b0\u1ee3c x\u00e2y d\u1ef1ng v\u00e0 t\u1ea3i l\u00ean th\u00e0nh c\u00f4ng. S\u1eed d\u1ee5ng&nbsp;<code>docker run<\/code>l\u1ec7nh \u0111\u1ec3 k\u00e9o container tr\u1edf l\u1ea1i m\u00e1y ch\u1ee7 v\u00e0 ch\u1ea1y \u1ee9ng d\u1ee5ng. Ch\u1ec9 \u0111\u1ecbnh t\u00ean container v\u00e0 \u0111\u1ecba ch\u1ec9 ch\u00ednh x\u00e1c \u0111\u01b0\u1ee3c ch\u1ec9 \u0111\u1ecbnh trong \u0111\u1ea7u ra c\u1ee7a&nbsp;<code>main.py<\/code>t\u1eadp l\u1ec7nh.<\/p>\n<pre class=\"wp-block-code\"><code>docker run -p 8080:80 example.com\/dagger\/daggerdemo:main@sha256:eb8dbf08fb05180ffbf56b602ee320ef5aa89b8f972f553e478f6b64a492dd50<\/code><\/pre>\n<p>\u0110i\u1ec1u h\u01b0\u1edbng \u0111\u1ebfn c\u1ed5ng&nbsp;<code>8080<\/code>c\u1ee7a n\u00fat, s\u1eed d\u1ee5ng \u0111\u1ecba ch\u1ec9 IP ho\u1eb7c t\u00ean mi\u1ec1n \u0111\u1ee7 \u0111i\u1ec1u ki\u1ec7n. Tr\u00ecnh duy\u1ec7t s\u1ebd hi\u1ec3n th\u1ecb trang web \u201cWelcome to Dagger\u201d.<\/p>\n<h2 id=\"conclusion\">Ph\u1ea7n k\u1ebft lu\u1eadn<a href=\"https:\/\/www.linode.com\/docs\/guides\/create-a-dagger-pipeline\/#conclusion\"><\/a><\/h2>\n<p>Dagger cung c\u1ea5p m\u1ed9t khu\u00f4n kh\u1ed5 \u0111a ng\u00f4n ng\u1eef cho t\u1ef1 \u0111\u1ed9ng h\u00f3a CI\/CD trong m\u1ed9t b\u1ed1i c\u1ea3nh ch\u1ee9a. N\u00f3 bao g\u1ed3m c\u00e1c kh\u1ea3 n\u0103ng \u0111\u1ec3 x\u00e2y d\u1ef1ng m\u1ed9t \u0111\u01b0\u1eddng \u1ed1ng l\u1eafp r\u00e1p, ki\u1ec3m tra, x\u00e2y d\u1ef1ng v\u00e0 xu\u1ea5t b\u1ea3n m\u1ed9t \u1ee9ng d\u1ee5ng b\u1eb1ng m\u1ed9t t\u1eadp l\u1ec7nh duy nh\u1ea5t. Dagger bao g\u1ed3m c\u00e1c SDK cho Python, Go v\u00e0 Node.js, c\u00f9ng v\u1edbi m\u1ed9t API GraphQL \u0111\u1ec3 t\u00edch h\u1ee3p c\u1ea5p th\u1ea5p v\u1edbi c\u00e1c ng\u00f4n ng\u1eef kh\u00e1c. \u0110\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 c\u00e1ch s\u1eed d\u1ee5ng Dagger, h\u00e3y tham kh\u1ea3o&nbsp;<a href=\"https:\/\/docs.dagger.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">T\u00e0i li\u1ec7u Dagger<\/a>&nbsp;.<\/p>\n<h2 id=\"more-information\">Th\u00f4ng tin th\u00eam<\/h2>\n<p>B\u1ea1n c\u00f3 th\u1ec3 mu\u1ed1n tham kh\u1ea3o c\u00e1c ngu\u1ed3n sau \u0111\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 ch\u1ee7 \u0111\u1ec1 n\u00e0y. M\u1eb7c d\u00f9 ch\u00fang t\u00f4i cung c\u1ea5p v\u1edbi hy v\u1ecdng r\u1eb1ng ch\u00fang s\u1ebd h\u1eefu \u00edch, nh\u01b0ng xin l\u01b0u \u00fd r\u1eb1ng ch\u00fang t\u00f4i kh\u00f4ng th\u1ec3 \u0111\u1ea3m b\u1ea3o t\u00ednh ch\u00ednh x\u00e1c ho\u1eb7c t\u00ednh k\u1ecbp th\u1eddi c\u1ee7a c\u00e1c t\u00e0i li\u1ec7u \u0111\u01b0\u1ee3c l\u01b0u tr\u1eef b\u00ean ngo\u00e0i.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dagger&nbsp;l\u00e0 m\u1ed9t \u1ee9ng d\u1ee5ng m\u00e3 ngu\u1ed3n m\u1edf v\u00e0 mi\u1ec5n ph\u00ed \u0111\u1ec3 t\u1ef1 \u0111\u1ed9ng h\u00f3a c\u00e1c \u0111\u01b0\u1eddng \u1ed1ng&nbsp;T\u00edch h\u1ee3p li\u00ean t\u1ee5c\/Ph\u00e2n ph\u1ed1i li\u00ean t\u1ee5c&nbsp;(CI\/CD). N\u00f3 cho ph\u00e9p c\u00e1c qu\u1ea3n tr\u1ecb vi\u00ean v\u00e0 nh\u00e0 ph\u00e1t tri\u1ec3n t\u1ea1o c\u00e1c t\u1eadp l\u1ec7nh \u0111\u1ec3 l\u1eafp r\u00e1p, th\u1eed nghi\u1ec7m, x\u00e2y d\u1ef1ng v\u00e0 th\u1eadm ch\u00ed xu\u1ea5t b\u1ea3n m\u1ed9t d\u1ef1 \u00e1n v\u00e0o m\u1ed9t<\/p>\n","protected":false},"author":1,"featured_media":36272,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[108],"tags":[],"class_list":["post-35043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-containers"],"_links":{"self":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/posts\/35043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/comments?post=35043"}],"version-history":[{"count":0,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/posts\/35043\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/media\/36272"}],"wp:attachment":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/media?parent=35043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/categories?post=35043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/tags?post=35043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}