<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Docker on Nguyen Ngoc Tin</title><link>https://ngoctin.me/tags/docker/</link><description>Recent content in Docker on Nguyen Ngoc Tin</description><generator>Hugo</generator><language>en</language><managingEditor>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</managingEditor><webMaster>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</webMaster><lastBuildDate>Thu, 10 Sep 2026 14:22:00 +0700</lastBuildDate><atom:link href="https://ngoctin.me/tags/docker/index.xml" rel="self" type="application/rss+xml"/><item><title>Migrate thư viện TV sang home server và triển khai Jellyfin bằng Docker</title><link>https://ngoctin.me/notes/migrate-media-va-trien-khai-jellyfin-home-server/</link><pubDate>Thu, 10 Sep 2026 14:22:00 +0700</pubDate><author>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</author><guid>https://ngoctin.me/notes/migrate-media-va-trien-khai-jellyfin-home-server/</guid><description>&lt;div class="admonition abstract open"&gt;&#10; &lt;div class="admonition-title"&gt;&#10; &lt;i class="icon ti ti-list-details" aria-hidden="true"&gt;&lt;/i&gt;Abstract&#10; &lt;/div&gt;&#10; &lt;div class="admonition-content"&gt;&lt;p&gt;Với một home server đơn giản chỉ có một HDD dữ liệu, cách triển khai hiệu quả là giữ media thành thư viện chuẩn trên &lt;code&gt;/data/media/tv&lt;/code&gt;, mount read-only vào Jellyfin container, dùng &lt;code&gt;Shows&lt;/code&gt; làm loại library cho TV series, và truy cập từ xa qua Tailscale thay vì public port trực tiếp.&lt;/p&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;h2 id="trạng-thái-cuối-cùng"&gt;Trạng thái cuối cùng&lt;/h2&gt;&#10;&lt;p&gt;Jellyfin đã chạy trên Mac mini Ubuntu bằng Docker Compose và đọc được thư viện TV từ HDD.&lt;/p&gt;</description></item><item><title>Cheatsheet Docker: Container và DevOps</title><link>https://ngoctin.me/cheatsheets/cheatsheet-docker/</link><pubDate>Thu, 20 Aug 2026 12:00:00 +0700</pubDate><author>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</author><guid>https://ngoctin.me/cheatsheets/cheatsheet-docker/</guid><description/></item><item><title>Bilingual Movie Learn: Nền tảng học tiếng Anh qua phim với Google Gemini API</title><link>https://ngoctin.me/posts/bilingual-movie-learning-platform/</link><pubDate>Fri, 20 Mar 2026 10:00:00 +0700</pubDate><author>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</author><guid>https://ngoctin.me/posts/bilingual-movie-learning-platform/</guid><description>&lt;div class="youtube-embed-wrapper" data-video-id="USj7dpTuOZI" data-speed="1.5"&gt;&#10; &lt;div class="youtube-lite-player" onclick="playYoutubeInstant(this)" role="button" tabindex="0" aria-label="Phát video YouTube Video (tốc độ 1.5x)" onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();playYoutubeInstant(this);}"&gt;&#10; &lt;picture&gt;&#10; &lt;source srcset="https://i.ytimg.com/vi_webp/USj7dpTuOZI/maxresdefault.webp" type="image/webp"&gt;&#10; &lt;img src="https://i.ytimg.com/vi/USj7dpTuOZI/hqdefault.jpg" alt="YouTube Video" loading="lazy" class="youtube-poster-img" onerror="this.onerror=null;this.src='https://i.ytimg.com/vi/USj7dpTuOZI/hqdefault.jpg';"&gt;&#10; &lt;/picture&gt;&#10; &lt;button class="youtube-play-btn" type="button" aria-hidden="true" tabindex="-1"&gt;&#10; &lt;svg viewBox="0 0 68 48" width="64" height="45" class="youtube-play-svg"&gt;&#10; &lt;path class="youtube-btn-bg" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f43f5e"&gt;&lt;/path&gt;&#10; &lt;path d="M 45,24 27,14 27,34" fill="#ffffff"&gt;&lt;/path&gt;&#10; &lt;/svg&gt;&#10; &lt;/button&gt;&#10; &lt;div class="youtube-badge-speed"&gt;1.5x Speed&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;script&gt;&#10;if (!window.playYoutubeInstant) {&#10; window._ytApiCallbacks = [];&#10; window._ytApiLoading = false;&#10;&#10; window.ensureYTAPILoaded = function(cb) {&#10; if (window.YT &amp;&amp; window.YT.Player) {&#10; cb();&#10; return;&#10; }&#10; window._ytApiCallbacks.push(cb);&#10; if (!window._ytApiLoading) {&#10; window._ytApiLoading = true;&#10; var tag = document.createElement('script');&#10; tag.id = 'yt-iframe-api';&#10; tag.src = 'https://www.youtube.com/iframe_api';&#10; var first = document.getElementsByTagName('script')[0];&#10; first.parentNode.insertBefore(tag, first);&#10;&#10; var prev = window.onYouTubeIframeAPIReady;&#10; window.onYouTubeIframeAPIReady = function() {&#10; if (typeof prev === 'function') prev();&#10; while (window._ytApiCallbacks.length) {&#10; var fn = window._ytApiCallbacks.shift();&#10; try { fn(); } catch (e) { console.error(e); }&#10; }&#10; };&#10; }&#10; };&#10;&#10; window.playYoutubeInstant = function(el) {&#10; var wrapper = el.closest('.youtube-embed-wrapper');&#10; if (!wrapper) return;&#10; var id = wrapper.getAttribute('data-video-id');&#10; var start = parseInt(wrapper.getAttribute('data-start'), 10) || 0;&#10; var speed = parseFloat(wrapper.getAttribute('data-speed')) || 1.5;&#10;&#10; var playerId = 'yt-player-' + Math.random().toString(36).substr(2, 9);&#10; var playerDiv = document.createElement('div');&#10; playerDiv.id = playerId;&#10; playerDiv.className = 'youtube-iframe-active';&#10;&#10; wrapper.innerHTML = '';&#10; wrapper.appendChild(playerDiv);&#10;&#10; window.ensureYTAPILoaded(function() {&#10; var speedApplied = false;&#10; new YT.Player(playerId, {&#10; videoId: id,&#10; playerVars: {&#10; autoplay: 1,&#10; playsinline: 1,&#10; rel: 0,&#10; modestbranding: 1,&#10; start: start&#10; },&#10; events: {&#10; onReady: function(event) {&#10; try {&#10; event.target.setPlaybackRate(speed);&#10; event.target.playVideo();&#10; } catch (err) {}&#10; },&#10; onStateChange: function(event) {&#10; if (!speedApplied &amp;&amp; event.data === YT.PlayerState.PLAYING) {&#10; try {&#10; event.target.setPlaybackRate(speed);&#10; speedApplied = true;&#10; } catch (err) {}&#10; }&#10; }&#10; }&#10; });&#10; });&#10; };&#10;}&#10;&lt;/script&gt;&#10;&lt;div class="admonition abstract open"&gt;&#10; &lt;div class="admonition-title"&gt;&#10; &lt;i class="icon ti ti-list-details" aria-hidden="true"&gt;&lt;/i&gt;Abstract&#10; &lt;/div&gt;&#10; &lt;div class="admonition-content"&gt;&lt;p&gt;Bilingual Movie Learn là nền tảng học tiếng Anh tương tác qua phim ảnh, giúp người học tra cứu từ vựng theo ngữ cảnh và giải thích ngữ pháp tức thì từ câu thoại video thông qua Google Gemini API.&lt;/p&gt;</description></item></channel></rss>