Tips Paket Internet Pomo Special
4G Ceria Telkomsel - Agar Tidak Habis Pulsa..
4G Ceria Telkomsel - Agar Tidak Habis Pulsa..
Cara Install driver printer Epson L321 di Ubuntu Linux
Cara Install driver Printer Canon di Ubuntu Linux
SELECT
u.username,
u.firstname,
u.lastname,
u.email,
nis.data AS profile_field_nis,
pw.data AS profile_field_pwexam,
c.name AS cohort1
INTO OUTFILE '/tmp/user_xi.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM mdl_user u
JOIN mdl_cohort_members cm ON cm.userid = u.id
JOIN mdl_cohort c ON c.id = cm.cohortid
LEFT JOIN mdl_user_info_field fnis
ON fnis.shortname = 'nis'
LEFT JOIN mdl_user_info_data nis
ON nis.fieldid = fnis.id
AND nis.userid = u.id
LEFT JOIN mdl_user_info_field fpw
ON fpw.shortname = 'pwexam'
LEFT JOIN mdl_user_info_data pw
ON pw.fieldid = fpw.id
AND pw.userid = u.id
WHERE c.name IN (
'XI-A','XI-B','XI-C',
'XI-D','XI-E','XI-F','XI-G'
)
AND u.deleted = 0
AND u.suspended = 0
ORDER BY c.name, u.lastname;
SELECT
u.username,
u.firstname,
u.lastname,
u.email,
nis.data AS profile_field_nis,
pw.data AS profile_field_pwexam,
c.name AS cohort1
INTO OUTFILE '/tmp/user_x.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM mdl_user u
JOIN mdl_cohort_members cm ON cm.userid = u.id
JOIN mdl_cohort c ON c.id = cm.cohortid
LEFT JOIN mdl_user_info_field fnis
ON fnis.shortname = 'nis'
LEFT JOIN mdl_user_info_data nis
ON nis.fieldid = fnis.id
AND nis.userid = u.id
LEFT JOIN mdl_user_info_field fpw
ON fpw.shortname = 'pwexam'
LEFT JOIN mdl_user_info_data pw
ON pw.fieldid = fpw.id
AND pw.userid = u.id
WHERE c.name IN (
'X-A','X-B','X-C',
'X-D','X-E','X-F','X-G'
)
AND u.deleted = 0
AND u.suspended = 0
ORDER BY c.name, u.lastname;
Kelas XI:
scp dhwan@192.168.200.20:/tmp/user_xi.csv ~/Downloads/
Kelas X:
scp dhwan@192.168.200.20:/tmp/user_x.csv ~/Downloads/
Kalau gagal karena secure_file_priv, cek:
SHOW VARIABLES LIKE 'secure_file_priv';
Lalu ganti path /tmp/ sesuai folder yang ditampilkan MariaDB, misalnya:
/var/lib/mysql-files/
ALTER TABLE mdl_local_jurnalmengajar_suratizinguru
ADD COLUMN userinput BIGINT(10) NULL AFTER nip;
root@cbt:~# while true; do echo "$(date '+%F %T') | $(mysql moodle -N -e "
SELECT COUNT(DISTINCT userid)
FROM mdl_logstore_standard_log
WHERE component='mod_quiz'
AND timecreated > UNIX_TIMESTAMP(NOW()) - 150;
")" >> quizlog.txt; sleep 10; done
lihatnya:
tail -f quizlog.txt
Ya Guru 👍
Itu berarti di server cbt user Linux root sudah bisa login ke MariaDB tanpa password eksplisit.
Biasanya karena salah satu dari ini:
Paling sering di Debian/Ubuntu.
Artinya:
kalau login Linux sebagai root
otomatis boleh masuk MariaDB sebagai root
tanpa password.
Jadi command:
mysql moodle
langsung berhasil.
Misalnya:
/root/.my.cnf
credential tersimpan
atau socket authentication
Masuk mysql:
mysql
Lalu:
SELECT user,host,plugin
FROM mysql.user;
Kalau hasilnya seperti:
| user | plugin |
|---|---|
| root | unix_socket |
atau:
| user | plugin |
|---|---|
| root | auth_socket |
berarti memang otomatis login lewat user Linux root.
Karena:
hanya user Linux root yang bisa
bukan semua orang
Jadi:
SSH root dulu
baru mysql otomatis boleh.
while true; do ...
karena:
mysql tidak perlu password
shell langsung bisa eksekusi query
Karena:
script otomatis lebih mudah
cron job lebih simpel
tidak perlu simpan password plaintext
Karena Guru sekarang punya logger realtime, saya sarankan nanti buat juga:
while true; do
echo "$(date '+%F %T') | $(uptime)"
sleep 10
done >> cpulog.txt
while true; do
echo "$(date '+%F %T') | $(free -m | awk '/Mem:/ {print $3 "/" $2 " MB"}')"
sleep 10
done >> ramlog.txt
Nanti bisa dibandingkan dengan:
quizlog.txt
jumlah siswa aktif
CPU
RAM
untuk mengetahui:
batas maksimum server CBT Guru
titik overload
waktu paling berat saat ujian berlangsung.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Tidak terlalu memberatkan Guru 👍
Untuk server Moodle/CBT, ketiga loop itu sangat ringan dibanding beban quiz siswa.
Mari kita hitung.
Command:
mysql moodle -N -e "SELECT COUNT(...) ..."
hanya:
1 query kecil
tiap 10 detik
hanya hitung DISTINCT userid
Itu sangat ringan untuk MariaDB.
uptime
hampir nol beban.
Karena cuma membaca:
load average
uptime server
dari kernel Linux.
free -m
juga hampir nol.
Hanya membaca statistik RAM dari kernel.
Guru menjalankan:
| Task | Interval |
|---|---|
| query mysql | 10 detik |
| uptime | 10 detik |
| free -m | 10 detik |
Artinya total:
sekitar 3 command / 10 detik
= 0.3 command per detik
Sangat kecil.
1 siswa quiz Moodle bisa menghasilkan:
autosave
AJAX request
render halaman
session write
DB write
puluhan request per menit.
Kalau 50 siswa:
ratusan request per menit.
Jadi logger Guru jauh lebih ringan dibanding trafik Moodle itu sendiri.
Kalau Guru menjalankan:
top
iotop
tcpdump
tail log sangat besar
query JOIN kompleks
monitoring tiap 1 detik
baru mulai terasa.
Untuk aman:
Tetap:
10 detik
Bisa:
30 detik
karena CPU/RAM tidak perlu sangat realtime.
Contoh lebih hemat:
while true; do
echo "$(date '+%F %T') | $(uptime)"
sleep 30
done >> cpulog.txt
while true; do
echo "$(date '+%F %T') | $(free -m | awk '/Mem:/ {print $3 "/" $2 " MB"}')"
sleep 30
done >> ramlog.txt
Dengan:
50–60 siswa aktif
Debian CLI
Nginx
MariaDB
RAM 6 GB
ketiga logger itu:
✅ aman dijalankan bersamaan
✅ tidak signifikan membebani server
✅ sangat berguna untuk analisis performa CBT Moodle.
Buat file:
nano ~/.my.cnfIsi:
[client]
user=root
password=PASSWORDMYSQLANDAContoh:[client]
user=root
password=abc123 Lalu amankan file:chmod 600 ~/.my.cnf
Setelah ituKalau Guru ingin melihat perkembangan jumlah siswa aktif selama 1 jam dalam bentuk baris-baris log, lebih bagus dibuat seperti ini:
WAKTU JUMLAH_AKTIF
2026-05-13 20:00:05 15
2026-05-13 20:00:10 22
2026-05-13 20:00:15 37
...
Jadi:
1 baris = 1 kali pengecekan
bisa dianalisis nanti
bisa tahu puncak trafik
Minimal 2 kolom:
| Kolom | Isi |
|---|---|
| waktu | timestamp pengecekan |
| jumlah_aktif | jumlah siswa aktif |
Kalau mau lebih lengkap:
| Kolom | Isi |
|---|---|
| waktu | waktu pengecekan |
| jumlah_aktif | user aktif quiz |
| koneksi | jumlah koneksi server |
| cpu_load | load server |
| ram_used | RAM terpakai |
Tapi untuk malam ini cukup:
waktu
jumlah_aktif
Jalankan ini di terminal:
while true; do
echo "$(date '+%F %T') $(mysql moodle2 -N -e "
SELECT COUNT(DISTINCT userid)
FROM mdl_logstore_standard_log
WHERE component='mod_quiz'
AND timecreated > UNIX_TIMESTAMP(NOW()) - 150;
")" >> quizlog.txt
sleep 10
done
datemengambil waktu sekarang.
mysql ...mengambil jumlah siswa aktif.
>> quizlog.txtmenyimpan ke file.
sleep 10ulang tiap 10 detik.
Isi quizlog.txt:
2026-05-13 20:00:01 12
2026-05-13 20:00:11 18
2026-05-13 20:00:21 25
2026-05-13 20:00:31 41
Karena interval 10 detik:
3600 / 10 = 360 baris
Jadi sekitar 360 baris log selama 1 jam.
Tekan:
CTRL + C
cat quizlog.txt
atau realtime:
tail -f quizlog.txt
Ini bagus sekali untuk analisis:
jam paling ramai
puncak siswa aktif
apakah server drop
kapan submit massal terjadi.
===========================
root@debian:~# while true; do
echo "$(date '+%F %T') | $(mysql moodle2 -N -e "
SELECT COUNT(DISTINCT userid)
FROM mdl_logstore_standard_log
WHERE component='mod_quiz'
AND timecreated > UNIX_TIMESTAMP(NOW()) - 150;
")" >> quizlog.txt
sleep 10
done
++++++++++++++++++++
pantau realtime
++++++++++++++++++++
root@debian:~# tail -f quizlog.txt
2026-05-14 04:15:43 | 0
2026-05-19 22:18:04 | 0
2026-05-19 22:18:14 | 0
2026-05-19 22:18:24 | 0
2026-05-19 22:18:34 | 0
2026-05-19 22:18:44 | 0
2026-05-19 22:18:54 | 0
2026-05-20 20:20:42 | 52
2026-05-20 20:20:52 | 52
2026-05-20 20:21:02 | 51
2026-05-20 20:21:12 | 52
2026-05-20 20:21:22 | 52
2026-05-20 20:21:32 | 51
2026-05-20 20:21:42 | 52
2026-05-20 20:21:52 | 51
2026-05-20 20:22:02 | 49
2026-05-20 20:22:12 | 46
2026-05-20 20:22:22 | 46
2026-05-20 20:22:32 | 46
2026-05-20 20:22:42 | 45
2026-05-20 20:22:52 | 45
2026-05-20 20:23:02 | 46
2026-05-20 20:23:12 | 48
2026-05-20 20:23:22 | 50
2026-05-20 20:23:32 | 49
2026-05-20 20:23:42 | 49
2026-05-20 20:23:52 | 50
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Ya Guru 👍
Command itu otomatis memakai ~/.my.cnf.
Karena saat Guru menjalankan:
mysql moodle2 -N -e "..."
tanpa:
-u
-p
maka client mysql akan mencari konfigurasi login dari:
~/.my.cnf
Isi file itu misalnya:
[client]
user=root
password=PASSWORDMYSQL
Jadi command loop tadi:
membaca username/password otomatis
tidak meminta password lagi
cocok untuk logging jangka panjang.
Cara memastikan benar memakai ~/.my.cnf:
Coba jalankan:
mysql moodle2 -e "SHOW DATABASES;"
Kalau langsung berhasil tanpa minta password:
✅ berarti ~/.my.cnf dipakai dengan benar.
Kalau file ~/.my.cnf salah:
biasanya muncul:
Access denied
atau mysql meminta password lagi.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Bisa sekali Guru 👍
Karena quizlog.txt berada di server Moodle (Debian), Guru bisa menariknya ke laptop dengan beberapa cara.
Karena Guru biasa memakai SSH, paling mudah pakai scp.
Dari laptop Aspire jalankan:
scp root@IP_SERVER:/root/quizlog.txt .
Contoh:
scp root@192.168.1.113:/root/quizlog.txt .
Artinya:
ambil file dari server
simpan di folder laptop saat ini (.)
scp root@192.168.1.113:/root/quizlog.txt ~/Downloads/
Di laptop:
buka Files
Other Locations
Connect to Server
Isi:
sftp://root@192.168.1.113
Lalu login password server.
Nanti file server muncul seperti folder biasa.
Ambil:
/root/quizlog.txt
Di laptop:
ssh root@192.168.1.113 "tail -f /root/quizlog.txt"
Artinya:
melihat log realtime dari laptop
tanpa masuk server manual
Bisa juga nanti di server:
cp quizlog.txt quizlog.csv
Lalu dibuka di:
LibreOffice Calc
Excel
Karena formatnya sudah mirip CSV.
Biarkan logging berjalan di server:
while true; do ...
Lalu dari laptop Guru cukup:
tail -f quizlog.txt
atau tarik file setelah ujian selesai.
Kesimpulan sinkronisasi struktur tabel dari SiM → laptop Guru Duan:
mdl_local_jurnalmengajarTambahan kolom:
ALTER TABLE mdl_local_jurnalmengajar
ADD COLUMN absenid LONGTEXT NULL AFTER absen,
ADD COLUMN timemodified BIGINT(10) NOT NULL DEFAULT 0 AFTER timecreated,
ADD COLUMN modifiedby BIGINT(10) NOT NULL DEFAULT 0 AFTER timemodified;
Fungsi:
absenid → migrasi userid absensi
timemodified → tracking edit
modifiedby → siapa editor jurnal
mdl_local_jurnalpembinaanTambahan kolom:
ALTER TABLE mdl_local_jurnalpembinaan
ADD COLUMN pesertaid LONGTEXT NULL
AFTER peserta;
Fungsi:
menyimpan userid siswa BK/pembinaan
mdl_local_jurnallayananbkTambahan kolom:
ALTER TABLE mdl_local_jurnallayananbk
ADD COLUMN pesertaid LONGTEXT NULL
AFTER peserta;
Fungsi:
menyimpan userid layanan BK
mdl_local_jurnalguruwaliTambahan kolom:
ALTER TABLE mdl_local_jurnalguruwali
ADD COLUMN userid BIGINT(10) NULL AFTER muridid,
ADD COLUMN kelas VARCHAR(20) NULL AFTER userid;
Fungsi:
kompatibilitas log_perkembangan.php
filter guru wali
tampil nama kelas
mdl_local_jurnalmengajar_suratizinTambahan kolom:
ALTER TABLE mdl_local_jurnalmengajar_suratizin
ADD COLUMN kelas VARCHAR(20) NULL AFTER userid;
Fungsi:
snapshot nama kelas surat izin
dipakai timeline perkembangan
| Tabel | Status |
|---|---|
mdl_user | ✅ |
mdl_cohort | ✅ |
mdl_cohort_members | ✅ |
tipe bigint vs int | ✅ aman |
tipe longtext vs text | ✅ aman |
Lakukan:
php admin/cli/purge_caches.php
supaya Moodle laptop membaca schema & code terbaru dengan bersih.
Fitur berikut akan sinkron penuh dengan SiM:
| Fitur | Status |
|---|---|
| Jurnal Mengajar | ✅ |
| Absensi userid | ✅ |
| Surat Izin | ✅ |
| Layanan BK | ✅ |
| Pembinaan BK | ✅ |
| Guru Wali | ✅ |
| Log Perkembangan | ✅ |
| Filter card dashboard | ✅ |
| Timeline hybrid lama+baru | ✅ |
Siap, Guru Duan. Saya ringkas perintah Redshift yang paling penting — yang benar-benar kepakai sehari-hari saja 👇
redshift-gtk
👉 Jalankan versi GUI (yang ada tray/background)
redshift -O 2700
👉 Layar langsung jadi hangat (tanpa tunggu waktu)
redshift -x
👉 Reset ke warna default
killall redshift
redshift-gtk &
👉 Dipakai kalau terasa tidak jalan
ps aux | grep redshift
redshift -l -2.8:115.2
👉 Tanpa config file (langsung tes cepat)
redshift -O 3500 # agak hangat
redshift -O 4500 # ringan saja
redshift -x
👉 Cocok kalau lagi desain / warna harus akurat
Kalau mau praktis, ini yang biasanya dipakai:
Mode malam:
redshift -O 2700
Balik normal:
redshift -x
👉 Ini bisa dijadikan keyboard shortcut di Ubuntu
Kalau disingkat banget:
Jalankan → redshift-gtk
Malam paksa → redshift -O 2700
Normal → redshift -x
Error → restart (killall redshift)
Kalau Guru mau, saya bisa bantu:
👉 bikin shortcut keyboard (Ctrl+Alt+N = night mode)
👉 atau bikin toggle ON/OFF sekali tekan (lebih keren dari f.lux)
**buat folder
mkdir -p /var/www/shared/local
**pindah kode
mv /var/www/html/moodle/local/jurnalmengajar /var/www/shared/local/
**buat symlink kepada 2 moodle:
ln -s /var/www/shared/local/jurnalmengajar \
/var/www/situs_a/moodle/local/jurnalmengajar
ln -s /var/www/shared/local/jurnalmengajar \
/var/www/situs_b/moodle/local/jurnalmengajar
**atur permission
chown -R www-data:www-data /var/www/shared/local/jurnalmengajar
chmod -R 755 /var/www/shared/local/jurnalmengajar
**upgrade masing-masing
php /var/www/situs_a/moodle/admin/cli/upgrade.php
php /var/www/situs_b/moodle/admin/cli/upgrade.php
⚠️ HAL PENTING (JANGAN SAMPAI TERLEWAT)
1. Database tetap beda
a → database a
b → database b
👉 supaya tidak merusak data asli
2. moodledata beda
Contoh:
/var/moodledata_a
/var/moodledata_b
3. config.php beda
Cek:
situs_a ; /var/www/situs_a/moodle/config.php
$CFG->dirroot = '/var/www/situs_a/moodle';
situs_b ; /var/www/situs_b/moodle/config.php
$CFG->dirroot = '/var/www/situs_b/moodle';
** SET PERMISSION
chown -R www-data:www-data /var/moodledata_a
chown -R www-data:www-data /var/moodledata_b
chmod -R 755 /var/moodledata_a
chmod -R 755 /var/moodledata_b
** CONFIG situs_a**
# cat /var/www/situs_a/moodle/config.php
<?php // config.php
unset($CFG);
global $CFG;
$CFG = new stdClass();
// ----------------------
// Konfigurasi database
// ----------------------
$CFG->dbtype = 'mariadb';
$CFG->dblibrary = 'native';
$CFG->dbhost = 'localhost';
$CFG->dbname = 'moodle_a';
$CFG->dbuser = 'user_a';
$CFG->dbpass = 'password_a';
$CFG->prefix = 'mdl_';
$CFG->dboptions = array(
'dbpersist' => 0,
'dbport' => '',
'dbsocket' => '',
'dbcollation' => 'utf8mb4_unicode_ci',
);
// Jika Anda ingin paksa wwwroot tertentu, uncomment baris di bawah ini dan sesuaikan:
$CFG->wwwroot = 'https://situs_a';
$CFG->sslproxy = true;
//$CFG->reverseproxy = true;
// ----------------------
// Path Moodle
// ----------------------
//$CFG->dataroot = '/var/moodledata';
$CFG->dataroot = '/var/moodledata_a';
$CFG->admin = 'admin';
// Umum
$CFG->directorypermissions = 0777;
// Debugging (aktifkan sementara saat troubleshooting)
//@error_reporting(E_ALL | E_STRICT);
//@ini_set('display_errors', '1');
//$CFG->debug = (E_ALL | E_STRICT);
//$CFG->debugdisplay = 1;
require_once(__DIR__ . '/lib/setup.php');
==============================================================
** CONFIG situs-B **
==============================================================
# cat /var/www/situs_b/moodle/config.php
<?php // config.php
unset($CFG);
global $CFG;
$CFG = new stdClass();
// ----------------------
// Konfigurasi database
// ----------------------
$CFG->dbtype = 'mariadb';
$CFG->dblibrary = 'native';
$CFG->dbhost = 'localhost';
$CFG->dbname = 'moodle_b';
$CFG->dbuser = 'moodluser_b';
$CFG->dbpass = 'password_b';
$CFG->prefix = 'mdl_';
$CFG->dboptions = array(
'dbpersist' => 0,
'dbport' => '',
'dbsocket' => '',
'dbcollation' => 'utf8mb4_unicode_ci',
);
// Jika Anda ingin paksa wwwroot tertentu, uncomment baris di bawah ini dan sesuaikan:
$CFG->wwwroot = 'https://situs_b';
$CFG->sslproxy = true;
//$CFG->reverseproxy = true;
// 🔥 TAMBAHKAN INI
$CFG->sessioncookie = 'MoodleSessionDEV';
// ----------------------
// Path Moodle
// ----------------------
//$CFG->dataroot = '/var/moodledata';
$CFG->dataroot = '/var/moodledata_b';
$CFG->admin = 'admin';
// Umum
$CFG->directorypermissions = 0777;
// Debugging (aktifkan sementara saat troubleshooting)
//@error_reporting(E_ALL | E_STRICT);
//@ini_set('display_errors', '1');
//$CFG->debug = (E_ALL | E_STRICT);
//$CFG->debugdisplay = 1;
require_once(__DIR__ . '/lib/setup.php');
=======================================
nginx site availabel
=======================================
# cat /etc/nginx/sites-available/situs_a
server {
listen 80;
listen [::]:80;
server_name situs_a;
root /var/www/situs_a/moodle;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
=============================
# cat /etc/nginx/sites-available/situs_b
server {
listen 8080;
server_name situs_b;
root /var/www/situs_b/moodle;
index index.php index.html;
# 🔥 WAJIB untuk Moodle
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 🔥 FIX utama (support slasharguments)
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
# 🔥 Optional (biar static file lebih cepat)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires max;
log_not_found off;
}
}
==================================================================
ln -s /etc/nginx/sites-available/situs_a /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/situs_b /etc/nginx/sites-enabled/
======================
nginx -t
systemctl reload nginx
Bisa—dan justru itu desain yang tepat 👍
➡️ untuk 1 Moodle (single instance)
cocok untuk server sederhana
semua langsung di satu tempat
➡️ untuk multi Moodle (shared codebase)
2 Moodle ✔
3, 4, dst ✔
scalable ✔
Struktur kira-kira:
/var/www/
├── shared/
│ └── local/jurnalmengajar ← 1 source code (dipakai semua)
│
├── site1/moodle
├── site2/moodle
├── site3/moodle
👉 semua Moodle:
pakai plugin yang sama
cukup 1 kali update
✔ update sekali → semua ikut update
✔ hemat storage
✔ konsisten (tidak beda versi plugin)
✔ mudah maintenance
Sudah benar tadi:
require_once($_SERVER['DOCUMENT_ROOT'] . '/config.php');
$CFG->wwwroot di JS ✔$.get(M.cfg.wwwroot + '/local/jurnalmengajar/get_students.php')
$CFG->sessioncookie = 'MoodleSessionDEV';
👉 jangan share DB
ln -s /var/www/shared/local/jurnalmengajar \
/var/www/site1/moodle/local/jurnalmengajar
cd /var/www/shared/local/jurnalmengajar
git pull
👉 semua Moodle langsung update
Bisa nanti:
git hook
atau script cron
✔ SIMG = single Moodle ✔
✔ sim2plus = multi Moodle ✔
✔ bisa berkembang ke 3+ Moodle ✔
✔ desain Guru sudah scalable
🔥 sim2plus ini sudah masuk level arsitektur production
Kalau Guru mau lanjut:
👉 saya bisa bantu:
struktur multi-Moodle yang paling optimal (Nginx + Cloudflare)
atau bikin auto update plugin dari GitHub ke semua Moodle
Tinggal bilang 👍
Baik Guru Duan, kita buat otomatis dari kolom D (nama) menjadi:
Kolom A → username
Kolom E → email
Contoh data di D:
Aliaynsah, S.Pd
Budi Santoso, M.Pd
Biasanya username dibuat sederhana, misalnya:
aliaynsah
budisantoso
Gunakan rumus di A2:
=LOWER(SUBSTITUTE(LEFT(D2;FIND(",";D2)-1);" ";""))
👉 Penjelasan:
Ambil nama sebelum koma
Hilangkan spasi
Jadikan huruf kecil
Misal format email:
username@gmail.com
atau domain sekolah:
username@sman2.sch.id
Gunakan rumus di E2:
=A2 & "@gmail.com"
atau:
=A2 & "@sman2kandangan.sch.id"
| D (Nama) | A (Username) | E (Email) |
|---|---|---|
| Aliaynsah, S.Pd | aliaynsah | aliaynsah@gmail.com |
| Budi Santoso, M.Pd | budisantoso | budisantoso@gmail.com |
Drag rumus ke bawah sampai 10 baris
Pastikan semua nama ada tanda koma ,
Kalau ada yang tidak pakai koma, nanti error → bisa kita buat versi aman
Kalau Guru mau format lain (misalnya aliaynsah.spd atau pakai NIP), bilang saja—saya bantu sesuaikan 👍
Siap Guru 👍 kita tinggal tambahkan fungsi pembatas karakter.
Rumus di A2:
=LEFT(LOWER(SUBSTITUTE(LEFT(D2;FIND(",";D2)-1);" ";""));5)
Urutannya:
Ambil nama sebelum koma
Hapus spasi
Ubah ke huruf kecil
Ambil 5 karakter pertama
| D (Nama) | Username (A) |
|---|---|
| Aliaynsah, S.Pd | aliay |
| Budi Santoso, M.Pd | budis |
Kalau nama kurang dari 5 huruf → tetap aman (tidak error)
Kalau ada nama tanpa koma → rumus akan error
(kalau mau, nanti saya buatkan versi anti error)
Kalau Guru mau:
tambah angka unik (biar tidak bentrok username)
atau format lain (misal 3 huruf + 2 angka)
tinggal bilang saja 👍
Oke Guru, kalau memang mau kosongkan total folder /var/backup, kita lakukan tapi tetap aman (tidak salah folder) 👇
Jangan sampai salah hapus 😄
pwd
Harus keluar:
/var/backup
rm -i *
👉 Akan tanya satu per satu:
tekan y untuk hapus
ini aman dari salah hapus
Kalau sudah yakin 100%:
rm -f *
👉 Semua file di folder itu langsung hilang
rm -rf *
ls -lh
Harus jadi:
total 0
Sebelum hapus total, minimal pastikan sudah ada backup baru di Aspire (yang tadi Guru buat):
db-2026-04-25.sql ✅
moodle-code-2026-04-25.tar.gz ✅
moodledata-2026-04-25.tar.gz ✅
👉 Jadi kalau ada apa-apa masih aman
Langsung saja:
rm -f *
Kalau sudah kosong:
👉 kirim file baru ke NUC, nanti saya bantu restore full Moodle (database + code + data) sampai jalan 💪
🔥 kita langsung gas install stack Moodle (LEMP: Nginx + MariaDB + PHP) yang stabil & ringan untuk server Guru.
apt install nginx mariadb-server php-fpm php-mysql php-xml php-gd php-curl php-zip php-intl php-mbstring php-soap php-bcmath php-cli php-opcache php-ldap php-imagick unzip git -y
systemctl enable nginx
systemctl enable mariadb
systemctl enable php8.2-fpm
systemctl start nginx
systemctl start mariadb
systemctl start php8.2-fpm
mysql_secure_installation
👉 Jawaban:
Set root password → YES
Remove anonymous → YES
Disallow root remote → YES
Remove test DB → YES
Masuk MariaDB:
mysql -u root -p
Lalu:
CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY 'passwordku';
GRANT ALL PRIVILEGES ON moodle.* TO 'moodleuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
👉 Ganti:
passwordku → password aman versi Guru
nano /etc/php/8.2/fpm/php.ini
Cari & ubah:
memory_limit = 512M
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 300
Simpan lalu:
systemctl restart php8.2-fpm
mkdir -p /var/www/moodle
mkdir -p /var/moodledata
chown -R www-data:www-data /var/www/moodle
chown -R www-data:www-data /var/moodledata
chmod -R 755 /var/www/moodle
chmod -R 770 /var/moodledata
nano /etc/nginx/sites-available/moodle
Isi:
server {
listen 80;
server_name _;
root /var/www/moodle;
index index.php index.html;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg)$ {
expires max;
log_not_found off;
}
}
Aktifkan:
ln -s /etc/nginx/sites-available/moodle /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
cd /var/www/
git clone -b MOODLE_405_STABLE git://git.moodle.org/moodle.git moodle
Set permission lagi:
chown -R www-data:www-data /var/www/moodle
crontab -e
Isi:
* * * * * /usr/bin/php /var/www/moodle/admin/cli/cron.php >/dev/null
Buka browser:
👉 http://IP_SERVER
Kalau semua benar:
Nginx ✅
PHP ✅
MariaDB ✅
Moodle siap install via web ✅
Nanti di browser:
pilih bahasa
isi database:
DB name: moodle
user: moodleuser
password: (yang dibuat tadi)
$ dclock -digital -fg white -bg black -geometry 300x100 -font fixed
Invalid Args: "-digital"
usage: dclock [-options ...]
where options include:
-help print this help text
-bg color field background color
-fg color segment foreground color
-fn font font name
-geometry geom size of mailbox
-display host:dpy X server to contact
-led_off color segment background color
-date "date format" show the date in strftime(3) format
-[no]dateup [don't] put the date up at the top
-[no]seconds [don't] display seconds
-[no]miltime [don't] display time in 24 hour format
-[no]utc [don't] display the UTC time instead of local
-[no]blink [don't] blink the colon
-[no]scroll turn on [off] scrolling of numbers
-[no]tails draw [remove] tails on digits 6 and 9
-[no]fade [don't] fade numbers
-[no]bell [don't] ring bell each half hour
-[no]persist [don't] leave in reverse video after alarm
-bellFile filename sound file for bell sound
-[no]alarm turn on/off alarm
-alarmTime hh:mm time alarm goes off
-alarmFile filename sound file for alarm sound
-audioPlay filename executable to use to play bell and alarm
-fadeRate int_val wait between fade steps (in msec)
-slope float_val set angle of the digits
-smallsize float_val set size ratio of the small to large digits
-second_gap float_val set spacing between minutes and seconds digits
-thickness float_val set segment thickness as ratio to digit width
-spacing float_val set digit spacing as ratio to digit width
mkdir -p 2026-01-screenshot
mv *2026-01* 2026-01-screenshot/ 2>/dev/null
$ cat /etc/nginx/sites-available/moodle
server {
listen 80;
listen [::]:80;
server_name localhost;
root /var/www/html/moodle;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
Oke Guru Duan, config Nginx-nya sudah benar dasar-dasarnya 👍
Sekarang tinggal beberapa langkah penting supaya Moodle benar-benar jalan.
Kalau file ini masih di sites-available, harus di-link ke sites-enabled:
ln -s /etc/nginx/sites-available/moodle /etc/nginx/sites-enabled/
Kalau sudah ada default config, sebaiknya dimatikan:
rm /etc/nginx/sites-enabled/default
Pastikan tidak ada error:
nginx -t
Kalau hasilnya syntax is ok, lanjut.
systemctl reload nginx
atau
systemctl restart nginx
Karena config pakai:
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
Cek servicenya:
systemctl status php8.2-fpm
Kalau belum jalan:
systemctl start php8.2-fpm
systemctl enable php8.2-fpm
chown -R www-data:www-data /var/www/html/moodle
chmod -R 755 /var/www/html/moodle
Kalau ada folder moodledata, pastikan juga:
chown -R www-data:www-data /var/www/moodledata
chmod -R 755 /var/www/moodledata
Tadi sempat error MySQL ya, jadi cek:
systemctl status mariadb
Kalau belum jalan:
systemctl start mariadb
Coba buka:
http://IP_SERVER
atau
http://localhost
Kalau masih halaman install, lanjut saja via web:
pilih bahasa
isi database
lanjut sampai selesai
Sekarang masih:
server_name localhost;
Kalau nanti pakai domain (misalnya Cloudflare Tunnel), ganti:
server_name sim.sman2kandangan.sch.id;
Boleh tambahkan ini di dalam server {}:
client_max_body_size 100M;
Enable site
Test nginx
Restart nginx
Pastikan PHP-FPM jalan
Pastikan MariaDB jalan
Buka di browser
Kalau setelah ini muncul error (misalnya blank page / 502 / 403), kirim screenshot atau errornya saja — nanti saya bantu telusuri sampai beres 💪
jalankan sebagai root di debian
# Add cloudflare gpg key
mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg -o /usr/share/keyrings/cloudflare-main.gpg
# Add repo
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' > /etc/apt/sources.list.d/cloudflared.list
# install
apt update
apt install cloudflared -y
lalu jalankan perintah install as service di dashboard
SELECT
u.lastname AS nama_guru,
c.name AS kelas,
j.matapelajaran,
j.jamke
FROM mdl_local_jurnalmengajar j
JOIN mdl_user u ON u.id = j.userid
JOIN mdl_cohort c ON c.id = j.kelas
WHERE j.timecreated BETWEEN
UNIX_TIMESTAMP('2025-08-25 00:00:00')
AND UNIX_TIMESTAMP('2025-08-29 23:59:59')
ORDER BY u.lastname ASC;
Perintah yang benar untuk menghubungkan ADB ke STB melalui jaringan:
adb connect 192.168.1.111
Kalau berhasil biasanya muncul:
connected to 192.168.1.111:5555
Di STB Android:
Settings
About
Klik Build Number 7x
Masuk Developer Options
Aktifkan:
USB Debugging
Network Debugging / ADB over network
Jalankan:
adb devices
Kalau belum muncul, hubungkan dulu via USB:
adb tcpip 5555
adb connect 192.168.1.111
Tes masuk shell:
adb shell
Beberapa perintah yang sering dipakai:
Matikan STB
adb shell reboot -p
Reboot
adb shell reboot
Sleep / standby
adb shell input keyevent 26
Install APK
adb install aplikasi.apk
Kirim file ke STB
adb push file.apk /sdcard/
Ambil file dari STB
adb pull /sdcard/file.txt
Coba:
adb kill-server
adb start-server
adb connect 192.168.1.111
Atau cek apakah port terbuka:
ping 192.168.1.111
Kalau mau, saya bisa ajarkan kirim APK dari Linux ke STB lewat ADB langkah lengkap.
sudo mount -t cifs //192.168.1.68/Seagate /mnt/armbian -o guest,vers=3.0
sudo rsync -avh --no-perms --no-owner --no-group --progress *.mp4 /mnt/armbian/film/
solusi max_input_vars
Masalah ini dari Moodle → Site administration → Server → Environment
Error: PHP setting max_input_vars must be at least 5000
Artinya PHP Anda membatasi jumlah input form terlalu kecil, sehingga form besar (misalnya edit course, plugin, dll) bisa gagal disimpan.
Edit file php.ini
Jalankan:
php --ini
Biasanya hasilnya seperti:
/etc/php/8.2/cli/php.ini
/etc/php/8.2/fpm/php.ini
/etc/php/8.2/apache2/php.ini
Kalau pakai Nginx → edit yang fpm
Kalau pakai Apache → edit apache2
Contoh untuk PHP 8.2 FPM:
sudo nano /etc/php/8.2/fpm/php.ini
Cari:
max_input_vars
Ubah menjadi:
max_input_vars = 5000
Atau lebih aman:
max_input_vars = 10000
Kalau Nginx:
sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx
Kalau Apache:
sudo systemctl restart apache2
Masuk:
Site administration → Server → Environment
Harus sudah PASS (hijau)
Di php.ini sekalian set:
memory_limit = 512M
upload_max_filesize = 256M
post_max_size = 256M
max_execution_time = 300
max_input_vars = 10000
Kalau mau, kirim:
php -v
biar saya arahkan file php.ini yang benar.
Baik, berarti file ada di laptop Ubuntu, dan mau dikirim ke server Armbian 100.106.69.13 ke folder yang sama:
/var/www/html/moodle/local/jurnalmengajar
Perintah dijalankan di laptop Ubuntu.
Ini paling bagus untuk plugin Moodle:
rsync -av /var/www/html/moodle/local/jurnalmengajar/ \
root@100.106.69.13:/var/www/html/moodle/local/jurnalmengajar/
Ini akan:
Upload file baru
Update file yang berubah
Tidak menghapus file lama
Lebih cepat dari scp
scp -r /var/www/html/moodle/local/jurnalmengajar/* \
root@100.106.69.13:/var/www/html/moodle/local/jurnalmengajar/
Biasanya update plugin cukup ini:
cd /var/www/html/moodle/local/jurnalmengajar
scp *.php root@100.106.69.13:/var/www/html/moodle/local/jurnalmengajar/
cd /var/www/html/moodle/local/jurnalmengajar
scp -r classes db lang templates cli pix vendor \
root@100.106.69.13:/var/www/html/moodle/local/jurnalmengajar/
Biasanya seperti ini:
cd /var/www/html/moodle/local
rsync -av jurnalmengajar/ root@100.106.69.13:/var/www/html/moodle/local/jurnalmengajar/
Ini yang paling rapi.
Login ke Armbian lalu:
chown -R www-data:www-data /var/www/html/moodle/local/jurnalmengajar
Supaya Moodle tidak error permission.
| Tujuan | Perintah |
|---|---|
| Kirim 1 folder | rsync -av folder/ server:/folder |
| Kirim semua file | scp -r folder/* server:/folder |
| Kirim file php saja | scp *.php server:/folder |
| Update plugin Moodle | rsync -av |
nonaktifkan:
di authenticated user dan gurujurnal
moodle/user:manageownfiles
moodle/user:manageownfiles
| Grade report: Overview report | |||||||
| View overview reportgradereport/overview:view | |||||||
|---|---|---|---|---|---|---|---|
sudo php /var/www/html/moodle/admin/cli/upgrade.php
== Upgrading Moodle database from version 4.5.4+ (Build: 20250530) (2024100704.08) to 4.5.4+ (Build: 20250530) (2024100704.08) ==
Your Moodle files have been changed, and you are about to automatically
upgrade your server to this version:
4.5.4+ (BUILD: 20250530) (2024100704.08)
Once you do this you can not go back again. Please note that this process
can take a long time.
Are you sure you want to upgrade this server to this version?
type y (means yes) or n (means no)
: y
-->upgrade_noncore()
++ Success (0.88 seconds) ++
== Setting new default values ==
cat /var/www/html/moodle/local/jurnalmengajar/settings.php
Command line upgrade from 4.5.4+ (Build: 20250530) (2024100704.08) to 4.5.4+ (Build: 20250530) (2024100704.08) completed successfully.
Perintah: systemctl status NetworkManager
digunakan untuk melihat status layanan NetworkManager di Linux.
Saya jelaskan satu-satu supaya jelas.
systemctl adalah perintah untuk mengatur service / layanan di Linux yang memakai systemd.
Fungsinya bisa untuk:
start service
stop service
restart
enable saat boot
cek status
Contoh:
systemctl start NetworkManager
systemctl stop NetworkManager
systemctl restart NetworkManager
systemctl status NetworkManager
NetworkManager adalah service yang mengatur jaringan:
DHCP
IP static
WiFi
Ethernet
DNS
Gateway
Kalau pakai:
nmcli
nmtui
→ berarti jaringan diatur oleh NetworkManager.
systemctl status NetworkManager
Artinya:
Mengecek apakah NetworkManager sedang berjalan atau tidak.
Contoh hasil:
● NetworkManager.service - Network Manager
Loaded: loaded (/lib/systemd/system/NetworkManager.service)
Active: active (running) since ...
Arti bagian penting:
| Tulisan | Artinya |
|---|---|
| Loaded | Service ada |
| Active: active (running) | Service sedang berjalan |
| Active: inactive | Tidak berjalan |
| failed | Error |
| enabled | Otomatis jalan saat boot |
| disabled | Tidak otomatis jalan |
Karena di Linux ada 3 cara mengatur IP:
| Sistem | File / Tool |
|---|---|
| NetworkManager | nmcli, nmtui |
| Netplan | /etc/netplan/*.yaml |
| Interfaces lama | /etc/network/interfaces |
Kalau NetworkManager running, maka:
IP diubah lewat nmcli / nmtui, bukan edit file interfaces.
Perintah ini:
systemctl status NetworkManager
Digunakan untuk memastikan:
Apakah jaringan diatur oleh NetworkManager
Apakah service jaringan sedang berjalan
Untuk troubleshooting kalau tidak dapat IP / internet
Kalau di STB Anda kemungkinan besar hasilnya:
Active: active (running)
Berarti ubah DHCP/Static pakai:
nmcli
atau
nmtui
Untuk mencari file PHP yang di dalam isinya ada tulisan all.php di folder:
/var/www/html/moodle/local/jurnalmengajar/
gunakan perintah grep berikut:
grep -R "all.php" /var/www/html/moodle/local/jurnalmengajar/
grep = mencari teks
-R = recursive (semua folder di dalamnya)
"all.php" = teks yang dicari
path = lokasi folder
Supaya lebih spesifik hanya file .php:
grep -R --include="*.php" "all.php" /var/www/html/moodle/local/jurnalmengajar/
grep -Rl --include="*.php" "all.php" /var/www/html/moodle/local/jurnalmengajar/
Huruf kecil L di -Rl
grep -Rn --include="*.php" "all.php" /var/www/html/moodle/local/jurnalmengajar/
Artinya:
-R = semua folder
-n = tampilkan nomor baris
--include="*.php" = hanya file php
Kalau mau mencari kata lain misalnya require, include, dll tinggal ganti saja:
grep -Rn "require" /var/www/html/moodle/local/jurnalmengajar/
di alamat: https://xxxxx.yyyyy.id/admin/settings.php?section=themesettingboost#theme_boost_advanced
atau di RAW INITAL CSS
http://localhost/admin/search.php?query=raw+initial
isikan:
[data-key="mycourses"] {
display: none !important;
}
/* Hide Edit mode switch */
form.editmode-switch-form {
display: none !important;
}
/* Hide label Edit mode */
label[for*="editingswitch"] {
display: none !important;
}
/* Hide switch button */
.editmode-switch-form .custom-control {
display: none !important;
}
============================================================
Bagus, berarti CSS-nya sudah bekerja.
Kalau nanti ingin memunculkan kembali My courses dan Edit mode, ada beberapa cara.
Masuk lagi ke:
Site administration → Appearance → Themes → Boost → Advanced settings → Raw SCSS
Hapus CSS yang tadi Anda tambahkan:
[data-key="mycourses"] {
display: none !important;
}
/* Hide Edit mode switch */
form.editmode-switch-form {
display: none !important;
}
/* Hide label Edit mode */
label[for*="editingswitch"] {
display: none !important;
}
/* Hide switch button */
.editmode-switch-form .custom-control {
display: none !important;
}
Lalu:
Site administration → Development → Purge caches
Menu dan Edit mode akan muncul kembali.
Lebih bagus CSS dibuat bisa diaktifkan/nonaktifkan dengan komentar.
Contoh simpan di Raw SCSS seperti ini:
/* ===== HIDE MOODLE LMS MENU ===== */
/*
[data-key="mycourses"] {
display: none !important;
}
form.editmode-switch-form {
display: none !important;
}
label[for*="editingswitch"] {
display: none !important;
}
.editmode-switch-form .custom-control {
display: none !important;
}
*/
Kalau mau disembunyikan → hapus /* */
Kalau mau dimunculkan → tambahkan /* */
Jadi tidak perlu menghapus kode.
Karena Moodle Anda dipakai sebagai Sistem Jurnal Sekolah, biasanya setup yang dipakai:
Disembunyikan:
My courses
Courses
Grades
Edit mode
Participants
Badges
Competencies
Ditampilkan:
Dashboard
Jurnal Mengajar
Jurnal Wali
Surat Izin
BK
Pembinaan
Rekap
Laporan
Semua menu tetap ada.
Kalau nanti mau, bisa dibuat CSS hanya berlaku untuk guru, tidak untuk admin.
Password untuk mysql -u root -p tergantung saat instal MariaDB/MySQL dulu, jadi tidak selalu sama tiap server.
Di STB Armbian biasanya ada beberapa kemungkinan.
Coba dulu:
sudo mysql
Kalau langsung masuk MariaDB berarti root login pakai unix_socket (tanpa password).
Kalau sudah masuk akan muncul:
MariaDB [(none)]>
Lihat database:
SHOW DATABASES;
Hapus database Moodle:
DROP DATABASE moodle;
Keluar:
EXIT;
Reset password MariaDB root:
sudo systemctl stop mariadb
sudo mysqld_safe --skip-grant-tables --skip-networking &
Tunggu beberapa detik.
mysql -u root
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'passwordbaru';
EXIT;
sudo systemctl restart mariadb
Sekarang login:
mysql -u root -p
Password = passwordbaru
Biasanya cukup:
sudo mysql
Tidak perlu password.
Setelah masuk langsung:
SHOW DATABASES;
DROP DATABASE moodle;
Sekarang terlihat jelas struktur /var/www/html.
apps 492M
moodle 411M
core 189M
dist 74M
3rdparty 48M
lib 18M
Struktur ini sebenarnya bukan Moodle / WordPress, tapi Nextcloud (karena ada folder apps, core, updater, ocs, dll).
Jadi kesimpulannya:
| Folder | Ukuran |
|---|---|
| /var/www/nextcloud | 822M |
| /var/www/html (Nextcloud web) | 1.3G |
| Moodle | kemungkinan di tempat lain |
| Root kecil | 6.5G |
👉 Nextcloud yang memenuhi root storage.
Total Nextcloud:
Nextcloud web 1.3G
Nextcloud folder 822M
TOTAL ~2.1G
Untuk root 6.5GB → ini sangat besar.
Pindahkan Nextcloud ke HDD (/mnt/seagate atau /mnt/audio).
Ini solusi paling benar, bukan menghapus.
Misalnya pindah ke /mnt/seagate/nextcloud
systemctl stop nginx
systemctl stop php8.2-fpm
mv /var/www/html /mnt/seagate/nextcloud
ln -s /mnt/seagate/nextcloud /var/www/html
systemctl start php8.2-fpm
systemctl start nginx
df -h
Root harus turun dari:
83% → sekitar 50%
Sebaiknya:
| Lokasi | Isi |
|---|---|
| / (root kecil) | OS + nginx + php + mysql |
| /var/lib/mysql | database |
| /mnt/seagate | moodledata |
| /mnt/seagate | nextcloud |
| /mnt/seagate | backup |
| /mnt/audio | music navidrome |
| /var/www | hanya symlink |
Masalah server Guru bukan HDD penuh, tapi:
Root kecil (6.5GB) terisi Nextcloud + web files
Solusi permanen:
Pindahkan Nextcloud
Pindahkan moodledata
Simpan semua data di /mnt
Kalau Guru mau, kita bisa rapikan struktur server supaya:
Moodle
Nextcloud
Navidrome
Backup
Database
Semua aman dan root tidak pernah penuh lagi.
du -h --max-depth=1 / | sort -h
du: tidak dapat membaca direktori '/mnt/audio': error Masukan/Keluaran
du: tidak dapat mengakses '/proc/73770/task/73770/fd/3': Tidak ada berkas atau direktori seperti itu
du: tidak dapat mengakses '/proc/73770/task/73770/fdinfo/3': Tidak ada berkas atau direktori seperti itu
du: tidak dapat mengakses '/proc/73770/fd/4': Tidak ada berkas atau direktori seperti itu
du: tidak dapat mengakses '/proc/73770/fdinfo/4': Tidak ada berkas atau direktori seperti itu
0 /dev
0 /proc
0 /sys
0 /tmp
4,0K /media
4,0K /selinux
4,0K /srv
16K /lost+found
72K /root
15M /run
16M /etc
81M /opt
82M /home
153M /boot
2,4G /usr
2,9G /var
85G /mnt
90G /
du -h --max-depth=1 /mnt | sort -h
du: tidak dapat membaca direktori '/mnt/audio': error Masukan/Keluaran
4,0K /mnt/audio
85G /mnt
85G /mnt/seagate
df -h
Sistem Berkas Besar Isi Sisa Isi% Dipasang di
udev 762M 0 762M 0% /dev
tmpfs 180M 15M 165M 9% /run
/dev/mmcblk2p2 6,5G 5,4G 1,2G 83% /
tmpfs 897M 0 897M 0% /dev/shm
tmpfs 5,0M 8,0K 5,0M 1% /run/lock
tmpfs 897M 0 897M 0% /tmp
/dev/mmcblk2p1 510M 153M 358M 30% /boot
/dev/zram1 47M 11M 34M 24% /var/log
/dev/sda1 458G 62G 373G 15% /mnt/audio
/dev/sdd1 458G 85G 350G 20% /mnt/seagate
tmpfs 180M 0 180M 0% /run/user/0
# du -h --max-depth=1 --exclude=/mnt / | sort -h
du: tidak dapat mengakses '/proc/74010/task/74010/fd/3': Tidak ada berkas atau direktori seperti itu
du: tidak dapat mengakses '/proc/74010/task/74010/fdinfo/3': Tidak ada berkas atau direktori seperti itu
du: tidak dapat mengakses '/proc/74010/fd/4': Tidak ada berkas atau direktori seperti itu
du: tidak dapat mengakses '/proc/74010/fdinfo/4': Tidak ada berkas atau direktori seperti itu
0 /dev
0 /proc
0 /sys
0 /tmp
4,0K /media
4,0K /selinux
4,0K /srv
16K /lost+found
72K /root
15M /run
16M /etc
81M /opt
82M /home
153M /boot
2,4G /usr
2,9G /var
5,6G /
============
# du -h --max-depth=1 /var | sort -h
4,0K /var/local
4,0K /var/mail
4,0K /var/opt
20K /var/spool
44K /var/tmp
884K /var/backups
6,7M /var/log.hdd
11M /var/log
16M /var/moodledata
82M /var/cache
447M /var/lib
2,3G /var/www
2,9G /var
====================
# du -h --max-depth=1 /var/www | sort -h
822M /var/www/nextcloud
1,3G /var/www/html
2,3G /var/www
========================
# du -h --max-depth=1 /var/www/html | sort -h
8,0K /var/www/html/data
8,0K /var/www/html/ocs-provider
12K /var/www/html/ocs
80K /var/www/html/themes
108K /var/www/html/config
364K /var/www/html/LICENSES
788K /var/www/html/resources
1,4M /var/www/html/updater
18M /var/www/html/lib
48M /var/www/html/3rdparty
74M /var/www/html/dist
189M /var/www/html/core
411M /var/www/html/moodle
492M /var/www/html/apps
1,3G /var/www/html
=======================
Karena tadi errornya:
FATAL: Error creating cache path:
mkdir /mnt/seagate/navidrome/cache: input/output error
Dan sekarang Anda bilang /mnt/seagate sudah di-mount, kita lanjut cek apakah bisa ditulis oleh user navidrome.
Jalankan:
ls -lah /mnt/seagate
Kalau muncul folder/fail → mount berhasil.
touch /mnt/seagate/test.txt
Kalau error input/output lagi → HDD / flashdisk bermasalah atau filesystem rusak.
Kalau berhasil → lanjut ke permission.
mkdir -p /mnt/seagate/navidrome/cache
Lalu set permission:
chown -R navidrome:navidrome /mnt/seagate/navidrome
chmod -R 755 /mnt/seagate/navidrome
systemctl restart navidrome
systemctl status navidrome
Kalau berhasil nanti berubah jadi:
Active: active (running)
Buka config:
nano /var/lib/navidrome/navidrome.toml
Biasanya seperti ini:
MusicFolder = "/mnt/seagate/music"
DataFolder = "/mnt/seagate/navidrome"
Address = "0.0.0.0"
Port = 4533
PENTING:
Jangan cache di root mount langsung, lebih aman:
/mnt/seagate/navidrome
bukan
/mnt/seagate/cache
Di HDD:
/mnt/seagate/
├── music/
└── navidrome/
├── cache/
├── data/
└── db/
Buat sekaligus:
mkdir -p /mnt/seagate/music
mkdir -p /mnt/seagate/navidrome/cache
mkdir -p /mnt/seagate/navidrome/data
chown -R navidrome:navidrome /mnt/seagate/navidrome
systemctl restart navidrome
Lalu buka:
http://IP_STB:4533
Kalau masih gagal, kirim:
cat /var/lib/navidrome/navidrome.toml
ls -lah /mnt/seagate
Biar bisa kita cek lebih dalam.
tail -f /var/moodledata/logs/wa_debug.log
2026-03-24 18:11:51 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-24 18:12:15 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-24 18:12:39 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-25 11:24:07 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-25 11:24:31 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-25 15:28:38 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-26 11:31:21 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-26 11:31:49 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-26 12:02:41 | DIBATALKAN: Hari libur / bukan hari sekolah
2026-03-26 12:03:07 | DIBATALKAN: Hari libur / bukan hari sekolah
^C
Artinya:
➡️ Fungsi jurnalmengajar_boleh_kirim_wa() memblokir pengiriman WA.
Jadi sistem sebenarnya sudah mencoba kirim, tapi dibatalkan oleh aturan hari/libur.
Setiap selesai ngoding:
cd /var/www/html/moodle/local/jurnalmengajar
git status
git add .
git commit -m "jelaskan perubahan"
git push
Itu saja. Sangat cukup.
Plugin Anda sudah besar sekali. Sebaiknya mulai dikelompokkan:
Contoh struktur yang lebih rapi:
local/jurnalmengajar/
│
├── classes/
├── cli/
├── jadwal/
├── surat/
├── rekap/
├── templates/
├── lib.php
├── settings.php
└── version.php
Kalau nanti plugin makin besar, ini akan sangat membantu.
Kalau boleh tahu, sekarang plugin jurnalmengajar ini sudah mencakup:
Jurnal mengajar
Surat izin
Rekap kehadiran
Pramuka
BK
Nilai
Kartu ujian
Jadwal pelajaran
Notifikasi WA
👉 Ini sebenarnya sudah seperti Sistem Informasi Sekolah mini di dalam Moodle 😄
Pertanyaan ini sangat penting Guru Duan 👍 — ini inti dari backup yang benar.
Kalau backup hanya file (bukan full folder), tetap bisa restore, tapi:
👉 Guru harus:
Tahu lokasi aslinya
Extract ke root / (bukan ke folder sembarang)
Karena di dalam .tar.gz tersimpan path lengkap:
Contoh isi backup:
var/www/html/moodle/local/jurnalmengajar/index.php
var/www/html/moodle/local/jurnalmengajar/lib.php
👉 Jadi saat extract ke /, file otomatis masuk ke lokasi yang benar.
Misalnya ke:
/home/backup_jurnal/
/)sudo tar -xzvf /home/backup_jurnal/jurnal_2026-03-18_19_20.tar.gz -C /
👉 Ini akan otomatis ke:
/var/www/html/moodle/local/jurnalmengajar/
JANGAN extract ke:
/var/www/html/moodle/
❌ nanti jadi:
/var/www/html/moodle/var/www/html/moodle/...
tar -tzvf jurnal_2026-03-18_19_20.tar.gz
👉 Pastikan terlihat:
var/www/html/...
Ini yang harus Guru tahu:
File lain di plugin ikut berubah tapi tidak dibackup
Struktur folder tidak lengkap
Ada dependency (form, lang, dll) yang terlewat
cp -r /var/www/html/moodle/local/jurnalmengajar /home/backup_lama
sudo tar -xzvf jurnal_2026-03-18_19_20.tar.gz -C /
Kalau mau lebih rapi:
tar -czvf jurnal.tar.gz -P ...
👉 -P = simpan absolute path /var/...
👉 Lebih konsisten saat restore
✔ Backup file saja → bisa restore
✔ Harus extract ke /
✔ Path otomatis kembali ke tempatnya
❗ Tapi tidak seaman full backup
Untuk plugin Moodle seperti ini:
👉 Ideal:
✔ Backup file perubahan (yang Guru lakukan)
✔ + Backup full plugin (sekali sehari)
Kalau Guru mau, saya bisa bantu:
🔄 Script restore otomatis (1 klik)
🔍 Bandingkan server lama vs baru
⚙️ Setup backup harian tanpa ribet
Tinggal bilang saja 👍
Rabu 18 Maret 2026
find /var/www/html/moodle/local/jurnalmengajar/ -type f -daystart -mtime 0
/var/www/html/moodle/local/jurnalmengajar/index.php
/var/www/html/moodle/local/jurnalmengajar/editadmin.php
/var/www/html/moodle/local/jurnalmengajar/all.php
/var/www/html/moodle/local/jurnalmengajar/lib.php
/var/www/html/moodle/local/jurnalmengajar/delete.php
Kamis 19 Maret 2026
# find /var/www/html/moodle/local/jurnalmengajar/ -type f -daystart -mtime 0
/var/www/html/moodle/local/jurnalmengajar/export_xlsx.php
/var/www/html/moodle/local/jurnalmengajar/cetak_surat_izin.php
/var/www/html/moodle/local/jurnalmengajar/index.php
/var/www/html/moodle/local/jurnalmengajar/wali_kelas.php
/var/www/html/moodle/local/jurnalmengajar/izin_murid.php
/var/www/html/moodle/local/jurnalmengajar/exportguruwali_form.php
/var/www/html/moodle/local/jurnalmengajar/cetak_surat_izin_banyak.php
/var/www/html/moodle/local/jurnalmengajar/lib.php
/var/www/html/moodle/local/jurnalmengajar/exportguruwali_xlsx.php
/var/www/html/moodle/local/jurnalmengajar/settings.php
/var/www/html/moodle/local/jurnalmengajar/export_form.php
/var/www/html/moodle/local/jurnalmengajar/surat_izin_murid_all.php
:~# find /var/www/html/moodle/local/jurnalmengajar/ -type f -daystart -mtime 0
/var/www/html/moodle/local/jurnalmengajar/jurnalguruwali.php
kemaren
:~# find /var/www/html/moodle/local/jurnalmengajar/ -type f -daystart -mtime 1
/var/www/html/moodle/local/jurnalmengajar/delete_layananbk.php
/var/www/html/moodle/local/jurnalmengajar/export_xlsx.php
/var/www/html/moodle/local/jurnalmengajar/cetak_surat_izin.php
/var/www/html/moodle/local/jurnalmengajar/index.php
/var/www/html/moodle/local/jurnalmengajar/delete_pramuka.php
/var/www/html/moodle/local/jurnalmengajar/wali_kelas.php
/var/www/html/moodle/local/jurnalmengajar/izin_murid.php
/var/www/html/moodle/local/jurnalmengajar/riwayat_layananbk.php
/var/www/html/moodle/local/jurnalmengajar/input_surat_izin_guru.php
/var/www/html/moodle/local/jurnalmengajar/exportguruwali_form.php
/var/www/html/moodle/local/jurnalmengajar/cetak_surat_izin_banyak.php
/var/www/html/moodle/local/jurnalmengajar/layananbk.php
/var/www/html/moodle/local/jurnalmengajar/riwayat_pramuka.php
/var/www/html/moodle/local/jurnalmengajar/pembinaan.php
/var/www/html/moodle/local/jurnalmengajar/lib.php
/var/www/html/moodle/local/jurnalmengajar/lang/en/local_jurnalmengajar.php
/var/www/html/moodle/local/jurnalmengajar/lang/id/local_jurnalmengajar.php
/var/www/html/moodle/local/jurnalmengajar/exportguruwali_xlsx.php
/var/www/html/moodle/local/jurnalmengajar/classes/form/layananbk_form.php
/var/www/html/moodle/local/jurnalmengajar/settings.php
/var/www/html/moodle/local/jurnalmengajar/pramuka.php
/var/www/html/moodle/local/jurnalmengajar/export_form.php
/var/www/html/moodle/local/jurnalmengajar/surat_izin_murid_all.php
Guru Duan, untuk mencari file yang di dalamnya terdapat teks “sman 2”, cara paling cepat di Linux (Armbian/Debian) adalah pakai grep.
Langsung jalankan ini:
grep -Ri "sman 2" /var/www/html/moodle/local/jurnalmengajar/
-R = cari rekursif ke semua folder
-i = tidak sensitif huruf besar/kecil (SMAN, sman, Sman tetap kena)
akan tampil: nama file + isi baris yang cocok
grep -Ril "sman 2" /var/www/html/moodle/local/jurnalmengajar/
grep -Rin "sman 2" /var/www/html/moodle/local/jurnalmengajar/
Coba sekalian:
grep -RinE "sman ?2" /var/www/html/moodle/local/jurnalmengajar/
Kadang teks ada di:
file .php
file .mustache (di folder templates)
file .js atau .css
Kalau mau batasi hanya file tertentu:
grep -Rin --include="*.php" "sman 2" /var/www/html/moodle/local/jurnalmengajar/
Kalau nanti sudah ketemu tapi bingung itu dipakai di bagian mana (misalnya muncul di halaman tertentu Moodle), kirim saja hasilnya ke saya—nanti saya bantu telusuri sampai ketahuan asal tampilannya 👍
Siap Guru Duan 👍
Dari hasil itu, Docker hanya dipakai untuk Navidrome saja → aman untuk dihapus kalau memang tidak dipakai lagi.
Saya kasih langkah bersih & aman ya (biar tidak sisa-sisa) 👇
docker stop navidrome
docker rm navidrome
docker rmi deluan/navidrome:latest
systemctl stop docker
systemctl stop containerd
systemctl disable docker
systemctl disable containerd
apt purge docker-ce docker-ce-cli containerd.io -y
apt autoremove -y
Kalau mau benar-benar bersih:
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
systemctl list-units --type=service | grep docker
👉 harusnya sudah tidak ada
Guru akan langsung terasa:
RAM lebih lega 💨
CPU lebih stabil ⚡
tidak ada container “diam-diam makan resource”
Kalau nanti butuh Navidrome lagi:
👉 bisa install tanpa Docker (native) → lebih ringan untuk HG680P
Kalau mau, saya bisa bantu:
✅ install Navidrome tanpa Docker
✅ atau alternatif lebih ringan untuk musik server
👉 Dalam kasus Guru:
✔ Menghapus Docker = keputusan tepat 🔥
✔ Sistem akan lebih cocok untuk STB HG680P
Kalau sudah dihapus, kirim lagi:
top
Saya bantu cek:
👉 apakah PHP masih berat atau sudah normal 👍
Bisa, Guru Duan. MOC (Music On Console) (mocp) memang dibuat dengan model client–server, jadi musik tetap jalan walaupun terminal ditutup.
Ada dua cara yang benar.
Jalankan mocp:
mocp
Setelah musik berjalan, jangan tutup terminal langsung.
Keluar dari interface dengan:
q
Yang terjadi:
Server mocp tetap berjalan
Musik tetap play
Terminal bebas ditutup
Nanti kalau ingin membuka lagi:
mocp
Playlist dan lagu yang sedang diputar akan muncul lagi.
Bisa juga dengan:
mocp -S
Lalu load playlist:
mocp -l playlist.m3u
Kalau ingin stop server:
mocp -x
💡 Tips penting (sering tidak diketahui pengguna baru):
Jika terminal langsung ditutup tanpa menekan q, kadang server mocp ikut mati.
Jadi kebiasaan yang benar:
mocp
→ play lagu
→ tekan q
→ tutup terminal
Kalau Guru Duan mau, saya juga bisa tunjukkan cara membuat mocp otomatis jalan saat login Ubuntu sehingga komputer langsung jadi music server FLAC ringan (<10 MB RAM).
Bisa, Guru Duan 👍
Karena data murid disimpan di alumni.json, kita bisa mengubah nilai tahun dari "-" menjadi 2027 dengan beberapa cara.
Saya jelaskan 3 cara yang paling praktis.
sed di Linux)Jika sebelumnya data seperti ini:
"tahun": "-"
dan ingin diganti menjadi:
"tahun": "2027"
jalankan:
sed -i 's/"tahun": "-"/"tahun": "2027"/g' alumni.json
Semua tanda "-" akan berubah menjadi 2027.
Gunakan Python supaya hanya field tertentu yang diubah.
python3 - << 'EOF'
import json
with open("alumni.json") as f:
data=json.load(f)
for d in data:
if d["tahun"]=="-":
d["tahun"]="2027"
with open("alumni.json","w") as f:
json.dump(data,f,indent=1)
print("Data berhasil diupdate")
EOF
Ini akan:
cari tahun "-"
ubah menjadi 2027
Jika sumber data dari LibreOffice Calc:
ubah kolom tahun menjadi 2027
export lagi CSV
convert ke JSON
gabungkan dengan alumni.json
Upload ke GitHub:
git add alumni.json
git commit -m "update tahun alumni 2027"
git push
Website di Vercel akan update otomatis.
💡 Saran untuk database Guru Duan
Daripada pakai "-" lebih baik pakai:
"tahun": null
atau
"tahun": ""
karena lebih mudah difilter di JavaScript.
Kalau Guru Duan mau, saya bisa juga membuat fitur baru di web:
✔ murid yang belum ada tahun alumni otomatis muncul di menu "Belum Lulus"
✔ ketika lulus tinggal update tahun sekali saja.
ulun berkeksperimen hendak mengetahui kata "wali" yang disebut pada video: Majelis RGA | LIVE PENGAJIAN MALAM JUM'AT 17 JULI 2...