<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="https://publishpress.com/"
	>

<channel>
	<title>Thuc Phan, Author at Tomoshare</title>
	<atom:link href="https://blog.tomosia.com.vn/author/thucphan/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.tomosia.com.vn/author/thucphan/</link>
	<description>Kênh chia sẻ kiến thức Tomosia Việt Nam</description>
	<lastBuildDate>Fri, 26 Jan 2024 07:12:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.tomosia.com.vn/wp-content/uploads/2023/09/cropped-icon-32x32.png</url>
	<title>Thuc Phan, Author at Tomoshare</title>
	<link>https://blog.tomosia.com.vn/author/thucphan/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Download files from remote server</title>
		<link>https://blog.tomosia.com.vn/download-files-from-remote-server/</link>
					<comments>https://blog.tomosia.com.vn/download-files-from-remote-server/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Fri, 26 Jan 2024 07:12:22 +0000</pubDate>
				<category><![CDATA[OS & Command]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=3103</guid>

					<description><![CDATA[<p>Use ssh key Use password Efficient log check command</p>
<p>The post <a href="https://blog.tomosia.com.vn/download-files-from-remote-server/">Download files from remote server</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 id="use-ssh-key" class="wp-block-heading">Use ssh key</h2>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="scp -i ~/path/to/your-key username@public-ip-address:~/path/to/your-project/log/production.log-20240126.gz ~/Downloads" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">scp</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">-i</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">~/path/to/your-key</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">username@public-ip-address:~/path/to/your-project/log/production.log-20240126.gz</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">~/Downloads</span></span></code></pre></div>



<h2 id="use-password" class="wp-block-heading">Use password</h2>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="scp username@public-ip-address:~/path/to/your-project/log/production.log-20240126.gz ~/Downloads" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">scp</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">username@public-ip-address:~/path/to/your-project/log/production.log-20240126.gz</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">~/Downloads</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Enter your server password</li>
</ul>



<h2 id="efficient-log-check-command" class="wp-block-heading">Efficient log check command</h2>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="grep -B 30 -A 30 --color &quot;keywords you want to search&quot; production.log-20240126" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">grep</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">-B</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">30</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">-A</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">30</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--color</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">keywords you want to search</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">production.log-20240126</span></span></code></pre></div>
<p>The post <a href="https://blog.tomosia.com.vn/download-files-from-remote-server/">Download files from remote server</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/download-files-from-remote-server/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Deploy Rails App: Tối Ưu Hóa Hiệu Suất Server Bằng Local Precompile</title>
		<link>https://blog.tomosia.com.vn/deploy-rails-app-toi-uu-hoa-hieu-suat-server-bang-local-precompile/</link>
					<comments>https://blog.tomosia.com.vn/deploy-rails-app-toi-uu-hoa-hieu-suat-server-bang-local-precompile/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Thu, 28 Dec 2023 02:18:33 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1273</guid>

					<description><![CDATA[<p>Giới thiệu Deploy bằng phương pháp mặc định: Precompile trực tiếp trên server config/deploy/production.rb config/deploy.rb config/puma/production.rb lib/capistrano/tasks/puma.rake Dùng&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/deploy-rails-app-toi-uu-hoa-hieu-suat-server-bang-local-precompile/">Deploy Rails App: Tối Ưu Hóa Hiệu Suất Server Bằng Local Precompile</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 id="gioi-thieu" class="wp-block-heading alignfull">Giới thiệu</h2>



<ul class="wp-block-list">
<li>Deploy đóng vai trò quan trọng trong quá trình phát triển ứng dụng. Rails đã tích hợp <strong><code>webpacker</code></strong> từ version <code>~&gt; 6.0</code> để quản lý tài nguyên JavaScript và CSS dễ dàng hơn</li>
</ul>



<ul class="wp-block-list">
<li>Khi ứng dụng của bạn ngày càng lớn thì việc <code><strong>assets:precompile</strong></code> sẽ tốn nhiều thời gian và tài nguyên của server. Điều này có thể gây downtime ứng dụng trong quá trình deploy, đặc biệt là trên các servers có tài nguyên hạn chế và workload cao</li>
</ul>



<ul class="wp-block-list">
<li>Bài viết này giới thiệu về cách dùng local precompile để tối ưu hoá hiệu suất trong quá trình deploy. Chúng ta sẽ tìm hiểu lý do tại sao việc <strong><code>assets:precompile</code></strong> trên server có thể gây nên vấn đề và giải pháp đơn giản chỉ là thực hiện precompile tại máy local</li>
</ul>



<h2 id="deploy-bang-phuong-phap-mac-dinh-precompile-truc-tiep-tren-server" class="wp-block-heading">Deploy bằng phương pháp mặc định: Precompile trực tiếp trên server</h2>



<ul class="wp-block-list">
<li>Bước đầu tiên là tạo mới một ứng dụng Rails</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="rails _6.0.6.1_ new local_precompile" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">rails</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">_6.0.6.1_</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">new</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">local_precompile</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="280" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.29.15-PM-1024x280.png" alt="" class="wp-image-2977" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.29.15-PM-1024x280.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.29.15-PM-300x82.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.29.15-PM-768x210.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.29.15-PM-380x104.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.29.15-PM-800x219.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.29.15-PM.png 1140w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Kiểm tra xem ứng dụng đã hoạt động chưa</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="rails s" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">rails</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="627" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-1024x627.png" alt="" class="wp-image-2978" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-1024x627.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-768x470.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-1536x940.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-2048x1254.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-800x490.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM-1160x710.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.33.00-PM.png 3198w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Thay đổi root path</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="rails g scaffold post title:string body:text" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">rails</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">g</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">scaffold</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">post</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">title:string</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">body:text</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="Rails.application.routes.draw do
  root to: 'posts#index'
  resources :posts
end" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #97E1F1; font-style: italic">Rails</span><span style="color: #F6F6F4">.application.routes.draw </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  root to</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">posts#index</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  resources </span><span style="color: #BF9EEE">:posts</span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="625" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-1024x625.png" alt="" class="wp-image-2979" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-1024x625.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-300x183.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-768x469.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-1536x938.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-2048x1250.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-380x232.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-800x488.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM-1160x708.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-31-at-6.35.36-PM.png 3198w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Commit code và push lên Git Repository của bạn</li>
</ul>



<ul class="wp-block-list">
<li>Tiếp theo mình sẽ Launch Instance và chọn OS là Ubuntu</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="583" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-1024x583.png" alt="" class="wp-image-1301" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-1024x583.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-300x171.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-768x438.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-1536x875.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-2048x1167.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-380x217.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-800x456.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM-1160x661.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-16-at-9.50.45-PM.png 3194w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>SSH vào server và cài đặt <strong><code>nginx</code></strong> làm web server</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="ssh -i ~/path-to-file-key ubuntu@public-ip-address
sudo apt update
sudo apt install nginx" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">ssh</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">-i</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">~/path-to-file-key</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">ubuntu@public-ip-address</span></span>
<span class="line"><span style="color: #62E884">sudo</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">apt</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">update</span></span>
<span class="line"><span style="color: #62E884">sudo</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">apt</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">install</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">nginx</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Sau khi cài đặt <code><strong>nginx</strong></code> và mở được trang &#8220;Welcome to nginx!&#8221; trên trình duyệt bằng public-ip-address thì bạn đã hoàn thành nhiệm vụ 🤣</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="622" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-46.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-10-16-at-10.35.14-PM-1024x622.png" class="wp-image-1316" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-46.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-46-300x182.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-46-768x467.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-46-380x231.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-46-800x486.png 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Tiếp theo, bạn cần cài đặt các packages cần thiết để ứng dụng Rails hoạt động được trên server</li>
</ul>



<ul class="wp-block-list">
<li>Đảm bảo cài đặt đúng version Ruby, Rails, Yarn, Node&#8230; mà bạn đã sử dụng để chạy ứng dụng ở máy local (điều này giúp tránh những lỗi không cần thiết liên quan đến version)</li>
</ul>



<ul class="wp-block-list">
<li>Quay lại ứng dụng Rails và cấu hình deploy bằng Capistrano. Cài đặt các gems cần thiết</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="group :development do
  # Capistrano - easy to deployment with Ruby over SSH
  gem 'capistrano', '~&gt; 3.18'
  # rbenv integration for Capistrano
  gem 'capistrano-rbenv', '~&gt; 2.2'
  # Rails specific Capistrano tasks
  gem 'capistrano-rails', '~&gt; 1.6', '&gt;= 1.6.3'
  # Bundler support for Capistrano 3.x
  gem 'capistrano-bundler', '~&gt; 2.1'
  # based on capistrano/npm gem
  gem 'capistrano-yarn', '~&gt; 2.0', '&gt;= 2.0.2'
  # nvm support for Capistrano 3.x
  gem 'capistrano-nvm', '~&gt; 0.0.7'
end" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">group </span><span style="color: #BF9EEE">:development</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Capistrano - easy to deployment with Ruby over SSH</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 3.18</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># rbenv integration for Capistrano</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-rbenv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 2.2</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Rails specific Capistrano tasks</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-rails</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 1.6</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">&gt;= 1.6.3</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Bundler support for Capistrano 3.x</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-bundler</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 2.1</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># based on capistrano/npm gem</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-yarn</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 2.0</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">&gt;= 2.0.2</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># nvm support for Capistrano 3.x</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-nvm</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 0.0.7</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="bundle install
cap install" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">bundle</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">install</span></span>
<span class="line"><span style="color: #62E884">cap</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">install</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Sau khi hoàn thành hai lệnh trên, hệ thống sẽ tự động tạo các files cần thiết để hỗ trợ deploy ứng dụng. Chỉnh sửa nội dụng các files sau<br></li>
</ul>



<p><code>config/deploy/production.rb</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="server &quot;public-ip-address&quot;, user: &quot;ubuntu&quot;, roles: %w{app db web}

set :ssh_options,
    forward_agent: true,
    auth_methods: %w[publickey],
    keys: %w[~/path-to-your-key]

set :branch, :main

set :rails_env, :production" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">server </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">public-ip-address</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, user</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">ubuntu</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, roles</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">%</span><span style="color: #F6F6F4">w{app db web}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:ssh_options</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    forward_agent</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    auth_methods</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">%</span><span style="color: #F6F6F4">w[publickey],</span></span>
<span class="line"><span style="color: #F6F6F4">    keys</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">%</span><span style="color: #F6F6F4">w[</span><span style="color: #F286C4">~</span><span style="color: #E7EE98">/path-to-your-key]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #E7EE98">set :branch, :main</span></span>
<span class="line"></span>
<span class="line"><span style="color: #E7EE98">set :rails_env, :production</span></span></code></pre></div>



<p><code>config/deploy.rb</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="# config valid for current version and patch releases of Capistrano
lock &quot;~&gt; 3.18.0&quot;

set :application, &quot;local_precompile&quot;
set :repo_url, &quot;your-repo-url&quot;

# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, &quot;/home/ubuntu/sites/local_precompile&quot;

# Default value for :pty is false
set :pty, true

# Default value for :linked_files is []
append :linked_files, &quot;config/master.key&quot;

# Default value for linked_dirs is []
append :linked_dirs, &quot;log&quot;, &quot;tmp/pids&quot;, &quot;tmp/cache&quot;, &quot;tmp/sockets&quot;, &quot;public/system&quot;, &quot;vendor&quot;, &quot;storage&quot;

# Default value for default_env is {}
set :default_env, { &quot;PATH&quot;: &quot;/home/ubuntu/.nvm/versions/node/v16.20.2/bin:$PATH&quot; }

set :puma_pid, shared_path.join('tmp/pids/server.pid')

set :puma_bind, &quot;unix://#{shared_path.join('tmp/sockets/puma.sock')}&quot;

set :puma_config_path, -&gt; { File.join(current_path, 'config', 'puma', &quot;#{fetch(:rails_env)}.rb&quot;) }" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B"># config valid for current version and patch releases of Capistrano</span></span>
<span class="line"><span style="color: #F6F6F4">lock </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">~&gt; 3.18.0</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:application</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">local_precompile</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:repo_url</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">your-repo-url</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Default deploy_to directory is /var/www/my_app_name</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:deploy_to</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">/home/ubuntu/sites/local_precompile</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Default value for :pty is false</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:pty</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">true</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Default value for :linked_files is []</span></span>
<span class="line"><span style="color: #F6F6F4">append </span><span style="color: #BF9EEE">:linked_files</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">config/master.key</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Default value for linked_dirs is []</span></span>
<span class="line"><span style="color: #F6F6F4">append </span><span style="color: #BF9EEE">:linked_dirs</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">log</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">tmp/pids</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">tmp/cache</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">tmp/sockets</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">public/system</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">vendor</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">storage</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Default value for default_env is {}</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:default_env</span><span style="color: #F6F6F4">, { </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">PATH</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">: </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">/home/ubuntu/.nvm/versions/node/v16.20.2/bin:$PATH</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:puma_pid</span><span style="color: #F6F6F4">, shared_path.join(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">tmp/pids/server.pid</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:puma_bind</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">unix://</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">shared_path.join(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">tmp/sockets/puma.sock</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:puma_config_path</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1">-&gt;</span><span style="color: #F6F6F4"> { </span><span style="color: #97E1F1; font-style: italic">File</span><span style="color: #F6F6F4">.join(current_path, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">config</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">puma</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:rails_env</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">.rb</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">) }</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Thêm các modules cần thiết vào <code>/Capfile</code></li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="require &quot;capistrano/rbenv&quot;
set :rbenv_type, :user
set :rbenv_ruby, &quot;2.7.0&quot;
set :rbenv_map_bins, %w[rake gem bundle ruby rails]
set :rbenv_roles, :all

require &quot;capistrano/bundler&quot;
require &quot;capistrano/rails/assets&quot;
require &quot;capistrano/rails/migrations&quot;

require &quot;capistrano/yarn&quot;
set :yarn_flags, '--frozen-lockfile'

require &quot;capistrano/nvm&quot;
set :nvm_type, :user
set :nvm_node, &quot;v16.20.2&quot;
set :nvm_map_bins, %w[node npm yarn]" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/rbenv</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_type</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:user</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_ruby</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">2.7.0</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_map_bins</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">%</span><span style="color: #F6F6F4">w[rake gem bundle ruby rails]</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_roles</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:all</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/bundler</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/rails/assets</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/rails/migrations</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/yarn</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:yarn_flags</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">--frozen-lockfile</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/nvm</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:nvm_type</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:user</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:nvm_node</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">v16.20.2</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:nvm_map_bins</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">%</span><span style="color: #F6F6F4">w[node npm yarn]</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Tạo một file puma configuration cho môi trường production như sau</li>
</ul>



<p><code>config/puma/production.rb</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
max_threads_count = ENV.fetch(&quot;RAILS_MAX_THREADS&quot;) { 5 }
min_threads_count = ENV.fetch(&quot;RAILS_MIN_THREADS&quot;) { max_threads_count }
threads min_threads_count, max_threads_count

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch(&quot;PORT&quot;) { 3000 }

# Specifies the `environment` that Puma will run in.
#
environment &quot;production&quot;

# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch(&quot;PIDFILE&quot;) { &quot;tmp/pids/server.pid&quot; }

tmp_path = &quot;#{File.expand_path('../../..', __FILE__)}/tmp&quot;
bind &quot;unix://#{tmp_path}/sockets/puma.sock&quot;

log_path = &quot;#{File.expand_path('../../..', __FILE__)}/log&quot;
stdout_redirect &quot;#{log_path}/puma.stdout.log&quot;, &quot;#{log_path}/puma.stderr.log&quot;, true

# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch(&quot;WEB_CONCURRENCY&quot;) { 2 }

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
preload_app!

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B"># Puma can serve each request in a thread from an internal thread pool.</span></span>
<span class="line"><span style="color: #7B7F8B"># The `threads` method setting takes two numbers: a minimum and maximum.</span></span>
<span class="line"><span style="color: #7B7F8B"># Any libraries that use thread pools should be configured to match</span></span>
<span class="line"><span style="color: #7B7F8B"># the maximum value specified for Puma. Default is set to 5 threads for minimum</span></span>
<span class="line"><span style="color: #7B7F8B"># and maximum; this matches the default thread size of Active Record.</span></span>
<span class="line"><span style="color: #7B7F8B">#</span></span>
<span class="line"><span style="color: #F6F6F4">max_threads_count </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">ENV</span><span style="color: #F6F6F4">.fetch(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">RAILS_MAX_THREADS</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">) { </span><span style="color: #BF9EEE">5</span><span style="color: #F6F6F4"> }</span></span>
<span class="line"><span style="color: #F6F6F4">min_threads_count </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">ENV</span><span style="color: #F6F6F4">.fetch(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">RAILS_MIN_THREADS</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">) { max_threads_count }</span></span>
<span class="line"><span style="color: #F6F6F4">threads min_threads_count, max_threads_count</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Specifies the `port` that Puma will listen on to receive requests; default is 3000.</span></span>
<span class="line"><span style="color: #7B7F8B">#</span></span>
<span class="line"><span style="color: #F6F6F4">port </span><span style="color: #97E1F1; font-style: italic">ENV</span><span style="color: #F6F6F4">.fetch(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">PORT</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">) { </span><span style="color: #BF9EEE">3000</span><span style="color: #F6F6F4"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Specifies the `environment` that Puma will run in.</span></span>
<span class="line"><span style="color: #7B7F8B">#</span></span>
<span class="line"><span style="color: #F6F6F4">environment </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">production</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Specifies the `pidfile` that Puma will use.</span></span>
<span class="line"><span style="color: #F6F6F4">pidfile </span><span style="color: #97E1F1; font-style: italic">ENV</span><span style="color: #F6F6F4">.fetch(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">PIDFILE</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">) { </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">tmp/pids/server.pid</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">tmp_path </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #97E1F1; font-style: italic">File</span><span style="color: #E7EE98">.expand_path(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">../../..</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">, </span><span style="color: #BF9EEE; font-style: italic">__FILE__</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/tmp</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">bind </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">unix://</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">tmp_path</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/sockets/puma.sock</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">log_path </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #97E1F1; font-style: italic">File</span><span style="color: #E7EE98">.expand_path(</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">../../..</span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">, </span><span style="color: #BF9EEE; font-style: italic">__FILE__</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/log</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">stdout_redirect </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">log_path</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/puma.stdout.log</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">log_path</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/puma.stderr.log</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">true</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Specifies the number of `workers` to boot in clustered mode.</span></span>
<span class="line"><span style="color: #7B7F8B"># Workers are forked web server processes. If using threads and workers together</span></span>
<span class="line"><span style="color: #7B7F8B"># the concurrency of the application would be max `threads` * `workers`.</span></span>
<span class="line"><span style="color: #7B7F8B"># Workers do not work on JRuby or Windows (both of which do not support</span></span>
<span class="line"><span style="color: #7B7F8B"># processes).</span></span>
<span class="line"><span style="color: #7B7F8B">#</span></span>
<span class="line"><span style="color: #7B7F8B"># workers ENV.fetch(&quot;WEB_CONCURRENCY&quot;) { 2 }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Use the `preload_app!` method when specifying a `workers` number.</span></span>
<span class="line"><span style="color: #7B7F8B"># This directive tells Puma to first boot the application and load code</span></span>
<span class="line"><span style="color: #7B7F8B"># before forking the application. This takes advantage of Copy On Write</span></span>
<span class="line"><span style="color: #7B7F8B"># process behavior so workers use less memory.</span></span>
<span class="line"><span style="color: #7B7F8B">#</span></span>
<span class="line"><span style="color: #F6F6F4">preload_app!</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Allow puma to be restarted by `rails restart` command.</span></span>
<span class="line"><span style="color: #F6F6F4">plugin </span><span style="color: #BF9EEE">:tmp_restart</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Tạo một file puma rake task như sau</li>
</ul>



<p><code>lib/capistrano/tasks/puma.rake</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="namespace :puma do
  desc 'Start puma'
  task :start do
    on roles(:app) do
      within current_path do
        execute :bundle, 'exec', 'puma', '--config', &quot;#{fetch(:puma_config_path)}&quot;, '--daemon'
      end
    end
  end

  desc 'Restart puma'
  task :restart do
    on roles(:app) do
      within current_path do
        if test(&quot;[ -f #{shared_path}/tmp/pids/server.pid ]&quot;)
          execute :bundle, :exec, :pumactl, '-P', fetch(:puma_pid), 'restart', '--config', fetch(:puma_config_path)
        else
          invoke 'puma:start'
        end
      end
    end
  end

  desc 'Stop puma'
  task :stop do
    on roles(:app) do
      within current_path do
        execute :bundle, :exec, 'pumactl', '-P', fetch(:puma_pid), 'stop'
      end
    end
  end
end

namespace :load do
  task :defaults do
    after 'deploy:publishing', 'puma:restart'
  end
end" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">namespace </span><span style="color: #BF9EEE">:puma</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  desc </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">Start puma</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  task </span><span style="color: #BF9EEE">:start</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    on roles(</span><span style="color: #BF9EEE">:app</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">      within current_path </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">        execute </span><span style="color: #BF9EEE">:bundle</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">exec</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">puma</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">--config</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:puma_config_path</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">--daemon</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  desc </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">Restart puma</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  task </span><span style="color: #BF9EEE">:restart</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    on roles(</span><span style="color: #BF9EEE">:app</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">      within current_path </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">test</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">[ -f </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">shared_path</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/tmp/pids/server.pid ]</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">          execute </span><span style="color: #BF9EEE">:bundle</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:exec</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:pumactl</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">-P</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, fetch(</span><span style="color: #BF9EEE">:puma_pid</span><span style="color: #F6F6F4">), </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">restart</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">--config</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, fetch(</span><span style="color: #BF9EEE">:puma_config_path</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">else</span></span>
<span class="line"><span style="color: #F6F6F4">          invoke </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">puma:start</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  desc </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">Stop puma</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  task </span><span style="color: #BF9EEE">:stop</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    on roles(</span><span style="color: #BF9EEE">:app</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">      within current_path </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">        execute </span><span style="color: #BF9EEE">:bundle</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:exec</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">pumactl</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">-P</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, fetch(</span><span style="color: #BF9EEE">:puma_pid</span><span style="color: #F6F6F4">), </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">stop</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">namespace </span><span style="color: #BF9EEE">:load</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  task </span><span style="color: #BF9EEE">:defaults</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    after </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">deploy:publishing</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">puma:restart</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Thêm cấu hình cho <strong><code>nginx</code></strong></li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="sudo vi /etc/nginx/conf.d/local_precompile.conf" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">sudo</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">vi</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/etc/nginx/conf.d/local_precompile.conf</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="upstream local_precompile {
  server unix:///home/ubuntu/sites/local_precompile/shared/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name 54.196.84.135;

  root /home/ubuntu/sites/local_precompile/current/public;
  try_files $uri/index.html $uri @puma;

  location @puma {
    proxy_pass http://unix:/home/ubuntu/sites/local_precompile/shared/tmp/sockets/puma.sock;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">upstream</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">local_precompile</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">{</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">server</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">unix:///home/ubuntu/sites/local_precompile/shared/tmp/sockets/puma.sock</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #62E884">server</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">{</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">listen</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">80</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">server_name</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">54.196</span><span style="color: #E7EE98">.84.135</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">root</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/home/ubuntu/sites/local_precompile/current/public</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">try_files</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">$uri</span><span style="color: #E7EE98">/index.html</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">$uri</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">@puma</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">location</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">@puma</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">{</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">proxy_pass</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">http://unix:/home/ubuntu/sites/local_precompile/shared/tmp/sockets/puma.sock</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">proxy_set_header</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">Host</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">$host</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">proxy_set_header</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">X-Real-IP</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">$remote_addr</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">proxy_set_header</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">X-Forwarded-For</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">$proxy_add_x_forwarded_for</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">proxy_set_header</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">X-Forwarded-Proto</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">$scheme</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">  }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="sudo service nginx restart" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">sudo</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">service</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">nginx</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">restart</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Khi tất cả đã được thiết lập xong thì chạy lệnh sau để deploy</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="cap production deploy" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">cap</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">production</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">deploy</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Trong những lần deploy đầu chắc chắn sẽ có những lỗi nhỏ, tuỳ trường hợp mà các bạn có thể tự xử lý nhé 🤣</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="626" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-1024x626.png" alt="" class="wp-image-2988" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-1024x626.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-300x183.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-768x470.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-1536x939.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-2048x1252.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-380x232.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-800x489.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM-1160x709.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2024-01-01-at-8.42.55-AM.png 3196w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Quan sát <code><strong>htop</strong></code> trong quá trình deploy, có thể thấy workload của CPU và Memory tăng cao rõ rệt trong lúc thực hiện<strong> <code>yarn:install</code></strong> và <code><strong>deploy:assets:precompile</strong></code></li>
</ul>



<ul class="wp-block-list">
<li>Đó là nguyên nhân chính có thể gây downtime ứng dụng</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="236" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-1024x236.png" alt="" class="wp-image-2989" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-1024x236.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-300x69.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-768x177.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-1536x354.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-380x88.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-800x185.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM-1160x268.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2024/01/Screen-Shot-2023-12-31-at-9.38.40-AM.png 1604w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 id="dung-local-precompile" class="wp-block-heading">Dùng Local Precompile</h2>



<ul class="wp-block-list">
<li>Phát hiện vấn đề chính nằm ở <code><strong>yarn:install</strong></code> và <code><strong>deploy:assets:precompile</strong></code></li>
</ul>



<ul class="wp-block-list">
<li>Tiếp theo chúng ta cần chuyển hai tác vụ này về xử lý ở máy local, sau đó upload các files cần thiết lên server là xong</li>
</ul>



<ul class="wp-block-list">
<li>Tạo một file deploy rake task như sau</li>
</ul>



<p><code>lib/capistrano/tasks/deploy.rake</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="namespace :deploy do
  namespace :assets do
    desc 'Precompile assets locally'
    task :local_precompile do
      run_locally do
        execute &quot;rm -rf #{fetch(:cache_dir)}&quot;
        execute &quot;RAILS_ENV=#{fetch(:rails_env)} bundle exec rake assets:clean&quot;
        execute &quot;RAILS_ENV=#{fetch(:rails_env)} bundle exec rake assets:precompile&quot;
      end
    end

    desc 'rsync assets to web server'
    task :rsync_assets do
      on roles(:web), in: :parallel do |server|
        run_locally do
          ssh_shell   = %(-e &quot;ssh -i #{fetch(:ssh_options)[:keys].first}&quot;)
          rsync_shell = &quot;rsync -avz #{ssh_shell}&quot;
          release_dir = &quot;username@public-ip-address:#{release_path}&quot;
          commands    = []

          commands &lt;&lt; &quot;#{rsync_shell} ./#{fetch(:assets_dir)} #{release_dir}/#{fetch(:assets_dir)}&quot; if Dir.exists?(fetch(:assets_dir))
          commands &lt;&lt; &quot;#{rsync_shell} ./#{fetch(:packs_dir)}  #{release_dir}/#{fetch(:packs_dir)}&quot;  if Dir.exists?(fetch(:packs_dir))
          commands &lt;&lt; &quot;#{rsync_shell} ./#{fetch(:cache_dir)}  #{release_dir}/#{fetch(:cache_dir)}&quot;  if Dir.exists?(fetch(:cache_dir))

          commands.each { |command| dry_run? ? SSHKit.config.output.info(command) : execute(command) }
        end
      end
    end
  end
end

namespace :load do
  task :defaults do
    set :assets_role, 'web'
    set :assets_dir,  'public/assets/'
    set :packs_dir,   'public/packs/'
    set :cache_dir,   'tmp/cache/'

    after 'deploy:migrate', 'deploy:assets:local_precompile'
    after 'deploy:assets:local_precompile', 'deploy:assets:rsync_assets'
  end
end" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">namespace </span><span style="color: #BF9EEE">:deploy</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  namespace </span><span style="color: #BF9EEE">:assets</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    desc </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">Precompile assets locally</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">    task </span><span style="color: #BF9EEE">:local_precompile</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">      run_locally </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">        execute </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">rm -rf </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:cache_dir</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">        execute </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">RAILS_ENV=</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:rails_env</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> bundle exec rake assets:clean</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">        execute </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">RAILS_ENV=</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:rails_env</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> bundle exec rake assets:precompile</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    desc </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">rsync assets to web server</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">    task </span><span style="color: #BF9EEE">:rsync_assets</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">      on roles(</span><span style="color: #BF9EEE">:web</span><span style="color: #F6F6F4">), in</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">:parallel</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span><span style="color: #F6F6F4"> |server|</span></span>
<span class="line"><span style="color: #F6F6F4">        run_locally </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">          ssh_shell   </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">%(</span><span style="color: #E7EE98">-e &quot;ssh -i </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:ssh_options</span><span style="color: #E7EE98">)[</span><span style="color: #BF9EEE">:keys</span><span style="color: #E7EE98">].first</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">&quot;</span><span style="color: #DEE492">)</span></span>
<span class="line"><span style="color: #F6F6F4">          rsync_shell </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">rsync -avz </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">ssh_shell</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">          release_dir </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">username@public-ip-address:</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">release_path</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">          commands    </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> []</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">          commands </span><span style="color: #F286C4">&lt;&lt;</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">rsync_shell</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> ./</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:assets_dir</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">release_dir</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:assets_dir</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Dir</span><span style="color: #F6F6F4">.exists?(fetch(</span><span style="color: #BF9EEE">:assets_dir</span><span style="color: #F6F6F4">))</span></span>
<span class="line"><span style="color: #F6F6F4">          commands </span><span style="color: #F286C4">&lt;&lt;</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">rsync_shell</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> ./</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:packs_dir</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">  </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">release_dir</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:packs_dir</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">  </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Dir</span><span style="color: #F6F6F4">.exists?(fetch(</span><span style="color: #BF9EEE">:packs_dir</span><span style="color: #F6F6F4">))</span></span>
<span class="line"><span style="color: #F6F6F4">          commands </span><span style="color: #F286C4">&lt;&lt;</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">rsync_shell</span><span style="color: #F286C4">}</span><span style="color: #E7EE98"> ./</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:cache_dir</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">  </span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">release_dir</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">/</span><span style="color: #F286C4">#{</span><span style="color: #E7EE98">fetch(</span><span style="color: #BF9EEE">:cache_dir</span><span style="color: #E7EE98">)</span><span style="color: #F286C4">}</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">  </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Dir</span><span style="color: #F6F6F4">.exists?(fetch(</span><span style="color: #BF9EEE">:cache_dir</span><span style="color: #F6F6F4">))</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">          commands.each { |command| dry_run? </span><span style="color: #F286C4">?</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">SSHKit</span><span style="color: #F6F6F4">.config.output.info(command) : execute(command) }</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">namespace </span><span style="color: #BF9EEE">:load</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  task </span><span style="color: #BF9EEE">:defaults</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">    set </span><span style="color: #BF9EEE">:assets_role</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">web</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">    set </span><span style="color: #BF9EEE">:assets_dir</span><span style="color: #F6F6F4">,  </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">public/assets/</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">    set </span><span style="color: #BF9EEE">:packs_dir</span><span style="color: #F6F6F4">,   </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">public/packs/</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">    set </span><span style="color: #BF9EEE">:cache_dir</span><span style="color: #F6F6F4">,   </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">tmp/cache/</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    after </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">deploy:migrate</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">deploy:assets:local_precompile</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">    after </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">deploy:assets:local_precompile</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">deploy:assets:rsync_assets</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">end</span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Rake task này có hai nhiệm vụ
<ul class="wp-block-list">
<li>Precompile assets ở local</li>



<li>Đồng bộ files lên server</li>
</ul>
</li>
</ul>



<ul class="wp-block-list">
<li>Server không cần phải thực hiện <code><strong>yarn:install</strong></code> và <code><strong>deploy:assets:precompile</strong></code> mỗi khi deploy nữa</li>
</ul>



<ul class="wp-block-list">
<li>Clean code khi dùng local precompile</li>
</ul>



<p><code>Gemfile</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="group :development do
  # Capistrano - easy to deployment with Ruby over SSH
  gem 'capistrano', '~&gt; 3.18'
  # rbenv integration for Capistrano
  gem 'capistrano-rbenv', '~&gt; 2.2'
  # Rails specific Capistrano tasks
  gem 'capistrano-rails', '~&gt; 1.6', '&gt;= 1.6.3'
  # Bundler support for Capistrano 3.x
  gem 'capistrano-bundler', '~&gt; 2.1'
end" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">group </span><span style="color: #BF9EEE">:development</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">do</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Capistrano - easy to deployment with Ruby over SSH</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 3.18</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># rbenv integration for Capistrano</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-rbenv</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 2.2</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Rails specific Capistrano tasks</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-rails</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 1.6</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">&gt;= 1.6.3</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #7B7F8B"># Bundler support for Capistrano 3.x</span></span>
<span class="line"><span style="color: #F6F6F4">  gem </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">capistrano-bundler</span><span style="color: #DEE492">&#39;</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&#39;</span><span style="color: #E7EE98">~&gt; 2.1</span><span style="color: #DEE492">&#39;</span></span>
<span class="line"><span style="color: #F286C4">end</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="bundle install" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">bundle</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">install</span></span></code></pre></div>



<p><code>Capfile</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="require &quot;capistrano/rbenv&quot;
set :rbenv_type, :user
set :rbenv_ruby, &quot;2.7.0&quot;
set :rbenv_map_bins, %w[rake gem bundle ruby rails]
set :rbenv_roles, :all

require &quot;capistrano/bundler&quot;
require &quot;capistrano/rails/migrations&quot;" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/rbenv</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_type</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:user</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_ruby</span><span style="color: #F6F6F4">, </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">2.7.0</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_map_bins</span><span style="color: #F6F6F4">, </span><span style="color: #F286C4">%</span><span style="color: #F6F6F4">w[rake gem bundle ruby rails]</span></span>
<span class="line"><span style="color: #F6F6F4">set </span><span style="color: #BF9EEE">:rbenv_roles</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">:all</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/bundler</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F286C4">require</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">capistrano/rails/migrations</span><span style="color: #DEE492">&quot;</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Commit code và push lên Git Repository của bạn</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="cap production deploy" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">cap</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">production</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">deploy</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Quan sát <code><strong>htop</strong></code> bạn sẽ không còn thấy sự ảnh hưởng đến workload của CPU và Memory trong quá trình deploy nữa</li>
</ul>



<h2 id="loi-ket" class="wp-block-heading">Lời kết</h2>



<ul class="wp-block-list">
<li>Bài viết là một trong những giải pháp liên quan đến hiệu suất server mà team mình đã từng áp dụng trong thực tế</li>
</ul>



<ul class="wp-block-list">
<li>Chúc các bạn thực hiện thành công và có những trải nghiệm tuyệt vời trên server yêu dấu của client nhé 😆</li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/deploy-rails-app-toi-uu-hoa-hieu-suat-server-bang-local-precompile/">Deploy Rails App: Tối Ưu Hóa Hiệu Suất Server Bằng Local Precompile</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/deploy-rails-app-toi-uu-hoa-hieu-suat-server-bang-local-precompile/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>htop: Đọc hiểu hiệu suất server</title>
		<link>https://blog.tomosia.com.vn/htop-doc-hieu-hieu-suat-server/</link>
					<comments>https://blog.tomosia.com.vn/htop-doc-hieu-hieu-suat-server/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Wed, 13 Dec 2023 09:43:03 +0000</pubDate>
				<category><![CDATA[OS & Command]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2527</guid>

					<description><![CDATA[<p>Đọc hiểu thông tin từ htop Tuỳ chỉnh hiển thị Lời kết</p>
<p>The post <a href="https://blog.tomosia.com.vn/htop-doc-hieu-hieu-suat-server/">htop: Đọc hiểu hiệu suất server</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<ul class="wp-block-list">
<li><strong><code>htop</code></strong> là một tiện ích quản lý tiến trình dựa trên dòng lệnh, cung cấp một cái nhìn trực quan về tình trạng hiệu suất của server</li>



<li>Trong bài viết này, mình sẽ chia sẻ cách đọc và hiểu thông tin từ <code><strong>htop</strong></code>, cũng như cách tùy chỉnh nó để phản ánh cho nhu cầu cụ thể của bạn</li>
</ul>



<h2 id="doc-hieu-thong-tin-tu-htop" class="wp-block-heading">Đọc hiểu thông tin từ htop</h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="631" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-1024x631.png" alt="" class="wp-image-2529" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-1024x631.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-300x185.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-768x473.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-1536x947.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-2048x1262.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-380x234.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-800x493.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM-1160x715.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-11-at-1.51.18-PM.png 3206w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Hình trên là giao diện mặc định của <strong><code>htop</code></strong></li>



<li>Layout hiển thị gồm ba thành phần chính</li>
</ul>



<ol class="wp-block-list">
<li><strong>Top left</strong>
<ul class="wp-block-list">
<li>Từ trên xuống
<ul class="wp-block-list">
<li><strong><code>CPU</code></strong>
<ul class="wp-block-list">
<li><strong><code>1 và 2</code></strong> là hai thanh tiến trình của CPU</li>



<li>Vì sao CPU lại có hai thanh tiến trình? vì server được cấu hình hai lõi CPU, nếu server của bạn có bốn lõi thì chỗ này có thể sẽ được hiển thị bốn thanh tiến trình</li>



<li>Để xem thông tin chi tiết về CPU trên ubuntu server, bạn có thể chạy lệnh sau: <code>lscpu</code></li>



<li>CPU Bar có thể giúp bạn nhanh chóng đánh giá tình trạng hiệu suất của server. Nếu bạn thấy thanh CPU màu đỏ, có thể là dấu hiệu server đang tải công việc nặng</li>
</ul>
</li>



<li><strong><code>Mem</code></strong>
<ul class="wp-block-list">
<li>Memory (RAM)</li>



<li>Các màu sắc thường thể hiện mức độ sử dụng bộ nhớ</li>



<li>+ <strong>Màu xanh lá cây:</strong> mức độ sử dụng bộ nhớ thấp hoặc không sử dụng</li>



<li>+ <strong>Màu vàng:</strong> mức độ sử dụng bộ nhớ trung bình</li>



<li>+ <strong>Màu đỏ:</strong> mức độ sử dụng bộ nhớ cao</li>



<li>Memory Bar giúp bạn đánh giá tình trạng sử dụng bộ nhớ của server và xác định xem liệu có cần thực hiện các biện pháp như giải phóng bộ nhớ, tối ưu hóa các tiến trình hoặc nâng cấp bộ nhớ hay không</li>
</ul>
</li>



<li><strong><code>Swp</code></strong>
<ul class="wp-block-list">
<li>Swap Usage</li>



<li>Là một phần không gian của ổ cứng được OS sử dụng như bộ nhớ ảo</li>



<li>Khi đầy RAM thì OS sẽ tự động chuyển một số dữ liệu không sử dụng sang vùng <strong><code>Swap</code></strong> để tạo không gian cho các tiến trình khác</li>



<li>Khi bạn quan sát thấy thanh <code><strong>Swp</strong></code> này thường xuyên đầy đặn là dấu hiệu server đang sử dụng nhiều swap, có thể ảnh hưởng đến performance vì truy cập dữ liệu từ ổ cứng thường sẽ chậm hơn RAM</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>



<li><strong>Top right</strong>
<ul class="wp-block-list">
<li>Từ trên xuống
<ul class="wp-block-list">
<li>Tasks
<ul class="wp-block-list">
<li>Số liệu về tổng số tiến trình đang chạy trên server</li>



<li><strong><code>Tasks: 39, 51 thr; 1 running</code></strong> có ý nghĩa</li>



<li>+ Tổng số tiến trình là 39</li>



<li>+ Tổng số luồng (bao gồm cả đang chạy và không chạy) là 51</li>



<li>+ Có 1 tiến trình đang chạy</li>
</ul>
</li>



<li>Load average
<ul class="wp-block-list">
<li>Chỉ số này thể hiện tải trung bình của server trong một khoảng thời gian nhất định, lần lượt theo thứ tự <code><strong>1 -&gt; 5 -&gt; 15</strong></code> phút</li>



<li><strong><code>Load average: 0.5 0.6 0.11</code></strong> có ý nghĩa</li>



<li>+ Load average trong 1 phút gần nhất là 0.5</li>



<li>+ Load average trong 5 phút gần nhất là 0.6</li>



<li>+ Load average trong 15 phút gần nhất là 0.11</li>



<li>Các con số này đại diện cho tỉ lệ của công việc đang chờ (đang chạy hoặc đợi) so với tổng số lõi CPU</li>



<li>Nếu số này thấp (gần 0) nghĩa là server đang chạy nhẹ và có nhiều tài nguyên còn trống</li>



<li>Nếu số này cao (lớn hơn số lõi CPU) thì đó có thể là dấu hiệu của tải nặng và hệ server phải xử lý nhiều công việc</li>
</ul>
</li>



<li>Uptime
<ul class="wp-block-list">
<li>Là khoảng thời gian hoạt động liên tục kể từ thời điểm gần nhất mà server được <code>start/restart</code></li>



<li><code><strong>uptime = DateTime.now - start/restart time</strong></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>



<li><strong>Bảng danh sách các tiến trình</strong>
<ul class="wp-block-list">
<li><strong>PID (Process ID)</strong> là một số nguyên duy nhất đại diện cho ID của tiến trình</li>



<li><strong>USER</strong> là tên người dùng chạy tiến trình. Cột này hiển thị thông tin về người dùng sở hữu tiến trình</li>



<li><strong>PRI (Priority)</strong> là độ ưu tiên của tiến trình. Số càng lớn thì độ ưu tiên càng thấp</li>



<li><strong>NI (Nice value)</strong> cũng là một số chỉ đánh giá sự ưu tiên của tiến trình. Nice value âm thường có độ ưu tiên cao hơn</li>



<li><strong>VIRT (Virtual memory)</strong> là lượng bộ nhớ ảo mà tiến trình đang sử dụng</li>



<li><strong>RES (Resident memory)</strong> là lượng bộ nhớ thực tế đang được sử dụng bởi tiến trình</li>



<li><strong>SHR (Shared memory)</strong> là lượng bộ nhớ được sử dụng chung giữa các tiến trình</li>



<li><strong>S (Status)</strong> là trạng thái của tiến trình
<ul class="wp-block-list">
<li><strong>R (Running)</strong> là tiến trình đang thực thi và đang chạy hoặc sẵn sàng chạy</li>



<li><strong>S (Sleeping)</strong> là tiến trình đang ở trạng thái chờ đợi mà không chiếm tài nguyên CPU. Có thể là đang chờ sự kiện nào đó để xảy ra</li>



<li><strong>D (Disk sleep)</strong> là tiến trình đang chờ đợi dữ liệu từ ổ đĩa hoặc thiết bị lưu trữ khác</li>



<li>Thông thường, trạng thái &#8220;<strong>D&#8221;</strong> không phải là điều tốt đẹp vì nó có thể làm tăng tải cho server nếu có quá nhiều tiến trình chờ đợi <code><strong>I/O</strong></code></li>



<li>Nếu bạn gặp phải trạng thái <strong>&#8220;D&#8221;</strong> liên tục cho một tiến trình cụ thể thì bạn nên kiểm tra và giải quyết vấn đề liên quan đến <code><strong>I/O</strong></code> như sự cố với ổ đĩa hoặc dữ liệu lưu trữ</li>
</ul>
</li>



<li><strong>CPU%</strong> là phần trăm của CPU mà tiến trình đang sử dụng</li>



<li><strong>MEM%</strong> là phần trăm của bộ nhớ RAM mà tiến trình đang sử dụng</li>



<li><strong>TIME+</strong> là thời gian tiêu thụ CPU của bởi tiến trình kể từ khi nó được bắt đầu</li>



<li><strong>Command</strong> là dòng lệnh hoặc tên của tiến trình</li>



<li><strong><em><code>Các tiến trình được sắp xếp mặc định theo CPU% giảm dần</code></em></strong></li>
</ul>
</li>
</ol>



<h2 id="tuy-chinh-hien-thi" class="wp-block-heading">Tuỳ chỉnh hiển thị</h2>



<ul class="wp-block-list">
<li>Bạn chỉ cần bấm F2 và tuỳ chỉnh những gì mình mong muốn</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="632" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-1024x632.png" alt="" class="wp-image-2570" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-1024x632.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-300x185.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-768x474.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-1536x949.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-2048x1265.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-380x235.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-800x494.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM-1160x716.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.46.50-PM.png 3206w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Phần <strong>Setup</strong> này mô tả rất chi tiết về công dụng của mỗi thuộc tính. Do đó, để điều chỉnh giao diện của <code><strong>htop</strong></code> phản ánh đúng nhu cầu thì bạn nên đọc kỹ hướng dẫn sử dụng trước khi dùng</li>



<li>Tuỳ chỉnh sẽ được hiển thị realtime ngay khi bạn lưu lại 🤣</li>



<li>Hình dưới là một ví dụ tuỳ chỉnh <code><strong>htop</strong></code> mà mình tự chế cho dễ nhìn hơn 😝</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="632" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-1024x632.png" alt="" class="wp-image-2571" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-1024x632.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-300x185.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-768x474.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-1536x948.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-2048x1264.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-380x234.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-800x494.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM-1160x716.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-12-at-9.53.25-PM.png 3206w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 id="loi-ket" class="wp-block-heading">Lời kết</h2>



<ul class="wp-block-list">
<li>Hi vọng bài viết của mình sẽ giúp bạn thoải mái sử dụng <code><strong>htop</strong></code> để theo dõi hiệu suất server và giải quyết các vấn đề liên quan, ví dụ như các câu hỏi của sếp: <em><code>mày có hiểu cái này là gì không? còn cái này và cái này...</code></em><code>😵‍💫 😂</code></li>



<li>Chúc bạn có những trải nghiệm tốt với <code><strong>htop</strong></code></li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/htop-doc-hieu-hieu-suat-server/">htop: Đọc hiểu hiệu suất server</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/htop-doc-hieu-hieu-suat-server/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Upload File Lên Amazon S3: Dùng Multipart Upload vs AWS CLI</title>
		<link>https://blog.tomosia.com.vn/upload-file-len-amazon-s3-dung-multipart-upload-vs-aws-cli/</link>
					<comments>https://blog.tomosia.com.vn/upload-file-len-amazon-s3-dung-multipart-upload-vs-aws-cli/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Mon, 11 Dec 2023 01:38:52 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[Aws]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2273</guid>

					<description><![CDATA[<p>Việc upload file lên Amazon S3 sẽ trở nên mạnh mẽ và hiệu quả hơn với Multipart Upload&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/upload-file-len-amazon-s3-dung-multipart-upload-vs-aws-cli/">Upload File Lên Amazon S3: Dùng Multipart Upload vs AWS CLI</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Việc upload file lên Amazon S3 sẽ trở nên mạnh mẽ và hiệu quả hơn với Multipart Upload và AWS CLI. Trong bài viết này, chúng ta sẽ khám phá cách sử dụng công cụ dòng lệnh mạnh mẽ của AWS để tối ưu hóa quá trình upload và đảm bảo tính toàn vẹn của dữ liệu</p>



<h2 id="aws-cli-configuration" class="wp-block-heading">AWS CLI Configuration</h2>



<ul class="wp-block-list">
<li>VIệc đầu tiên cần kiểm tra xem máy của bạn đã được cấu hình AWS CLI chưa</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws configure list" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">configure</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">list</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="222" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-8.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-12-05-at-8.08.01-AM-1024x222.png" class="wp-image-2284" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-8.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-8-300x65.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-8-768x167.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-8-380x82.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-8-800x173.png 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Bạn có thể cấu hình một profile mới như sau</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws configure" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">configure</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="148" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM-1024x148.png" alt="" class="wp-image-2285" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM-1024x148.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM-300x43.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM-768x111.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM-380x55.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM-800x116.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM-1160x168.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.18.15-AM.png 1452w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Tạo một bucket trên S3</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="601" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-10.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-12-05-at-8.32.39-PM-1024x601.png" class="wp-image-2331" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-10.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-10-300x176.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-10-768x451.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-10-380x223.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-10-800x470.png 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Chuẩn bị file muốn upload</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="96" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM-1024x96.png" alt="" class="wp-image-2329" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM-1024x96.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM-300x28.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM-768x72.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM-380x36.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM-800x75.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM-1160x109.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-05-at-8.44.24-PM.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 id="use-high-level-aws-s3-commands" class="wp-block-heading">Use high-level aws s3 commands</h2>



<ul class="wp-block-list">
<li>Để dùng high-level&nbsp;command cho multipart upload, có thể chạy lệnh sau</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3 cp large_test_file s3://DOC-EXAMPLE-BUCKET/" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">cp</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">large_test_file</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3://DOC-EXAMPLE-BUCKET/</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="59" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM-1024x59.png" alt="" class="wp-image-2427" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM-1024x59.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM-300x17.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM-768x44.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM-380x22.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM-800x46.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM-1160x67.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-8.00.07-AM.png 1494w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Khi bạn sử dụng lệnh <code><strong>aws s3 cp</strong></code> để tải lên một file vào Amazon S3, AWS CLI có thể tự quyết định xem có nên dùng <strong><code>multipart upload</code></strong> hay không, dựa vào kích thước của file và các cấu hình liên quan</li>
</ul>



<ul class="wp-block-list">
<li>Tốc độ upload còn phụ thuộc vào tốc độ wifi nhưng nhìn chung là upload khá nhanh</li>
</ul>



<ul class="wp-block-list">
<li>Để mã hoá file khi upload, có thể dùng lệnh sau</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3 cp large_test_file s3://DOC-EXAMPLE-BUCKET/ --metadata md5=&quot;examplemd5value1234/4Q&quot;" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">cp</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">large_test_file</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3://DOC-EXAMPLE-BUCKET/</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--metadata</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">md5=</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">examplemd5value1234/4Q</span><span style="color: #DEE492">&quot;</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Để config max concurrent request, có thể chạy lệnh sau <em>(mặc định là 10)</em></li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws configure set default.s3.max_concurrent_requests 20" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">configure</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">set</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">default.s3.max_concurrent_requests</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">20</span></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>Lưu ý:</strong> max_concurrent_requests càng nhiều thì trong quá trình upload sẽ tiêu hao nhiều băng thông và tài nguyên của máy chủ hơn</li>
</ul>



<ul class="wp-block-list">
<li>Để biết thêm thông tin về cách định cấu hình AWS CLI với Amazon S3 thì hãy xem <a href="https://awscli.amazonaws.com/v2/documentation/api/latest/topic/s3-config.html" target="_blank" rel="noreferrer noopener"><strong>AWS CLI S3 configuration</strong></a></li>
</ul>



<ul class="wp-block-list">
<li>Ngoài lệnh copy, bạn cũng có thể sử dụng các lệnh AWS S3 khác liên quan đến việc tải object lên S3 như <strong><code>aws s3 sync</code></strong> hoặc <strong><code>aws s3 mv</code></strong></li>
</ul>



<ul class="wp-block-list">
<li> Để xem thêm các options khi copy, có thể dùng lệnh sau</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3 cp help" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">cp</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">help</span></span></code></pre></div>



<h2 id="use-low-level-aws-s3api-commands" class="wp-block-heading">Use low-level aws s3api commands</h2>



<p>1. Chia file bạn muốn tải lên thành nhiều phần</p>



<ul class="wp-block-list">
<li><strong>Ubuntu:</strong> <a href="https://askubuntu.com/questions/54579/how-to-split-larger-files-into-smaller-parts">https://askubuntu.com/questions/54579/how-to-split-larger-files-into-smaller-parts</a></li>
</ul>



<ul class="wp-block-list">
<li><strong>MacOS</strong></li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="split -b fileSize path/to/filename" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">split</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">-b</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">fileSize</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">path/to/filename</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="114" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM-1024x114.png" alt="" class="wp-image-2453" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM-1024x114.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM-300x33.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM-768x86.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM-380x42.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM-800x89.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM-1160x129.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-2.17.51-PM.png 1454w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Mình thử split một file hơn 20MB thì nó sẽ tự động sinh ra 5 files con với tên random như hình minh hoạ</li>
</ul>



<p>2. Chạy lệnh sau để khởi tạo multipart upload và truy xuất liên kết với một <strong>UploadID</strong>, kết quả phản hồi có chứa UploadID value</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3api create-multipart-upload --bucket DOC-EXAMPLE-BUCKET --key large-test-file" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3api</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">create-multipart-upload</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--bucket</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">DOC-EXAMPLE-BUCKET</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--key</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">large-test-file</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="118" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-15.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-12-08-at-2.37.13-PM-1024x118.png" class="wp-image-2463" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-15.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-15-300x35.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-15-768x89.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-15-380x44.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/image-15-800x92.png 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>3. Copy UploadID value để dùng cho các bước sau</p>



<p>4. Chạy lệnh sau để upload các files part đã split ở trên, kết quả phản hồi có chứa <strong>ETag</strong> value</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3api upload-part --bucket DOC-EXAMPLE-BUCKET --key large-test-file --part-number 1 --body large-test-file.001 --upload-id UploadID" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3api</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">upload-part</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--bucket</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">DOC-EXAMPLE-BUCKET</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--key</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">large-test-file</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--part-number</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--body</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">large-test-file.001</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--upload-id</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">UploadID</span></span></code></pre></div>



<p>5.&nbsp;&nbsp;&nbsp;&nbsp;Copy&nbsp;<strong>ETag</strong>&nbsp;value để dùng cho bước sau</p>



<p>6. Lặp lại bước 4 &amp; 5 đến khi upload hết các files part</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="304" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-1024x304.png" alt="" class="wp-image-2468" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-1024x304.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-300x89.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-768x228.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-1536x456.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-2048x607.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-380x113.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-800x237.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM-1160x344.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.06.30-PM.png 3196w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>7. Tạo một file <strong>fileparts.json</strong> với nội dung là <strong>ETag</strong> value của các part đã upload ở trên</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">JSON</span><span role="button" tabindex="0" data-code="{
  &quot;Parts&quot;: [
    {
      &quot;ETag&quot;: &quot;example8be9a0268ebfb8b115d4c1fd3&quot;,
      &quot;PartNumber&quot;:1
    },
    {
        &quot;ETag&quot;: &quot;example246e31ab807da6f62802c1ae8&quot;,
        &quot;PartNumber&quot;:2
    }
  ]
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">{</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">Parts</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> [</span></span>
<span class="line"><span style="color: #F6F6F4">    {</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">ETag</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">example8be9a0268ebfb8b115d4c1fd3</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">      </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">PartNumber</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">1</span></span>
<span class="line"><span style="color: #F6F6F4">    },</span></span>
<span class="line"><span style="color: #F6F6F4">    {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">ETag</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">example246e31ab807da6f62802c1ae8</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">PartNumber</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #BF9EEE">2</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">  ]</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="791" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM-1024x791.png" alt="" class="wp-image-2470" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM-1024x791.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM-300x232.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM-768x593.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM-380x293.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM-800x618.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM-1160x896.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.19.55-PM.png 1238w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>8. Chạy lệnh sau để hoàn thành quá trình upload</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3api complete-multipart-upload --multipart-upload file://path/to/fileparts.json --bucket DOC-EXAMPLE-BUCKET --key large-test-file --upload-id UploadID" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3api</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">complete-multipart-upload</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--multipart-upload</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">file://path/to/fileparts.json</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--bucket</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">DOC-EXAMPLE-BUCKET</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--key</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">large-test-file</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--upload-id</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">UploadID</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Kết quả phản hồi sẽ có chứa <strong>Location</strong> value là url dẫn đến file trên S3 của bạn</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">JSON</span><span role="button" tabindex="0" data-code="{
    &quot;ETag&quot;: &quot;exampleae01633ff0af167d925cad279-2&quot;,
    &quot;Bucket&quot;: &quot;DOC-EXAMPLE-BUCKET&quot;,
    &quot;Location&quot;: &quot;https://DOC-EXAMPLE BUCKET.s3.amazonaws.com/large-test-file&quot;,
   
    &quot;Key&quot;: &quot;large-test-file&quot;
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">{</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">ETag</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">exampleae01633ff0af167d925cad279-2</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">Bucket</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">DOC-EXAMPLE-BUCKET</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">Location</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">https://DOC-EXAMPLE BUCKET.s3.amazonaws.com/large-test-file</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">   </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">Key</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">large-test-file</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="122" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-1024x122.png" alt="" class="wp-image-2471" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-1024x122.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-300x36.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-768x91.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-1536x183.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-2048x244.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-380x45.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-800x95.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM-1160x138.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screen-Shot-2023-12-08-at-3.31.56-PM.png 3194w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 id="resolve-upload-failures" class="wp-block-heading">Resolve upload failures</h2>



<p>1. Chạy lệnh sau để xem tất cả multipart-upload chưa hoàn thành</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3api list-multipart-uploads --bucket DOC-EXAMPLE-BUCKET" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3api</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">list-multipart-uploads</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--bucket</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">DOC-EXAMPLE-BUCKET</span></span></code></pre></div>



<pre class="wp-block-code"><code>{
  "Uploads": &#91;
    {     
      "Initiator": {
        "DisplayName": "multipartmessage",
        "ID": "290xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      },
      "Initiated": "2016-03-31T06:13:15.000Z",
      "UploadId": "examplevQpHp7eHc_J5s9U.kzM3GAHeOJh1P8wVTmRqEVojxxu...",
      "StorageClass": "STANDARD", 
      "Key": "",
      "Owner": {
        "DisplayName": "multipartmessage",
        "ID": "290xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  ]
}</code></pre>



<p>2. Chạy lệnh sau để remove UploadID chưa hoàn thành</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="aws s3api abort-multipart-upload --bucket DOC-EXAMPLE-BUCKET --key Key --upload-id UploadID" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3api</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">abort-multipart-upload</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--bucket</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">DOC-EXAMPLE-BUCKET</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--key</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">Key</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--upload-id</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">UploadID</span></span></code></pre></div>



<h2 id="tai-lieu-tham-khao" class="wp-block-heading">Tài liệu tham khảo</h2>



<ul class="wp-block-list">
<li><a href="https://repost.aws/knowledge-center/s3-multipart-upload-cli">https://repost.aws/knowledge-center/s3-multipart-upload-cli</a></li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/upload-file-len-amazon-s3-dung-multipart-upload-vs-aws-cli/">Upload File Lên Amazon S3: Dùng Multipart Upload vs AWS CLI</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/upload-file-len-amazon-s3-dung-multipart-upload-vs-aws-cli/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Logrotate: Compress và push file log lên S3</title>
		<link>https://blog.tomosia.com.vn/logrotate-compress-va-push-file-log-len-s3/</link>
					<comments>https://blog.tomosia.com.vn/logrotate-compress-va-push-file-log-len-s3/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Wed, 22 Nov 2023 01:54:57 +0000</pubDate>
				<category><![CDATA[Web Server]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[logrotate]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1939</guid>

					<description><![CDATA[<p>Log files giúp bạn hiểu rõ về lịch sử hoạt động của máy chủ nhưng chúng có thể&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/logrotate-compress-va-push-file-log-len-s3/">Logrotate: Compress và push file log lên S3</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Log files giúp bạn hiểu rõ về lịch sử hoạt động của máy chủ nhưng chúng có thể trở nên nặng nề và khó quản lý</p>



<p>Logrotate không chỉ giúp giảm kích thước file log một cách tự động mà còn có thể nén file để tiết kiệm không gian lưu trữ</p>



<p>Trong bài viết này, chúng ta sẽ tìm hiểu cách Logrotate được cấu hình để tự động nén và đẩy file lên S3, giúp bạn duy trì hệ thống được sạch sẽ và dễ quản lý hơn</p>



<h2 id="config" class="wp-block-heading">Config</h2>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="cd /etc/logrotate.d
touch rails_log_rotation" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #97E1F1">cd</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/etc/logrotate.d</span></span>
<span class="line"><span style="color: #62E884">touch</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">rails_log_rotation</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="/home/ubuntu/path-to-deploy/current/log/production.log {
  daily
  dateext
  missingok
  rotate 90
  compress
  copytruncate
  lastaction
    aws s3 sync /home/ubuntu/path-to-deploy/current/log/ s3://path-to-bucket-name --exclude &quot;*&quot; --include &quot;production.log*.gz&quot; 2&gt;&amp;1
  endscript
  create 0644 root root
  su root root
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">/home/ubuntu/path-to-deploy/current/log/production.log</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">{</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">daily</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">dateext</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">missingok</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">rotate</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">90</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">compress</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">copytruncate</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">lastaction</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">aws</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">sync</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/home/ubuntu/path-to-deploy/current/log/</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">s3://path-to-bucket-name</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--exclude</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">*</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">--include</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">production.log*.gz</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">2&gt;&amp;1</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">endscript</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">create</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0644</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">root</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">root</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #62E884">su</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">root</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">root</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p><code><strong>home/ubuntu/path-to-deploy/current/log/production.log</strong></code></p>



<ul class="wp-block-list">
<li>Link đến file log cần được quản lý bởi logrotate</li>
</ul>



<p><code><strong>daily</strong></code></p>



<ul class="wp-block-list">
<li>Thực hiện xoay vòng log hàng ngày (được thực hiện bằng cron-job)</li>
</ul>



<ul class="wp-block-list">
<li>Có nghĩa là file <code>/home/ubuntu/path-to-deploy/current/log/production.log</code> sẽ được làm mới mỗi ngày</li>
</ul>



<ul class="wp-block-list">
<li>Check cron configuration</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="cd /etc/
ls | grep cron
cron.d
cron.daily
cron.hourly
cron.monthly
cron.weekly
crontab" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #97E1F1">cd</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/etc/</span></span>
<span class="line"><span style="color: #62E884">ls</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">|</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">grep</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">cron</span></span>
<span class="line"><span style="color: #62E884">cron.d</span></span>
<span class="line"><span style="color: #62E884">cron.daily</span></span>
<span class="line"><span style="color: #62E884">cron.hourly</span></span>
<span class="line"><span style="color: #62E884">cron.monthly</span></span>
<span class="line"><span style="color: #62E884">cron.weekly</span></span>
<span class="line"><span style="color: #62E884">crontab</span></span></code></pre></div>



<p><code><strong>dateext</strong></code></p>



<ul class="wp-block-list">
<li>Thêm ngày vào filename của file log được xoay vòng để đảm bảo không bị trùng tên</li>
</ul>



<p><code><strong>missingok</strong></code></p>



<ul class="wp-block-list">
<li>Cho phép logrotate bỏ qua nếu không tìm thấy file</li>
</ul>



<p><code><strong>rotate 90</strong></code></p>



<ul class="wp-block-list">
<li>Giữ lại tối đa 90 file logs đã quay vòng</li>



<li>Trong trường hợp này, có thể hiểu là cho phép lưu trữ file logs của 90 ngày gần nhất</li>
</ul>



<p><code><strong>compress</strong></code></p>



<ul class="wp-block-list">
<li>Nén file log đã xoay vòng để tiết kiệm không gian lưu trữ</li>
</ul>



<p><code><strong>copytruncate</strong></code></p>



<ul class="wp-block-list">
<li>Sao chép nội dung từ file cũ vào file mới, sau đó quay lại đầu file cũ và cắt bớt nó. Điều này giúp logrotate có thể xoay vòng mà không làm ảnh hưởng đến ứng dụng đang chạy</li>
</ul>



<p><code><strong>lastaction</strong></code> và <code><strong>endscript</strong></code> </p>



<ul class="wp-block-list">
<li>Bọc một đoạn code hoặc command được thực thi sau khi xoay vòng</li>



<li>Trong trường hợp này, sử dụng AWS CLI để đồng bộ hóa các file logs đã xoay vòng với Amazon S3</li>



<li>Loại trừ tất cả các files, chỉ bao gồm các file logs đã nén <code>(production.log*.gz)</code></li>



<li>Lưu ý
<ul class="wp-block-list">
<li>Bạn cần thay thế <code>path-to-bucket-name</code> bằng đường dẫn thích hợp đến S3 Bucket của bạn</li>



<li>EC2 phải tương tác được với S3 Bucket của bạn (có thể dùng <code>aws configure</code> hoặc <code>attached IAM role</code> đều được)</li>
</ul>
</li>
</ul>



<p><code><strong>create 0644 root root</strong></code></p>



<ul class="wp-block-list">
<li>Tạo một file log mới với quyền truy cập <code>0644</code> và chủ sở hữu là <code>root</code></li>
</ul>



<p><code><strong>su root root</strong></code></p>



<ul class="wp-block-list">
<li>Chuyển quyền sở hữu của file sang <code>root</code> sau khi tạo mới để đảm bảo an toàn và bảo mật</li>
</ul>



<p><strong>Tóm lại</strong></p>



<ul class="wp-block-list">
<li>Config này giúp bạn quản lý và tự động xoay vòng file <code>production.log</code> mỗi ngày</li>



<li>Nén file để tiết kiệm không gian và đồng thời sao chép lên Amazon S3 để lưu trữ</li>
</ul>



<p><strong>Manual test config</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">ShellScript</span><span role="button" tabindex="0" data-code="sudo logrotate -f /etc/logrotate.conf" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #62E884">sudo</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">logrotate</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">-f</span><span style="color: #F6F6F4"> </span><span style="color: #E7EE98">/etc/logrotate.conf</span></span></code></pre></div>
<p>The post <a href="https://blog.tomosia.com.vn/logrotate-compress-va-push-file-log-len-s3/">Logrotate: Compress và push file log lên S3</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/logrotate-compress-va-push-file-log-len-s3/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Proc và Lambda trong Ruby: Sự Khác Biệt và Cách Sử Dụng</title>
		<link>https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/</link>
					<comments>https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Wed, 15 Nov 2023 09:40:16 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1826</guid>

					<description><![CDATA[<p>Trong ngôn ngữ lập trình Ruby, Proc và Lambda đóng vai trò quan trọng, mang lại sự linh&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/">Proc và Lambda trong Ruby: Sự Khác Biệt và Cách Sử Dụng</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Trong ngôn ngữ lập trình Ruby, Proc và Lambda đóng vai trò quan trọng, mang lại sự linh hoạt cho việc xử lý hàm và thực hiện các tác vụ khác nhau. Trong bài viết này, chúng ta sẽ khám phá sự khác biệt giữa Proc và Lambda, cách chúng được tích hợp có thể làm cho mã nguồn của bạn trở nên mạnh mẽ, linh hoạt, và dễ đọc hơn. Cùng đi sâu vào thế giới của Proc và Lambda để hiểu rõ hơn và nâng cao kĩ năng lập trình của bạn!</p>



<h2 id="1-proc" class="wp-block-heading">1. Proc</h2>



<p><strong>1.1 Khái niệm</strong></p>



<ul class="wp-block-list">
<li>Proc là một class trong Ruby</li>
</ul>



<ul class="wp-block-list">
<li>Đối tượng Proc là sự đóng gói của một khối mã, có thể được lưu trữ trong một biến, được truyền vào một method hoặc Proc khác và được gọi khi cần dùng</li>
</ul>



<p><strong>1.2 Khai báo và sử dụng Proc</strong></p>



<ul class="wp-block-list">
<li>Proc có 2 cách khai báo và nhiều cách gọi</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="# Lambda-like syntax
sample_proc = Proc.new {|x| puts x}
# Or short syntax
sample_proc = proc {|x| puts x}

# Call proc (Output: 10)
sample_proc.call(10) 
# Or
sample_proc[10]
# Or
sample_proc.10
# Or
sample_proc.yield(10)" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #7B7F8B"># Lambda-like syntax</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Proc</span><span style="color: #F6F6F4">.</span><span style="color: #F286C4">new</span><span style="color: #F6F6F4"> {|x| </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span>
<span class="line"><span style="color: #7B7F8B"># Or short syntax</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">proc</span><span style="color: #F6F6F4"> {|x| </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B"># Call proc (Output: 10)</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc.call(</span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">) </span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc[</span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">]</span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc.</span><span style="color: #BF9EEE">10</span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_proc.yield(</span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">)</span></span></code></pre></div>



<h2 id="2-lambda" class="wp-block-heading">2. Lambda</h2>



<p><strong>2.1 Khái niệm</strong></p>



<ul class="wp-block-list">
<li>Lambda là một đối tượng đặc biệt của Proc, mang lại cú pháp đơn giản hơn cho việc định nghĩa hàm</li>
</ul>



<p><strong>2.2 Khai báo và sử dụng Lambda</strong></p>



<ul class="wp-block-list">
<li>Lambda có 2 cách khai báo. Cách gọi Lambda cũng giống như  gọi Proc</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Ruby</span><span role="button" tabindex="0" data-code="sample_lambda = lambda {|x| puts x}
# Or
sample_lambda = -&gt;(x) {puts x}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">sample_lambda </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">lambda</span><span style="color: #F6F6F4"> {|x| </span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span>
<span class="line"><span style="color: #7B7F8B"># Or</span></span>
<span class="line"><span style="color: #F6F6F4">sample_lambda </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">-&gt;</span><span style="color: #F6F6F4">(x) {</span><span style="color: #97E1F1">puts</span><span style="color: #F6F6F4"> x}</span></span></code></pre></div>



<h2 id="3-su-khac-biet" class="wp-block-heading">3. Sự khác biệt</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Ngoài  syntax khai báo thì Proc và Lambda còn có những điểm khác biệt sau</p>
</blockquote>



<p><strong>3.1 Parameters</strong></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="393" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-11-15-at-9.42.33-AM-1024x393.png" class="wp-image-1848" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-300x115.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-768x295.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-380x146.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-19-800x307.png 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Proc không cần truyền đúng số lượng <code>arguments</code> vẫn hoạt động tốt</li>



<li>Lambda bắt buộc truyền đúng số lượng <code>arguments</code> nếu không sẽ raise errors</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="370" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1024x370.png" alt="" class="wp-image-1876" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1024x370.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-300x108.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-768x277.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1536x554.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-380x137.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-800x289.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM-1160x419.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.58.53-AM.png 1718w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Proc có khả năng giải cấu trúc mảng để tương ứng với <code>arguments</code></li>



<li>Lambda thì không</li>
</ul>



<p><strong>3.2 Return</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="450" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-1024x450.png" alt="" class="wp-image-1854" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-1024x450.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-300x132.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-768x337.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-380x167.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-800x352.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM-1160x510.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.05.44-AM.png 1238w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Khi gặp lệnh <code>return</code> trong method
<ul class="wp-block-list">
<li>Proc lập tức thoát hàm và không xử lý gì thêm</li>



<li>Lambda vẫn xử lý như một method thông thường</li>
</ul>
</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="497" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1024x497.png" alt="" class="wp-image-1860" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1024x497.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-300x146.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-768x373.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1536x745.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-380x184.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-800x388.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM-1160x563.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-10.21.13-AM.png 1670w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Khi <code>return</code> hiện diện trực tiếp trong block
<ul class="wp-block-list">
<li>Proc sẽ báo lỗi khi gọi</li>



<li>Lambda vẫn hoạt động tốt<br></li>
</ul>
</li>
</ul>



<pre class="wp-block-code"><code>Đây là lý do vì sao trong Rails, bạn sẽ hiếm khi thấy ai dùng Proc để viết scope, vì Proc kém linh hoạt hơn Lambda ở cú pháp return này</code></pre>



<h2 id="4-mot-vai-method-khac" class="wp-block-heading">4. Một vài method khác</h2>



<p><strong>4.1 lambda?</strong></p>



<p>Để kiểm tra một đối tượng Proc có phải là lambda hay không</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="628" height="202" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM.png" alt="" class="wp-image-1877" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM.png 628w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM-300x96.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-15-at-11.06.07-AM-380x122.png 380w" sizes="auto, (max-width: 628px) 100vw, 628px" /></figure>



<p><strong>4.2 <strong>source_location</strong></strong></p>



<p>Trả về tên file và số dòng chứa đối tượng Proc này</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="924" height="202" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-11-15-at-11.13.57-AM.png" class="wp-image-1881" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20.png 924w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-300x66.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-768x168.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-380x83.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/image-20-800x175.png 800w" sizes="auto, (max-width: 924px) 100vw, 924px" /></figure>



<p><strong>4.3 Others</strong></p>



<p>Còn rất nhiều method hữu ích dành cho <code>proc</code> và <code>lambda</code>, bạn có thể tham khảo trực tiếp trên docs của Ruby</p>



<p><a href="https://ruby-doc.org/3.1.2/Proc.html">https://ruby-doc.org/3.1.2/Proc.html</a></p>



<h2 id="5-loi-ket" class="wp-block-heading">5. Lời kết</h2>



<ul class="wp-block-list">
<li>Chúng ta đã khám phá xong sự khác biệt giữa <code>Proc</code> và <code>Lambda</code> trong Ruby</li>



<li>Dù cả hai đều là đối tượng của Proc nhưng Lambda mang lại sự linh hoạt hơn với cú pháp khai báo, xử lý tham số nghiêm túc, và kiểm soát lệnh <code>return</code></li>



<li><code>Proc</code> và <code>Lambda</code> đều có vai trò quan trọng trong việc làm cho mã nguồn Ruby trở nên mạnh mẽ và dễ đọc hơn, tùy thuộc vào ngữ cảnh sử dụng</li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/">Proc và Lambda trong Ruby: Sự Khác Biệt và Cách Sử Dụng</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/proc-va-lambda-trong-ruby-su-khac-biet-va-cach-su-dung/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Các bước triển khai trang web tĩnh bằng AWS S3</title>
		<link>https://blog.tomosia.com.vn/cac-buoc-trien-khai-trang-web-tinh-bang-aws-s3/</link>
					<comments>https://blog.tomosia.com.vn/cac-buoc-trien-khai-trang-web-tinh-bang-aws-s3/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Wed, 08 Nov 2023 09:19:24 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1750</guid>

					<description><![CDATA[<p>Triển khai trang web tĩnh (static web page) bằng Amazon Web Services (AWS) S3 là một cách hiệu&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/cac-buoc-trien-khai-trang-web-tinh-bang-aws-s3/">Các bước triển khai trang web tĩnh bằng AWS S3</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Triển khai trang web tĩnh (static web page) bằng Amazon Web Services (AWS) S3 là một cách hiệu quả và tiết kiệm chi phí để đưa trang web của bạn lên internet. Bài viết này sẽ hướng dẫn bạn từng bước cách triển khai trang web tĩnh bằng AWS S3</p>



<h3 id="buoc-1-chuan-bi-noi-dung-trang-web" class="wp-block-heading">Bước 1: Chuẩn bị nội dung trang web</h3>



<p>Trước tiên, bạn cần chuẩn bị nội dung cho trang web tĩnh của mình. Đây có thể là các tệp HTML, CSS, JavaScript, hình ảnh và bất kỳ tài liệu tĩnh nào khác bạn muốn hiển thị trên trang web của mình</p>



<p>Static website template source code: <a href="https://github.com/thuc-pt/fe-zing-mp3">https://github.com/thuc-pt/fe-zing-mp3</a></p>



<h3 id="buoc-2-tao-mot-s3-bucket" class="wp-block-heading">Bước 2: Tạo một S3 bucket</h3>



<ul class="wp-block-list">
<li>Đăng nhập vào AWS Management Console</li>
</ul>



<ul class="wp-block-list">
<li>Chuyển đến dịch vụ <code>"S3"</code> bằng cách tìm kiếm trong thanh tìm kiếm hoặc nhấp vào nó trong danh sách các dịch vụ</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="627" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-1024x627.png" alt="" class="wp-image-1751" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-1024x627.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-768x470.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-1536x940.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-2048x1253.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-800x490.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM-1160x710.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.44.20-PM.png 3200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Click nút <code>"Create bucket"</code> để tạo mới một bucket</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="627" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-1024x627.png" alt="" class="wp-image-1752" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-1024x627.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-768x471.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-1536x941.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-2048x1255.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-800x490.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM-1160x711.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.45.40-PM.png 3196w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>AWS S3 quy định <code><strong>bucket name</strong></code> là duy nhất trên toàn cầu. Nên đặt tên bucket dạng <code><strong>your-domain-name.com</strong></code></li>
</ul>



<ul class="wp-block-list">
<li>Chọn khu vực AWS (Region) mà bạn muốn lưu trữ bucket</li>
</ul>



<ul class="wp-block-list">
<li>Bỏ qua các cài đặt còn lại (hoặc tuỳ chỉnh theo nhu cầu của bạn) và nhấp vào nút <code>"Create bucket"</code> ở cuối trang để tạo bucket</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="628" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-1024x628.png" alt="" class="wp-image-1753" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-1024x628.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-768x471.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-1536x942.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-2048x1256.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-800x491.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM-1160x711.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.56.50-PM.png 3200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 id="buoc-3-upload-noi-dung-trang-web" class="wp-block-heading">Bước 3: Upload nội dung trang web</h3>



<ul class="wp-block-list">
<li>Chọn bucket bạn đã tạo trong danh sách S3 buckets</li>
</ul>



<ul class="wp-block-list">
<li>Nhấp vào nút <code>"Upload"</code> và sau đó chọn files bạn muốn tải lên</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="629" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-1024x629.png" alt="" class="wp-image-1754" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-1024x629.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-768x472.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-1536x943.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-2048x1258.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-800x491.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM-1160x712.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-7.59.14-PM.png 3198w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Sau khi bạn tải lên nội dung của trang web, hãy đảm bảo rằng tất cả các tệp và thư mục đều có quyền truy cập public để mọi người có thể xem được trang web của bạn. Có thể thực hiện theo các bước sau</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="628" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-1024x628.png" alt="" class="wp-image-1755" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-1024x628.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-768x471.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-1536x942.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-2048x1256.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-800x491.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM-1160x711.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.12.25-PM.png 3196w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="627" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-1024x627.png" alt="" class="wp-image-1756" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-1024x627.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-768x470.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-1536x940.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-2048x1254.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-800x490.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM-1160x710.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.13.21-PM.png 3198w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="629" data-id="1758" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-1024x629.png" alt="" class="wp-image-1758" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-1024x629.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-768x472.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-1536x944.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-2048x1258.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-800x492.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM-1160x713.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.16.27-PM.png 3200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="630" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-1024x630.png" alt="" class="wp-image-1760" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-1024x630.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-300x185.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-768x473.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-1536x945.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-2048x1260.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-380x234.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-800x492.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM-1160x714.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.19.10-PM.png 3198w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="629" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-1024x629.png" alt="" class="wp-image-1761" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-1024x629.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-768x471.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-1536x943.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-2048x1257.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-800x491.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM-1160x712.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.20.16-PM.png 3196w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Sau khi <code>"Make public"</code> xong thì tất cả các files trong bucket đều có thể được truy cập từ internet</li>
</ul>



<h3 id="buoc-4-cau-hinh-trang-web" class="wp-block-heading">Bước 4: Cấu hình trang web</h3>



<ul class="wp-block-list">
<li>Chọn bucket của bạn và chọn <code>"Properties"</code></li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="630" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-1024x630.png" alt="" class="wp-image-1762" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-1024x630.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-768x472.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-1536x944.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-2048x1259.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-380x234.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-800x492.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM-1160x713.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.28.29-PM.png 3194w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="629" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-1024x629.png" alt="" class="wp-image-1763" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-1024x629.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-300x184.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-768x472.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-1536x943.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-2048x1258.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-380x233.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-800x491.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM-1160x712.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.29.42-PM.png 3198w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Sau khi click <code>"Save changes"</code> thì tại block <strong>Static website hosting</strong> sẽ hiển thị một URL. Đây là đường dẫn đến trang web của bạn</li>



<li>Click vào URL để kiểm tra hoạt động</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="630" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-1024x630.png" alt="" class="wp-image-1764" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-1024x630.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-300x185.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-768x473.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-1536x946.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-2048x1261.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-380x234.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-800x493.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM-1160x714.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/11/Screen-Shot-2023-11-07-at-8.32.33-PM.png 3200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 id="buoc-5-tuy-chinh-ten-mien-va-ssl-optional" class="wp-block-heading">Bước 5: Tùy chỉnh tên miền và SSL (optional)</h3>



<p>Nếu bạn muốn sử dụng tên miền tùy chỉnh và cài đặt SSL cho trang web của bạn, bạn có thể sử dụng dịch vụ như Amazon CloudFront hoặc AWS Amplify</p>



<p>Bài viết này đã hướng dẫn cách triển khai trang web tĩnh bằng AWS S3. Bằng cách làm theo các bước trên, bạn có thể đưa trang web của mình lên internet một cách dễ dàng và tiết kiệm chi phí. Chúc các bạn thành công!</p>
<p>The post <a href="https://blog.tomosia.com.vn/cac-buoc-trien-khai-trang-web-tinh-bang-aws-s3/">Các bước triển khai trang web tĩnh bằng AWS S3</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/cac-buoc-trien-khai-trang-web-tinh-bang-aws-s3/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Cách Tích Hợp Python Vào Rails App</title>
		<link>https://blog.tomosia.com.vn/cach-tich-hop-python-vao-rails-app/</link>
					<comments>https://blog.tomosia.com.vn/cach-tich-hop-python-vao-rails-app/#comments</comments>
		
		<dc:creator><![CDATA[Thuc Phan]]></dc:creator>
		<pubDate>Wed, 18 Oct 2023 09:03:11 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=1350</guid>

					<description><![CDATA[<p>Giới thiệu Ứng dụng thực tế Kết luận</p>
<p>The post <a href="https://blog.tomosia.com.vn/cach-tich-hop-python-vao-rails-app/">Cách Tích Hợp Python Vào Rails App</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h3 id="gioi-thieu" class="wp-block-heading">Giới thiệu</h3>



<ul class="wp-block-list">
<li>Ruby on Rails là một framework phát triển ứng dụng web mạnh mẽ và phổ biến nhưng có những hạn chế về việc hỗ trợ các lĩnh vực như: trí tuệ nhân tạo (AI), machine learning, đồ hoạ&#8230; và nhiều thư viện đặc biệt khác. Tuy nhiên với sự đa dạng và sức mạnh của Python, chúng ta có thể dễ dàng giải quyết những thách thức này</li>



<li>Rất may là Rails cho phép chúng ta tận dụng tốt cả hai thế giới, và bài viết này sẽ hướng dẫn bạn cách làm điều đó</li>
</ul>



<h3 id="ung-dung-thuc-te" class="wp-block-heading">Ứng dụng thực tế</h3>



<ul class="wp-block-list">
<li>Cài đặt <code><strong>python3</strong></code> và <code><strong>python3-pip</strong></code> vào máy tính của bạn</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="219" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-1024x219.png" alt="" class="wp-image-1351" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-1024x219.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-300x64.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-768x164.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-1536x328.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-380x81.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-800x171.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM-1160x248.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-2.09.13-PM.png 1574w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li>Add gem <strong><code>pycall</code></strong> vào Rails App</li>
</ul>



<pre class="wp-block-code"><code>gem 'pycall', '1.5.1'</code></pre>



<ul class="wp-block-list">
<li>Tiếp theo mình sẽ tạo hai tệp mã nguồn, một cho Ruby và một cho Python, để cho phép chúng tương tác với nhau thông qua gem pycall. Mình sẽ đặt các tệp này trong thư mục <code>"lib"</code></li>
</ul>



<pre class="wp-block-code"><code>lib/python/image_generator.py
lib/image_generator.rb</code></pre>



<ul class="wp-block-list">
<li>Mình sẽ định nghĩa một phương thức trong tệp <code>"image_generator.py"</code> và output &#8220;Hello world&#8221; để kiểm tra hoạt động</li>
</ul>



<pre class="wp-block-code"><code>def hello_world():
    print("Hello world!")</code></pre>



<ul class="wp-block-list">
<li>Kế tiếp là tệp &#8220;<code>image_generator.rb</code>&#8221; để gọi python script</li>
</ul>



<pre class="wp-block-code"><code>require 'pycall/import'

module ImageGenerator
  extend PyCall::Import

  pyimport 'sys'
  sys.path.append File.expand_path('../../lib/python', __FILE__)
  pyfrom 'image_generator', import: :hello_world

  class &lt;&lt; self
    def run
      hello_world
    end
  end
end</code></pre>



<ul class="wp-block-list">
<li>Test hoạt động bằng <code>rails console</code></li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="798" height="194" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-53.png" alt="This image has an empty alt attribute; its file name is Screen-Shot-2023-10-18-at-2.42.11-PM.png" class="wp-image-1356" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-53.png 798w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-53-300x73.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-53-768x187.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-53-380x92.png 380w" sizes="auto, (max-width: 798px) 100vw, 798px" /></figure>



<ul class="wp-block-list">
<li>Sau đây mình sẽ ví một bài toán nan giải đối với Rails nhưng dễ dàng khi sử dụng Python&#8217;s libs: <strong>Tạo một hình ảnh có chứa biểu đồ</strong></li>
</ul>



<ul class="wp-block-list">
<li>Cài đặt các thư viện cần thiết</li>
</ul>



<pre class="wp-block-code"><code>pip3 install pandas
pip3 install matplotlib</code></pre>



<ul class="wp-block-list">
<li>File <code><em>image_generator.py</em></code></li>
</ul>



<pre class="wp-block-code"><code>import json
import matplotlib
from matplotlib import pyplot as plt
import pandas as pd

def hello_world():
    print("Hello world!")

def generate_chart_image(info, image_path):
    info = json.load(info)
    matplotlib.style.use('ggplot')

    categories = info.get('categories')
    series = info.get('series')

    if categories and series:
        mapped_data = {entry&#91;'name']: entry&#91;'values'] for entry in series}
        df = pd.DataFrame(mapped_data, index=categories)

        _, ax = plt.subplots(figsize=(20, 5))

        colors = &#91;&#91;'#4c5fcb', '#2196f3'], &#91;'#8bc34a', '#673ab7']]
        stacks = get_stacks_from_data(mapped_data)

        # Plotting the stacked bar chart
        df&#91;stacks&#91;0]].plot.bar(stacked=True, width=0.2, position=1.25, color=colors&#91;0], ax=ax, alpha=1)
        df&#91;stacks&#91;1]].plot.bar(stacked=True, width=0.2, position=-0.25, color=colors&#91;1], ax=ax, alpha=1)

        ax.tick_params(axis='x', rotation=0)
        legend = ax.legend(loc='upper center', ncol=2, bbox_to_anchor=(0.5, 1.15))
        legend.get_frame().set_facecolor('none')
        ax.set_xlim(left=-0.5)
        plt.savefig(image_path, dpi=300, bbox_inches='tight')
        print("Generate image successfully!")

def get_stacks_from_data(mapped_data={}):
    years = &#91;]

    for key in mapped_data:
        year, _ = key.split('・')
        years.append(year.strip())

    years = sorted(set(years))
    result = &#91;]

    for year in years:
        sub_list = &#91;key for key in mapped_data if key.startswith(year)]
        result.append(sub_list)

    return result</code></pre>



<ul class="wp-block-list">
<li>File <code>image_generator.rb</code></li>
</ul>



<pre class="wp-block-code"><code>require 'pycall/import'

module ImageGenerator
  extend PyCall::Import

  pyimport 'sys'
  sys.path.append File.expand_path('../../lib/python', __FILE__)
  pyfrom 'image_generator', import: &#91;:hello_world, :generate_chart_image]

  class &lt;&lt; self
    def run
      hello_world
      info = {
        'categories': &#91;"1", "2", "3", "4", "5", "6"],
        'series': &#91;
          {'name': 'CurY.Google', 'values': &#91;1000, 1998, 3323, 1838, 1111, 6666]},
          {'name': 'CurY.GoogleMap', 'values': &#91;1997, 2461, 6232, 1838, 2222, 8888]},
          {'name': 'PrevY.Google', 'values': &#91;1000, 1998, 3323, 1838, 1111, 6666]},
          {'name': 'PrevY.GoogleMap', 'values': &#91;1997, 2461, 6232, 1838, 2222, 8888]}
        ]
      }.to_json
      image_path = 'tmp/chart_image.png'
      generate_chart_image(info, image_path)
    end
  end
end</code></pre>



<ul class="wp-block-list">
<li>Reload <code>rails console</code> và test hoạt động</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="916" height="238" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-3.21.13-PM.png" alt="" class="wp-image-1359" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-3.21.13-PM.png 916w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-3.21.13-PM-300x78.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-3.21.13-PM-768x200.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-3.21.13-PM-380x99.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/Screen-Shot-2023-10-18-at-3.21.13-PM-800x208.png 800w" sizes="auto, (max-width: 916px) 100vw, 916px" /></figure>



<ul class="wp-block-list">
<li>Và đây là kết quả</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="302" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-1024x302.png" alt="" class="wp-image-1360" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-1024x302.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-300x89.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-768x227.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-1536x453.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-2048x605.png 2048w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-380x112.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-800x236.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2023/10/image-54-1160x342.png 1160w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 id="ket-luan" class="wp-block-heading">Kết luận</h3>



<ul class="wp-block-list">
<li>Có thể thấy nhờ sự hỗ trợ của thư viện và vài dòng code Python đơn giản thì chúng ta đã tạo ra được một hình ảnh với chất lượng nét nèn nẹt</li>



<li>Hi vọng bài viết của mình sẽ giúp ích được cho các bạn khi có một tính năng nào đó khó khăn và phải cần đến sự trợ giúp của Python</li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/cach-tich-hop-python-vao-rails-app/">Cách Tích Hợp Python Vào Rails App</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/cach-tich-hop-python-vao-rails-app/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
