Lewati ke konten

Cara Menambah Blok HTTPS

Asisten TrainerBelum diujiArti badge ini

Panduan ini menerangkan letak setiap baris yang perlu ditambahkan, dan urutan pengerjaannya. Ada dua berkas di repository dan satu berkas yang dibuat di VM.

Berkas Di mana Siapa yang membuat
nginx.conf repository fork Peserta, disunting dari laptop
docker-compose.yml repository fork Peserta, disunting dari laptop
tls/aktifkan.conf VM, di /opt/webgis/app/tls/ Dibuat di VM setelah sertifikat terbit

Berkas versi modul berisi satu blok server dengan listen 80 dan empat location. Ada dua tempat yang perlu diubah.

1a. Tambahkan blok ACME di dalam blok server

Section titled “1a. Tambahkan blok ACME di dalam blok server”

Letakkannya setelah baris server_name dan sebelum location = /. Blok ACME harus berada di dalam server { }, bukan di luarnya.

server {
listen 80;
server_name _;
location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
default_type "text/plain";
try_files $uri =404;
}
location = / {
return 302 /portal;
}
...location lain tetap apa adanya...
}

Arti ^~: bila cocok, Nginx berhenti mencari dan memakai blok ini. Tanpa ^~, permintaan /.well-known/acme-challenge/... akan jatuh ke location / dan diteruskan ke Next.js.

root /var/www/certbot menunjuk ke dalam container, bukan ke VM. Pemetaannya diurus volume pada bagian 2.

1b. Tambahkan include di akhir berkas, di luar blok server

Section titled “1b. Tambahkan include di akhir berkas, di luar blok server”
}
include /etc/nginx/tls/*.conf;

Baris include ini harus di luar server { }, karena berkas yang di-include berisi blok server utuh. Kalau include ditaruh di dalam server, Nginx akan mengeluh "server" directive is not allowed here.

Direktori /etc/nginx/tls/ juga menunjuk ke dalam container. Pemetaannya di bagian 2.

Wildcard * dipakai dengan sengaja: sebelum sertifikat terbit, direktori itu kosong dan tidak ada yang di-include, sehingga Nginx tetap bisa start. Setelah sertifikat terbit, baru berkasnya dibuat dan Nginx dimuat ulang.


Pada service nginx, tambahkan satu port dan tiga volume.

nginx:
image: nginx:1.27-alpine
container_name: nginx_proxy
depends_on:
- nextjs
- geoserver
ports:
- "80:80"
- "443:443" # tambahan
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./certbot-webroot:/var/www/certbot:ro # tambahan, untuk ACME
- ./tls:/etc/nginx/tls:ro # tambahan, untuk server block 443
- /etc/letsencrypt:/etc/letsencrypt:ro # tambahan, untuk sertifikat
networks:
- app-network
restart: unless-stopped

Perhatikan bahwa ./certbot-webroot dan ./tls bersifat relatif terhadap folder repository di VM, yaitu /opt/webgis/app. Jadi:

./certbot-webroot -> /opt/webgis/app/certbot-webroot
./tls -> /opt/webgis/app/tls

Kedua direktori itu sudah dibuat oleh Tahap 6 modul dengan perintah mkdir -p certbot-webroot tls, jadi tidak perlu dibuat lagi.

Mount /etc/letsencrypt memakai jalur absolut karena menunjuk ke lokasi di VM, bukan di dalam repository. Ini juga sebabnya direktori itu tidak bisa ditulis relatif.

Volume Isi Kenapa perlu
./certbot-webroot:/var/www/certbot berkas challenge Certbot menulis ke VM, Nginx membacanya di container
./tls:/etc/nginx/tls aktifkan.conf tempat server block 443 diletakkan
/etc/letsencrypt:/etc/letsencrypt sertifikat Nginx harus bisa membaca fullchain.pem dan privkey.pem

Tanpa mount ketiga, nginx -t gagal dengan pesan bahwa berkas sertifikat tidak ditemukan, walaupun sertifikatnya ada di VM.


Kedua perubahan itu tersedia sebagai berkas jadi di Berkas Alat dan Perbaikan: perbaikan/nginx.conf dan perbaikan/docker-compose.yml. Keduanya bisa dibandingkan langsung dengan berkas modul.

Berkas ini dibuat di VM, bukan di repository. Isinya blok server utuh untuk port 443, bukan tiga directive lepas seperti pada modul Tahap 10.

server {
listen 443 ssl;
http2 on;
server_name SUBDOMAIN;
ssl_certificate /etc/letsencrypt/live/SUBDOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/SUBDOMAIN/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location = / {
return 302 /portal;
}
location = /geoserver {
return 302 /geoserver/web;
}
location /geoserver/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $geoserver_upstream http://geoserver:8080;
rewrite ^/geoserver/(.*)$ /geoserver/$1 break;
proxy_pass $geoserver_upstream;
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 https;
}
location / {
resolver 127.0.0.11 valid=10s ipv6=off;
set $nextjs_upstream http://nextjs:3000;
proxy_pass $nextjs_upstream;
proxy_http_version 1.1;
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;
}
}

Ganti SUBDOMAIN dengan subdomain peserta. Blok 443 memuat location yang sama dengan blok 80, karena Nginx memilih blok berdasarkan port, bukan berbagi location antar blok.

X-Forwarded-Proto https ditulis tetap, bukan $scheme, karena aplikasi berada di balik Nginx yang sudah menangani TLS. NextAuth memakai header ini untuk menentukan apakah cookie sesi bertanda Secure.


Urutan ini penting. Menjalankan Certbot sebelum Nginx siap akan gagal dan menghabiskan kuota penerbitan sertifikat.

Langkah 1, dari laptop. Sunting nginx.conf dan docker-compose.yml, lalu:

Terminal window
git add nginx.conf docker-compose.yml
git commit -m "fix: tambah blok ACME dan dukungan HTTPS"
git push origin main

Langkah 2, dari Cloud Shell, di VM. Tarik perubahan dan buat ulang container Nginx:

Terminal window
gcloud compute ssh "$VM_NAME" \
--zone="$ZONE" --tunnel-through-iap \
--command='cd /opt/webgis/app && git pull --ff-only && \
sudo docker compose up -d nginx && sudo docker compose ps'

docker compose up -d nginx cukup, tidak perlu up -d seluruh service. Perintah itu membuat ulang container Nginx karena konfigurasinya berubah.

Langkah 3, periksa jalur ACME. Ini yang harus dijalankan sebelum Certbot:

Terminal window
curl -sS -o /dev/null -w "acme %{http_code}\n" \
"http://$SUBDOMAIN/.well-known/acme-challenge/uji"

Harus 404. Bila 502 atau 200, artinya permintaan masih diteruskan ke Next.js, dan blok ACME belum terbaca. Periksa dengan:

Terminal window
gcloud compute ssh "$VM_NAME" \
--zone="$ZONE" --tunnel-through-iap \
--command='sudo docker exec nginx_proxy nginx -T | grep -A3 acme'

Langkah 4, terbitkan sertifikat. Sama seperti Tahap 9 modul:

Terminal window
gcloud compute ssh "$VM_NAME" \
--zone="$ZONE" --tunnel-through-iap \
--command="cd /opt/webgis/app && sudo certbot certonly --webroot \
-w /opt/webgis/app/certbot-webroot -d $SUBDOMAIN \
--non-interactive --agree-tos -m $EMAIL"

Langkah 5, tulis server block 443 di VM. Ganti SUBDOMAIN dengan nilai sebenarnya:

Terminal window
gcloud compute ssh "$VM_NAME" \
--zone="$ZONE" --tunnel-through-iap \
--command='sudo tee /opt/webgis/app/tls/aktifkan.conf >/dev/null' <<'EOF'
server {
listen 443 ssl;
server_name SUBDOMAIN;
ssl_certificate /etc/letsencrypt/live/SUBDOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/SUBDOMAIN/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location = / { return 302 /portal; }
location / {
resolver 127.0.0.11 valid=10s ipv6=off;
set $nextjs_upstream http://nextjs:3000;
proxy_pass $nextjs_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
}
}
EOF

Ganti kedua SUBDOMAIN sebelum menjalankannya. Untuk perintah yang lebih panjang, menyunting berkasnya di VM dengan nano /opt/webgis/app/tls/aktifkan.conf lebih mudah dibaca.

Langkah 6, periksa dan muat ulang:

Terminal window
gcloud compute ssh "$VM_NAME" \
--zone="$ZONE" --tunnel-through-iap \
--command='cd /opt/webgis/app && sudo docker compose exec -T nginx nginx -t && \
sudo docker compose exec -T nginx nginx -s reload'

nginx -t harus lulus sebelum reload. Bila gagal, jangan dilanjutkan.

Langkah 7, verifikasi:

Terminal window
curl -sSIL --max-redirs 3 "https://$SUBDOMAIN/portal"

Harus 200.


Penyebab paling sering, berurutan:

Pesan Sebab Perbaikan
"server" directive is not allowed here include ditaruh di dalam server { } Pindahkan ke luar blok
cannot load certificate ... No such file /etc/letsencrypt tidak di-mount Tambahkan volume ketiga
host not found in upstream resolver hilang di salah satu location Tambahkan resolver 127.0.0.11
bind() to 0.0.0.0:443 failed port 443 belum dipublikasikan Tambahkan - "443:443"

Untuk melihat konfigurasi yang benar-benar dibaca container:

Terminal window
sudo docker exec nginx_proxy nginx -T

Perintah itu mencetak konfigurasi lengkap setelah semua include diproses. Ini cara tercepat memastikan blok ACME dan blok 443 benar-benar terbaca.


Sertifikat Let’s Encrypt berlaku 90 hari dan diperbarui otomatis. Nginx perlu dimuat ulang agar memakai berkas baru. Modul Tahap 12 sudah menyiapkan hook untuk itu:

Terminal window
sudo certbot renew --dry-run

Hook reload-nginx.sh menjalankan docker compose exec -T nginx nginx -s reload setiap kali sertifikat diperbarui.


Skrip uji-subdomain.mjs menjalankan pemeriksaan berurutan: resolusi DNS, akses HTTP, kesiapan jalur ACME, lalu keabsahan sertifikat. Urutannya sengaja, supaya Anda tidak menjalankan Certbot sebelum syaratnya siap.

Terminal window
node uji-subdomain.mjs nama01.gisbigtrainer.com --ip ALAMAT_IP_STATIS

Skrip periksa-deploy.mjs memeriksa berkasnya sebelum di-push:

Terminal window
node periksa-deploy.mjs /path/ke/file-latihan

Keduanya ada di Berkas Alat dan Perbaikan.