<?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/"
	>

<channel>
	<title>docker - Hard Wired</title>
	<atom:link href="https://www.hardwired.dev/tag/docker/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.hardwired.dev</link>
	<description></description>
	<lastBuildDate>Sat, 11 Oct 2025 04:47:46 +0000</lastBuildDate>
	<language>cs</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.hardwired.dev/wp-content/uploads/2022/10/android-chrome-256x256-1-150x150.png</url>
	<title>docker - Hard Wired</title>
	<link>https://www.hardwired.dev</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Outline &#8211; selfhostovaná znalostní báze</title>
		<link>https://www.hardwired.dev/2025/09/27/outline-selfhostovana-znalostni-baze/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Sat, 27 Sep 2025 19:59:00 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Různé]]></category>
		<category><![CDATA[.env]]></category>
		<category><![CDATA[autentizace]]></category>
		<category><![CDATA[databáze]]></category>
		<category><![CDATA[dex]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[docker-compose]]></category>
		<category><![CDATA[Gmail]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[in-memory databáze]]></category>
		<category><![CDATA[konfigurace]]></category>
		<category><![CDATA[kontejnerizace]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[linxu]]></category>
		<category><![CDATA[návod]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[Nginx konfigurace]]></category>
		<category><![CDATA[notion]]></category>
		<category><![CDATA[oidc]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[OpenID Connect]]></category>
		<category><![CDATA[outline]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[přihlašování]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[reverse-proxy]]></category>
		<category><![CDATA[reverzní proxy]]></category>
		<category><![CDATA[self-hosting]]></category>
		<category><![CDATA[selfhosted]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[YAML]]></category>
		<category><![CDATA[znalostní báze]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=2836</guid>

					<description><![CDATA[<p>Takovej selfhosting Notionu bez fancy tabulek. Outline je open-source nástroj pro tvorbu a správu interní dokumentace a znalostních bází. Použité &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2025/09/27/outline-selfhostovana-znalostni-baze/">Outline – selfhostovaná znalostní báze</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Takovej selfhosting Notionu bez fancy tabulek.<br />
<a href="https://www.getoutline.com">Outline</a> je open-source nástroj pro tvorbu a správu interní dokumentace a znalostních bází.</p>
<p><span id="more-2836"></span></p>
<h2>Použité technologie</h2>
<h3>Nginx</h3>
<p>Nginx je výkonný webový server a reverzní proxy, který se používá pro obsluhu statického obsahu, směrování požadavků na backend služby a vyvažování zátěže. Je známý svou rychlostí, nízkou spotřebou paměti a spolehlivostí při vysoké zátěži.</p>
<h3>Outline</h3>
<p><a href="https://www.getoutline.com">Outline</a> je open-source nástroj pro tvorbu a správu interní dokumentace a znalostních bází. Poskytuje jednoduché a přehledné uživatelské rozhraní pro týmovou spolupráci, verzování a rychlé vyhledávání obsahu.</p>
<h3>Dex</h3>
<p><a href="https://dexidp.io">Dex</a> je open-source identitní služba, která funguje jako „OpenID Connect“ provider. Slouží k centralizovanému ověřování uživatelů a umožňuje propojit různé aplikace s externími identity providery (např. Google, GitHub nebo LDAP).</p>
<h3>Postgres</h3>
<p>PostgreSQL (Postgres) je pokročilý open-source relační databázový systém. Nabízí podporu pro komplexní dotazy, transakce, indexy, JSON data a rozšiřitelnost pomocí vlastních funkcí, čímž se hodí pro širokou škálu aplikací od menších po enterprise řešení.</p>
<h3>Redis</h3>
<p>Redis je in-memory databáze a cache systém, který umožňuje velmi rychlý přístup k datům. Často se používá pro ukládání relací, front, výsledků výpočtů nebo jako prostředník pro komunikaci mezi službami díky podpoře publikace a odběru zpráv (pub/sub).</p>
<h3>Docker / Docker Compose</h3>
<p>Docker je platforma pro kontejnerizaci aplikací, která umožňuje spouštět software izolovaně s veškerými závislostmi. Docker Compose pak usnadňuje definování a správu vícekontejnerových aplikací pomocí jednoduchého konfiguračního souboru.</p>
<h2>Diagram</h2>
<p><img decoding="async" src="https://www.hardwired.dev/wp-content/uploads/2025/09/diagram.avif" alt="" /></p>
<h2>Postřehy</h2>
<h3>Outline</h3>
<p>Outline neumožňuje přihlašování pomocí uživatelského jména a hesla, což je poněkud nepříjemné. Musí se nakonfigurovat jedna z podporovaných služeb. Aplikace umí pracovat se Slack identitami, Google identitami a dalšími poskytovateli. Pokud nemůžete použít žádnou z těchto služeb, je tam naštěstí možnost Magic Link via Email. Je to sice nepříjemné, ale funkční řešení. Pokaždé, když se chcete přihlásit, pošle vám aplikace email s přihlašovacím odkazem. V mém setupu jsem se rozhodl použít Dex jako OIDC službu, přes kterou se mohu přihlašovat pomocí emailu a hesla.</p>
<h3>Dex</h3>
<p><a href="https://dexidp.io">Dex</a> je velmi minimalistický, takže nemá webové rozhraní. Navíc jeho dokumentace je hodně nekvalitní. Nejjednodušším způsobem, jak vše rozchodit, je přidat statického klienta a uživatele přímo do konfiguračního souboru. Musíte si ale vytvořit bcrypt hashovaná hesla. Vycházel jsem z tohoto <a href="https://mrkaran.dev/posts/setting-outline/">návodu</a>.</p>
<h3>SMTP</h3>
<p>Aby fungovalo odesílání emailů, je potřeba nakonfigurovat SMTP server. Pokud žádný po ruce nemáte, můžete použít váš Gmail účet. V nastavení Gmailu se musí vytvořit aplikační klíč, který se pak vloží do .env souboru do SMTP sekce.</p>
<h2>Setup</h2>
<h3>.env</h3>
<pre><code class="language-ini">URL=https://outline.&lt;domain.com&gt;
PORT=3050
WEB_CONCURRENCY=1
SECRET_KEY=&lt;secret key&gt;
UTILS_SECRET=&lt;utils secret&gt;
DATABASE_URL=postgres://outline:&lt;db password&gt;@outline-postgres:5432/outline
PGSSLMODE=disable

POSTGRES_USER=outline
POSTGRES_PASSWORD=&lt;db password&gt;
POSTGRES_DB=outline

REDIS_URL=redis://outline-redis:6379

FILE_STORAGE=local

FORCE_HTTPS=true

OIDC_CLIENT_ID=outline
OIDC_CLIENT_SECRET=&lt;oidc client secret&gt;
OIDC_AUTH_URI=https://auth.&lt;domain.com&gt;/dex/auth
OIDC_TOKEN_URI=http://dex:5556/dex/token
OIDC_USERINFO_URI=http://dex:5556/dex/userinfo
OIDC_USERNAME_CLAIM=email
OIDC_DISPLAY_NAME=OIDC Provider
OIDC_SCOPES=openid profile email

SMTP_SERVICE=gmail
SMTP_USERNAME=&lt;you&gt;@gmail.com
SMTP_PASSWORD=&quot;&lt;app code&gt;&quot;
SMTP_FROM_EMAIL=&lt;you&gt;@gmail.com

RATE_LIMITER_ENABLED=true
RATE_LIMITER_REQUESTS=1000
RATE_LIMITER_DURATION_WINDOW=60

ENABLE_UPDATES=true
DEBUG=http
LOG_LEVEL=info</code></pre>
<h3>DEX Config (config.yaml)</h3>
<pre><code class="language-yaml">issuer: https://auth.&lt;domain.com&gt;/dex

storage:
  type: sqlite3
  config:
    file: /var/dex/dex.db

web:
  http: 0.0.0.0:5556

staticClients:
  - id: outline
    redirectURIs:
      - &quot;https://outline.&lt;domain.com&gt;/auth/oidc.callback&quot;
    name: &quot;Knowledge Base&quot;
    secret: &lt;oidc client secret&gt;

oauth2:
  skipApprovalScreen: true

enablePasswordDB: true

staticPasswords:
  # Admin
  - email: &quot;&lt;admin&gt;@gmail.com&quot;
    hash: &quot;&lt;bcrypt password hash&gt;&quot;
    username: &quot;admin&quot;
    userID: &quot;admin-001&quot;

  - email: &quot;&lt;user&gt;@gmail.com&quot;
    hash: &quot;&lt;bcript password hash&gt;&quot;
    username: &quot;user&quot;
    userID: &quot;user-001&quot;

# Pro debug
logger:
  level: &quot;info&quot;
  format: &quot;text&quot;</code></pre>
<h3>Docker Compose</h3>
<pre><code class="language-yaml">services:
  outline:
    image: docker.getoutline.com/outlinewiki/outline:latest
    env_file: ./.env
    ports:
      - &quot;3050:3050&quot;
    expose:
      - &quot;3050&quot;
    volumes:
      - storage-data:/var/lib/outline/data
    depends_on:
      - outline-postgres
      - outline-redis

  outline-redis:
    image: redis
    env_file: ./.env
    expose:
      - &quot;6379&quot;
    volumes:
      - ./redis.conf:/redis.conf
    command: [&quot;redis-server&quot;, &quot;/redis.conf&quot;]
    healthcheck:
      test: [&quot;CMD&quot;, &quot;redis-cli&quot;, &quot;ping&quot;]
      interval: 10s
      timeout: 30s
      retries: 3

  outline-postgres:
    image: postgres
    env_file: ./.env
    expose:
      - &quot;5432&quot;
    volumes:
      - database-data:/var/lib/postgresql/data
    healthcheck:
      test: [&quot;CMD&quot;, &quot;pg_isready&quot;, &quot;-d&quot;, &quot;outline&quot;, &quot;-U&quot;, &quot;user&quot;]
      interval: 30s
      timeout: 20s
      retries: 3

  dex:
    image: dexidp/dex:v2.37.0
    ports:
      - &quot;5556:5556&quot;  # Vystaveno pro nginx proxy
    expose:
      - &quot;5556&quot;
    volumes:
      - ./dex-config:/etc/dex:ro  # Read-only mount konfigurace
      - dex-data:/var/dex         # Persistentni SQLite databáze
    command: [&quot;dex&quot;, &quot;serve&quot;, &quot;/etc/dex/config.yaml&quot;]
    healthcheck:
      test: [&quot;CMD&quot;, &quot;wget&quot;, &quot;--no-verbose&quot;, &quot;--tries=1&quot;, &quot;--spider&quot;, &quot;http://localhost:5556/dex/healthz&quot;]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped

volumes:
  storage-data:
  database-data:
  dex-data:</code></pre>
<h3>Nginx</h3>
<h4>auth.<domain.com></h4>
<pre><code class="language-nginx">server {
    listen 80;
    server_name auth.&lt;domain.com&gt;;

    # P┼Öesm─Ťrov├ín├ş HTTP na HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name auth.&lt;domain.com&gt;;

    # SSL certifik├íty (upravte cestu podle va┼í├ş konfigurace)
    ssl_certificate /etc/nginx/ssl/&lt;domain.com&gt;/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/&lt;domain.com&gt;/privkey.pem;

    # SSL konfigurace
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    # Proxy nastaven├ş pro Home Assistant
    location / {
        proxy_pass http://&lt;service ip&gt;:5556;
        proxy_set_header Host $http_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;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &quot;upgrade&quot;;

        # Timeout nastaven├ş
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # Buffering nastaven├ş
        proxy_buffering off;
        proxy_request_buffering off;
    }

    # Logov├ín├ş
    access_log /var/log/nginx/auth.&lt;domain.com&gt;.access.log;
    error_log /var/log/nginx/auth.&lt;domain.com&gt;.error.log;
}</code></pre>
<h4>outline.<domain.com></h4>
<pre><code class="language-nginx">server {
    listen 80;
    server_name outline.&lt;domain.com&gt;;

    # P┼Öesm─Ťrov├ín├ş HTTP na HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name outline.&lt;domain.com&gt;;

    # SSL certifik├íty (upravte cestu podle va┼í├ş konfigurace)
    ssl_certificate /etc/nginx/ssl/&lt;domain.com&gt;/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/&lt;domain.com&gt;/privkey.pem;

    # SSL konfigurace
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    # Proxy nastaven├ş pro Home Assistant
    location / {
        proxy_pass http://&lt;service ip&gt;:3050;
        proxy_set_header Host $http_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;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &quot;upgrade&quot;;

        # Timeout nastaven├ş
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # Buffering nastaven├ş
        proxy_buffering off;
        proxy_request_buffering off;
    }

    # Logov├ín├ş
    access_log /var/log/nginx/outline.&lt;domain.com&gt;.access.log;
    error_log /var/log/nginx/outline.&lt;domain.com&gt;.error.log;
}</code></pre>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2025%2F09%2F27%2Foutline-selfhostovana-znalostni-baze%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2025/09/27/outline-selfhostovana-znalostni-baze/">Outline – selfhostovaná znalostní báze</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Gitea a první soukromý repozitář</title>
		<link>https://www.hardwired.dev/2024/09/16/gitea-a-prvni-soukromy-repozitar/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Sun, 15 Sep 2024 22:15:31 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gitea]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[self-hosted]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[windows]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=2348</guid>

					<description><![CDATA[<p>Článek navazuje na Gitea v Dockeru s daty na Synology a Gitea na veřejné subdoméně. Tentokrát si ukážeme, jak vytvořit &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2024/09/16/gitea-a-prvni-soukromy-repozitar/">Gitea a první soukromý repozitář</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Článek navazuje na <a href="https://www.hardwired.dev/2024/09/14/gitea-v-dockeru-s-daty-na-synology/">Gitea v Dockeru s daty na Synology</a> a <a href="https://www.hardwired.dev/2024/09/15/gitea-na-verejne-subdomene/">Gitea na veřejné subdoméně</a>. Tentokrát si ukážeme, jak vytvořit nový soukromý repozitář a posílat do něj změny.</p>
<h1>Předpoklady</h1>
<ul>
<li>Máme funkční Giteu na vlastní subdoméně, do které se dokážeme přihlásit</li>
<li>Byly provedeny všechny kroky z předchozích návodů</li>
<li>Článek se zaměřuje na Windows ale na Linuxu to bude to samé nebo hodně podobné</li>
<li>Na počítači máme funkční SSH a <a href="https://git-scm.com/">GIT</a>.</li>
</ul>
<h1>Vytvoření soukromého repozitáře</h1>
<p>Přihlásíme se do naší Gitey. <code>Pluskem</code> zvolíme nový repozitář. Zadáme název repozitáře, <code>soukromy-repo-na-smazani</code>. Vybereme <code>Nastavit repozitář jako soukromý</code> a potvrdíme. Vytvoří se prázdný repozitář.</p>
<h1>Vytvoření SSH klíče</h1>
<p>Pro komunikaci s repozitářem budeme používat <a href="https://cs.wikipedia.org/wiki/Secure_Shell">SSH</a>. Budeme muset vytvořit pár klíčů, soukromý a veřejný. Soukromý bude u nás na počítači a veřejný budeme nahrajeme k repozitáři, jako přístupový.</p>
<p>Ujistíme se že v <code>c:\Users\&lt;username&gt;</code> máme složku <code>.ssh</code>. Poté v terminálu zadáme příkaz na vygenerování klíče pro přístup do Gitea. </p>
<p><code>ssh-keygen -t rsa -b 4096 -C &quot;&lt;váš email&gt;&quot; -f ~/.ssh/gitea-example-com</code></p>
<p>To ve složce <code>.ssh</code> vytvoří dva soubory. <code>gitea-example-com</code> a <code>gitea-example-com.pub</code>. Ten druhý musíme nahrát k repozitáři.</p>
<h1>Přidání klíče do Gitea repozitáře</h1>
<p>Otevřeme si repozitář. <code>Nastavení &gt; Klíče pro nasazení &gt; Přidat klič pro nasazení</code>. Pojmenujeme si ho, například <code>Domácí klíč</code>. A obsah <code>gitea-example-com.pub</code> zkopírujeme do pole <code>Obsah</code>. Nesmíme zapomenout zaškrtnout volbu <code>Povolit zápis</code> a potvrdit.</p>
<h1>Nastavení SSH na počítači</h1>
<p>Pokud ve složce <code>c:\Users\&lt;username&gt;\.ssh</code> nemáte soubor <code>config</code>, vytvořte ho a přidejte následující.</p>
<pre><code>Host gitea.example.com
  HostName gitea.example.com
  User git
  Port 222
  IdentityFile c:\Users\&lt;username&gt;\.ssh\gitea-example-com
  IdentitiesOnly yes</code></pre>
<p>Pro hosta <code>gitea.example.com</code> se nastaví odpovídající <code>host name</code>, <code>uživatel</code>, <code>port</code> pro připojení a <code>cesta k privátnímu klíči</code>. Volba <code>IdentitiesOnly</code> zajistí, že pro konkrétního hosta se použijí parametry, které jsou nastaveny.</p>
<h1>Připojení repozitáře</h1>
<p>Buď můžete připojit už existující repozitář z vašeho počítače, nebo vytvoříte nový. Vytvoříme nový.</p>
<p>Vytvořte složku kde bude nový repozitář. Obecně se pojmenuje názvem repozitáře co jsme vytvořili na naší Gitea.</p>
<pre><code class="language-shell">mkdir soukromy-repo-na-smazani</code></pre>
<p>Přesuneme se do něj.</p>
<pre><code class="language-shell">cd soukromy-repo-na-smazani</code></pre>
<p>Inicializujeme prázdný repozitář.</p>
<pre><code class="language-shell">git init</code></pre>
<p>Vytvoříme první soubor <code>README.md</code>.</p>
<pre><code class="language-shell">touch README.md</code></pre>
<p>Vytvoříme hlavní větev <code>main</code>.</p>
<pre><code class="language-shell">git checkout -b main</code></pre>
<p>Přidáme soubor <code>README.md</code> do <code>git</code> repozitáře.</p>
<pre><code class="language-shell">git add README.md</code></pre>
<p>Vytvoříme první <code>commit</code>.</p>
<pre><code class="language-shell">git commit -m &quot;První commit&quot;</code></pre>
<p>Napojíme náš repozitář z Gitea.</p>
<pre><code class="language-shell">git remote add origin git@gitea.example.com:&lt;gitea username&gt;/soukromy-repo-na-smazani.git</code></pre>
<p>Odešleme změny do vzdáleného repozitáře.</p>
<pre><code class="language-shell">git push -u origin main</code></pre>
<p>Když se nyní podíváme do repozitáře na <code>gitea.example.com</code>, uvidíme náš první <code>commit</code>.</p>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2024%2F09%2F16%2Fgitea-a-prvni-soukromy-repozitar%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2024/09/16/gitea-a-prvni-soukromy-repozitar/">Gitea a první soukromý repozitář</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Gitea na veřejné subdoméně</title>
		<link>https://www.hardwired.dev/2024/09/15/gitea-na-verejne-subdomene/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Sun, 15 Sep 2024 18:55:58 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[domain]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gitea]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[portainer]]></category>
		<category><![CDATA[reverse-proxy]]></category>
		<category><![CDATA[self-hosted]]></category>
		<category><![CDATA[subdomain]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=2345</guid>

					<description><![CDATA[<p>Volné pokračování Gitea v Dockeru s daty na Synology. Tentokrát nastavíme aby nám naše self-hostovaná Gitea jela na naší veřejné &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2024/09/15/gitea-na-verejne-subdomene/">Gitea na veřejné subdoméně</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Volné pokračování <a href="https://www.hardwired.dev/2024/09/14/gitea-v-dockeru-s-daty-na-synology/">Gitea v Dockeru s daty na Synology</a>. Tentokrát nastavíme aby nám naše self-hostovaná <a href="https://about.gitea.com/">Gitea</a> jela na naší veřejné doméně.</p>
<h1>Předpoklady</h1>
<ul>
<li>Máme nainstalovanou Giteu podle předchozího návodu.</li>
<li>Máme koupenou vlastní doménu. (pro tutoriál to bude <code>example.com</code>)</li>
<li>Používáme <a href="https://nginx.org/en/">Nginx</a> jako <a href="https://en.wikipedia.org/wiki/Reverse_proxy">reverzní proxy</a>.</li>
<li>Máme přistup do routeru nebo možnost přesměrovávat porty.</li>
<li>Už jste Giteu jednou spustili a nastavili admin účet.</li>
</ul>
<h1>Nastavení reverzní proxy</h1>
<p>Vytvoříme soubor <code>gitea.example.com</code>.</p>
<pre><code class="language-shell">nano /etc/nginx/sites-available/gitea.example.com</code></pre>
<pre><code>server {
    listen 80;
    server_name gitea.example.com;

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name gitea.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://<ip adresa serveru s Gitea>:3000;
        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;
    }
}</code></pre>
<p>Při zadání <code>gitea.example.com</code> budou všechny požadavky přesměrovávány na server, kde sedí Gitea a naslouchá na portu 3000. Také se automaticky provede přesměrování z HTTP na HTTPS.</p>
<p>Certifikáty jsou pomocí <a href="https://letsencrypt.org/getting-started/">Let's Encrypt</a> a <a href="https://certbot.eff.org/">Certbot</a>, ale to je na jiný návod. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Poté je potřeba dostat <a href="https://cs.wikipedia.org/wiki/Symbolick%C3%BD_odkaz">symlink</a> do <code>/etc/nginx/sites-enabled</code>.</p>
<pre><code class="language-shell">sudo ln -s /etc/nginx/sites-available/gitea.example.com /etc/nginx/sites-enabled/</code></pre>
<p>Pak je dobré zkontrolovat, jestli Nginx naši novou konfiguraci vezme za svou.</p>
<pre><code class="language-shell">sudo nginx -t</code></pre>
<p>Jestli je vše OK, tak bude potřeba Nginx restartovat.</p>
<pre><code class="language-shell">sudo systemctl restart nginx</code></pre>
<p>Od teď bude <code>gitea.example.com</code> směrovat na naši Giteu.</p>
<h1>Nastavení Gitea</h1>
<p>Předpoklad je, že Gitea běží v kontejneru. Musíme upravit nastavení. Do <a href="https://www.docker.com/resources/what-container/">Docker kontejneru</a> se můžete dostat pomocí příkazové řádky <code>docker exec -it &lt;container_name_or_id&gt; /bin/bash</code>. Pokud máte rozchozený <a href="https://www.portainer.io/">Portainer</a>, stačí v něm kliknout na ikonku shellu a připojíte se do kontejneru jako <code>root</code>.</p>
<p>Po připojení do kontejneru bude pravděpodobně jako uživatel <code>root</code>. Gitea (v závislosti na typu image) má data uložena v <code>/data</code>. Ale jako uživatel <code>git</code>. Proto než začnete něco měnit, tak je dobré se přepnout za uživatele <code>git</code>. To provedete pomocí <code>su git</code>.</p>
<p>Bude potřeba udělat pár úprav v souboru <code>app.ini</code>, ten se nachází v <code>/data/gitea/conf</code>. (v Gitea kontejneru je dostupný editor <a href="https://www.atmos.albany.edu/daes/atmclasses/atm350/vi_cheat_sheet.pdf">VI</a>)</p>
<pre><code class="language-ini">DOMIAN = gitea.example.com
SSH_DOMAIN = gitea.example.com
ROOT_URL = https://gitea.example.com</code></pre>
<p>Tím nastavíme Giteu na naši doménu.</p>
<p>Je předpoklad, že je to soukromý git server, takže nechceme aby se tam mohli lidé samovolně registrovat. Takže je potřeba vypnout registrace. </p>
<pre><code class="language-ini">DISABLE_REGISTRATIONS = true</code></pre>
<p>Poté je potřeba kontejner restartovat.</p>
<h1>Přesměrování portů</h1>
<p>Gitea cotainer (pokud jste to nezměnili) propaguje porty 3000 (web) a 222 (ssh). Proto je potřeba zajistit aby byl port 222 zvenku dostupný a přesměrovával na server kde Gitea sedí. Jestli máte domácí router který sedí na veřejné IP adrese tak provedete přesměrování portů na něm.</p>
<h1>Závěr</h1>
<p>Existují ještě další nastavení, ale po těchto pár krocích by už měla Gitea fungovat na vaší doméně.</p>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2024%2F09%2F15%2Fgitea-na-verejne-subdomene%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2024/09/15/gitea-na-verejne-subdomene/">Gitea na veřejné subdoméně</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Gitea v Dockeru s daty na Synology</title>
		<link>https://www.hardwired.dev/2024/09/14/gitea-v-dockeru-s-daty-na-synology/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Fri, 13 Sep 2024 22:39:52 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[docker-compose]]></category>
		<category><![CDATA[gitea]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nfs]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[synology]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=2336</guid>

					<description><![CDATA[<p>Gitea je self-hostovaná varianta Bitbucketu nebo GitHubu. V následujícím krátkém návodu se podíváme jak nainstalovat Giteu pomocí Dockeru a ukládat &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2024/09/14/gitea-v-dockeru-s-daty-na-synology/">Gitea v Dockeru s daty na Synology</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p><a href="https://about.gitea.com/">Gitea</a> je self-hostovaná varianta <a href="https://bitbucket.org/">Bitbucketu</a> nebo <a href="https://github.com/">GitHubu</a>. V následujícím krátkém návodu se podíváme jak nainstalovat Giteu pomocí <a href="https://www.docker.com/">Dockeru</a> a ukládat data na <a href="https://www.synology.com/en-us">Synology NAS</a>.</p>
<h1>Prerekvizity</h1>
<ul>
<li>Nainstalovaný a nastavený Docker</li>
<li>Nainstalovaný a nastavený Synology NAS</li>
</ul>
<h1>Myšlenka</h1>
<p>Pro spuštění Gitea serveru použijeme <a href="https://docs.docker.com/compose/">docker compose</a>. Gitea bude používat <a href="https://www.postgresql.org/">PostgreSQL</a> databázi. Pro ukládání dat jak pro Giteu, tak i pro Postgres, použijeme <a href="https://docs.docker.com/engine/storage/volumes/">docker volumes</a>. <code>Docker volumes</code> nebudou lokální, ale přes protokol <a href="https://cs.wikipedia.org/wiki/Network_File_System">NFS</a> budou směřovat na Synology NAS.</p>
<p>Pro potřeby tutoriálu bude mít server IP adresu <code>192.168.10.1</code> a Synology NAS <code>192.168.10.2</code>.</p>
<h1>Nastavení Synology</h1>
<p><code>Ovládací panel</code> &gt; <code>Souborové služby</code> &gt; <code>NFS</code> povolte službu <code>NFS</code>.</p>
<p><code>Ovládací panel</code> &gt; <code>Sdílená složka</code> &gt; <code>Vytvoření sdílené složky</code>. Název <code>docker-volumes</code>. Nepřiřazujeme oprávnění pro uživatele nebo skupiny.</p>
<p>Klikneme na složku <code>docker-volumes</code> a zvolíme upravit. Poté <code>Oprávnění NFS</code>. Klikneme na tlačítko <code>Vytvořit</code>. Do pole <code>Název hostitele nebo IP adresa</code> vložíme IP adresu našeho serveru, tedy <code>192.168.10.1</code>. Tím umožníme našemu serveru přístup k této složce. Dále nastavíme:</p>
<ul>
<li>Oprávnění: <code>Čtení/Zápis</code></li>
<li>Squash: <code>Žádné mapování</code></li>
<li>Zabezpečení: <code>sys</code></li>
<li>Povolit asynchronní</li>
<li>Povolit připojení z portů bez oprávnění (porty vyšší než 1024)</li>
<li>Umožňuje uživatelům přístup k připojeným podsložkám</li>
</ul>
<p>A uložíme.</p>
<p>Poté otevřeme <code>File Station</code> a v naší složce <code>docker-volumes</code> vytvoříme následující podsložky:</p>
<ul>
<li><code>gitea-data</code></li>
<li><code>gitea-postgres</code></li>
</ul>
<p>To je na Synology vše.</p>
<h1>docker-compose.yaml</h1>
<p>Konfigurační soubor vytvoří síť <code>gitea</code> kde na sebe uvidí kontejnery <code>gitea</code> a <code>gitea-db</code>. Vytvoří <code>dva volumes</code> a pomocí protokolu NFS je nasměruje na námi sdílenou složku v Synology NAS.</p>
<p>Docker-compose soubor můžeme spustit pomocí <code>docker-compose up -d</code>. Pokud máte na serveru nainstalovaný a spuštěný <a href="https://www.portainer.io/">Portainer</a>, tak jde <code>docker-compose konfigurace</code> spustit jako <a href="https://docs.portainer.io/user/docker/stacks">stack</a>.</p>
<p>Webové rozhraní poté bude přístupné na <code>http://192.168.10.1:3000</code>.</p>
<pre><code class="language-yaml">networks:
  gitea:

volumes:
  gitea-data:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.1.251,rw
      device: ":/volume1/docker-volumes/gitea-data"

  gitea-postgres:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.1.251,rw
      device: ":/volume1/docker-volumes/gitea-postgres"

services:
  server:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=gitea-db:5432
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=supersecretpassword
    restart: always
    networks:
      - gitea
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - gitea-db

  gitea-db:
    image: postgres:16
    container_name: gitea-db
    restart: always
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=supersecretpassword
      - POSTGRES_DB=gitea
    networks:
      - gitea
    volumes:
      - gitea-postgres:/var/lib/postgresql/data</code></pre>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2024%2F09%2F14%2Fgitea-v-dockeru-s-daty-na-synology%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2024/09/14/gitea-v-dockeru-s-daty-na-synology/">Gitea v Dockeru s daty na Synology</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Puppeteer download BOT</title>
		<link>https://www.hardwired.dev/2022/10/31/puppeteer-download-bot/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Mon, 31 Oct 2022 13:35:28 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Různé]]></category>
		<category><![CDATA[bot]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[headless]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[puppeteer]]></category>
		<category><![CDATA[scraping]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web-scraping]]></category>
		<guid isPermaLink="false">http://wordpress.hardwired.dev/?p=774</guid>

					<description><![CDATA[<p>O co jde Uděláme bota co načte webovou stránku, klikne na čudlík a stáhne soubor. Použijeme k tomu knihovnu Puppeteer &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2022/10/31/puppeteer-download-bot/">Puppeteer download BOT</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><h1>O co jde</h1>
<p>Uděláme bota co načte webovou stránku, klikne na čudlík a stáhne soubor.</p>
<p>Použijeme k tomu knihovnu <a href="https://pptr.dev/" title="Puppeteer">Puppeteer</a> a samotný kód budeme pouštět v <a href="https://www.docker.com/" title="Dockeru">Dockeru</a>.</p>
<blockquote>
<p>Větší podrobnosti a vysvětlení zakládání NodeJs projektu v Dockeru najde v článku <a href="http://wordpress.hardwired.dev/nodejs-develompent-v-dockeru/" title="NodeJS develompent v Dockeru">NodeJS develompent v Dockeru</a>.</p>
</blockquote>
<h1>Příprava projektu</h1>
<p>Založíme nový projekt:</p>
<pre><code class="language-shell">mkdir puppet
cd puppet
npm init -y</code></pre>
<p>Upravíme <code>package.json</code> a přidáme do něj knihovnu <code>puppeteer</code>:</p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;puppet&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;node index.js&quot;
  },
  &quot;keywords&quot;: [],
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;dependencies&quot;: {
    &quot;puppeteer&quot;: &quot;^19.2.0&quot;
  }
}</code></pre>
<p>Vytvoříme <code>Dockerfile</code>, který použije jako základ obraz s <code>node v16</code>, nainstaluje <code>Chrome prohlížeč</code> a nakopíruje projekt do Docker obrazu.</p>
<pre><code class="language-shell">FROM node:16

RUN apt-get update &amp;&amp; apt-get install gnupg wget -y &amp;&amp; \
  wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor &gt; /etc/apt/trusted.gpg.d/google-archive.gpg &amp;&amp; \
  sh -c &#039;echo &quot;deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main&quot; &gt;&gt; /etc/apt/sources.list.d/google.list&#039; &amp;&amp; \
  apt-get update &amp;&amp; \
  apt-get install google-chrome-stable -y --no-install-recommends &amp;&amp; \
  rm -rf /var/lib/apt/lists/*

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
    PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome-stable

WORKDIR /app
COPY package*.json .
RUN npm install
COPY . ./</code></pre>
<p>Vytvoříme <code>index.js</code> soubor a necháme ho jen vypsat zprávu do konzole.</p>
<pre><code class="language-shell">touch index.js</code></pre>
<pre><code class="language-javascript">console.log(&#039;Hello from docker&#039;)</code></pre>
<p>Není úplně špatné vytvořit i <code>.dockerignore</code> soubor.</p>
<pre><code class="language-shell">node_modules
Dockerfile
.dockerignore
.git
.gitignore
README.md
docker-compose*</code></pre>
<p>Sestavíme obraz.</p>
<pre><code class="language-shell">docker build -t puppet-app-image .</code></pre>
<p>A spustíme Docker kontejner.</p>
<pre><code class="language-bash"># %cd% je aktuální složka ve Windows, pro jiné systémy použijte adekvátní náhradu

docker run -d --tty --name puppet-app -v %cd%:/app -v /app/node_modules puppet-app-image</code></pre>
<blockquote>
<p>--tty parametr je nutný. V opačném případě se Docker kontejner spustí a pak hned úspěšně ukončí. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Za normálních okolností předpokládá, že v něm něco poběží a až se to ukončí tak skončí taky. TTY toto chování potlačí.</p>
</blockquote>
<p>Jakmile kontejner běží, můžeme se do něj přihlásit:</p>
<pre><code class="language-shell">docker exec -it puppet-app bash</code></pre>
<p>Vevnitř se ocitneme ve složce <code>/app</code>, kde je náš projekt a můžeme zkusit spustit náš program.</p>
<pre><code class="language-shell">nodejs index.js</code></pre>
<p>Měl by nám odpovědět <code>Hello from docker</code>.</p>
<h1>Bot</h1>
<p>Pro ukázku bude bot stahovat zdrojový kód puppeteeru z githubu. Upravíme <code>index.js</code> následovně.</p>
<pre><code class="language-javascript">const puppeteer = require(&#039;puppeteer&#039;)

;(async () =&gt; {
    const browser = await puppeteer.launch({
        headless: true,
        args: [&#039;--no-sandbox&#039;],
    })

    const page = await browser.newPage()
    page.setViewport({ width: 1920, height: 1080 })

    const client = await page.target().createCDPSession()
    await client.send(&quot;Page.setDownloadBehavior&quot;, {
        behavior: &quot;allow&quot;,
        downloadPath: &#039;./&#039;
    })

    await page.goto(
        &#039;https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v19.2.0&#039;,
        { waitUntil: &#039;networkidle2&#039; }
    )
    await page.waitForTimeout(1000)

    await page.click(&#039;#repo-content-turbo-frame div.mb-3 &gt; details &gt; div &gt; div &gt; ul &gt; li:nth-child(1) &gt; div.d-flex.flex-justify-start.col-12.col-lg-9 &gt; a&#039;)
    await page.waitForTimeout(5000)

    await page.screenshot({ path: &#039;./screen.jpg&#039;, fullPage: true })

    await browser.close()
})()</code></pre>
<p>Naimportujeme do našeho projektu knihovnu <code>puppeteer</code>.</p>
<pre><code class="language-javascript">const puppeteer = require(&#039;puppeteer&#039;)</code></pre>
<p>Budeme volat asynchronní funkce v java scriptu a budeme používat klíčové slovo <code>await</code>, které čeká na provedení asynchronní funkce. Problém je to, že <code>await</code> se může objevit jen v asynchronní funkci. Tudíž náš kód musíme do jedné takové zabalit a rovnou spustit.</p>
<pre><code class="language-javascript">;(async () =&gt; {
    // code
})()</code></pre>
<p>Vytvoříme nový <code>headless prohlížeč</code>.</p>
<pre><code class="language-javascript">const browser = await puppeteer.launch({
    headless: true,
    args: [&#039;--no-sandbox&#039;],
})</code></pre>
<p>Vytvoříme novou <code>stránku/tab</code> a nastavíme rozlišení.</p>
<pre><code class="language-javascript">const page = await browser.newPage()
page.setViewport({ width: 1920, height: 1080 })</code></pre>
<p>Pro tuto konkrétní stránku nastavíme automatické stahovaní do určitého adresáře. V našem případě adresář s projektem. Takhle nebudeme vyvolávat dialog pro umístění stahovaného souboru.</p>
<pre><code class="language-javascript">const client = await page.target().createCDPSession()
await client.send(&quot;Page.setDownloadBehavior&quot;, {
    behavior: &quot;allow&quot;,
    downloadPath: &#039;./&#039;
})</code></pre>
<p>V naší <code>stránce/tabu</code> otevřeme požadovanou github stránku.</p>
<pre><code class="language-javascript">await page.goto(
    &#039;https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v19.2.0&#039;,
    { waitUntil: &#039;networkidle2&#039; }
)
await page.waitForTimeout(1000)</code></pre>
<p>Klikneme na odkaz pro stažení a chvíli počkáme, než se soubor stáhne <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<pre><code class="language-javascript">await page.click(&#039;#repo-content-turbo-frame div.mb-3 &gt; details &gt; div &gt; div &gt; ul &gt; li:nth-child(1) &gt; div.d-flex.flex-justify-start.col-12.col-lg-9 &gt; a&#039;)
await page.waitForTimeout(5000)</code></pre>
<p>K definování toho na co se má kliknout se používá <a href="https://www.w3schools.com/CSSREF/css_selectors.php" title="CSS Selector">CSS Selector</a> (<a href="https://drafts.csswg.org/selectors/" title="draft">draft</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors" title="mdn">mdn</a>). Ten pomocí html elementů, tříd, atributů a dalších dokáže sestavit unikátní cestu k prvku na stránce. Stránky generované nějakým frameworkem umí potrápit i s takhle dlouhým selektorem, jako v tomto případě.</p>
<p><img decoding="async" src="http://wordpress.hardwired.dev/wp-content/uploads/2022/10/githubsource.jpg" alt="" /></p>
<p>Pak už si jen uděláme momentku, v jakém stavu stránku opouštíme.</p>
<pre><code class="language-javascript">await page.screenshot({ path: &#039;./screen.jpg&#039;, fullPage: true })</code></pre>
<p>A prohlížeč korektně zavřeme.</p>
<pre><code class="language-javascript">await browser.close()</code></pre>
<h1>Spuštění kódu</h1>
<p>V konzoli se připojíme k našemu kontejneru.</p>
<pre><code class="language-bash">docker exec -it puppet-app bash</code></pre>
<p>A spustíme našeho bota.</p>
<pre><code class="language-bash">node index.js</code></pre>
<p>Pokud vše proběhne, jak má, tak ve složce projektu budete mít jak stažený soubor, tak fotku stránky těsně před tím než jste ji opustili.</p>
<p><img decoding="async" src="http://wordpress.hardwired.dev/wp-content/uploads/2022/10/puppeteer_screen.jpg" alt="" /></p>
<p>Toto je velice hrubý nástřel toho, co Puppeteer dokáže na konkrétním případě. Výhodou je, že se opravdu spustí prohlížeč, ve kterém můžeme ovládat i dynamicky generované <code>single page</code> aplikace. Nevýhodou je, že pokud se struktura stránky změní moc, tak musíte upravit i váš kód.</p>
<p>Happy coding!</p>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2022%2F10%2F31%2Fpuppeteer-download-bot%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2022/10/31/puppeteer-download-bot/">Puppeteer download BOT</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>NodeJS develompent v Dockeru</title>
		<link>https://www.hardwired.dev/2022/09/17/nodejs-develompent-v-dockeru/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Sat, 17 Sep 2022 12:39:52 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Různé]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[docker-compose]]></category>
		<category><![CDATA[expressjs]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[nvm]]></category>
		<category><![CDATA[vagrant]]></category>
		<category><![CDATA[vscode]]></category>
		<guid isPermaLink="false">https://hessevalentino.cz/?p=378</guid>

					<description><![CDATA[<p>Pokud se motáte okolo webového vývoje (frontendy, api a pod...) a používáte JavaScript (respektive NodeJS), tak jste se určitě už &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2022/09/17/nodejs-develompent-v-dockeru/">NodeJS develompent v Dockeru</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Pokud se motáte okolo webového vývoje (frontendy, api a pod...) a používáte <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">JavaScript</a> (respektive <a href="https://nodejs.org/en/">NodeJS</a>), tak jste se určitě už setkali s následujícím problémem. Různé projekty jsou napsány pod různými verzemi programovacího jazyka a ne vždy je možné vše upgradovat na poslední verzi. </p>
<p><span id="more-378"></span></p>
<ul>
<li>Můžete používat knihovny, které ještě nejsou upraveny pro novou verzi.</li>
<li>Starší verze frameworku s poslední verzí jazyka nefunguje.</li>
<li>Zpětná nekompatibilita.</li>
<li>Prostě nejsou peníze nebo není čas zabývat se přechodem a přepisem aplikace na poslední verzi.</li>
</ul>
<p>Důvodů může být milión, ale klíčové je to, že pokud jste to vy co musí do těchto  projektů zasahovat, tak musíte provozovat více verzí jazyka.</p>
<p>Pokud se potýkáte s tímto problémem, tak nehledě na jakém operačním systému se nacházíte, budou scénáře podobné.</p>
<h2>Scénář 1 - Jedna verze v systému</h2>
<p>Tohle je pro popisovaný problém asi nejhorší situace. Máte v systému jednu verzi jazyka. Všechny projekty, na kterých pracujete, musejí běžet pod touhle verzí. Zpravidla to skončí tak, že verze jazyka bude taková, jakou potřebuje ten nejstarší (legacy) projekt. Může vás to zablokovat na tolik, že nebudete moci použít poslední verze frameworků nebo poslední funkcionalitu, protože nebudou tak starou verzi jazyka podporovat.</p>
<h2>Scénář 2 - NVM</h2>
<p><a href="https://github.com/nvm-sh/nvm">Node Version Manager</a> (NVM) je utilita, která vám umožní provozovat více verzí jazyka na jednom stroji a přepínat mezi nimi. Existuje jak pro Linux, MacOs, tak i pro Windows. Ve chvíli kdy se přepínáte mezi verzemi a používáte současně jednu, je to přímočaré a elegantní řešení. Ve chvíli, kdy potřebujete mít několik projektů puštěných naráz, pod různými verzemi jazyka, už samozřejmě vyžaduje určitou míru konfigurace. Ale zrovna k tomuto scénáři nemám moc co říct, protože jsem provozoval jen tu nejprimitivnější formu čistě přepínání mezi verzemi. Každopádně se jedná o funkční řešení.</p>
<h2>Scénář 3 - Vagrant</h2>
<p><a href="https://www.vagrantup.com/">Vagrant od HashiCorp</a> používá pro oddělení prostředí virtualizaci. Vytvoříte předpis, který nakonfiguruje virtuální stroj, ve kterém následně aplikaci vyvíjíte. Je možné nakonfigurovat celý ekosystém, aplikace, databáze, cache atd.  Teoreticky je to geniální věc. Nehledě na systém máte předpis, který spustíte na jakémkoliv systému a vytvoří vám stejné prostředí pro vývoj. V praxi to už tak veselé nebylo. Je pravda, že jsem Vagrant použil naposledy před několika lety. Problémy byly zpravidla nějaká specifika operačních systému, zvláště Windows. Nebo situace co se musely řešit &quot;hackem&quot;, protože ještě neexistovalo nativní řešení a samozřejmě hromada virtuálních mašin, když bylo prostředí pro vývoj rozsáhle. I tak jsem na tom byl nějakou dobu schopný vyvíjet a šlo to docela dobře. Čas pokročil a určitě byla hromada věcí dotažena. Určitě se jedná o funkční řešení.</p>
<h2>Scénář 4 - Docker</h2>
<p>Jak už název článku napovídá, budeme řešit <a href="https://www.docker.com/">Docker</a>. Docker používá kontejnery. Kontejner je softwarová jednotka, která zapouzdřuje kód i s jeho závislostmi. Na rozdíl od standardní virtualizace, nerozebíhá znovu celý operační systém, ale používá operační systém hostitele. Nejlíp to asi vysvětlí přímo citace ze stránek Dockeru.</p>
<blockquote>
<p>A container is a standard unit of software that packages up code and  all its dependencies so the application runs quickly and reliably from  one computing environment to another. A Docker container image is a  lightweight, standalone, executable package of software that includes  everything needed to run an application: code, runtime, system tools,  system libraries and settings.</p>
<p>Container images become containers at runtime and in the case of Docker containers – images become containers when they run on <a href="https://www.docker.com/products/container-runtime">Docker Engine</a>. Available for both Linux and Windows-based applications, containerized  software will always run the same, regardless of the infrastructure.  Containers isolate software from its environment and ensure that it  works uniformly despite differences for instance between development and staging.</p>
<p>from <a href="https://www.docker.com/resources/what-container/">https://www.docker.com/resources/what-container/</a></p>
</blockquote>
<p>V praxi to znamená, že máte v kontejneru souborový systém operačního systému dle libosti. Doinstalujete si potřebné balíčky pro běh vašeho projektu a tento kontejner můžete izolovaně pouštět tam, kde jsou kontejnery podporované. Speciálně Docker funguje pod Linuxem, MacOs i Windows.</p>
<pre><code>+------------++-----------+
|    APP1    ||   APP2    |
+------------++-----------+
+------------++-----------+
|  Bin/Libs  ||  Bin/Libs |
+------------++-----------+
+-------------------------+
|         Docker          |
+-------------------------+
+-------------------------+
|    Operační systém      |
+-------------------------+
+-------------------------+
|         Server          |
+-------------------------+</code></pre>
<p>&quot;Back in my days&quot;, když jsem si chtěl na serveru rozjet nějaké služby, buď jsem provozoval nějakou virtualizaci nebo jsem to všechno naplácal do jednoho operačního systému. Jedno ze zásadních úskalí bylo to, že různé služby potřebovaly různé balíky, verze knihoven a míru konfigurace. Pokud člověk nebyl dostatečně obezřetný mohl si &quot;roze***t&quot; celý systém a vše poslat do kytek. V lepším případě byla mašina v jakémsi meta ezo stavu, kdy něco jelo a něco ne.</p>
<p>S Dockerem hromada problémů opadla. Každá služba je izolovaný kontejner, který si své závislosti bere sebou. Pokud něco nefunguje, vadný kontejner se vymaže, ale vše ostatní jede dál. Drtivé množství běžných služeb (wiki, databáze, ...) mají už dnes nachystané a nakonfigurované obrazy. V uvozovkách je stačí jen spustit. Jako všechno si to sebou nese i negativa. Neaktualizované knihovny v kontejneru jsou bezpečnostní riziko. Nebo pokud si nevytváříte kontejner sami tak musíte důvěřovat autorovi, že tam nenasadil nějakou breberku. Ale vždy je něco za něco.</p>
<p>Jak už asi tušíte, z tohoto stručného popisu, použití pro výše popsaný problém bude jasné. Vytvoří se pro projekt Docker kontejner a tak budou všechny závislosti projektu izolovány od hlavního operačního systému. Takhle můžete mít pohodlně puštěné aplikace pod různou verzí NodeJS na jednom stroji. Je to v podstatě jako Vagrant, <a href="https://www.virtualbox.org/">VirtualBox</a> nebo obecně virtualizace. Akorát teda ne tak úplně. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Nešpinit systém, na kterém vyvíjíte, závislostmi projektu je podle mě dlouhodobě udržitelná cesta.</p>
<p>Plus mají kontejnery dnes ještě jednu výhodu. <a href="https://aws.amazon.com/getting-started/hands-on/deploy-docker-containers/">Cloudové služby</a> vám zpravidla umožňují posílat kontejnery i do produkce.</p>
<h2>Čestná zmínka</h2>
<p>Výše uvedené scénáře nejsou určitě jediné, ale jsou to ty, se kterými jsem se setkal osobně.</p>
<p>Minimálně ještě existuje možnost vyvíjet na vzdáleném operačním systému přes <a href="https://cs.wikipedia.org/wiki/Secure_Shell">SSH</a>. <a href="https://code.visualstudio.com/">Visual Studio Code</a> tento <a href="https://code.visualstudio.com/docs/remote/ssh">vzdálený vývoj</a> umožňuje. Jako taky možnost, ale za mě teda trochu exotická. Ale když není zbytí, lepší než drátem do oka.</p>
<h2>NodeJS projekt v Dockeru</h2>
<blockquote>
<p>Toto není kompletní návod pro člověka, který se v životě neotřel o Docker nebo o NodeJS a vývoj API. Do takových podrobností článek nejde. Zabývá se jak rozjet projekt v Dockeru a předpokládá už určité znalosti. Pardon. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</blockquote>
<p>V první řadě budeme potřebovat <a href="http://wordpress.hardwired.dev/instalace-dockeru/">nainstalovat Docker</a>. Případně na desktopu (a hlavně na Windows) to bude <a href="https://docs.docker.com/desktop/">Docker Desktop</a>.</p>
<p>Pokusíme se rozjet vývoj <a href="https://zdrojak.cz/clanky/rest-architektura-pro-webove-api/">REST API</a> s použitím <a href="https://expressjs.com/">ExpressJs</a>.</p>
<p>Pro náš projekt budeme mít následující strukturu.</p>
<pre><code class="language-bash">nodejs-docker-workflow \
    .dockerignore
    .env
    Dockerfile
    index.js
    package.json
    package-lock.json</code></pre>
<p><code>pakcage.json</code> obsahuje konfiguraci projektu.</p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;nodejs-docker-workflow&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;node index.js&quot;,
    &quot;dev&quot;: &quot;nodemon -L index.js&quot;
  },
  &quot;keywords&quot;: [],
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;dependencies&quot;: {
    &quot;express&quot;: &quot;^4.18.1&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;nodemon&quot;: &quot;^2.0.20&quot;
  }
}</code></pre>
<p>V části závislostí budeme pro náš jednoduchý projekt potřebovat pouze balíček <a href="https://www.npmjs.com/package/express">express</a>. V rámci vývojových závislostí (devDependencies) budeme používat <a href="https://www.npmjs.com/package/nodemon">nodemon</a>. Ten nám umožní restart serveru, pokud se vyskytne změna v hlídaném adresáři.</p>
<p><code>index.js</code> obsahuje kód našeho REST API.</p>
<pre><code class="language-javascript">const express = require(&#039;express&#039;)

const app = express()

app.get(&#039;/&#039;, (req, res) =&gt; {
    res.send({
        data: {
            message: &#039;Hello world!&#039;,
            exclamation: &#039;!!!&#039;,
        },
    })
})

const port = process.env.PORT || 3000

app.listen(port, () =&gt; console.log(`listening on port ${port}`))</code></pre>
<p>Primitivní API vracející &quot;Hello world!&quot;.</p>
<p><code>Dockerfile</code> obsahuje sestavení našeho obrazu kontejneru.</p>
<pre><code class="language-dockerfile">FROM node:16
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . ./
ENV PORT 3000
EXPOSE $PORT
CMD [&quot;npm&quot;, &quot;run&quot;, &quot;dev&quot;]</code></pre>
<p><code>FROM node:16</code> říká, že použijeme základní image, na kterém je už nachystán NodeJS verze 16.</p>
<p><code>WORKDIR /app</code> nás v rámci kontextu přesune do složky <code>/app</code>.</p>
<p><code>COPY package*.json</code> . překopíruje do obrazu do <code>/app</code> soubor <code>package.json</code>.</p>
<p><code>RUN npm install</code> spustí instalaci závislostí na základe <code>package.json</code>.</p>
<p><code>COPY . ./</code> překopíruje soubory z aktuálního adresáře do obrazu do <code>/app</code>.</p>
<p><code>ENV PORT 3000</code> vytvoří proměnou prostředí.</p>
<p><code>CMD [&quot;npm&quot;, &quot;run&quot;, &quot;dev&quot;]</code> spustí skript definovaný v <code>package.json</code>, který spustí nodemon.</p>
<p><code>.dockerignore</code> obsahuje seznam souboru a složek co se nebudou kopírovat do obrazu.</p>
<pre><code class="language-bash">node_modules
Dockerfile
.dockerignore
.git
.gitignore
README.md
docker-compose*</code></pre>
<p><code>.env</code> je seznam proměnných prostředí, které chceme aplikovat na kontejner.</p>
<pre><code>PORT=4000</code></pre>
<p>Základní projekt máme nachystaný. A sestavíme na základě <code>Dockerfile</code> obraz pro náš kontejner.</p>
<pre><code class="language-bash">docker build -t node-app-image .</code></pre>
<p>Následně pak můžeme překontrolovat, že obraz skutečně existuje.</p>
<pre><code class="language-bash">docker image ls</code></pre>
<p>Obraz je nachystaný a můžeme spustit samotný kontejner.</p>
<pre><code class="language-bash"># WINDOWS %cd%
# POWERSHELL ${pwd}
# MAC, LINUX $(pwd)

# --env PORT=4000
# --env-file ./.env

docker run -p 3000:4000 -d --name node-app --env-file ./.env -v %cd%:/app -v /app/node_modules node-app-image</code></pre>
<p><code>-p 3000:4000</code> přesměruje port 3000 z hostitelského systému na port 4000 Docker kontejneru.</p>
<p><code>-d</code> spustí Docker kontejner na pozadí.</p>
<p><code>--name node-app</code> pojmenuje kontejner.</p>
<p><code>--env-file ./.env</code> nastaví proměnné systému na základě souboru <code>.env</code>.</p>
<p><code>-v %cd%:/app</code> zajistí zrcadlení aktuálního adresáře a jeho změny do <code>/app</code> v kontejneru.</p>
<p><code>-v /app/node_modules</code> vytvoří volume pro node moduly. Díky tomu se nestane to, že přes zrcadlený adresář pošleme příkaz k jejich smazání v kontejneru. Je to trochu &quot;ohák&quot;, ale funční.</p>
<p><code>node-app-image</code> je název obrazu na základě kterého vytváříme kontejner.</p>
<p>Pokud nedostaneme nějaké chybové hlášení, můžeme zkontrolovat, že vše jede.</p>
<p>Můžeme se podívat na aktuálně běžící kontejnery.</p>
<pre><code class="language-bash">docker ps</code></pre>
<p>A můžeme také zkontrolovat logy pro konkrétní kontejner.</p>
<pre><code class="language-bash">docker logs node-app</code></pre>
<p>Když do prohlížeče zadáme <code>localhost:3000</code> dostaneme následující.</p>
<pre><code class="language-json">{&quot;data&quot;:{&quot;message&quot;:&quot;Hello world!&quot;,&quot;exclamation&quot;:&quot;!!!&quot;}}</code></pre>
<p>Pokud v souboru <code>index.js</code> upravíme odpověď serveru, <code>nodemon</code> na to zareaguje a restartuje API s aktuální změnou.</p>
<p>Jestliže se potřebujeme &quot;přihlásit&quot; dovnitř kontejneru do příkazové řádky, použijeme <code>docker exec</code>.</p>
<pre><code class="language-bash">docker exec -it node-app bash</code></pre>
<p>V této chvíli máme plně funkční NodeJS projekt v Dockeru. Pokud přidáme nebo odebereme balíčky, musím znovu sestavit obraz pomocí <code>docker build -t node-app-image .</code> a Docker kontejner spustit.</p>
<p>Předtím je teda nutné kontejner zabít, to uděláme pomocí <code>docker rm</code>.</p>
<pre><code class="language-bash">docker rm node-app -fv</code></pre>
<p><code>-fv</code> odstraní i běžící kontejner (nemusíme zastavovat) a na něj navázané anonymní volumes (svazky).</p>
<p>Tohle je taková &quot;základní&quot; verze. Spouštění Docker kontejneru, s veškerou konfigurací v příkazové řádce může být po čase otrava. Jednodušším řešením je použití <a href="https://docs.docker.com/compose/gettingstarted/">Docker-Compose</a>.</p>
<p>V našem projektu vytvoříme soubor <code>docker-compose.yml</code>.</p>
<pre><code class="language-yaml">version: &quot;3&quot;
services:
  node-app:
    container_name: node-app
    build: .
    ports:
      - &quot;3000:4000&quot;
    volumes:
      - ./:/app
      - /app/node_modules
    env_file:
      - ./.env
#    environment:
#      - PORT=4000 </code></pre>
<p><code>version: &quot;3&quot;</code> je <a href="https://docs.docker.com/compose/compose-file/compose-versioning/">verze zápisu Docker Compose</a> souboru.</p>
<p><code>node-app:</code> uvozuje sekci našeho kontejneru.</p>
<p><code>container_name: node-app</code> pojmenuje náš kontejner. Pokud ho nepojmenujeme sami, Docker to udělá za nás.</p>
<p><code>build: .</code> sestaví obraz pomocí <code>Dockerfile</code>.</p>
<p><code>ports:</code> přesměrování portů.</p>
<p><code>volumes:</code> seznam volumes.</p>
<p><code>env_file:</code> nastavuje proměnné prostředí.</p>
<p>Docker Compose soubor jen kopíruje to, co jsme nastavovali pro <code>docker run</code>. Ale takhle nám zůstane nastavení pěkně a strukturovaně uloženo.</p>
<p>Předpis spustíme pomocí příkazu <code>docker-compose</code>.</p>
<pre><code class="language-bash">docker-compose up -d</code></pre>
<p>Pokud přidáme parametr <code>--build</code>, tak se při každém spuštění znovu sestaví obraz.</p>
<pre><code class="language-bash">docker-compose up -d --build</code></pre>
<p>Pomocí <code>docker-compose</code> provádíme i smazání.</p>
<pre><code class="language-bash">docker-compose down -v</code></pre>
<p><code>-v</code> jako v předchozím případě smaže i připojené anonymní volumes.</p>
<p>Tohle je už o něco lepší verze, ale nepočítá s tím, že bychom chtěli různá prostředí. Například <code>development</code> a <code>production</code>. Budeme muset upravit <code>Dockerfile</code>, <code>docker-compose.yml</code> a přidat <code>docker-compose.dev.yml</code> a <code>docker-compose.prod.yml</code>.</p>
<p>Do <code>Dockerfile</code> přidáme podmínku pro různá prostředí.</p>
<pre><code class="language-dockerfile">FROM node:16
WORKDIR /app
COPY package*.json .

ARG NODE_ENV
RUN if [ &quot;$NODE_ENV&quot; = &quot;development&quot; ]; \
        then npm install; \
        else npm install --only=production; \
        fi

COPY . ./
ENV PORT 3000
EXPOSE $PORT
CMD [&quot;node&quot;, &quot;index.js&quot;]</code></pre>
<p><code>ARG NODE_ENV</code> definujeme použití argumentu <code>NODE_ENV</code>.</p>
<p><code>RUN if [ &quot;$NODE_ENV&quot; = &quot;development&quot; ]; \</code> na základě aktuální typu prostředí provedeme klasický <code>npm install</code> nebo produkční.</p>
<p><code>CMD [&quot;node&quot;, &quot;index.js&quot;]</code> je příkaz do produkčního prostředí, protože nespouštíme <code>nodemon</code>. Každopádně ho stejně budeme definovat znovu v Docker Compose souborech.</p>
<p><code>docker-compose.yml</code> trošku zeštíhlíme a necháme v něm jen společná nastavení pro všechna prostředí.</p>
<pre><code class="language-yaml">version: &quot;3&quot;
services:
  node-app:
    container_name: node-app
    build: .
    ports:
      - &quot;3000:4000&quot;
    environment:
      - PORT=4000  </code></pre>
<p><code>docker-compose.dev.yml</code> nastavím pro naše <code>development</code> prostředí.</p>
<pre><code class="language-yaml">version: &quot;3&quot;
services:
  node-app:
    build:
      context: . 
      args:
        NODE_ENV: development
    volumes:
      - ./:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development  
    command: npm run dev</code></pre>
<p>Všimněte si, že jsme rozšířili definici <code>build</code> a přidali argument <code>NODE_ENV</code>, který se používá v <code>Dockerfile</code>. Nastavení <code>volumes</code> je stejné jako předtím a přepsali jsme <code>CMD</code> v <code>Dockerfile</code> na náš <code>development</code> příkaz.</p>
<p><code>docker-compose.prod.yml</code> bude jednodušší, protože pro produkci nepotřebujeme zrcadlit adresáře.</p>
<pre><code class="language-yaml">version: &quot;3&quot;
services:
  node-app:
    build:
      context: . 
      args:
        NODE_ENV: production
    environment:
      - NODE_ENV=production
    command: node index.js</code></pre>
<p>Principiálně je to to samé co <code>docker-compose.dev.yml</code>.</p>
<p>Pokud budeme chtít spustit <code>development</code> verzi, zavoláme.</p>
<pre><code class="language-bash">docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d</code></pre>
<p>Popřípadě, pokud chceme spustit i vytváření obrazu.</p>
<pre><code class="language-bash">docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build</code></pre>
<p>Odstranění kontejneru provedeme promocí.</p>
<pre><code class="language-shell">docker-compose -f docker-compose.yml -f docker-compose.dev.yml down -v</code></pre>
<p>Pro produkční build to bude analogické.</p>
<pre><code class="language-bash">docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
docker-compose -f docker-compose.yml -f docker-compose.prod.yml down -v</code></pre>
<p>TADÁ a to je vše přátele. Aplikace funguje pořád stejně, ale už můžeme rozlišovat mezi <code>development</code> a <code>production</code> prostředtím.</p>
<hr />
<p><em>ad1)</em> Článek popisuje pouze absolutní základ, pravá síla Dockeru se projeví ve chvíli, kdy si nakonfigurujete kompletní ekosystém a budete ho schopni jednoduše replikovat.</p>
<p>ad2) Článek ukazuje situaci, kdy nebudete mít na svém stroji nainstalován NodeJS a nepustíte <code>npm install</code> na svém stroji. Tím si nevygenerujete <code>package-lock.json</code>. To může být problém při generování produkčních kontejnerů. <code>package-lock.json</code> obsahuje deterministický popis závislostí. Do produkce chcete jít s takovým stromem závislostí, který už máte odzkoušený. Pro doplnění citace z <a href="https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json">docs.npm.com</a>.</p>
<blockquote>
<p><code>package-lock.json</code> is automatically generated for any operations where npm modifies either the <code>node_modules</code> tree, or <code>package.json</code>. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.</p>
<p>Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.</p>
<p>from <a href="https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json">https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json</a></p>
</blockquote>
<p>Proto je vhodnější postup na hostitelské systému používat <code>npm i</code> pro instalaci nových balíčku do projektu. Tím se bude generovat i <code>package-lock.json</code>. Toto nijak neomezuje používání rozličných verzí NodeJS v kontejnerech.</p>
<p>ad3) Docker se chová tak, že spustí příkaz a když doběhne, tak se vypne. V případě, že rozjíždíte NodeJs API, tak je to jedno. Tam se předpokládá, že pouštíte nějaký <code>nodemon</code> nebo něco co udrží API v běhu. Pokud ale chcete vyvíjet něco co neběží ve smyčce a z <code>Dockerfile</code> odeberete <code>CMD příkaz</code>, tak se <code>Docker container</code> spustí a úspěšně ukončí. Jde tím předejít přidáním parametru <code>tty</code>.<br />
Ten zajistí, že se kontejner hned neukončí.</p>
<p>Pro <code>docker-compose</code>:</p>
<pre><code class="language-yaml">mydocker:
    tty: true</code></pre>
<p>Pro <code>docker run</code>:</p>
<pre><code class="language-bash">docker run -d --tty ......</code></pre>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2022%2F09%2F17%2Fnodejs-develompent-v-dockeru%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2022/09/17/nodejs-develompent-v-dockeru/">NodeJS develompent v Dockeru</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Self hosted Matrix server</title>
		<link>https://www.hardwired.dev/2022/09/15/self-hosted-matrix-server/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Thu, 15 Sep 2022 15:19:19 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[element]]></category>
		<category><![CDATA[end-to-end]]></category>
		<category><![CDATA[fediverse]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[portainer]]></category>
		<category><![CDATA[postgre]]></category>
		<category><![CDATA[privacy]]></category>
		<category><![CDATA[raspberry]]></category>
		<category><![CDATA[rpi]]></category>
		<category><![CDATA[synapse]]></category>
		<guid isPermaLink="false">https://hessevalentino.cz/?p=297</guid>

					<description><![CDATA[<p>Těžko by jste asi hledali někoho, kdo nikdy neposlal ani jednu zprávu přes Messenger nebo podobnou službu. Asi můžeme říct, &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2022/09/15/self-hosted-matrix-server/">Self hosted Matrix server</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Těžko by jste asi hledali někoho, kdo nikdy neposlal ani jednu zprávu přes Messenger nebo podobnou službu. Asi můžeme říct, že je to jeden z nejrozšířenějších komunikačních prostředků současnosti.</p>
<p>S rostoucím podílem těchto služeb v oblasti všeobecné komunikace vyvstal i takový nešvar. Hovorově bychom mohli říct &quot;fízlování&quot;. V reálu to bude nějaká sada algoritmů, která se snaží na základě klíčových slov, frází nebo nějaké sofistikovanější analýzy rozpoznat závadný či protiprávní obsah. Tyto praktiky se většinou zaštiťují ochranou dětí před XYZ a podobné zavádějící důvody. Ale o problematice svobody slova a práva na soukromí tento příspěvek není.</p>
<p>Klasické textové komunikační služby ukládají vaše zprávy v nešifrované podobě. Nemáte vůbec tušení jak dlouho se vaše data uchovávají a za jakým účelem (většinou marketing) mohou být přeprodávána. A už vůbec nevíte, kdy a kdo, to může použít proti vám. (byť třeba vytržené z kontextu)</p>
<p>Situaci si můžete vylepšit tím, že používáte &quot;end-to-end&quot; šifrované komunikátory. Telegram, Signal, Threema a podobně. Při této metodě komunikace by v ideálním případě zprostředkovatel neměl být schopný zprávy jakkoliv dešifrovat.</p>
<p>Tak je to možná v ideálním světě. V tom našem můžeme narazit na pár úskalí. Musíme zprostředkovateli věřit, že dodává takovou službu jakou inzeruje. I když nemusí vidět přímo obsah zpráv, stále si může uchovávat kdo, kdy a s kým komunikoval. Nepříjemností taky je registrace podmíněná poskytnutím telefonního čísla. Telefonní číslo za určitých podmínek dává smysl a používání aplikace je díky němu komfortnější, ale taky je to další vektor útoku na vaši identitu.</p>
<p>Alternativní možností je zprovoznit vlastní Matrix server. Pokud o tom slyšíte poprvé, můžete prozkoumat <a href="https://fediverse.party/" title="Fediverse ekosystém">Fediverse ekosystém</a> a pořádně se ponořit do králičí nory.</p>
<p>Jen ve zkratce popis na wikipedii.</p>
<blockquote>
<p>The fediverse (a portmanteau of federation and universe) is an ensemble of federated (i.e. interconnected) servers that are used for web publishing (i.e. social networking, microblogging, blogging, or websites) and file hosting, but which, while independently hosted, can communicate with each other. On different servers (instances), users can create so-called identities. These identities are able to communicate over the boundaries of the instances because the software running on the servers supports one or more communication protocols which follow an open standard.[1] As an identity on the fediverse, users are able to post text and other media, or to follow posts by other identities.[2] In some cases, users can show or share data (video, audio, text, and other files) publicly or to a selected group of identities and allow other identities to edit other users\' data (such as a calendar or an address book). from <a href="https://en.wikipedia.org/wiki/Fediverse">https://en.wikipedia.org/wiki/Fediverse</a> </p>
</blockquote>
<p>Pro naše účely není tento aspekt úplně klíčový.</p>
<p>Co vlastně získáme tím, že zprovozníme vlastní Matrix server?</p>
<ul>
<li>Komunikace používá end-to-end šifrování. Nikdo kromě příjemce by neměl být schopný zprávu vidět.</li>
<li>Data leží na našem &quot;železe&quot; a v námi kontrolovaném operačním systému. Sami si můžete překontrolovat jak a jaká data jsou v databázi ukládána.</li>
<li>Starou dobrou registraci s uživatelským jménem a heslem. Nejsou potřeba žádné emaily nebo telefonní čísla.</li>
<li>Nikdo probíhající komunikaci &quot;nefízluje&quot;.</li>
<li>Kód je open source. Každý do něho může nahlédnout. Možnost úmyslného zanešení nějakého škodlivého kusu kódu je hodně malá. Komunita by jim to brzy omlátila o hlavu.</li>
<li>Máte na výběr z vícero klientů. I když tohle může být někdy i negativum než pozitivum.</li>
<li>Moderní klienti moc nezaostávají za předními hráči na trhu. Ano jde poznat, že do toho nebylo nasypáno tolik peněz a „user experience“ není tak „smooth“. To ale nic nemění na tom, že můžete posílat zprávy, fotky, videa, emoji, nálepky, gify nebo provádět video telefonáty. Všechno je technicky funkční.</li>
<li>Je možné provozovat komunikaci s jednotlivými lidmi, skupinové komunikace nebo vytvářet místnosti.</li>
</ul>
<p>Výhod se najde asi ještě více, ale tou nejdůležitější vlastní kontrola.</p>
<p>Nevýhod se najde taky dost. Vůbec samotné rozeběhnutí vyžaduje lehce technický „skill“. Plus věci okolo jako domény, reverzní proxy atd.</p>
<p>Tak a teď teda k tomu co a jak je potřeba rozeběhnout.</p>
<p>Rozeběhnout to můžete skoro na čemkoliv, ale já pro naše účely použil RPi 3B+ s SSD diskem. Pro běh jednotlivých služeb použijeme Docker a Docker-Compose. Jak nainstalovat Docker <a href="http://wordpress.hardwired.dev/instalace-dockeru/" title="je popsáno v jiném článku">je popsáno v jiném článku</a> na tomto blogu.</p>
<p>Náš stack obsahje následující Docker obrazy.</p>
<ul>
<li>portainer/portainer-ce:latest</li>
<li>matrixdotorg/synapse:latest</li>
<li>postgres:14</li>
<li>vectorim/element-web:latest</li>
</ul>
<p><a href="https://www.portainer.io/" title="Portainer">Portainer</a> slouží jen pro pohodlnější správu Docker kontejnerů.</p>
<p>Jako <a href="https://matrix.org/" title="Matrix">Matrix</a> server použijeme <a href="https://github.com/matrix-org/synapse" title="Synapse">Synapse</a>. Je to implementace Matrix serveru v Pythonu.</p>
<p>Postgres 14 bude naše databáze. V základu používá Synapse Sqlite3, ale pokud máme tu možnost, bude lepší použít Postgres.</p>
<p><a href="https://element.io/" title="Element">Element</a> je webový klient pro Matrix server.</p>
<p>V domovském adresáři si vytvoříme složku matrix-stack a začneme skládat Docker-Compose soubor.</p>
<pre><code class="language-shell">cd ~
mkdir matrix-stack
nano ./matix-stack/docker-compose.yml</code></pre>
<pre><code class="language-yaml">version: &#039;3.3&#039;

services:
  portainer:
    container_name: portainer
    image: portainer/portainer-ce:latest
    restart: always
    ports:
      - &quot;9000:9000&quot;
    volumes:
      - portainer_data:/data
      - /var/run/docker.sock:/var/run/docker.sock

  synapse:
    container_name: synapse
    image: matrixdotorg/synapse:latest
    restart: always
    ports:
      - 8008:8008
    volumes:
      - /var/docker_data/matrix:/data

  postgres:
    container_name: postgres
    image: postgres:14
    restart: unless-stopped
    ports:
      - &quot;5432:5432&quot;
    volumes:
     - /var/docker_data/postgresdata:/var/lib/postgresql/data

    environment:
     - POSTGRES_DB=synapse
     - POSTGRES_USER=synapse
     - POSTGRES_PASSWORD=SUPERSECRETLONGPASSWORD
     - POSTGRES_INITDB_ARGS=--lc-collate C --lc-ctype C --encoding UTF8

  element:
    container_name: element
    image: vectorim/element-web:latest
    restart: unless-stopped
    ports:
      - &quot;80:80&quot;
    volumes:
      - /var/docker_data/element-config.json:/app/config.json

volumes:
  portainer_data:</code></pre>
<p>Pro Synapse místo Sqlite3 použijeme Postgre databázi. Víceméně se standardním nastavením kromě jedné věci.</p>
<pre><code class="language-yaml">POSTGRES_INITDB_ARGS=--lc-collate C --lc-ctype C --encoding UTF8</code></pre>
<p>Matrix vyžaduje aby <strong>LC_COLLATE</strong> a <strong>LC_TYPE</strong> nastaveny na <strong>C</strong>. Má to co do činění s akceptováním různých znakových sad.</p>
<blockquote>
<p>When LC_CTYPE is C or POSIX, any character set is allowed, but for other settings of LC_CTYPE there is only one character set that will work correctly. Since the LC_CTYPE setting is frozen by initdb, the apparent flexibility to use different encodings in different databases of a cluster is more theoretical than real, except when you select C or POSIX locale (thus disabling any real locale awareness).</p>
</blockquote>
<p>Před tím, než pustíme <strong>docker-compose</strong>, je potřeba udělat ještě pár věcí.</p>
<p>Potřebujeme vygenerovat konfigurační soubor pro <strong>Synapse</strong> server.</p>
<pre><code class="language-bash">docker run -it --rm \
    -v &quot;/var/docker_data/matrix:/data&quot; \
    -e SYNAPSE_SERVER_NAME=matrix.YOUR_DOMAIN.com \
    -e SYNAPSE_REPORT_STATS=no \
    matrixdotorg/synapse:latest generate</code></pre>
<p>A v nově vygenerovaném souboru předělat Sqlite3 na Postgre. Stačí zakomentovat sekci s Sqlite3 a vložit novou.</p>
<pre><code class="language-yaml">database:
  name: psycopg2
  args:
    user: synapse
    password: SUPERSECRETLONGPASSWORD
    database: synapse
    host: postgres
    cp_min: 5
    cp_max: 10</code></pre>
<p>Potom je potřeba vytořit konfigurační soubor pro Element.</p>
<pre><code class="language-bash">sudo nano /etc/docker_data/element-config.yaml</code></pre>
<pre><code class="language-json">{
    &quot;default_server_config&quot;: {
        &quot;m.homeserver&quot;: {
            &quot;base_url&quot;: &quot;https://matrix.YOUR_DOMAIN.com&quot;,
            &quot;server_name&quot;: &quot;matrix.YOUR_DOMAIN.com&quot;
        },
        &quot;m.identity_server&quot;: {
            &quot;base_url&quot;: &quot;https://vector.im&quot;
        }
    },
    &quot;brand&quot;: &quot;Element&quot;,
    &quot;integrations_ui_url&quot;: &quot;https://scalar.vector.im/&quot;,
    &quot;integrations_rest_url&quot;: &quot;https://scalar.vector.im/api&quot;,
    &quot;integrations_widgets_urls&quot;: [
        &quot;https://scalar.vector.im/_matrix/integrations/v1&quot;,
        &quot;https://scalar.vector.im/api&quot;,
        &quot;https://scalar-staging.vector.im/_matrix/integrations/v1&quot;,
        &quot;https://scalar-staging.vector.im/api&quot;,
        &quot;https://scalar-staging.riot.im/scalar/api&quot;
    ],
    &quot;hosting_signup_link&quot;: &quot;https://element.io/matrix-services?utm_source=element-web&amp;utm_medium=web&quot;,
    &quot;bug_report_endpoint_url&quot;: &quot;https://element.io/bugreports/submit&quot;,
    &quot;uisi_autorageshake_app&quot;: &quot;element-auto-uisi&quot;,
    &quot;showLabsSettings&quot;: true,
    &quot;piwik&quot;: {
        &quot;url&quot;: &quot;https://piwik.riot.im/&quot;,
        &quot;siteId&quot;: 1,
        &quot;policyUrl&quot;: &quot;https://element.io/cookie-policy&quot;
    },
    &quot;roomDirectory&quot;: {
        &quot;servers&quot;: [
            &quot;matrix.org&quot;,
            &quot;gitter.im&quot;,
            &quot;libera.chat&quot;
        ]
    },
    &quot;enable_presence_by_hs_url&quot;: {
        &quot;https://matrix.org&quot;: false,
        &quot;https://matrix-client.matrix.org&quot;: false
    },
    &quot;terms_and_conditions_links&quot;: [
        {
            &quot;url&quot;: &quot;https://element.io/privacy&quot;,
            &quot;text&quot;: &quot;Privacy Policy&quot;
        },
        {
            &quot;url&quot;: &quot;https://element.io/cookie-policy&quot;,
            &quot;text&quot;: &quot;Cookie Policy&quot;
        }
    ],
    &quot;hostSignup&quot;: {
      &quot;brand&quot;: &quot;Element Home&quot;,
      &quot;cookiePolicyUrl&quot;: &quot;https://element.io/cookie-policy&quot;,
      &quot;domains&quot;: [
          &quot;matrix.org&quot;
      ],
      &quot;privacyPolicyUrl&quot;: &quot;https://element.io/privacy&quot;,
      &quot;termsOfServiceUrl&quot;: &quot;https://element.io/terms-of-service&quot;,
      &quot;url&quot;: &quot;https://ems.element.io/element-home/in-app-loader&quot;
    },
    &quot;sentry&quot;: {
        &quot;dsn&quot;: &quot;https://029a0eb289f942508ae0fb17935bd8c5@sentry.matrix.org/6&quot;,
        &quot;environment&quot;: &quot;develop&quot;
    },
    &quot;posthog&quot;: {
        &quot;projectApiKey&quot;: &quot;phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO&quot;,
        &quot;apiHost&quot;: &quot;https://posthog.element.io&quot;
    },
    &quot;features&quot;: {
        &quot;feature_spotlight&quot;: true
    },
    &quot;map_style_url&quot;: &quot;https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx&quot;
}</code></pre>
<p>V horní části souboru upravte pro vaši doménu.</p>
<pre><code class="language-json">&quot;default_server_config&quot;: {
        &quot;m.homeserver&quot;: {
            &quot;base_url&quot;: &quot;https://matrix.YOUR_DOMAIN.com&quot;,
            &quot;server_name&quot;: &quot;matrix.YOUR_DOMAIN.com&quot;
        },
        &quot;m.identity_server&quot;: {
            &quot;base_url&quot;: &quot;https://vector.im&quot;
        }
    }</code></pre>
<p>Tak a teď už můžeme pustit ten docker. Přesuneme se do složky s Docker-Compose souborem a spustíme příkaz docker-compose.</p>
<pre><code class="language-bash">cd ~/matrix-stack
docker-compose up -d</code></pre>
<p>Pokud všechno proběhne dle plánu, tak se můžete zkusit přihlásit do Portaineru a měli byste vidět něco takového.</p>
<p><img decoding="async" src="http://wordpress.hardwired.dev/wp-content/uploads/2022/09/matrix-containers.jpg" alt="" /></p>
<p>Teď se potřebujeme připojit do docker kontejneru kde beží Synapse odkud budeme přes příkaz <code>register_new_matrix_user</code> přidávat uživatele.</p>
<pre><code class="language-bash">docker exec -it synapse /bin/bash</code></pre>
<pre><code class="language-bash">register_new_matrix_user -c /data/homeserver.yaml http://127.0.0.1:8008</code></pre>
<p>Příkaz vás následně navede co vyplnit.</p>
<p>V tomto bodě nám už vše běží a máme vytvořeného prvního uživatele. Pokud se přes prohlížeč podíváte na <code>http://&lt;ip-adresa-vaseho-stroje&gt;:8008</code> uvidíte že Matrix server běži.</p>
<p><img decoding="async" src="http://wordpress.hardwired.dev/wp-content/uploads/2022/09/matirx-is-running.jpg" alt="" /></p>
<p>Určitě se nechceme vždy připojovat na <code>http://&lt;ip-adresa-vaseho-stroje&gt;:8008</code>. To by bylo poněkud nepohodlné a pravděpodobně by to fungovalo jen v lokální síti. Ještě bychom mohli přesměrovat porty na router, ale to je prašť jako uhoď.</p>
<p>Lepší bude použít doménu jako <code>matrix.nasedomena.eu</code> a samozřejmě <code>https</code> protokol, aby naše data po internetu nelítala jen tak. </p>
<p>Bude to chtít zařídit několik věcí. </p>
<ul>
<li>Je potřeba mít veřejnou statickou IP.</li>
<li>Koupit nějakou doménu.</li>
<li>Vyřídit si certifikát. Například přes službu <a href="https://letsencrypt.org/" title="Let&#039;s Encrypt">Let's Encrypt</a>.</li>
<li>Zprovoznit reverzní proxy, která bude zpracovávat příchozí požadavky. Pro tento článek použijeme webový server <a href="https://www.nginx.com/" title="Nginx">Nginx</a> jako reverzní proxy. Jak zprovoznit Nginx jako reverzní proxy najdete v <a href="http://wordpress.hardwired.dev/nginx-jako-reverzni-proxy/" title="článku na tomto webu">článku na tomto webu</a>.</li>
</ul>
<p>Budeme chtít používat <code>https://matrix.nasedomena.eu</code> a <code>https://element.nasedomena.eu</code>.</p>
<p>Pro <code>element.nasedomena.eu</code> bude konfigurační soubor pro Nginx vypadat nějak takhle.</p>
<pre><code> server {
    listen 80;
    server_name element.nasedomena.eu;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name element.nasedomena.eu;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/nasedomena.eu/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/nasedomena.eu/privkey.pem; # managed by Certbot

    location / {
        proxy_pass http://192.168.1.111:80;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &#039;upgrade&#039;;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}</code></pre>
<p>Veškerý nešifrovaný provoz směrující na <code>element.nasedomena.eu</code> bude přesměrován na šifrovaný.</p>
<p>Pro samotný Matrix server je nutné do konfigurace přidat ještě pár věcí.</p>
<pre><code>server {
    listen 80;
    server_name matrix.nasedomena.eu;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    listen 8448 ssl http2 default_server;
    listen [::]:8448 ssl http2 default_server;

    server_name matrix.nasedomena.eu;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/nasedomena.eu/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/nasedomena.eu/privkey.pem; # managed by Certbot

     location /.well-known/matrix/client {
                return 200 &#039;{&quot;m.server&quot;: {&quot;base_url&quot;: &quot;matrix.nasedomena.eu:443&quot;}}&#039;;
                default_type application/json;
                add_header Access-Control-Allow-Origin *;
        }

    location /.well-known/matrix/server {
                default_type application/json;
                add_header Access-Control-Allow-Origin *;
                return 200 &#039;{&quot;m.server&quot;:&quot;matrix.nasedomena.eu:443&quot;}&#039;;
        }

    location / {
        proxy_pass http://192.168.1.111:8008;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &#039;upgrade&#039;;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}</code></pre>
<p>Jestli máme všechno dobře nakonfigurováno, můžeme zkusit <code>https://element.nasedomena.eu</code>. Poběží tu webový klient pro Matrix. Budeme muset upravit domovský server na náš <code>matrix.nasedomena.eu</code>, protože v základu je tam nastavený <code>matrix.org</code>. Poté se můžeme přihlásit jako uživatel, kterého jsme vytvořili v jednom z předchozích kroků.</p>
<p><img decoding="async" src="http://wordpress.hardwired.dev/wp-content/uploads/2022/09/element-login.jpg" alt="" /></p>
<p>K připojení můžete samozřejmě využít jakéhokoliv klienta Matrixu. Přidejte další další uživatele pomocí kroků výše a můžete začít komunikovat naprosto soukromě. Komunikace s dalšími uživateli v rámci Fediverse je také možná. Samotný Synapse jde různě nakonfigurovat. Můžete například povolit registraci uživatelů přes klienty a další možnosti. Konfigurace Synapse ale není náplní tohoto článku.</p>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2022%2F09%2F15%2Fself-hosted-matrix-server%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2022/09/15/self-hosted-matrix-server/">Self hosted Matrix server</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Instalace Dockeru</title>
		<link>https://www.hardwired.dev/2022/09/11/instalace-dockeru/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Sun, 11 Sep 2022 17:50:48 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[docker-compose]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[raspberry]]></category>
		<category><![CDATA[rpi]]></category>
		<guid isPermaLink="false">https://hessevalentino.cz/?p=263</guid>

					<description><![CDATA[<p>Rychlý přehled jak nainstalovat Docker a Docker-Compose. Vždy je dobré systém aktualizovat. sudo apt update &#38;&#38; sudo apt upgrade -y &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2022/09/11/instalace-dockeru/">Instalace Dockeru</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Rychlý přehled jak nainstalovat Docker a Docker-Compose.</p>
<p>Vždy je dobré systém aktualizovat.</p>
<pre><code class="language-shell">sudo apt update &amp;&amp; sudo apt upgrade -y</code></pre>
<p>Instalace dockeru.</p>
<pre><code class="language-shell">curl -sSL https://get.docker.com | sh</code></pre>
<p>Povolíme uživateli používat Docker. V opačném případě je nutné používat docker jako root. Přidáme uživatele do skupiny docker.</p>
<pre><code class="language-shell">sudo usermod -aG docker &lt;user_name&gt;</code></pre>
<p>Nainstalujeme Docker-Compose.</p>
<pre><code class="language-shell">sudo apt install libffi-dev libssl-dev python3-dev python3 python3-pip -y
sudo pip3 install docker-compose</code></pre>
<p>Zapneme docker po startu systému.</p>
<pre><code class="language-shell">sudo systemctl enable docker</code></pre>
<p>Tadá, je možné používat Docker a Docker-Compose.</p>
<hr />
<p>Pokud vám nedělá dobře spouštět &quot;on demand&quot; stažené skripty, můžete vše udělat pěkně postupně.</p>
<pre><code class="language-bash">curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo &quot;deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable&quot; | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null

sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release -y

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io -y

sudo usermod -aG docker $USER</code></pre>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2022%2F09%2F11%2Finstalace-dockeru%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2022/09/11/instalace-dockeru/">Instalace Dockeru</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
