Server Commento Asli dengan Docker Compose

Catatan: ini adalah terjemahan dari postingan saya (Bahasa Inggris), yang menggambarkan implementasi dari server komentar yang digunakan di situs yang sama di mana dokumen asli berada.


TL; Versi DR: Saya mengembangkan konfigurasi server Commento, yang mudah dan sederhana digunakan dalam mode semi-otomatis. Salin repositori ini kepada Anda sendiri dari GitHub dan ikuti instruksi di README .

Beberapa waktu lalu, saya ingin sekali mengubah Disqus - yang mungkin merupakan sistem paling umum untuk menambahkan komentar ke halaman - menjadi Commento yang gratis dan terbuka.


Mengapa berkomentar


Masalah dengan Disqus, seperti banyak produk "gratis" lainnya, adalah bahwa produk dalam hal ini adalah pengguna - yaitu, Anda. Selain itu, Disqus “memperkaya” setiap halaman yang digunakannya dengan megabita skrip dan lebih dari seratus permintaan HTTP tambahan.


Plus, versi gratisnya menampilkan iklan dari mana Anda dapat membayar "hanya" sebesar $ 9 per bulan (paket Plus). Ini saja sudah cukup untuk ingin menemukan sesuatu yang lebih baik.


Pada titik tertentu, saya menemukan posting ini dan mengetahui tentang keberadaan server komentar gratis bernama Commento . Secara kebetulan, Commento baru-baru ini menjadi sangat terbuka - sebelum tersedia dalam dua versi, Komunitas gratis dan Perusahaan komersial. Terima kasih kepada pengembangnya Adhityaa Chandrasekar.


Commento adalah pesanan yang besarnya lebih efisien daripada Disqus, ukuran khas dari beban tambahan dengannya sekitar 11 KB , ditambah komentar itu sendiri, tentu saja. Kira-kira situasi yang sama dengan permintaan HTTP yang diperlukan.


Kelebihan lain dari server Commento adalah sangat cepat, seperti yang tertulis di Go.


Nah, sebagai ceri pada kue, ia memiliki impor komentar dari Disqus, apa lagi yang bisa ia impikan?


Gunakan case untuk Commento


Untuk pengguna yang tidak mahir (secara teknis), Commento memiliki layanan cloud yang siap digunakan di commento.io . Penulis menawarkan Anda untuk memilih sendiri biaya bulanan, tetapi tidak kurang dari $ 3 "untuk alasan teknis."


Bpk. Chandrasekar juga dengan murah hati menawarkan akun gratis di Commento.io dengan imbalan “patch non-sepele” untuk produk tersebut.


Yah, saya memilih opsi ketiga: untuk meningkatkan server Commento sendiri. Dalam hal ini, Anda tidak bergantung pada siapa pun (selain sang hoster, tentu saja), dan saya suka kemerdekaan.


Kesulitan


Saya penggemar berat wadah Docker dan juga sering menggunakan Docker Compose , alat untuk mengelola grup dari beberapa kontainer terkait. Commento memiliki gambar Docker yang siap digunakan di registri kontainer GitLab.


Oleh karena itu, keputusan untuk menggunakan wadah matang dengan sendirinya - tetapi beberapa hal pertama harus diputuskan.


Kesulitan No. 1: PostgreSQL


Commento memerlukan versi terbaru dari server PostgreSQL, sayangnya tidak ada server SQL lain yang didukung.


Yah, kami masih menjalankan semuanya dalam wadah, jadi ini cukup sederhana.


Kesulitan # 2: Tidak Ada Dukungan HTTPS


Commento sendiri adalah server web, tetapi hanya mendukung protokol HTTP yang tidak aman.


Perlu dicatat bahwa praktik ini cukup umum hari ini: dalam hal ini, server tersembunyi di belakang proksi terbalik , yang juga melakukan pembongkaran SSL. Masalahnya adalah bahwa dukungan SSL / HTTPS mutlak diperlukan dalam kasus ini, setelah semua, di halaman 2019 dan melihat upaya untuk mengotorisasi pengguna menggunakan protokol Internet tanpa jaminan akan sangat masam.


Saya memutuskan untuk menggunakan server Nginx , pertama, saya punya banyak pengalaman bekerja dengannya, dan kedua, sangat cepat, ekonomis dan stabil. Dan menerbitkan versi resmi dari gambar Docker .


Bahan kedua dalam resep HTTPS adalah sertifikat SSL untuk domain tersebut. Saya senantiasa berterima kasih kepada EFF dan Mozilla karena telah menciptakan Let's Encrypt Certificate Authority , yang menerbitkan jutaan sertifikat gratis setiap bulan.


Let's Encrypt juga menyediakan utilitas baris perintah gratis yang disebut certbot , yang sangat menyederhanakan proses memperoleh dan memperbarui sertifikat. Nah, dan - tentu saja - gambar Docker untuknya!


Kesulitan # 3: Masalah Telur Ayam Certbot


Tapi trik ini lebih rumit.


Kami ingin merujuk ke sertifikat SSL dalam konfigurasi proksi terbalik kami di Nginx, yang berarti bahwa tanpa sertifikat itu hanya menolak untuk memulai. Pada saat yang sama, untuk mendapatkan sertifikat SSL untuk suatu domain, Anda memerlukan server HTTP yang berfungsi, yang Let's Encrypt akan membuktikan kepemilikan Anda atas domain ini.


Saya berhasil memecahkan masalah ini, dan, menurut saya, cukup elegan:


  1. Pertama, dummy, sertifikat tidak valid dibuat, yang tujuan utamanya adalah untuk membiarkan Nginx memulai.
  2. Nginx dan certbot bersama-sama menerima sertifikat baru yang sekarang valid.
  3. Segera setelah sertifikat diterima, certbot masuk ke "mode siaga", bangun setiap 12 jam untuk memeriksa apakah perlu diperbarui - sesuai dengan rekomendasi dari Let's Encrypt.
  4. Ketika saatnya tiba dan sertifikat telah diperbarui, certbot akan memberi sinyal Nginx untuk memulai kembali.

Kesulitan No. 4: sesuatu harus dilestarikan


Saya sangat curiga bahwa Anda ingin komentar pengguna disimpan setelah reboot atau pembaruan sistem.


Juga, agar Let's Encrypt tidak mencekal Anda karena terlalu sering meminta, alangkah baiknya untuk menyimpan sertifikat yang diterima untuk seluruh tanggal kedaluwarsa.


Kedua poin diselesaikan dalam konfigurasi yang diusulkan menggunakan volume Docker, secara otomatis dibuat oleh systemd ketika Commento pertama kali diluncurkan. Volume ditandai sebagai "eksternal," sehingga Docker melompati mereka ketika menghapus wadah menggunakan docker-compose down -v .


Satukan semuanya


Sekarang Anda bisa melihat bagaimana semuanya bekerja bersama.


Gambar di bawah ini menunjukkan interaksi dan lalu lintas antara empat kontainer:



Saya menerapkan opsi Docker Compose depends_on untuk memastikan bahwa wadah mulai dalam urutan yang benar.


Jika Anda hanya ingin memulai server Commento Anda sendiri, Anda dapat melewati sisa artikel dan langsung menuju ke kode di GitHub .


Baiklah, saya akan berbicara lebih banyak tentang implementasi ini secara lebih rinci nanti.


Bagaimana cara kerjanya?


Tulis File


Seperti yang Anda lihat pada gambar di atas, "komposisi" saya terdiri dari empat layanan:


  1. certbot - utilitas certbot dari EFF
  2. nginx - membalikkan proxy yang menerapkan SSL offloading
  3. app - server Commento
  4. postgres - Database PostgreSQL

File docker-compose.yml berisi deklarasi jaringan Docker-nya sendiri, yang disebut commento_network , dan tiga volume, yang dua di antaranya eksternal (yaitu, harus dibuat di luar Compose):


  • commento_postgres_volume menyimpan data server PostgreSQL untuk Commento: pengguna, moderator, komentar, dll.
  • certbot_etc_volume berisi sertifikat yang diterima oleh certbot .

Nginx


Wadah Nginx dibuat berdasarkan gambar resmi ringan berdasarkan Alpine dan menggunakan skrip berikut untuk menjalankan:


 #!/bin/sh trap exit TERM # Wait for the certificate file to arrive wait_for_certs() { echo 'Waiting for config files from certbot...' i=0 while [[ ! -f /etc/letsencrypt/options-ssl-nginx.conf ]]; do sleep 0.5 [[ $((i++)) -gt 20 ]] && echo 'No files after 10 seconds, aborting' && exit 2 done } # Watches for a "reload flag" (planted by certbot container) file and reloads nginx config once it's there watch_restart_flag() { while :; do [[ -f /var/www/certbot/.nginx-reload ]] && rm -f /var/www/certbot/.nginx-reload && echo 'Reloading nginx' && nginx -s reload sleep 10 done } # Wait for certbot wait_for_certs # Start "reload flag" watcher watch_restart_flag & # Run nginx in the foreground echo 'Starting nginx' exec nginx -g 'daemon off;' 

  • Baris 3 ( ARRGHHH, Habr tidak mendukung tampilan nomor baris dalam kode - kira-kira diterjemahkan. ) Penangan interupsi terdaftar sehingga Nginx dan proses pemantauan latar belakang berhasil menyelesaikan pekerjaan ketika wadah berhenti.
  • Line 27 memanggil fungsi wait, yang menghentikan proses startup Nginx sampai file konfigurasi SSL yang dibuat oleh wadah certbot . Tanpa ini, Nginx akan menolak untuk memulai.
  • Baris 30 menciptakan proses latar belakang yang secara teratur, setiap sepuluh detik, memeriksa keberadaan file flag dengan nama .nginx-reload , dan segera setelah terdeteksi, memerintahkan Nginx untuk memuat ulang konfigurasi. File ini juga membuat certbot ketika sertifikat diperbarui.
  • Baris 34 memulai Nginx dalam mode normal. Dalam hal ini, exec berarti bahwa proses shell saat ini digantikan oleh proses Nginx.

File penting lainnya dalam gambar ini adalah konfigurasi server virtual Commento, yang memaksa Nginx untuk meneruskan permintaan HTTPS ke wadah commento :


 server { listen [::]:443 ssl ipv6only=on; listen 443 ssl; server_tokens off; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name __DOMAIN__; location / { proxy_pass http://app:8080/; 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; } ssl_certificate /etc/letsencrypt/live/__DOMAIN__/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/__DOMAIN__/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { listen 80 default_server; listen [::]:80 default_server; server_tokens off; server_name __DOMAIN__; location /.well-known/acme-challenge/ { root /var/www/certbot; } # Redirect to HTTPS on port 80 location / { return 301 https://$host$request_uri; } } 

Blok server pertama (baris 1-21 ) menjelaskan cara bekerja dengan HTTPS dan aturan penerusan. Di sinilah file sertifikat Mari Enkripsi disebutkan (atau bertopik digunakan sebagai gantinya).


Domain yang dilayani oleh server dilewatkan sebagai argumen saat membangun gambar; ia menggantikan baris __DOMAIN__ pada konfigurasi server.


Blok kedua (baris 23-38 ) adalah konfigurasi server HTTP, yang digunakan oleh certbot untuk mengkonfirmasi kepemilikan domain (yang disebut "tantangan ACME"). Semua permintaan lain menyebabkan pengalihan ke alamat yang sesuai melalui HTTPS.


certbot


Gambar certbot kami didasarkan pada bangunan resmi dengan skrip berikut:


 #!/bin/sh trap exit TERM # Wait until nginx is up and running, up to 10 seconds wait_for_nginx() { echo 'Waiting for nginx...' i=0 while ! nc -z nginx 80 &>/dev/null; do sleep 0.5 [[ $((i++)) -gt 20 ]] && echo "nginx isn't online after 10 seconds, aborting" && exit 4 done echo 'nginx is up and running' } # Check vars [[ -z "$DOMAIN" ]] && echo "Environment variable 'DOMAIN' isn't defined" && exit 2 [[ -z "$EMAIL" ]] && echo "Environment variable 'EMAIL' isn't defined" && exit 2 TEST="${TEST:-false}" # Check external mounts data_dir='/etc/letsencrypt' www_dir='/var/www/certbot' [[ ! -d "$data_dir" ]] && echo "Directory $data_dir must be externally mounted" [[ ! -d "$www_dir" ]] && echo "Directory $www_dir must be externally mounted" # If the config/certificates haven't been initialised yet if [[ ! -e "$data_dir/options-ssl-nginx.conf" ]]; then # Copy config over from the initial location echo 'Initialising nginx config' cp /conf/options-ssl-nginx.conf /conf/ssl-dhparams.pem "$data_dir/" # Copy dummy certificates mkdir -p "$data_dir/live/$DOMAIN" cp /conf/privkey.pem /conf/fullchain.pem "$data_dir/live/$DOMAIN/" # Wait for nginx wait_for_nginx # Remove dummy certificates rm -rf "$data_dir/live/$DOMAIN/" # Run certbot to validate/renew certificate test_arg= $TEST && test_arg='--test-cert' certbot certonly --webroot -w /var/www/certbot -n -d "$DOMAIN" $test_arg -m "$EMAIL" --rsa-key-size 4096 --agree-tos --force-renewal # Reload nginx config touch /var/www/certbot/.nginx-reload # nginx config has been already initialised - just give nginx time to come up else wait_for_nginx fi # Run certbot in a loop for renewals while :; do certbot renew # Reload nginx config touch /var/www/certbot/.nginx-reload sleep 12h done 

Tur singkat tentang garis-garisnya:


  • Baris 3 , seperti pada skrip sebelumnya, diperlukan untuk melengkapi wadah secara teratur.
  • Baris 17-19 memeriksa variabel yang diperlukan.
  • Dan di baris 22-25 - bahwa direktori yang diperlukan untuk certbot berfungsi sudah terpasang dengan benar.
  • Garpu berikut:
    • Baris 30-50 dieksekusi hanya pada awal pertama wadah:
      • Sertifikat tiruan disalin, memungkinkan Nginx untuk memulai secara normal.
      • Nginx, sementara itu, menunggu akhir dari proses ini, setelah itu terus mengunduh.
      • Setelah Nginx dimulai, certbot memulai proses untuk mendapatkan sertifikat yang valid dari Let's Encrypt.
      • Dan akhirnya, segera setelah sertifikat diterima, file .nginx-reload dibuat, mengisyaratkan kepada Nginx bahwa sudah waktunya untuk memuat ulang konfigurasi.
    • Baris 54 menunggu Nginx untuk memulai - dalam kasus ketika sertifikat lengkap sudah tersedia.
  • Setelah semua ini (baris 58-63 ), ia terus berputar, setiap 12 jam sekali memeriksa kebutuhan untuk memperbarui sertifikat dan memberi tanda Nginx untuk memulai kembali.

Commento dan PostgreSQL


app dan wadah postgres menggunakan gambar asli yang disediakan oleh pengembang tanpa perubahan apa pun.


Layanan Systemd


Bagian terakhir dari teka-teki ini adalah file unit systemd commento.service , di mana Anda perlu membuat symlink di /etc/systemd/system/commento.service sehingga itu dimulai pada saat yang tepat ketika sistem dimulai:


 [Unit] Description=Commento server [Service] TimeoutStopSec=30 WorkingDirectory=/opt/commento ExecStartPre=-/usr/bin/docker volume create commento_postgres_volume ExecStartPre=-/usr/bin/docker volume create certbot_etc_volume ExecStartPre=-/usr/local/bin/docker-compose -p commento down -v ExecStart=/usr/local/bin/docker-compose -p commento up --abort-on-container-exit ExecStop=/usr/local/bin/docker-compose -p commento down -v [Install] WantedBy=multi-user.target 

Baris:


  • Baris 6 menyiratkan bahwa kode proyek diklon ke direktori /opt/commento - ini jauh lebih sederhana.
  • Baris 7-8 membuat volume eksternal, jika belum.
  • Pada baris 9 , sisa-sisa yang mungkin dari wadah sebelumnya dihapus. Volume eksternal dipertahankan.
  • Baris 10 menandai peluncuran Docker Compose yang sebenarnya. --abort-on-container-exit seluruh kawanan kontainer ketika salah satu dari mereka --abort-on-container-exit . Berkat ini, systemd setidaknya akan menyadari bahwa layanan dihentikan.
  • Saluran 11 lagi-lagi membersihkan dan menghapus wadah, jaringan, dan volume.

Kode sumber


Implementasi yang berfungsi penuh, hanya membutuhkan konfigurasi variabel di docker-compose.yml , tersedia di GitHub . Anda hanya perlu mengikuti langkah-langkah yang dijelaskan dalam README dengan hati-hati.


Kode ini tunduk pada Lisensi MIT .


Terima kasih sudah membaca ke tempat ini, komentarnya disambut dengan panik!

Source: https://habr.com/ru/post/id464105/


All Articles