mirror of
https://github.com/ditatompel/insights.git
synced 2025-01-08 03:12:06 +07:00
Merge branch 'main' into renovate/github.com-hugomods-icons-vendors-bootstrap-0.x
This commit is contained in:
commit
c91732cb95
11 changed files with 637 additions and 4 deletions
|
@ -9,12 +9,12 @@ hb:
|
||||||
# see https://hbstack.dev/en/docs/modules/socials/.
|
# see https://hbstack.dev/en/docs/modules/socials/.
|
||||||
socials:
|
socials:
|
||||||
github: https://github.com/ditatompel/insights
|
github: https://github.com/ditatompel/insights
|
||||||
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ?sub_confirmation=1
|
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ
|
||||||
footer:
|
footer:
|
||||||
# see https://hbstack.dev/en/docs/modules/socials/.
|
# see https://hbstack.dev/en/docs/modules/socials/.
|
||||||
socials:
|
socials:
|
||||||
github: https://github.com/ditatompel/insights
|
github: https://github.com/ditatompel/insights
|
||||||
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ?sub_confirmation=1
|
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ
|
||||||
blog:
|
blog:
|
||||||
paginate: 12 # paginate.
|
paginate: 12 # paginate.
|
||||||
# post_thumbnail: false # whether to show the thumbnails.
|
# post_thumbnail: false # whether to show the thumbnails.
|
||||||
|
|
|
@ -7,5 +7,5 @@ socials:
|
||||||
github: ditatompel
|
github: ditatompel
|
||||||
website: https://www.ditatompel.com
|
website: https://www.ditatompel.com
|
||||||
patreon: svcadm
|
patreon: svcadm
|
||||||
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ?sub_confirmation=1
|
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ
|
||||||
---
|
---
|
||||||
|
|
|
@ -7,5 +7,5 @@ socials:
|
||||||
github: ditatompel
|
github: ditatompel
|
||||||
website: https://www.ditatompel.com
|
website: https://www.ditatompel.com
|
||||||
patreon: svcadm
|
patreon: svcadm
|
||||||
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ?sub_confirmation=1
|
youtube: https://www.youtube.com/channel/UCDV5fWBAvJdULelWdOa3ubQ
|
||||||
---
|
---
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
|
@ -0,0 +1,318 @@
|
||||||
|
---
|
||||||
|
title: Akses Aplikasi Self-Hosted di Rumah Dari Manapun
|
||||||
|
description: Tujuan artikel ini adalah untuk menunjukkan bagaimana saya dapat mengakses foto dan video saya di rumah dari mana saja, menggunakan VPN tunnel yang terhubung ke server Immich lokal saya.
|
||||||
|
summary: Bagaimana saya dapat mengakses aplikasi Immich saya di rumah dari mana saja.
|
||||||
|
# linkTitle:
|
||||||
|
date: 2024-10-23T07:50:00+07:00
|
||||||
|
lastmod:
|
||||||
|
draft: false
|
||||||
|
noindex: false
|
||||||
|
# comments: false
|
||||||
|
nav_weight: 1000
|
||||||
|
categories:
|
||||||
|
- Self-Hosted
|
||||||
|
tags:
|
||||||
|
- Immich
|
||||||
|
- WireGuard
|
||||||
|
- Nginx
|
||||||
|
- Cloudflare
|
||||||
|
- DNS
|
||||||
|
- MikroTik
|
||||||
|
- AdGuard
|
||||||
|
images:
|
||||||
|
authors:
|
||||||
|
- ditatompel
|
||||||
|
---
|
||||||
|
|
||||||
|
Ada banyak cara untuk mengekspose _HTTP service_ yang berada dibalik NAT supaya
|
||||||
|
dapat diakses dari internet. Pada umumnya, teknik yang dilakukan adalah
|
||||||
|
melakukan _network tunnel_ menggunakan VPN dan HTTP _reverse proxy_.
|
||||||
|
[Cloudflare Tunnel][cloudflare-tunnel] adalah salah satu contoh yang
|
||||||
|
menggunakan teknik ini.
|
||||||
|
|
||||||
|
Di artikel ini saya ingin berbagi pengalaman dan cara saya mengekspose HTTP
|
||||||
|
service yang berada di jaringan lokal ke internet menggunakan WireGuard VPN
|
||||||
|
tunnel dan Nginx sebagai _HTTP reverse proxy_. HTTP service yang akan saya
|
||||||
|
expose adalah [Immich][immich-web]. Bagi yang belum tahu, Immich adalah solusi
|
||||||
|
manajemen foto dan video yang dapat dihosting sendiri; sebuah alternatif dari
|
||||||
|
[Google Photos][google-photos].
|
||||||
|
|
||||||
|
Saya tidak akan membahas detail cara menginstall Immich karena proses [instalasi Immich menggunakan Docker][immich-docker-install] sangat mudah dilakukan. Saya akan lebih fokus ke konfigurasi Nginx dan VPN tunnel, serta topologi yang digunakan.
|
||||||
|
|
||||||
|
## Prasyarat
|
||||||
|
|
||||||
|
Sebelum memulai ada beberapa kondisi yang perlu dipenuhi, yaitu:
|
||||||
|
|
||||||
|
1. Sebuah nama domain atau subdomain yang menggunakan Cloudflare sebagai
|
||||||
|
_authoritative DNS server_.
|
||||||
|
2. Sebuah VPS dengan IP public (sudah terinstall WireGuard dan Nginx yang
|
||||||
|
nantinya digunakan untuk _reverse proxy_ ke jaringan lokal).
|
||||||
|
3. Sebuah PC / VM / LXC di jaringan lokal untuk menjalankan Nginx, Docker dan
|
||||||
|
Certbot.
|
||||||
|
|
||||||
|
## Topologi
|
||||||
|
|
||||||
|
Sebelum memulai, saya ingin membagikan topologi jaringan yang saya gunakan saat
|
||||||
|
artikel ini dibuat.
|
||||||
|
|
||||||
|
![gambar topologi jaringan](topology.jpg#center)
|
||||||
|
|
||||||
|
Ijinkan saya menjelaskan topologi diatas dan memberikan tambahan informasi
|
||||||
|
untuk mengikuti artikel ini:
|
||||||
|
|
||||||
|
- Subdomain yang saya gunakan untuk Immich adalah `i.arch.or.id`.
|
||||||
|
- IP publik VPS server yang saya gunakan adalah `154.26.xxx.xx`.
|
||||||
|
- IP VPS server untuk WireGuard tunnel adalah `10.88.88.51`.
|
||||||
|
- Jaringan LAN menggunakan segmen `192.168.2.0/24`.
|
||||||
|
- Immich terinstall di LXC yang berada di jaringan lokal dengan alamat IP
|
||||||
|
`192.168.2.105`.
|
||||||
|
- LXC Immich terkoneksi ke VPS server dan menggunakan IP tunnel `10.88.88.105`.
|
||||||
|
- Di LXC Immich juga terinstall Nginx dan Certbot.
|
||||||
|
|
||||||
|
Tujuan akhir dari artikel ini adalah aplikasi Immich dapat diakses dari
|
||||||
|
internet dan seluruh perangkat yang berada pada jaringan lokal dapat terkoneksi
|
||||||
|
secara langsung ke server Immich tanpa harus memutar ke internet.
|
||||||
|
|
||||||
|
Jadi ketika saya berada di luar rumah, saya masih tetap bisa mengakses foto dan
|
||||||
|
video saya yang berada di rumah melalui aplikasi Immich. Sedangkan saat saya
|
||||||
|
berada dirumah, saya dapat secara leluasa melakukan sinkronisasi atau upload
|
||||||
|
foto dan video lebih cepat karena terkoneksi langsung menggunakan jaringan LAN.
|
||||||
|
|
||||||
|
## Konfigurasi
|
||||||
|
|
||||||
|
### Cloudflare: DNS record & Edge Certificates
|
||||||
|
|
||||||
|
Anda perlu mendelegasikan _authoritative DNS server_ ke Cloudflare kemudian
|
||||||
|
tambahkan atau arahkan `A`/`AAAA` record untuk subdomain yang akan digunakan
|
||||||
|
oleh immich ke IP public VPS Anda. Di artikel ini berarti saya mengarahkan `A`
|
||||||
|
record `i.arch.or.id` ke IP `154.26.xxx.xx`.
|
||||||
|
|
||||||
|
![](cf-dns-record.jpg#center)
|
||||||
|
|
||||||
|
Ada beberapa setting default dari Cloudflare yang perlu dirubah supaya LXC
|
||||||
|
dapat melakukan request sertifikat SSL menggunakan certbot, yaitu:
|
||||||
|
|
||||||
|
1. Mengubah **mode enkripsi** ke `Full`. Caranya masuk ke manajemen domain ->
|
||||||
|
**SSL/TLS** -> **Overview**. Pada bagian **"SSL/TLS encryption"** ubah
|
||||||
|
**_encryption mode_** ke `Full`. Hal ini perlu dilakukan supaya Cloudflare
|
||||||
|
mau menerima _"self-signed certificate"_ dari _origin server_.
|
||||||
|
![](cf-encryption-mode.jpg#center)
|
||||||
|
2. Mendisable **"Always Use HTTPS"** dan **"Automatic HTTPS Rewrites"**.
|
||||||
|
Caranya masuk ke manajemen domain -> **Edge Certificates**. Pastikan
|
||||||
|
**"Always Use HTTPS"** dan **"Automatic HTTPS Rewrites"** tidak aktif. Hal
|
||||||
|
ini perlu dilakukan supaya verifikasi SSL request dari LXC ke **Let's
|
||||||
|
Encrypt** server berjalan dengan lancar.
|
||||||
|
![](cf-automatic-https.jpg#center)
|
||||||
|
|
||||||
|
### VPS: WireGuard & Nginx
|
||||||
|
|
||||||
|
Anda perlu mensetting dan menjalankan WireGuard di VPS server yang nantinya
|
||||||
|
digunakan untuk berkomunikasi dengan LXC server yang berada di jaringan lokal.
|
||||||
|
Jika Anda belum pernah melakukan konfigurasi WireGuard, Anda dapat membaca
|
||||||
|
artikel saya sebelumnya tentang [cara setup WireGuard VPN server secara
|
||||||
|
manual]({{< ref "/tutorials/how-to-setup-your-own-wireguard-vpn-server/index.id.md" >}})
|
||||||
|
atau [menggunakan WireGuard-UI]({{< ref "/tutorials/installing-wireguard-ui-to-manage-your-wireguard-vpn-server/index.id.md" >}}).
|
||||||
|
|
||||||
|
Kurang lebih, konfigurasi WireGuard di VPS server saya sebagai berikut:
|
||||||
|
|
||||||
|
```plain
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = SomeRandomStringThatShouldBePrivate
|
||||||
|
Address = 10.88.88.51/22
|
||||||
|
ListenPort = 51822
|
||||||
|
|
||||||
|
# Immich LXC server
|
||||||
|
[Peer]
|
||||||
|
PublicKey = SomeRandomStringThatPublicMayKnow
|
||||||
|
AllowedIPs = 10.88.88.105/32
|
||||||
|
```
|
||||||
|
|
||||||
|
Kemudian konfigurasi Nginx di VPS server sebagai reverse proxy ke LXC server,
|
||||||
|
kurang lebih konfigurasi Nginx saya sebagai berikut:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
upstream immich_app {
|
||||||
|
server 10.88.88.105:443;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name i.arch.or.id;
|
||||||
|
|
||||||
|
# Self-signed certificates
|
||||||
|
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||||
|
|
||||||
|
# Acme challenge handler
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
allow all;
|
||||||
|
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 https;
|
||||||
|
|
||||||
|
# This avoid SSL_do_handshake() failed on HTTPS upstream
|
||||||
|
proxy_ssl_name $host;
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
proxy_ssl_verify off;
|
||||||
|
|
||||||
|
proxy_pass https://immich_app;
|
||||||
|
}
|
||||||
|
|
||||||
|
keepalive_timeout 70;
|
||||||
|
sendfile on;
|
||||||
|
client_max_body_size 100m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
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 https;
|
||||||
|
|
||||||
|
# This avoid SSL_do_handshake() failed on HTTPS upstream
|
||||||
|
proxy_ssl_name $host;
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
proxy_ssl_verify off;
|
||||||
|
|
||||||
|
# enable websockets: http://nginx.org/en/docs/http/websocket.html
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_pass https://immich_app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Bisa dilihat bahwa Nginx di VPS server menggunakan _Self-signed certificates_.
|
||||||
|
Hal ini tidak menjadi masalah karena kita sudah mengkonfigurasi Cloudflare
|
||||||
|
SSL/TLS **encryption mode** ke `Full`.
|
||||||
|
|
||||||
|
Dengan konfigurasi diatas, _HTTP request_ dari internet akan melewati
|
||||||
|
Cloudflare dan menggunakan sertifikat SSL yang valid dari Cloudflare. Request
|
||||||
|
dilanjutkan ke VPS server dan kemudian diteruskan ke LXC server melalui
|
||||||
|
WireGuard VPN tunnel.
|
||||||
|
|
||||||
|
### Lokal LXC: WireGuard, Immich (Docker), Nginx, Certbot
|
||||||
|
|
||||||
|
Install WireGuard dan buat konfigurasi supaya bisa terhubung ke WireGuard
|
||||||
|
server di VPS. Berikut ini contoh konfigurasi WireGuard di LXC server saya:
|
||||||
|
|
||||||
|
```plain
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = SomeRandomStringThatShouldBePrivateII
|
||||||
|
Address = 10.88.88.105/22
|
||||||
|
|
||||||
|
# VPS server
|
||||||
|
[Peer]
|
||||||
|
PublicKey = SomeRandomStringThatPublicMayKnowII
|
||||||
|
AllowedIPs = 10.88.88.51/32
|
||||||
|
Endpoint = 154.26.xxx.xxx:51822
|
||||||
|
PersistentKeepalive = 15
|
||||||
|
```
|
||||||
|
|
||||||
|
Kemudian, install Immich dengan mengikuti proses [instalasi Immich menggunakan
|
||||||
|
Docker dari situs resminya][immich-docker-install]. Secara default, Immich akan
|
||||||
|
menggunakan TCP port `2283`.
|
||||||
|
|
||||||
|
Buat konfigurasi Nginx virtual host untuk Immich. Nginx di LXC ini akan
|
||||||
|
berfungsi sebagai reverse proxy dan menghandle **Acme challenge** sehingga
|
||||||
|
server LXC memiliki sertifikat yang valid. Berikut ini adalah contoh
|
||||||
|
konfigurasi Nginx virtual host untuk Immich di server LXC lokal:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
upstream immich_app {
|
||||||
|
server 127.0.0.1:2283;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name i.arch.or.id;
|
||||||
|
root /srv/http/default;
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
allow all;
|
||||||
|
}
|
||||||
|
location / { return 301 https://$host$request_uri; }
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name i.arch.or.id;
|
||||||
|
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||||
|
|
||||||
|
# allow large file uploads
|
||||||
|
client_max_body_size 50000M;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# Set headers
|
||||||
|
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;
|
||||||
|
|
||||||
|
# enable websockets: http://nginx.org/en/docs/http/websocket.html
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_pass http://immich_app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Dari konfigurasi Nginx diatas, perlu diperhatikan bahwa untuk konfigurasi awal
|
||||||
|
saya masih menggunakan _Self-signed certificate_. Langkah selanjutnya adalah
|
||||||
|
melakukan request sertifikat SSL menggunakan Certbot.
|
||||||
|
|
||||||
|
> **Catatan**: Sebelum melakukan request serifikat SSL, pastikan koneksi antara
|
||||||
|
> VPS server dan LXC melalui WireGuard tunnel berjalan dengan baik. Begitu pula
|
||||||
|
> dengan konfigurasi Nginx baik di VPS server dan LXC server.
|
||||||
|
|
||||||
|
Install certbot Nginx plugin. Di Ubuntu, Anda bisa menginstall cerbot Nginx
|
||||||
|
plugin menggunakan `sudo apt install python3-certbot-nginx`. Setelah Certbot
|
||||||
|
Nginx plugin terinstall, lakukan request sertifikat SSL dari XLC server:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo certbot --nginx -d i.arch.or.id
|
||||||
|
```
|
||||||
|
|
||||||
|
Ubah `i.arch.or.id` ke (sub)domain milik Anda.
|
||||||
|
|
||||||
|
### LAN: Lokal DNS resolver
|
||||||
|
|
||||||
|
Langkah terakhir adalah mengkonfigurasi perangkat-perangkat di jaringan LAN
|
||||||
|
supaya subdomain `i.arch.or.id` mengarah ke IP lokal server LXC
|
||||||
|
(192.169.2.105). Cara paling efektif adalah menggunakan lokal _DNS resolver_
|
||||||
|
yang bisa digunakan oleh seluruh perangkat di jaringan LAN. Untuk konfigurasi
|
||||||
|
_DNS resolver_ akan sangat bervariasi tergantung seperti apa jaringan LAN
|
||||||
|
masing-masing.
|
||||||
|
|
||||||
|
Untuk jaringan LAN saya, saya mempunyai dua buah DNS resolver. DNS resolver
|
||||||
|
pertama berada di Router **MikroTik**, dan resolver kedua menggunakan
|
||||||
|
**AdGuard Home** yang berjalan di Linux Container. AdGuard home disini saya
|
||||||
|
gunakan juga sebagai DHCP server untuk jaringan lokal saya.
|
||||||
|
|
||||||
|
Berikut capture konfigurasi DNS resolver di MikroTik router dan AdGuard Home
|
||||||
|
saya:
|
||||||
|
|
||||||
|
![](lan-dns-resolver.jpg#center)
|
||||||
|
|
||||||
|
Dengan konfigurasi tersebut, seluruh perangkat yang ada di jaringan lokal
|
||||||
|
menggunakan DHCP akan langsung akan menggunakan IP `192.168.2.105` ketika
|
||||||
|
mencoba mengakses subdomain `i.arch.or.id`.
|
||||||
|
|
||||||
|
## limitasi
|
||||||
|
|
||||||
|
- Karena maksimum upload di Cloudflare hanya 100MB per request (untuk free
|
||||||
|
version), maka proses sinkronisasi Immich dari internet kemungkinan besar
|
||||||
|
banyak yang gagal, terutama saat sinkronisasi video.
|
||||||
|
|
||||||
|
[cloudflare-tunnel]: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/ "Cloudflare Tunnel"
|
||||||
|
[immich-web]: https://immich.app/ "Immich website"
|
||||||
|
[immich-docker-install]: https://immich.app/docs/install/docker-compose "Install Immich using Docker"
|
||||||
|
[google-photos]: https://photos.google.com/ "Google Photos website"
|
|
@ -0,0 +1,315 @@
|
||||||
|
---
|
||||||
|
title: Access Any Self-Hosted Applications at Home From Anywhere
|
||||||
|
description: The goal of this article is to demonstrate how I can access my photos and videos at home from anywhere, using a network tunnel to connect to my local Immich server.
|
||||||
|
summary: How I can access my Immich application at home from anywhere.
|
||||||
|
# linkTitle:
|
||||||
|
date: 2024-10-23T07:50:00+07:00
|
||||||
|
lastmod:
|
||||||
|
draft: false
|
||||||
|
noindex: false
|
||||||
|
# comments: false
|
||||||
|
nav_weight: 1000
|
||||||
|
categories:
|
||||||
|
- Self-Hosted
|
||||||
|
tags:
|
||||||
|
- Immich
|
||||||
|
- WireGuard
|
||||||
|
- Nginx
|
||||||
|
- Cloudflare
|
||||||
|
- DNS
|
||||||
|
- MikroTik
|
||||||
|
- AdGuard
|
||||||
|
images:
|
||||||
|
authors:
|
||||||
|
- ditatompel
|
||||||
|
---
|
||||||
|
|
||||||
|
There are many ways to expose HTTP services behind NAT so that they can be
|
||||||
|
accessed from the internet. The technique commonly employed involves setting
|
||||||
|
up a network tunnel using VPN and an HTTP reverse proxy. [Cloudflare
|
||||||
|
Tunnel][cloudflare-tunnel] is one example.
|
||||||
|
|
||||||
|
In this article, I want to share my experience and how I expose HTTP services
|
||||||
|
on a local network to the internet using WireGuard VPN tunnel and Nginx as an
|
||||||
|
HTTP reverse proxy. The HTTP service I will expose is [Immich][immich-web].
|
||||||
|
For those who don't know, Immich is a self-hosted photo and video management
|
||||||
|
solution; an alternative to [Google Photos][google-photos].
|
||||||
|
|
||||||
|
I won't discuss the details of how to install Immich because [installing Immich
|
||||||
|
using Docker][immich-docker-install] is very easy to do. Instead, I'll focus on
|
||||||
|
the configuration of Nginx and VPN tunnel, as well as the [topology
|
||||||
|
used](#topology).
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before we get started, there are a few conditions that need to be met:
|
||||||
|
|
||||||
|
1. A domain name or subdomain that uses Cloudflare as its authoritative DNS
|
||||||
|
server.
|
||||||
|
2. A VPS with a public IP address (WireGuard and Nginx installed, which will
|
||||||
|
later be used for reverse proxying the local network).
|
||||||
|
3. A PC, VM, or LXC on the local network to run Immich, Nginx, Docker, and
|
||||||
|
Certbot.
|
||||||
|
|
||||||
|
## Topology
|
||||||
|
|
||||||
|
When writing this article, I used the following network topology:
|
||||||
|
|
||||||
|
![network topology image](topology.jpg#center)
|
||||||
|
|
||||||
|
To provide further context, let me break down the components of the above
|
||||||
|
topology:
|
||||||
|
|
||||||
|
- The subdomain used for Immich is `i.arch.or.id`.
|
||||||
|
- The public IP address of the VPS server is `154.26.xxx.xx`.
|
||||||
|
- The VPS server's WireGuard tunnel IP address is `10.88.88.51`.
|
||||||
|
- The local area network (LAN) uses the `192.168.2.0/24` subnet.
|
||||||
|
- Immich is installed on an LXC container located on the local network,
|
||||||
|
with an IP address of `192.168.2.105`.
|
||||||
|
- The Immich LXC is connected to the VPS server and utilizes the IP tunnel
|
||||||
|
`10.88.88.105`.
|
||||||
|
- Nginx and Certbot are also installed on the Immich LXC.
|
||||||
|
|
||||||
|
The ultimate goal of this article is to demonstrate how I can access my photos
|
||||||
|
and videos at home from anywhere, using a network tunnel to connect to my local
|
||||||
|
Immich server. This setup allows me to synchronize or upload files faster when
|
||||||
|
I'm at home, while still being able to access my media remotely through the
|
||||||
|
Immich application.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Cloudflare: DNS records & Edge Certificates
|
||||||
|
|
||||||
|
To configure Cloudflare, you need to delegate the authoritative DNS server and
|
||||||
|
add or point the `A`/`AAAA` record for the subdomain that will be used by
|
||||||
|
Immich to your VPS public IP. In this article, I pointed the `A` record
|
||||||
|
`i.arch.or.id` to the IP `154.26.xxx.xx`.
|
||||||
|
|
||||||
|
![](cf-dns-record.jpg#center)
|
||||||
|
|
||||||
|
To ensure that LXC on your local network can make a smooth request for SSL
|
||||||
|
certificates using Certbot, you'll need to modify several default Cloudflare
|
||||||
|
settings:
|
||||||
|
|
||||||
|
1. Update the **encryption mode** to `Full`. To do this, navigate to domain
|
||||||
|
management -> **SSL/TLS** -> **Overview**, and modify the **"SSL/TLS
|
||||||
|
encryption"** to `Full`. This is necessary for Cloudflare to accept the
|
||||||
|
_"self-signed certificate"_ from the _origin server_.
|
||||||
|
![](cf-encryption-mode.jpg#center)
|
||||||
|
2. Disable both **"Always Use HTTPS"** and **"Automatic HTTPS Rewrites"**. To
|
||||||
|
achieve this, go to domain management -> **Edge Certificates**, and ensure
|
||||||
|
that these features are not active. This is necessary for the SSL request
|
||||||
|
verification from LXC to the **Let's Encrypt** server to run smoothly.
|
||||||
|
![](cf-automatic-https.jpg#center)
|
||||||
|
|
||||||
|
### VPS: WireGuard & Nginx
|
||||||
|
|
||||||
|
You need to set up and run WireGuard on the VPS server which will be used to
|
||||||
|
communicate with the LXC server on the local network. If you're new to
|
||||||
|
WireGuard configuration, I recommend reviewing my previous articles on [setting
|
||||||
|
up a WireGuard VPN server manually]({{< ref "/tutorials/how-to-setup-your-own-wireguard-vpn-server/index.id.md" >}})
|
||||||
|
or [using WireGuard-UI]({{< ref "/tutorials/installing-wireguard-ui-to-manage-your-wireguard-vpn-server/index.id.md" >}}).
|
||||||
|
|
||||||
|
Here's an example of my WireGuard configuration on my VPS server:
|
||||||
|
|
||||||
|
```plain
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = SomeRandomStringThatShouldBePrivate
|
||||||
|
Address = 10.88.88.51/22
|
||||||
|
ListenPort = 51822
|
||||||
|
|
||||||
|
# Immich LXC server
|
||||||
|
[Peer]
|
||||||
|
PublicKey = SomeRandomStringThatPublicMayKnow
|
||||||
|
AllowedIPs = 10.88.88.105/32
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, I configured Nginx on the VPS server as a reverse proxy to the LXC
|
||||||
|
server. My Nginx configuration is similar to the following:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
upstream immich_app {
|
||||||
|
server 10.88.88.105:443;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name i.arch.or.id;
|
||||||
|
|
||||||
|
# Self-signed certificates
|
||||||
|
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||||
|
|
||||||
|
# Acme challenge handler
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
allow all;
|
||||||
|
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 https;
|
||||||
|
|
||||||
|
# This avoid SSL_do_handshake() failed on HTTPS upstream
|
||||||
|
proxy_ssl_name $host;
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
proxy_ssl_verify off;
|
||||||
|
|
||||||
|
proxy_pass https://immich_app;
|
||||||
|
}
|
||||||
|
|
||||||
|
keepalive_timeout 70;
|
||||||
|
sendfile on;
|
||||||
|
client_max_body_size 100m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
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 https;
|
||||||
|
|
||||||
|
# This avoid SSL_do_handshake() failed on HTTPS upstream
|
||||||
|
proxy_ssl_name $host;
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
proxy_ssl_verify off;
|
||||||
|
|
||||||
|
# enable websockets: http://nginx.org/en/docs/http/websocket.html
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_pass https://immich_app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It's worth noting that Nginx virtual host configuration for `i.arch.or.id` on
|
||||||
|
the VPS server uses _Self-signed certificates_ for SSL/TLS encryption. This
|
||||||
|
isn't an issue, as we've previously configured Cloudflare's SSL/TLS
|
||||||
|
**encryption mode** to `Full`.
|
||||||
|
|
||||||
|
With this configuration in place, HTTP requests from the internet are routed
|
||||||
|
through Cloudflare and utilize a valid SSL certificate from Cloudflare. The
|
||||||
|
request is then forwarded to the VPS server and subsequently to the LXC server
|
||||||
|
via the WireGuard VPN tunnel.
|
||||||
|
|
||||||
|
### Local LXC: WireGuard, Immich (Docker), Nginx, Certbot
|
||||||
|
|
||||||
|
Install WireGuard and configure it to connect to the WireGuard server on the
|
||||||
|
VPS. Here's an example of my WireGuard configuration on my LXC server:
|
||||||
|
|
||||||
|
```plain
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = SomeRandomStringThatShouldBePrivateII
|
||||||
|
Address = 10.88.88.105/22
|
||||||
|
|
||||||
|
# VPS server
|
||||||
|
[Peer]
|
||||||
|
PublicKey = SomeRandomStringThatPublicMayKnowII
|
||||||
|
AllowedIPs = 10.88.88.51/32
|
||||||
|
Endpoint = 154.26.xxx.xxx:51822
|
||||||
|
PersistentKeepalive = 15
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, install Immich by following the process outlined on its official website
|
||||||
|
for [installing Immich using Docker][immich-docker-install]. By default,
|
||||||
|
Immich will use TCP port `2283`.
|
||||||
|
|
||||||
|
Create an Nginx virtual host configuration for Immich. On my local LXC server,
|
||||||
|
Nginx will function as a reverse proxy and handle Acme challenges to obtain a
|
||||||
|
valid certificate. Here's an example of the Nginx virtual host configuration
|
||||||
|
for Immich:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
upstream immich_app {
|
||||||
|
server 127.0.0.1:2283;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name i.arch.or.id;
|
||||||
|
root /srv/http/default;
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
allow all;
|
||||||
|
}
|
||||||
|
location / { return 301 https://$host$request_uri; }
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name i.arch.or.id;
|
||||||
|
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||||
|
|
||||||
|
# allow large file uploads
|
||||||
|
client_max_body_size 50000M;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# Set headers
|
||||||
|
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;
|
||||||
|
|
||||||
|
# enable websockets: http://nginx.org/en/docs/http/websocket.html
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_pass http://immich_app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
From the configuration above, it is clear that I initially uses a self-signed
|
||||||
|
certificate. Later, the certificate will be automatically replaced with a valid
|
||||||
|
one from Let's Encrypt, utilizing Certbot.
|
||||||
|
|
||||||
|
> **Note**: Before requesting an SSL certificate, ensure that the connection
|
||||||
|
> between the VPS server and LXC via the WireGuard tunnel is running smoothly.
|
||||||
|
> Also, verify that the Nginx configuration on both the VPS server and LXC
|
||||||
|
> server is correctly set up.
|
||||||
|
|
||||||
|
Install the Certbot Nginx plugin. On Ubuntu-based systems, you can install the
|
||||||
|
certbot Nginx plugin using `sudo apt install python3-certbot-nginx`. After
|
||||||
|
installing the plugin, request an SSL certificate from the XLC server:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo certbot --nginx -d i.arch.or.id
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `i.arch.or.id` with your (sub)domain.
|
||||||
|
|
||||||
|
### LAN: Local DNS resolver
|
||||||
|
|
||||||
|
The final step is to configure devices on the local area network (LAN) so that
|
||||||
|
the subdomain `i.arch.or.id` resolves to the local IP address of the LXC server
|
||||||
|
(`192.168.2.105`). A reliable approach is to use a local DNS resolver that can
|
||||||
|
be utilized by all devices within the LAN network. The configuration for this
|
||||||
|
DNS resolver will depend on the specific characteristics of each LAN network.
|
||||||
|
|
||||||
|
For my LAN setup, I have two DNS resolvers. The first one is located on my
|
||||||
|
Router (MikroTik), and the second is AdGuard Home running on a Linux Container.
|
||||||
|
In addition, I utilize AdGuard home as a DHCP server for my local network.
|
||||||
|
|
||||||
|
Here's a capture of the DNS resolver configuration on my MikroTik router and
|
||||||
|
AdGuard Home:
|
||||||
|
|
||||||
|
![](lan-dns-resolver.jpg#center)
|
||||||
|
|
||||||
|
With this setup, all devices on the local network that obtain their IP
|
||||||
|
addresses via DHCP will immediately use the IP `192.168.2.105` when attempting
|
||||||
|
to access the subdomain `i.arch.or.id`.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- Due to the 100MB per request upload limit imposed by Cloudflare (for its
|
||||||
|
free version), the Immich synchronization process from the internet is
|
||||||
|
likely to fail, particularly when synchronizing videos.
|
||||||
|
|
||||||
|
[cloudflare-tunnel]: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/ "Cloudflare Tunnel"
|
||||||
|
[immich-web]: https://immich.app/ "Immich website"
|
||||||
|
[immich-docker-install]: https://immich.app/docs/install/docker-compose "Install Immich using Docker"
|
||||||
|
[google-photos]: https://photos.google.com/ "Google Photos website"
|
Binary file not shown.
After Width: | Height: | Size: 115 KiB |
Binary file not shown.
After Width: | Height: | Size: 109 KiB |
Loading…
Reference in a new issue