Deploy Iceshrimp.NET di fly.io
Kalau sebelumnya saya deploy GoToSocial, yang masih mendukung perangkat mini saya, kali ini saya akan menggunakan salah satu server yang memiliki banyak fitur, merupakan fork dari Firefish (ceritanya panjang, ini adalah fork dari fork, tapi intinya mirip Misskey) dan berasal dari NodeJS. Keluarlah rewrite menggunakan bahasa C# .NET, yang tentunya tidak mendukung armv6.
Pada laman dokumentasi asli dari iceshrimp.net (disini), sebetulnya sudah disediakan instalasi dalam bentuk docker. Namun, entah kenapa jika kamu menggunakan docker, kamu tidak bisa mendaftarkan akun. Ya, namanya juga alpha.
Akhirnya saya berinisiatif seperti ketika saya mencoba dendrite, saya akan membuat image docker saya sendiri. Beberapa masalah yang saya temukan adalah:
- Copas menggunakan
Dockerfile
asli tidak bisa berjalan, karena ketikadotnet restore
pasti ada protes kalau beberapafsproj
tidak ditemukan. - Menggunakan
-o /app
memang berhasil, namun ketika dijalankan, Iceshrimp masih beranggapan bahwa frontend berada di direktori lain, bukan di/app
. - Tidak bisa menggunakan
-publish
karena, entah mengapa, ketika dipublikasikan ada protes bahwa file tidak ditemukan.
Sehingga saya mencoba seakurat dan sesederhana mungkin untuk membuat image ini.
{{< callout emoji=“💡” >}}
Hari ini, 22 Mei 2024, docker image resmi dari iceshrimp.net bekerja
dengan baik, jadi kamu sekarang tidak perlu mengikuti langkah pembuatan
Dockerfile
yang saya jelaskan di bawah.
{{< /callout >}}
Dockerfile
Berikut adalah isi dari Dockerfile
yang saya gunakan
untuk dideploy ke fly.io:
# Builder
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine as BUILDER
RUN apk add -U git
RUN dotnet workload install wasm-tools # boleh dihilangkan jika tidak ingin menggunakan AOT
# harusnya disini diberi args agar perintah dibawah akan diupdate ketika kita mau update buildnya.
RUN git clone https://iceshrimp.dev/iceshrimp/iceshrimp.net --depth=1
WORKDIR /iceshrimp.net/Iceshrimp.Backend
RUN dotnet build -c Release -p:EnableAOT=true # hapus EnableAOT jika tidak menggunakan wasm-tools
# Prod
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine-composite as PROD
COPY --from=BUILDER /iceshrimp.net /iceshrimp.net
WORKDIR /iceshrimp.net/Iceshrimp.Backend/bin/Release/net8.0/linux-musl-x64
COPY ./configuration.overrides.ini . # Kamu harus menyiapkan config ini.
EXPOSE 3000
ENTRYPOINT ["./Iceshrimp.Backend", "--environment", "Production", "--migrate-and-start"]
Isi dari Dockerfile yang saya gunakan
Configuration.ini
Mengenai configuration.overrides.ini
, kamu bisa copy
paste file configuration.ini
dan mengubah seperlunya,
sebagai contoh seperti berikut.
[Instance]
;; karena didalam docker, maka kita harus listen ke semuanya
ListenHost = 0.0.0.0
WebDomain = iceshrimp.domain.kamu
;; jika kamu menginginkan split domain, kamu bisa mengisi ini
AccountDomain = domain.kamu
[Security]
;; Options: [Closed, Invite, Open]
;; perlu diganti untuk pertama kali agar kamu bisa mendaftarkan diri
Registrations = Closed
Beberapa konfigurasi yang perlu diganti
Tentunya database dan storage juga perlu kamu atur, namun saya tidak akan menjelaskannya. Ada permintaan dari rekan mengenai pengaturan storage.
Untuk konfigurasi pada fly.io, saya tidak akan menjelaskan, karena
ketika kamu membuat proyek baru dan di dalam folder tersebut ada file
Dockerfile
, fly akan otomatis menggunakan file itu untuk
dideploy.
Setup Storage dengan tebi.io
Pada dokumentasi iceshrimp.net terdapat tutorial untuk penyedia layanan Garage, Cloudflare R2, Blackblaze, Digital Ocean, namun tidak ada tebi, padahal tebi menurut saya sederhana dan it works.
Berikut adalah konfigurasi yang harus kamu masukkan kedalam
configuration.overrides.ini
jika menggunakan tebi:
[Storage:ObjectStorage]
Endpoint = s3.tebi.io
Region = us-east-1
KeyId = <keyID>
SecretKey = <applicationKey>
Bucket = <bucket name>
;;Prefix =
AccessUrl = https://s3.tebi.io/<nama bucket>
configuration.overrides.ini untuk storage
- Sedikit penjelasan tentang
Region
, tebi tidak mengenal region (ada, namun tidak diperlukan ketika kita “mengakses” bucket nya karena kita bisa mengatur itu pada dasbor tebi) namun karena iceshrimp ini minta, ya kita kasih. Kamu bisa menggunakan region apa saja seperti yang ada pada dokumentasi aws. - Sedangkan untuk
AccessUrl
bucket pada tebi pada dasarnya adalah public, dan itu adalah nama bucket yang sudah kamu buat, misalnya saya pernah membuat bucket bernamagts
, maka bisa dibuka dengan menuju ke alamathttps://s3.tebi.io/gts/
atauhttps://gts.s3.tebi.io/
. - Silahkan isi
Prefix
jika kamu ingin file kamu berada didalam folder di bucket.
Sifat bucket pada tebi adalah unik, yang artinya kamu tidak
bisa membuat bucket dengan nama gts
. Semua orang bisa
mengakses bucket tersebut, namun secara default tidak ada peraturan
Access Policy pada tebi, sehingga kamu tidak akan bisa iseng
membuka bucket orang lain tanpa ijin meski orangnya tidak sadar, hal ini
juga terjadi pada instalasi iceshrimp kita, tidak bisa akses kecuali
kita berikan akses.
Mari kita menuju dasbor tebi, kemudian Edit Bucket dan masuk ke tab Bucket Policy, enable dan masukkan kode berikut (kode ini saya ambil dari dokumentasi tebi):
{
"Version": "2012-10-17",
"Id": "S3PolicyAllow-IP",
"Statement": [{
"Sid": "IP-Allow",
"Effect": "Allow",
"Action": ["s3:ListObjects","s3:GetObject", "s3:HeadObject", "s3:DeleteObject", "s3:PutObject"],
"Resource": ["bucket/folder", "bucket/folder/*"],
"Condition": {
"IpAddress": {"aws:SourceIp": ["<ip machine fly io kamu>", "<ip public kamu jika mau>"]},
}
}]
}
Access Policy pada tebi.io
- IP machine dapat kamu ambil ketika ada pada laman overview, yang perlu diperhatikan adalah IPv4 pada fly.io sekarang bersifat shared, jadi bisa saja ada orang iseng 1 IP pada fly.io bisa menguntit.
- Resource bisa diisi spesifik “bucket dan folder mana yang boleh
diakses”, alias kombinasi
prefix
pada konfigurasi sebelumnya. Kamu bisa isi dengan format<nama bucket>/<nama folder>
. Atau semuanya saja.
{{< callout emoji=“💡” >}}
Sebetulnya saya masih kurang begitu paham dengan policy yang diperlukan, namun jika berkaca dari dokumentasi iceshrimp.net mereka hanya menuliskan put, delete, dan get saja.
{{< /callout >}}
{{< callout emoji=“⚠️” >}}
Jika anda seperti saya yang menggunakan Iceshrimp.NET ini sejak awal,
terdapat bug pada Iceshrimp yang membuat media tidak terhapus meskipun
sudah dihapus dari database. Kamu bisa menjalankan
iceshrimp.backend --cleanup-storage
untuk membersihkan
media yang gagal terhapus karena bug ini.
{{< /callout >}}
Split Domain
Split domain adalah cara dimana kamu bisa host iceshrimp mu di
iceshrimp.domain.kamu
dan menggunakan username seperti
[email protected]
, lebih pendek dan keren bukan? caranya
cukup mudah, bagi yang punya perangkat sendiri. Penjelasan bagus ada di
laman milik GoToSocial disini.
Sama seperti ketika saya mencoba dendrite, saya pun memanfaatkan
cloudflare worker untuk melakukan redirect ini. Apakah bekerja
sesuai harapan? ya! namun ini software alpha.. dimana beberapa kali
/.well-known/webfinger
,
/.well-known/host-meta
, /.well-known/nodeinfo
tidak merespon seperti yang seharusnya. Berikut adalah skrip yang saya
gunakan, saya tidak bilang skrip ini sangat bagus ya:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
// Dapatkan URL permintaan
const url = new URL(request.url)
// Periksa apakah permintaan menuju ke .well-known/webfinger
if (url.pathname === '/.well-known/webfinger') {
// Buat objek baru untuk menyimpan parameter
const params = new URLSearchParams()
// Salin semua parameter dari URL permintaan ke objek params
for (const [key, value] of url.searchParams) {
.set(key, value)
params
}
// Buat URL tujuan redirect
const redirectUrl = `iceshrimp.domain.kamu/.well-known/webfinger?${params.toString()}`
// Kembalikan respons redirect
return Response.redirect(redirectUrl, 301)
}// Periksa apakah permintaan menuju ke .well-known/host-meta
else if (url.pathname === '/.well-known/host-meta') {
// Buat URL tujuan redirect
const redirectUrl = 'https://iceshrimp.domain.kamu/.well-known/host-meta'
// Kembalikan respons redirect
return Response.redirect(redirectUrl, 301)
}// Periksa apakah permintaan menuju ke .well-known/nodeinfo
else if (url.pathname === '/.well-known/nodeinfo') {
// Buat URL tujuan redirect
const redirectUrl = 'https://iceshrimp.domain.kamu/.well-known/nodeinfo'
// Kembalikan respons redirect
return Response.redirect(redirectUrl, 301)
}
// Jika bukan permintaan ke .well-known/webfinger, .well-known/host-meta, atau .well-known/nodeinfo, lanjut
// return fetch(request)
// atau kembalikan respons ke eror (domain saya ini tidak terpakai)
return new Response('Hello World, nothing here', { status: 404 })
}
worker.js
Selanjutnya kamu bisa mengatur routing ke workers ini, sebagai info terdapat perubahan pada halaman routing cloudflare workers (jika dibandingkan ketika saya membuat routing pada dendrite) dimana waktu itu ada pengaturan route dan zone.
Untuk mengatur route, kamu bisa menuju halaman dari worker yang sudah
kamu buat (bukan halaman edit) kemudian buka tab Settings
> Triggers
. Tampilannya kurang lebih seperti ini:

Pada setup saya, saya menggunakan 1 domain saya (yang tidak terpakai)
sehingga saya menggunakan Custom Domains
dan bukan
Routes
, sehingga semua request yang akan menuju domain
ktem.eu.org akan di proses oleh 1 workers ini. Untuk penjelasannya kamu
bisa membaca dokumentasi dari cloudflare workers mana pengaturan yang
tepat untukmu disini.
Setelah status certificatenya berubah menjadi valid, kamu bisa
melakukan cek domain kamu apakah sudah berhasil redirect dengan benar,
misalnya saya membuka
https://ktem.eu.org/.well-known/nodeinfo
seharusnya akan
diredirect ke https://ice.ktem.eu.org/.well-known/nodeinfo
.
Lakukan juga pada webfinger
dan host-meta
.
Khusus untuk webfinger
, kamu setidaknya harus mencoba
untuk membuka laman dengan format seperti ini:
domain.kamu/.well-known/webfinger?resource=acct:[email protected]
.
Pastikan outputnya tidak 400 BadRequest karena parameternya tidak ikut
dibawa ketika redirect.
Viola split domain. Setidaknya kalau saya lihat dari server teman saya disini.
Machine di Fly.io restart?
Mungkin kamu menginginkan untuk menambahkan 1 baris berisikan
swap_size_mb = 512
kedalam fly.toml
jika kamu
menggunakan shared machine dengan ram 256 MB. Atau tentu saja, kamu bisa
scaling memori pada fly.io dengan perintah
fly scale memory
.
Ada toot yang tidak masuk?
Jika toot yang dimaksud adalah toot dengan media seperti gambar / video, kemungkinan VM milik fly kita yang terbatas ini mengalami timeout. Solusinya tentu kamu bisa melakukan retry job pada jobs yang mengalami timeout.
Namun jika toot yang dimaksud dari server lain, ada beberapa penyebab:
- Threads, lemmy, bridgy : tidak menggunakan actor, tidak sesuai standar AP jadi dev Iceshrimp.NET memilih menunda untuk memperbaiki ini.
- server AP : kemungkinan kesalahan dalam mengatur webfinger.
Mendaftarkan akun
Untuk mendaftarkan akun, kamu perlu mengubah 1 baris konfigurasi yang
sebelumnya sudah saya tuliskan. Agar lebih mudah, kamu bisa membuka
iceshrimp.domain.anda/swagger
dan mencari bagian auth
register. Kamu bisa menggunakan alat tersebut.
{{< callout emoji=“💡” >}}
Jangan lupa, setelah berhasil mendaftar, matikan konfigurasi registrasi di atas.
{{< /callout >}}
Seingat saya, sampai tulisan ini ditayangkan, Iceshrimp.NET belum memiliki antarmuka, jadi kamu bisa menggunakan antarmuka lain yang ada di internet yang mendukung Mastodon atau dengan menggunakan aplikasi di smartphone Anda. Ya, program ini masih dalam tahap alpha, sekarang sudah BETA!
Jika nanti saya teringat sesuatu, saya akan memperbarui tulisan ini.
small note: entah kenapa saya selalu
menuliskan entah kenapa
, alasannya tentu saya tidak tahu
kenapa. duh.