One place for hosting & domains

      dengan

      Cara Menginstal dan Menyiapkan Laravel dengan Docker Compose pada Ubuntu 20.04


      Pengantar

      Kontainerisasi aplikasi mengacu pada suatu proses adaptasi aplikasi dan komponennya dengan tujuan agar dapat menjalankannya dalam lingkungan ringan yang dikenal sebagai kontainer. Lingkungan tersebut terisolasi dan dapat dibuang, serta dapat dimanfaatkan lebih lanjut untuk pengembangan, pengujian, dan penyebaran aplikasi hingga produksi.

      Dalam panduan ini, kita akan menggunakan Docker Compose untuk melakukan kontainerisasi aplikasi Laravel sebagai pengembangan. Ketika selesai, Anda akan memiliki aplikasi Laravel demo yang berjalan di tiga kontainer layanan terpisah:

      • Layanan app yang menjalankan PHP7.4-FPM;
      • Layanan db yang menjalankan MySQL 5.7;
      • Layanan nginx yang menggunakan layanan app untuk mengurai kode PHP sebelum menyajikan aplikasi Laravel ke pengguna akhir.

      Untuk mengizinkan proses pengembangan yang lebih efisien dan memfasilitasi pengawakutuan aplikasi, kita akan membuat berkas aplikasi tetap sinkron menggunakan volume bersama. Kita juga akan melihat cara menggunakan perintah docker-compose exec untuk menjalankan Composer dan Artisan di kontainer app.

      Prasyarat

      Langkah 1 — Memperoleh Aplikasi Demo

      Untuk memulai, kita akan mengambil aplikasi Laravel demo dari repositori Github. Kita tertarik dengan cabang tutorial-01, yang mengandung aplikasi Laravel dasar yang telah kita ciptakan dalam panduan pertama dari seri ini.

      Untuk memperoleh kode aplikasi yang kompatibel dengan tutorial ini, unduh rilis tutorial-1.0.1 ke direktori rumah dengan:

      • cd ~
      • curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zip

      Kita akan memerlukan perintah unzip untuk membongkar kode aplikasi. Jika Anda belum menginstal paket ini sebelumnya, lakukan sekarang dengan:

      • sudo apt update
      • sudo apt install unzip

      Sekarang, lakukan unzip konten aplikasi dan ganti nama direktori yang belum dibongkar untuk memudahkan akses:

      • unzip travellist.zip
      • mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo

      Bernavigasilah ke direktori travellist-demo:

      Dalam langkah selanjutnya, kita akan menciptakan berkas konfigurasi .env untuk menyiapkan aplikasi.

      Langkah 2 — Menyiapkan Berkas .env Aplikasi

      Berkas konfigurasi Laravel terletak di dalam direktori yang bernama config, di dalam direktori root aplikasi. Sebagai tambahan, berkas .env digunakan untuk menyiapkan konfigurasi dependen lingkungan, seperti kredensial dan informasi apa pun yang mungkin bervariasi di antara penyebaran. Berkas ini tidak disertakan dalam kontrol revisi.

      Peringatan: Berkas konfigurasi lingkungan berisi informasi sensitif tentang server Anda, termasuk kredensial basis data dan kunci keamanan. Dengan alasan itu, Anda jangan pernah membagikan berkas ini secara publik.

      Nilai-nilai yang terkandung di dalam berkas .env akan lebih diutamakan daripada nilai-nilai yang ditetapkan dalam berkas konfigurasi reguler yang terletak di direktori config. Setiap instalasi pada lingkungan baru membutuhkan berkas lingkungan yang dibuat khusus untuk menentukan hal-hal seperti pengaturan koneksi basis data, opsi awakutu, URL aplikasi, di antara hal-hal lainnya yang mungkin dapat bervariasi tergantung pada lingkungan aplikasi yang berjalan.

      Sekarang kita akan menciptakan berkas .env baru untuk menyesuaikan opsi konfigurasi lingkungan pengembangan yang kita siapkan. Laravel disertakan dengan berkas .env contoh yang dapat kita salin untuk menciptakan berkas sendiri:

      Buka berkas ini menggunakan nano atau editor teks pilihan Anda:

      Berkas .env saat ini dari aplikasi demo travellist berisi pengaturan untuk menggunakan basis data MySQL lokal, dengan 127.0.0.1 sebagai hos basis data. Kita perlu memperbarui variabel DB_HOST, sehingga mengarah ke layanan basis data yang akan kita ciptakan dalam lingkungan Docker. Dalam panduan ini, kita akan menyebut layanan basis data kita db. Lanjutkan dan ganti nilai yang tercantum di DB_HOST dengan nama layanan basis data:

      .env

      APP_NAME=Travellist
      APP_ENV=dev
      APP_KEY=
      APP_DEBUG=true
      APP_URL=http://localhost:8000
      
      LOG_CHANNEL=stack
      
      DB_CONNECTION=mysql
      DB_HOST=db
      DB_PORT=3306
      DB_DATABASE=travellist
      DB_USERNAME=travellist_user
      DB_PASSWORD=password
      ...
      

      Silakan mengubah nama basis data, nama pengguna, dan kata sandi, jika Anda ingin. Variabel-variabel ini akan digunakan dalam langkah selanjutnya saat kita akan menyiapkan berkas docker-compose.yml untuk mengonfigurasi layanan kita.

      Simpan berkas itu saat Anda selesai mengedit. Jika menggunakan nano, Anda dapat melakukannya dengan menekan Ctrl+x, lalu Y, dan Enter untuk mengonfirmasi.

      Langkah 3 — Menyiapkan Dockerfile Aplikasi

      Meskipun kedua layanan MySQL dan Nginx akan berdasarkan citra asali yang diperoleh dari Docker Hub, kita tetap perlu membangun citra khusus untuk kontainer aplikasi. Kita akan menciptakan Dockerfile yang baru untuk itu.

      Citra travellist kita akan berdasarkan citra PHP resmi php:7.4-fpm dari Docker Hub. Selain lingkungan PHP-FPM dasar tersebut, kita akan menginstal beberapa modul PHP tambahan dan alat manajemen dependensi Composer.

      Kita juga akan menciptakan pengguna sistem baru; ini diperlukan untuk mengeksekusi perintah artisan dan composer ketika mengembangkan aplikasi. Pengaturan uid memastikan bahwa pengguna di dalam kontainer memiliki uid yang sama seperti pengguna sistem di mesin hos, tempat Anda menjalankan Docker. Dengan cara ini, berkas apa pun yang diciptakan oleh perintah-perintah ini direplikasi di dalam hos dengan izin yang benar. Ini juga berarti Anda dapat menggunakan editor kode pilihan Anda di mesin hos untuk mengembangkan aplikasi yang berjalan di dalam kontainer.

      Buat Dockerfile yang baru dengan:

      Salin konten berikut ke Dockerfile Anda:

      Dockerfile

      FROM php:7.4-fpm
      
      # Arguments defined in docker-compose.yml
      ARG user
      ARG uid
      
      # Install system dependencies
      RUN apt-get update && apt-get install -y 
          git 
          curl 
          libpng-dev 
          libonig-dev 
          libxml2-dev 
          zip 
          unzip
      
      # Clear cache
      RUN apt-get clean && rm -rf /var/lib/apt/lists/*
      
      # Install PHP extensions
      RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
      
      # Get latest Composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      
      # Create system user to run Composer and Artisan Commands
      RUN useradd -G www-data,root -u $uid -d /home/$user $user
      RUN mkdir -p /home/$user/.composer && 
          chown -R $user:$user /home/$user
      
      # Set working directory
      WORKDIR /var/www
      
      USER $user
      
      

      Jangan lupa simpan berkas itu saat Anda selesai.

      Dockerfile dimulai dengan menentukan citra dasar yang kita gunakan: php:7.4-fpm.

      Setelah menginstal paket sistem dan ekstensi PHP, kita menginstal Composer dengan menyalin perintah composer yang dapat dieksekusi dari citra resmi terbarunya ke citra aplikasi kita.

      Pengguna sistem baru kemudian diciptakan dan disiapkan dengan menggunakan argumen user dan uid yang dinyatakan di awal Dockerfile. Nilai-nilai ini akan dimasukkan oleh Docker Compose saat pembangunan.

      Terakhir, kita mengatur dir kerja asali sebagai /var/www dan mengganti ke pengguna yang baru diciptakan. Ini akan memastikan Anda terhubung sebagai pengguna reguler, dan berada di direktori yang tepat, saat menjalankan perintah composer dan artisan di kontainer aplikasi.

      Langkah 4 — Menyiapkan Konfigurasi Nginx dan Berkas Buangan Basis Data

      Ketika menciptakan lingkungan pengembangan dengan Docker Compose, seringkali diperlukan untuk berbagi berkas konfigurasi atau inisialisasi dengan kontainer layanan, yang bertujuan menyiapkan atau melakukan bootstrap terhadap layanan tersebut. Praktik ini memfasilitasi pembuatan perubahan terhadap berkas konfigurasi untuk menyetel lingkungan saat Anda mengembangkan aplikasi.

      Sekarang kita akan menyiapkan folder dengan berkas yang akan digunakan untuk mengonfigurasi dan menginisialisasi kontainer layanan.

      Untuk menyiapkan Nginx, kita akan berbagi berkas travellist.conf yang akan mengonfigurasi cara penyajian aplikasi. Buat folder docker-compose/nginx dengan:

      • mkdir -p docker-compose/nginx

      Buka berkas baru yang bernama travellist.conf di dalam direktori itu:

      • nano docker-compose/nginx/travellist.conf

      Salin konfigurasi Nginx berikut ke berkas itu:

      docker-compose/nginx/travellist.conf

      
      server {
          listen 80;
          index index.php index.html;
          error_log  /var/log/nginx/error.log;
          access_log /var/log/nginx/access.log;
          root /var/www/public;
          location ~ .php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+.php)(/.+)$;
              fastcgi_pass app:9000;
              fastcgi_index index.php;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
          }
          location / {
              try_files $uri $uri/ /index.php?$query_string;
              gzip_static on;
          }
      }
      

      Berkas ini akan mengonfigurasi Nginx untuk mendengarkan porta 80 dan menggunakan index.php sebagai laman indeks asali. Ini akan menetapkan root dokumen menjadi /var/www/public, lalu mengonfigurasi Nginx untuk menggunakan layanan app pada porta 9000 yang memproses berkas *.php.

      Simpan dan tutup berkas setelah Anda selesai mengedit.

      Untuk menyiapkan basis data MySQL, kita akan berbagi buangan basis data yang akan diimpor saat kontainer diinisialisasi. Ini adalah fitur yang yang disediakan oleh citra MySQL 5.7 yang akan kita gunakan pada kontainer itu.

      Buat folder baru untuk berkas inisialisasi MySQL Anda di dalam folder docker-compose:

      • mkdir docker-compose/mysql

      Buka berkas .sql yang baru:

      • nano docker-compose/mysql/init_db.sql

      Buangan MySQL berikut ini berdasarkan basis data yang telah kita siapkan dalam panduan Laravel pada LEMP dari kami. Ini akan menciptakan tabel baru yang bernama places. Lalu, tabel akan terisi dengan serangkaian tempat sampel.

      Tambahkan kode berikut ke berkas:

      docker-compose/mysql/db_init.sql

      DROP TABLE IF EXISTS `places`;
      
      CREATE TABLE `places` (
        `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
        `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
        `visited` tinyint(1) NOT NULL DEFAULT '0',
        PRIMARY KEY (`id`)
      ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
      
      INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);
      

      Tabel places berisi tiga bidang: id, name, dan visited. Bidang visited adalah bendera yang digunakan untuk mengidentifikasi tempat-tempat yang masih harus* dikunjungi*. Silakan ganti tempat sampel atau masukkan tempat yang baru. Simpan dan tutup berkas setelah Anda selesai.

      Kita telah selesai menyiapkan Dockerfile aplikasi dan berkas konfigurasi layanan. Selanjutnya, kita akan menyiapkan Docker Compose untuk menggunakan berkas-berkas ini saat menciptakan layanan kita.

      Langkah 5 — Menciptakan Lingkungan Multi-Kontainer dengan Docker Compose

      Docker Compose memungkinkan Anda menciptakan lingkungan multi-kontainer untuk aplikasi yang berjalan pada Docker. Ini menggunakan definisi layanan untuk sepenuhnya membangun lingkungan yang dapat disesuaikan dengan beberapa kontainer yang dapat berbagi volume data dan jaringan. Ini memungkinkan integrasi tanpa hambatan di antara komponen aplikasi.

      Untuk menyiapkan definisi layanan, kita akan menciptakan berkas baru yang bernama docker-compose.yml. Biasanya, berkas ini berada di root dari folder aplikasi, dan mendefinisikan lingkungan terkontainerisasi, termasuk citra dasar yang Anda gunakan untuk membangun kontainer, dan bagaimana layanan Anda berinteraksi.

      Kita akan mendefinisikan tiga layanan berbeda dalam berkas docker-compose.yml: app, db, dan nginx.

      Layanan app akan membangun citra yang disebut travellist, berdasarkan Dockerfile yang kita ciptakan sebelumnya. Kontainer yang didefinisikan oleh layanan ini akan menjalankan server php-fpm untuk mengurai kode PHP dan mengirim hasilnya kembali ke layanan nginx, yang akan berjalan pada kontainer terpisah. Layanan mysql mendefinisikan kontainer yang menjalankan server MySQL 5.7. Layanan kita akan berbagi jaringan jembatan bernama travellist.

      Berkas aplikasi akan disinkronkan baik pada layanan app dan nginx melalui bind mounts. Bind mounts berguna dalam lingkungan pengembangan karena mengizinkan sinkronisasi dua arah dengan performa yang baik antara mesin hos dan kontainer.

      Buat berkas docker-compose.yml baru di root dari folder aplikasi:

      Berkas docker-compose.yml khusus dimulai dengan definisi versi, diikuti oleh node services, yang mendefinisikan semua layanan. Jaringan bersama biasanya didefinisikan di bagian bawah berkas itu.

      Untuk memulai, salin kode boilerplate ini ke berkas docker-compose.yml:

      docker-compose.yml

      version: "3.7"
      services:
      
      
      networks:
        travellist:
          driver: bridge
      

      Sekarang kita akan mengedit node services untuk menyertakan layanan app, db, dan nginx.

      Layanan app

      Layanan app akan menyiapkan kontainer bernama travellist-app. Ini membangun citra Docker baru berdasarkan Dockerfile yang terletak di jalur yang sama seperti berkas docker-compose.yml. Citra baru akan disimpan secara lokal dengan nama travellist.

      Meskipun root dokumen yang disajikan sebagai aplikasi berada di dalam kontainer nginx, kita juga memerlukan berkas aplikasi di suatu tempat di dalam kontainer app, sehingga kita dapat melaksanakan tugas baris perintah dengan alat Laravel Artisan.

      Salin definisi layanan berikut di bawah node services, di dalam berkas docker-compose.yml:

      docker-compose.yml

        app:
          build:
            args:
              user: sammy
              uid: 1000
            context: ./
            dockerfile: Dockerfile
          image: travellist
          container_name: travellist-app
          restart: unless-stopped
          working_dir: /var/www/
          volumes:
            - ./:/var/www
          networks:
            - travellist
      

      Pengaturan ini melakukan yang berikut:

      • build: Konfigurasi ini memberi tahu Docker Compose untuk membangun citra lokal layanan app, menggunakan jalur yang ditentukan (context) dan Dockerfile untuk instruksi. Argumen user dan uid dimasukkan ke Dockerfile untuk menyesuaikan perintah penciptaan pengguna saat pembangunan.
      • image: Nama yang akan digunakan untuk citra yang sedang dibangun.
      • container_name: Menyiapkan nama kontainer untuk layanan ini.
      • restart: Selalu mulai ulang, kecuali layanan dihentikan.
      • working_dir: Menetapkan direktori asali untuk layanan ini sebagai /var/www.
      • volumes: Menciptakan volume bersama yang akan menyinkronkan konten dari direktori saat ini dengan /var/www di dalam kontainer. Perhatikan bahwa ini bukan root dokumen Anda, karena itu akan hidup di dalam kontainer nginx.
      • networks: Menyiapkan layanan ini untuk menggunakan jaringan yang bernama travellist.

      Layanan db

      Layanan db menggunakan citra MySQL 5.7 yang telah disiapkan sebelumnya dari Docker Hub. Karena Docker Compose secara otomatis memuat berkas variabel .env yang terletak di dalam direktori yang sama dengan berkas docker-compose.yml, kita dapat memperoleh pengaturan basis data dari berkas .env Laravel yang kita ciptakan dalam langkah sebelumnya.

      Sertakan definisi layanan berikut di node services Anda, tepat setelah layanan app:

      docker-compose.yml

        db:
          image: mysql:5.7
          container_name: travellist-db
          restart: unless-stopped
          environment:
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
            MYSQL_PASSWORD: ${DB_PASSWORD}
            MYSQL_USER: ${DB_USERNAME}
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
          volumes:
            - ./docker-compose/mysql:/docker-entrypoint-initdb.d
          networks:
            - travellist
      

      Pengaturan ini melakukan yang berikut:

      • image: Menetapkan citra Docker yang harus digunakan untuk kontainer ini. Dalam kasus ini, kita menggunakan citra MySQL 5.7 dari Docker Hub.
      • container_name: Menyiapkan nama kontainer untuk layanan ini: travellist-db.
      • restart: Selalu mulai ulang layanan ini, kecuali jika layanan secara eksplisit dihentikan.
      • environment: Menetapkan variabel lingkungan di dalam kontainer baru. Kita menggunakan nilai yang diperoleh dari berkas .env Laravel untuk menyiapkan layanan MySQL, yang secara otomatis akan menciptakan pengguna dan basis data baru berdasarkan variabel lingkungan yang disediakan.
      • volumes: Menciptakan volume untuk berbagi buangan basis data .sql yang akan digunakan untuk menginisialisasi basis data aplikasi. Citra MySQL akan secara otomatis mengimpor berkas .sql yang ditempatkan di direktori /docker-entrypoint-initdb.d di dalam kontainer.
      • networks: Menyiapkan layanan ini untuk menggunakan jaringan yang bernama travellist.

      Layanan nginx

      Layanan nginx menggunakan citra Nginx yang telah disiapkan sebelumnya di atas Alpine, distribusi Linux yang ringan. Ini menciptakan kontainer bernama travellist-nginx, dan menggunakan definisi ports untuk menciptakan pengarahan ulang dari porta 8000 pada sistem hos ke porta 80 di dalam kontainer.

      Sertakan definisi layanan berikut di node services, tepat setelah layanan db:

      docker-compose.yml

        nginx:
          image: nginx:1.17-alpine
          container_name: travellist-nginx
          restart: unless-stopped
          ports:
            - 8000:80
          volumes:
            - ./:/var/www
            - ./docker-compose/nginx:/etc/nginx/conf.d
          networks:
            - travellist
      

      Pengaturan ini melakukan yang berikut:

      • image: Menetapkan citra Docker yang harus digunakan untuk kontainer ini. Dalam kasus ini, kita menggunakan citra Alpine Nginx 1.17.
      • container_name: Menyiapkan nama kontainer untuk layanan ini: travellist-nginx.
      • restart: Selalu mulai ulang layanan ini, kecuali jika layanan secara eksplisit dihentikan.
      • ports: Menyiapkan pengarahan ulang porta yang akan mengizinkan akses eksternal melalui porta 8000 ke server web yang berjalan di porta 80 di dalam kontainer.
      • volumes: Menciptakan dua volume bersama. Yang pertama akan melakukan sinkronisasi konten dari direktori saat ini dengan /var/www di dalam kontainer. Dengan cara ini, saat Anda melakukan perubahan lokal pada berkas aplikasi, itu akan segera tercermin dengan cepat di aplikasi yang disajikan oleh Nginx di dalam kontainer. Volume kedua akan memastikan berkas konfigurasi Nginx, yang terletak di docker-compose/nginx/travellist.conf, disalin ke folder konfigurasi Nginx di dalam kontainer.
      • networks: Menyiapkan layanan ini untuk menggunakan jaringan bernama travellist.

      Berkas docker-compose.yml yang Sudah Selesai

      Berkas docker-compose.yml yang sudah selesai akan terlihat seperti ini:

      docker-compose.yml

      version: "3.7"
      services:
        app:
          build:
            args:
              user: sammy
              uid: 1000
            context: ./
            dockerfile: Dockerfile
          image: travellist
          container_name: travellist-app
          restart: unless-stopped
          working_dir: /var/www/
          volumes:
            - ./:/var/www
          networks:
            - travellist
      
        db:
          image: mysql:5.7
          container_name: travellist-db
          restart: unless-stopped
          environment:
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
            MYSQL_PASSWORD: ${DB_PASSWORD}
            MYSQL_USER: ${DB_USERNAME}
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
          volumes:
            - ./docker-compose/mysql:/docker-entrypoint-initdb.d
          networks:
            - travellist
      
        nginx:
          image: nginx:alpine
          container_name: travellist-nginx
          restart: unless-stopped
          ports:
            - 8000:80
          volumes:
            - ./:/var/www
            - ./docker-compose/nginx:/etc/nginx/conf.d/
          networks:
            - travellist
      
      networks:
        travellist:
          driver: bridge
      

      Pastikan menyimpan berkas itu saat Anda selesai.

      Langkah 6 — Menjalankan Aplikasi dengan Docker Compose

      Sekarang kita akan menggunakan perintah docker-compose untuk membangun citra aplikasi dan menjalankan layanan yang kita tetapkan dalam penyiapan.

      Bangun citra app dengan perintah berikut:

      Perintah ini mungkin membutuhkan waktu beberapa menit untuk selesai. Anda akan melihat keluaran yang serupa dengan ini:

      Output

      Building app Step 1/11 : FROM php:7.4-fpm ---> fa37bd6db22a Step 2/11 : ARG user ---> Running in f71eb33b7459 Removing intermediate container f71eb33b7459 ---> 533c30216f34 Step 3/11 : ARG uid ---> Running in 60d2d2a84cda Removing intermediate container 60d2d2a84cda ---> 497fbf904605 Step 4/11 : RUN apt-get update && apt-get install -y git curl libpng-dev libonig-dev ... Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ---> e499f74896e3 Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user ---> Running in 232ef9c7dbd1 Removing intermediate container 232ef9c7dbd1 ---> 870fa3220ffa Step 9/11 : RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user ---> Running in 7ca8c0cb7f09 Removing intermediate container 7ca8c0cb7f09 ---> 3d2ef9519a8e Step 10/11 : WORKDIR /var/www ---> Running in 4a964f91edfa Removing intermediate container 4a964f91edfa ---> 00ada639da21 Step 11/11 : USER $user ---> Running in 9f8e874fede9 Removing intermediate container 9f8e874fede9 ---> fe176ff4702b Successfully built fe176ff4702b Successfully tagged travellist:latest

      Ketika proses pembangunan selesai, Anda dapat menjalankan lingkungan dalam mode latar belakang dengan:

      Output

      Creating travellist-db ... done Creating travellist-app ... done Creating travellist-nginx ... done

      Ini akan menjalankan kontainer Anda di latar belakang. Untuk menunjukkan informasi tentang kondisi layanan aktif, jalankan:

      Anda akan melihat keluaran seperti ini:

      Output

      Name Command State Ports -------------------------------------------------------------------------------- travellist-app docker-php-entrypoint php-fpm Up 9000/tcp travellist-db docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp travellist-nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp

      Lingkungan Anda kini sudah aktif dan berjalan, tetapi kita masih perlu mengeksekusi beberapa perintah untuk menyelesaikan pengaturan aplikasi. Anda dapat menggunakan perintah docker-compose exec untuk mengeksekusi perintah di dalam kontainer layanan, seperti ls -l untuk menampilkan informasi detail tentang berkas di dalam direktori aplikasi:

      • docker-compose exec app ls -l

      Output

      total 260 -rw-rw-r-- 1 sammy sammy 737 Jun 9 11:19 Dockerfile -rw-rw-r-- 1 sammy sammy 101 Jan 7 08:05 README.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 app -rwxr-xr-x 1 sammy sammy 1686 Jan 7 08:05 artisan drwxrwxr-x 3 sammy sammy 4096 Jan 7 08:05 bootstrap -rw-rw-r-- 1 sammy sammy 1501 Jan 7 08:05 composer.json -rw-rw-r-- 1 sammy sammy 179071 Jan 7 08:05 composer.lock drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 config drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 database drwxrwxr-x 4 sammy sammy 4096 Jun 9 11:19 docker-compose -rw-rw-r-- 1 sammy sammy 965 Jun 9 11:27 docker-compose.yml -rw-rw-r-- 1 sammy sammy 1013 Jan 7 08:05 package.json -rw-rw-r-- 1 sammy sammy 1405 Jan 7 08:05 phpunit.xml drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 public -rw-rw-r-- 1 sammy sammy 273 Jan 7 08:05 readme.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 resources drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 routes -rw-rw-r-- 1 sammy sammy 563 Jan 7 08:05 server.php drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 storage drwxrwxr-x 4 sammy sammy 4096 Jan 7 08:05 tests drwxrwxr-x 41 sammy sammy 4096 Jun 9 11:32 vendor -rw-rw-r-- 1 sammy sammy 538 Jan 7 08:05 webpack.mix.js

      Sekarang kita akan menjalankan composer install untuk menginstal dependensi aplikasi:

      • docker-compose exec app composer install

      Anda akan melihat keluaran seperti ini:

      Output

      Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 85 installs, 0 updates, 0 removals - Installing doctrine/inflector (1.3.1): Downloading (100%) - Installing doctrine/lexer (1.2.0): Downloading (100%) - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%) - Installing erusev/parsedown (1.7.4): Downloading (100%) - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%) - Installing phpoption/phpoption (1.7.2): Downloading (100%) - Installing vlucas/phpdotenv (v3.6.0): Downloading (100%) - Installing symfony/css-selector (v5.0.2): Downloading (100%) … Generating optimized autoload files > IlluminateFoundationComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully.

      Hal terakhir yang perlu kita lakukan sebelum menguji aplikasi ini adalah menghasilkan kunci aplikasi unik dengan alat baris perintah Laravel artisan. Kunci ini digunakan untuk mengenkripsi sesi pengguna dan data sensitif lainnya:

      • docker-compose exec app php artisan key:generate

      Output

      Application key set successfully.

      Sekarang, buka peramban Anda dan akses nama domain server atau alamat IP Anda pada porta 8000:

      http://server_domain_or_IP:8000
      

      Catatan: Jika Anda menjalankan demo ini pada mesin lokal, gunakan http://localhost:8000 untuk mengakses aplikasi dari peramban Anda.

      Anda akan melihat sebuah laman seperti ini:

      Aplikasi Laravel Demo

      Anda dapat menggunakan perintah logs untuk memeriksa log yang dihasilkan oleh layanan Anda:

      • docker-compose logs nginx
      Attaching to travellist-nginx
      …
      travellist-nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
      travellist-nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
      travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:34 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
      travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:35 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
      

      Jika Anda ingin menghentikan sementara lingkungan Docker Compose sembari tetap mempertahankan kondisi semua layanan, jalankan:

      Output

      Pausing travellist-db ... done Pausing travellist-nginx ... done Pausing travellist-app ... done

      Kemudian, Anda dapat melanjutkan layanan dengan:

      Output

      Unpausing travellist-app ... done Unpausing travellist-nginx ... done Unpausing travellist-db ... done

      Untuk mematikan lingkungan Docker Compose dan menghapus semua kontainer, jaringan, dan volumenya, jalankan:

      Output

      Stopping travellist-nginx ... done Stopping travellist-db ... done Stopping travellist-app ... done Removing travellist-nginx ... done Removing travellist-db ... done Removing travellist-app ... done Removing network travellist-laravel-demo_travellist

      Untuk ikhtisar dari semua perintah Docker Compose, lihat referensi baris perintah Docker Compose.

      Kesimpulan

      Dalam panduan ini, kita telah menyiapkan lingkungan Docker dengan tiga kontainer yang menggunakan Docker Compose untuk mendefinisikan infrastruktur dalam berkas YAML.

      Mulai dari sekarang, Anda dapat bekerja di aplikasi Laravel tanpa perlu menginstal dan menyiapkan server web lokal untuk pengembangan dan pengujian. Lebih jauh lagi, Anda akan bekerja dengan lingkungan yang dapat dibuang serta mudah direplikasi dan didistribusikan, yang dapat membantu saat mengembangkan aplikasi Anda dan menjelang pembuatan suatu lingkungan.



      Source link

      Cara Menginstal WordPress di Ubuntu 20.04 dengan Tumpukan LAMP


      Pengantar

      WordPress adalah teknologi sumber terbuka yang saat ini sangat populer untuk membuat situs web dan blog di internet. Digunakan oleh 63% dari seluruh situs web yang menggunakan sistem manajemen konten (CMS), situs WordPress mencakup 36% dari semua situs web yang kini online.

      Ada banyak pendekatan berbeda untuk memperoleh akses ke WordPress dan beberapa proses penyiapan itu lebih kompleks dari yang lain. Tutorial ini dimaksudkan bagi mereka yang ingin menginstal dan mengelola instans WordPress di server awan yang tidak diawasi melalui baris perintah. Meskipun membutuhkan langkah lebih banyak daripada instalasi WordPress siap-pakai, pendekatan ini memberikan kontrol lebih besar terhadap lingkungan WordPress kepada administrator.

      Jika Anda sedang berusaha mengakses instalasi WordPress siap-pakai, DigitalOcean Marketplace menyajikan aplikasi sekali-klik untuk memandu Anda melakukan instalasi WordPress saat menjalankan server.

      Tergantung kebutuhan dan tujuan, Anda mungkin merasa lebih cocok dengan opsi lain. Sebagai perangkat lunak sumber terbuka, WordPress bebas diunduh dan diinstal, tetapi agar tersedia di web, Anda mungkin perlu membeli infrastruktur awan dan nama domain. Ikuti terus panduan ini jika Anda tertarik mengerjakan instalasi di sisi server dan menyiapkan situs WordPress.

      Tutorial ini akan menggunakan tumpukan LAMP (Linux, Apache, MySQL, dan PHP), yang merupakan satu opsi bagi arsitektur server yang mendukung WordPress dengan menyediakan sistem operasi Linux, server web Apache, basis data MySQL, dan bahasa pemrograman PHP. Kita akan menginstal dan menyiapkan WordPress melalui LAMP di server Linux Ubuntu 20.04.

      Prasyarat

      Untuk menyelesaikan tutorial ini, Anda akan membutuhkan akses ke server Ubuntu 20.04 dan perlu menyelesaikan langkah-langkah berikut sebelum memulai panduan ini:

      • Siapkan server Anda dengan mengikuti panduan penyiapan awal server Ubuntu 20.04 dari kami, dan pastikan Anda memiliki pengguna sudo non-root.
      • Instal tumpukan LAMP dengan mengikuti panduan LAMP kami untuk menginstal dan mengonfigurasi perangkat lunak ini.
      • Amankan situs Anda: WordPress mengambil masukan pengguna dan menyimpan data pengguna, sehingga perlu memiliki lapisan keamanan. TLS/SSL adalah teknologi yang memungkinkan Anda mengenkripsi lalu lintas dari situs Anda sehingga koneksi Anda dan pengguna Anda aman. Berikut ini dua opsi yang tersedia untuk memenuhi persyaratan ini:
        • Jika memiliki nama domain… Anda dapat mengamankan situs dengan Let’s Encrypt, yang menyediakan sertifikat gratis dan tepercaya. Ikuti panduan Let’s Encrypt untuk Apache dari kami untuk menyiapkannya.
        • Jika tidak memiliki domain… dan Anda hanya menggunakan konfigurasi ini untuk pengujian atau penggunaan pribadi, Anda dapat menggunakan sertifikat yang ditandatangani sendiri sebagai gantinya. Sertifikat ini menyediakan tipe enkripsi yang sama, tetapi tanpa validasi domain. Untuk menyiapkan, ikuti panduan SSL yang ditandatangani sendiri untuk Apache dari kami.

      Bila telah menyelesaikan langkah-langkah penyiapan, masuk ke server Anda sebagai pengguna sudo dan lanjutkan di bawah ini.

      Langkah 1 — Membuat Basis Data dan Pengguna MySQL untuk WordPress

      Langkah pertama yang akan kita ambil merupakan persiapan. WordPress menggunakan MySQL untuk mengelola dan menyimpan informasi situs dan pengguna. Kita sudah menginstal MySQL, tetapi kita perlu membuat basis data dan pengguna yang akan digunakan oleh WordPress.

      Untuk memulai, log masuk ke akun root (administratif) MySQL dengan mengeluarkan perintah ini (ingat, ini bukan pengguna root di server Anda):

      Anda akan diminta memasukkan kata sandi yang Anda buat untuk akun root MySQL saat menginstal perangkat lunak itu.

      Catatan: Jika Anda tidak dapat mengakses basis data MySQL melalui root, Anda sebagai pengguna sudo dapat memperbarui kata sandi pengguna root dengan masuk ke basis data seperti ini:

      Setelah menerima prompt MySQL, Anda dapat memperbarui kata sandi pengguna root. Di sini, ganti new_password dengan kata sandi yang kuat pilihan Anda.

      • ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'new_password';

      Anda sekarang dapat mengetikkan EXIT; dan dapat log masuk kembali ke dalam basis data melalui kata sandi dengan perintah berikut:

      Di dalam basis data, kita dapat membuat basis data eksklusif yang akan dikontrol WordPress. Anda dapat menamainya sesuai keinginan, tetapi kami akan menggunakan nama wordpress dalam panduan ini. Buat basis data untuk WordPress dengan mengetikkan:

      • CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

      Catatan: Setiap pernyataan MySQL harus diakhiri dengan titik koma (;). Periksa untuk memastikan keberadaannya jika Anda mengalami masalah.

      Selanjutnya, kita akan membuat akun pengguna MySQL terpisah yang akan digunakan secara eksklusif untuk mengoperasikan basis data kita yang baru. Membuat basis data dan akun spesifik dapat mendukung kita dari sudut pandang manajemen dan keamanan. Kita akan menggunakan nama wordpressuser di dalam panduan ini, tetapi silakan menggunakan nama apa pun yang relevan bagi Anda.

      Kita akan membuat akun ini, menentukan kata sandi, dan memberikan akses ke basis data yang kita telah buat. Kita dapat melakukannya dengan mengetikkan perintah berikut. Ingatlah memilih kata sandi yang kuat di sini bagi pengguna basis data Anda dengan password yang kita miliki:

      • CREATE USER 'wordpressuser'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

      Selanjutnya, beri tahu basis data bahwa wordpressuser kita harus memiliki akses lengkap ke basis data yang kita siapkan:

      • GRANT ALL ON wordpress.* TO 'wordpressuser'@'%';

      Kini, Anda memiliki basis data dan akun pengguna, masing-masing dibuat khusus untuk WordPress. Kita perlu memberikan privilese agar instans MySQL saat ini mengetahui perubahan terbaru yang kita lakukan:

      Keluarlah dari MySQL dengan mengetikkan:

      Pada langkah selanjutnya, kita akan menambahkan beberapa fondasi untuk plugin WordPress dengan mengunduh ekstensi PHP bagi server kita.

      Langkah 2 — Menginstal Ekstensi Tambahan PHP

      Saat menyiapkan tumpukan LAMP, kita hanya membutuhkan sedikit ekstensi untuk membuat PHP berkomunikasi dengan MySQL. WordPress dan kebanyakan plugin-nya memanfaatkan ekstensi tambahan PHP.

      Kita dapat mengunduh dan menginstal beberapa ekstensi PHP paling populer yang digunakan bersama WordPress dengan mengetikkan:

      • sudo apt update
      • sudo apt install php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip

      Ini akan menjadi dasar untuk menginstal plugin tambahan ke dalam situs WordPress kita.

      Catatan: Setiap plugin WordPress memiliki persyaratannya sendiri. Sebagian mungkin mengharuskan instalasi paket PHP tambahan. Periksa dokumentasi plugin Anda untuk mengetahui persyaratan PHP-nya. Jika ada, itu dapat diinstal dengan apt seperti diperagakan di atas.

      Kita perlu memulai ulang Apache untuk memuat ekstensi baru ini, tetapi kita akan melakukan konfigurasi lebih banyak pada Apache di bagian selanjutnya, sehingga Anda bisa menunggu sampai konfigurasi Apache selesai atau memulai ulang sekarang untuk menyelesaikan proses ekstensi PHP.

      • sudo systemctl restart apache2

      Langkah 3 — Menyesuaikan Konfigurasi Apache untuk Memungkinkan Pengesampingan dan Penulisan Ulang .htaccess

      Selanjutnya, kita akan membuat beberapa penyesuaian kecil pada konfigurasi Apache. Berdasarkan tutorial prasyarat, Anda harus memiliki berkas konfigurasi untuk situs Anda di direktori /etc/apache2/sites-available/.

      Dalam panduan ini, kita akan menggunakan /etc/apache2/sites-available/wordpress.conf sebagai contoh di sini, tetapi Anda harus mengganti jalur ke berkas konfigurasi bila diperlukan. Selain itu, kita akan menggunakan /var/www/wordpress sebagai direktori root instalasi WordPress. Anda harus menggunakan root web yang ditetapkan dalam konfigurasi Anda. Jika mengikuti tutorial LAMP dari kami, ini bisa berupa nama domain Anda sebagai pengganti wordpress dalam kedua instans ini.

      Catatan: Anda dapat menggunakan konfigurasi asali 000-default.conf (dengan /var/www/html sebagai root web Anda). Hal ini bisa digunakan jika Anda hanya akan melaksanakan hos satu situs web di server ini. Jika tidak, sebaiknya membagi konfigurasi yang diperlukan menjadi beberapa potongan logis, satu berkas per situs.

      Dengan mengidentifikasi jalur, kita dapat beralih menangani .htaccess agar Apache dapat menangani perubahan konfigurasi berdasarkan masing-masing direktori.

      Mengaktifkan Pengesampingan .htaccess

      Saat ini, penggunaan berkas .htaccess dinonaktifkan. WordPress dan banyak plugin WordPress menggunakan berkas-berkas ini secara luas untuk penyesuaian di dalam direktori pada perilaku server web.

      Buka berkas konfigurasi Apache untuk situs web Anda dengan editor teks seperti nano.

      • sudo nano /etc/apache2/sites-available/wordpress.conf

      Untuk mengizinkan berkas .htaccess, kita perlu menetapkan arahan AllowOverride di dalam blok Directory yang mengarah ke root dokumen kita. Tambahkan blok teks berikut di dalam blok VirtualHost berkas konfigurasi Anda, pastikan menggunakan direktori root web yang benar:

      /etc/apache2/sites-available/wordpress.conf

      <Directory /var/www/wordpress/>
          AllowOverride All
      </Directory>
      

      Setelah Anda selesai, simpan dan tutup berkas. Di nano, Anda dapat melakukannya dengan menekan CTRL dan X bersamaan, lalu Y, lalu ENTER.

      Mengaktifkan Modul Penulisan Ulang

      Selanjutnya, kita dapat mengaktifkan mod_rewrite untuk memanfaatkan fitur permalink WordPress:

      Hal ini memungkinkan Anda memiliki permalink yang lebih mudah dipahami orang pada pos Anda, seperti dua contoh berikut ini:

      http://example.com/2012/post-name/
      http://example.com/2012/12/30/post-name
      

      Perintah a2enmod memanggil skrip yang akan mengaktifkan modul yang ditetapkan dalam konfigurasi Apache.

      Mengaktifkan Perubahan

      Sebelum menerapkan perubahan yang kita buat, periksa untuk memastikan kita tidak membuat kesalahan sintaks apa pun dengan menjalankan tes berikut.

      • sudo apache2ctl configtest

      Anda mungkin menerima keluaran seperti berikut:

      Output

      AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message Syntax OK

      Jika Anda ingin menyembunyikan baris teratas, tambahkan saja arahan ServerName ke berkas konfigurasi utama (global) Apache di /etc/apache2/apache2.conf. ServerName bisa berupa domain atau alamat IP server Anda. Namun, ini hanya pesan dan tidak akan memengaruhi fungsi situs Anda. Asalkan keluarannya berisi Syntax OK, Anda siap melanjutkan.

      Mulai ulang Apache untuk menerapkan perubahan. Pastikan memulai ulang sekarang sekalipun Anda telah memulai ulang sebelumnya dalam tutorial ini.

      • sudo systemctl restart apache2

      Selanjutnya, kita akan mengunduh dan menyiapkan WordPress itu sendiri.

      Langkah 4 — Mengunduh WordPress

      Kini setelah perangkat lunak server dikonfigurasi, kita dapat mengunduh dan menyiapkan WordPress. Karena alasan keamanan tertentu, selalu disarankan untuk mendapatkan versi terbaru WordPress dari situsnya.

      Ubah menjadi direktori yang dapat ditulis (kami merekomendasikan direktori sementara seperti /tmp) dan unduh rilis yang dikompresi.

      • cd /tmp
      • curl -O https://wordpress.org/latest.tar.gz

      Ekstrak berkas yang dikompresi untuk membuat struktur direktori WordPress:

      Kita akan memindahkan berkas-berkas ini ke root dokumen sebentar lagi. Sebelum melakukannya, kita dapat menambah berkas .htaccess semu agar nanti dapat digunakan WordPress.

      Buat berkas dengan mengetikkan:

      • touch /tmp/wordpress/.htaccess

      Kita juga akan menyalin berkas konfigurasi sampel ke nama berkas yang dibaca WordPress:

      • cp /tmp/wordpress/wp-config-sample.php /tmp/wordpress/wp-config.php

      Kita juga dapat membuat direktori upgrade, agar WordPress tidak mengalami masalah izin saat mencoba melakukannya sendiri setelah pembaruan pada perangkat lunaknya:

      • mkdir /tmp/wordpress/wp-content/upgrade

      Sekarang, kita dapat menyalin seluruh isi direktori ke dalam root dokumen. Kita menggunakan titik di akhir direktori sumber untuk menunjukkan bahwa semua yang ada di dalam direktori harus disalin, termasuk berkas tersembunyi (seperti berkas .htaccess yang kita buat):

      • sudo cp -a /tmp/wordpress/. /var/www/wordpress

      Pastikan Anda mengganti direktori /var/www/wordpress dengan direktori yang telah Anda siapkan di server.

      Langkah 5 — Mengonfigurasi Direktori WordPress

      Sebelum melakukan penyiapan WordPress berbasis web, kita perlu menyesuaikan beberapa item dalam direktori WordPress.

      Menyesuaikan Kepemilikan dan Izin

      Langkah penting yang perlu kita lakukan adalah menyiapkan izin dan kepemilikan berkas yang semestinya.

      Kita akan mulai dengan memberikan kepemilikan semua berkas ke pengguna dan grup www-data. Inilah pengguna yang berjalan di server web Apache, dan Apache perlu bisa membaca dan menulis berkas WordPress untuk menyajikan situs web dan melakukan pembaruan otomatis.

      Perbarui kepemilikan dengan perintah chown yang memungkinkan Anda memodifikasi kepemilikan berkas. Pastikan mengarahkan ke direktori yang relevan di server Anda.

      • sudo chown -R www-data:www-data /var/www/wordpress

      Selanjutnya, kita akan menjalankan dua perintah find untuk mengatur izin yang benar pada direktori dan berkas WordPress:

      • sudo find /var/www/wordpress/ -type d -exec chmod 750 {} ;
      • sudo find /var/www/wordpress/ -type f -exec chmod 640 {} ;

      Izin ini akan membuat Anda bekerja secara efektif dengan WordPress, tetapi ingatlah bahwa beberapa plugin dan prosedur mungkin membutuhkan penyesuaian tambahan.

      Menyiapkan Berkas Konfigurasi WordPress

      Sekarang, kita perlu membuat beberapa perubahan pada berkas konfigurasi utama WordPress.

      Ketika membuka berkas itu, tugas pertama kita adalah menyesuaikan beberapa kunci rahasia untuk memberikan suatu tingkat keamanan bagi instalasi kita. WordPress menyediakan generator yang aman untuk nilai-nilai ini sehingga Anda tidak perlu memikirkan nilai yang bagus. Ini hanya digunakan secara internal, sehingga menggunakan nilai-nilai yang kompleks dan aman di sini tidak akan mengurangi kegunaan.

      Untuk mengambil nilai-nilai yang aman dari generator kunci rahasia WordPress, ketikkan:

      • curl -s https://api.wordpress.org/secret-key/1.1/salt/

      Anda akan mendapatkan kembali nilai-nilai unik yang menyerupai keluaran seperti blok di bawah ini.

      Peringatan! Anda perlu meminta nilai-nilai unik ini setiap kali. JANGAN menyalin nilai-nilai di bawah ini!

      Output

      define('AUTH_KEY', '1jl/vqfs<XhdXoAPz9 DO NOT COPY THESE VALUES c_j{iwqD^<+c9.k<J@4H'); define('SECURE_AUTH_KEY', 'E2N-h2]Dcvp+aS/p7X DO NOT COPY THESE VALUES {Ka(f;rv?Pxf})CgLi-3'); define('LOGGED_IN_KEY', 'W(50,{W^,OPB%PB<JF DO NOT COPY THESE VALUES 2;y&,2m%3]R6DUth[;88'); define('NONCE_KEY', 'll,4UC)7ua+8<!4VM+ DO NOT COPY THESE VALUES #`DXF+[$atzM7 o^-C7g'); define('AUTH_SALT', 'koMrurzOA+|L_lG}kf DO NOT COPY THESE VALUES 07VC*Lj*lD&?3w!BT#-'); define('SECURE_AUTH_SALT', 'p32*p,]z%LZ+pAu:VY DO NOT COPY THESE VALUES C-?y+K0DK_+F|0h{!_xY'); define('LOGGED_IN_SALT', 'i^/G2W7!-1H2OQ+t$3 DO NOT COPY THESE VALUES t6**bRVFSD[Hi])-qS`|'); define('NONCE_SALT', 'Q6]U:K?j4L%Z]}h^q7 DO NOT COPY THESE VALUES 1% ^qUswWgn+6&xqHN&%');

      Ini adalah baris konfigurasi yang dapat kita tempelkan langsung dalam berkas konfigurasi untuk mengatur kunci aman. Salin keluaran yang Anda terima sekarang.

      Selanjutnya, buka berkas konfigurasi WordPress:

      • sudo nano /var/www/wordpress/wp-config.php

      Temukan bagian yang berisi nilai-nilai contoh untuk pengaturan itu.

      /var/www/wordpress/wp-config.php

      . . .
      
      define('AUTH_KEY',         'put your unique phrase here');
      define('SECURE_AUTH_KEY',  'put your unique phrase here');
      define('LOGGED_IN_KEY',    'put your unique phrase here');
      define('NONCE_KEY',        'put your unique phrase here');
      define('AUTH_SALT',        'put your unique phrase here');
      define('SECURE_AUTH_SALT', 'put your unique phrase here');
      define('LOGGED_IN_SALT',   'put your unique phrase here');
      define('NONCE_SALT',       'put your unique phrase here');
      
      . . .
      

      Hapus baris-baris itu dan tempelkan dalam nilai-nilai yang Anda salin dari baris perintah:

      /var/www/wordpress/wp-config.php

      . . .
      
      define('AUTH_KEY',         'VALUES COPIED FROM THE COMMAND LINE');
      define('SECURE_AUTH_KEY',  'VALUES COPIED FROM THE COMMAND LINE');
      define('LOGGED_IN_KEY',    'VALUES COPIED FROM THE COMMAND LINE');
      define('NONCE_KEY',        'VALUES COPIED FROM THE COMMAND LINE');
      define('AUTH_SALT',        'VALUES COPIED FROM THE COMMAND LINE');
      define('SECURE_AUTH_SALT', 'VALUES COPIED FROM THE COMMAND LINE');
      define('LOGGED_IN_SALT',   'VALUES COPIED FROM THE COMMAND LINE');
      define('NONCE_SALT',       'VALUES COPIED FROM THE COMMAND LINE');
      
      . . .
      

      Selanjutnya, kita akan memodifikasi beberapa pengaturan koneksi basis data di awal berkas. Anda perlu menyesuaikan nama basis data, pengguna basis data, dan kata sandi yang terkait yang Anda konfigurasikan dalam MySQL.

      Perubahan lain yang perlu kita buat adalah mengatur metode yang harus digunakan WordPress untuk menulis sistem berkas. Karena kita telah memberi izin server web untuk menulis bila membutuhkan, kita dapat secara eksplisit mengatur metode sistem berkas ke “direct”. Tidak mengaturnya dengan pengaturan saat ini akan mengakibatkan WordPress meminta kredensial FTP saat kita melakukan beberapa tindakan.

      Pengaturan ini dapat ditambahkan di bawah pengaturan koneksi basis data, atau di tempat lain dalam berkas:

      /var/www/wordpress/wp-config.php

      . . .
      
      // ** MySQL settings - You can get this info from your web host ** //
      /** The name of the database for WordPress */
      define( 'DB_NAME', 'wordpress' );
      
      /** MySQL database username */
      define( 'DB_USER', 'wordpressuser' );
      
      /** MySQL database password */
      define( 'DB_PASSWORD', 'password' );
      
      /** MySQL hostname */
      define( 'DB_HOST', 'localhost' );
      
      /** Database Charset to use in creating database tables. */
      define( 'DB_CHARSET', 'utf8' );
      
      /** The Database Collate type. Don't change this if in doubt. */
      define( 'DB_COLLATE', '' );
      
      
      . . .
      
      define('FS_METHOD', 'direct');
      

      Simpan dan tutup berkas saat Anda sudah selesai.

      Langkah 6 — Menyelesaikan Instalasi Melalui Antarmuka Web

      Karena konfigurasi server selesai, kita dapat menyelesaikan instalasi melalui antarmuka web.

      Dalam browser web Anda, navigasikan ke nama domain server atau alamat IP publik server Anda:

      https://server_domain_or_IP
      

      Pilih bahasa yang ingin Anda gunakan:

      Pemilihan bahasa WordPress

      Selanjutnya, Anda akan masuk ke halaman penyiapan utama.

      Pilih nama untuk situs WordPress Anda dan pilih nama pengguna. Disarankan memilih nama yang unik dan hindari nama pengguna yang umum seperti “admin” untuk keperluan keamanan. Kata sandi yang kuat dibuat secara otomatis. Simpan kata sandi ini atau pilih alternatif kata sandi yang kuat.

      Masukkan alamat surel Anda dan pilih apakah ingin mencegah mesin pencari mengindeks situs Anda:

      Instalasi penyiapan WordPress

      Bila telah mengklik, Anda akan dibawa ke laman yang meminta Anda untuk log masuk:

      Prompt log masuk WordPress

      Setelah log masuk, Anda akan dibawa ke dasbor administrasi WordPress:

      Prompt log masuk WordPress

      Saat ini, Anda dapat mulai mendesain situs web WordPress! Jika ini adalah kali pertama Anda menggunakan WordPress, jelajahi sedikit antarmukanya untuk mengenal CMS Anda yang baru.

      Kesimpulan

      Selamat, WordPress sekarang telah diinstal dan siap digunakan!

      Saat ini, Anda mungkin perlu melakukan hal berikut:

      • Pilih pengaturan permalink untuk pos WordPress, yang dapat ditemukan di Settings > Permalink.
      • Pilih tema baru di Appearance > Themes.
      • Instal plugin baru untuk menambah fungsionalitas situs Anda di Plugins > Add New.
      • Jika akan bekerja sama dengan orang lain, Anda mungkin perlu juga menambahkan pengguna tambahan saat ini di Users > Add New.

      Anda dapat menemukan sumber daya tambahan untuk cara alternatif menginstal WordPress, mempelajari cara menginstal WordPress pada distribusi server lain, mengotomatiskan instalasi WordPress, dan menskalakan situs WordPress dengan memeriksa tag Komunitas WordPress dari kami.



      Source link

      Cara Mengamankan Apache dengan Let’s Encrypt pada Ubuntu 20.04


      Pengantar

      Let’s Encrypt adalah Otoritas Sertifikat (CA) yang memfasilitasi perolehan dan penginstalan sertifikat TLS/SSL gratis, yang dengan demikian mengaktifkan HTTPS terenkripsi pada server web. Ini menyederhanakan proses dengan menyediakan klien perangkat lunak, Certbot, yang berusaha mengotomatiskan sebagian besar (jika bukan semua) langkah yang diperlukan. Saat ini, seluruh proses memperoleh dan menginstal sertifikat secara sepenuhnya berjalan otomatis baik pada Apache dan Nginx.

      Dalam panduan ini, kita akan menggunakan Certbot untuk memperoleh sertifikat SSL gratis untuk Apache pada Ubuntu 20.04, dan memastikan agar sertifikat ini disiapkan untuk diperbarui secara otomatis.

      Tutorial ini menggunakan berkas hos virtual yang terpisah alih-alih berkas konfigurasi asali Apache untuk menyiapkan situs web yang akan diamankan dengan Let’s Encrypt. Kami menyarankan untuk menciptakan berkas hos virtual Apache yang baru untuk setiap domain yang dihos di server, karena ini membantu menghindari kesalahan umum dan mempertahankan berkas konfigurasi asali sebagai penyiapan fallback.

      Prasyarat

      Untuk mengikuti tutorial ini, Anda akan membutuhkan:

      • Satu server Ubuntu 20.04 yang disiapkan dengan mengikuti tutorial penyiapan server awal untuk Ubuntu 20.04 ini, termasuk satu pengguna non-root sudo dan satu firewall.

      • Nama domain yang terdaftar penuh. Tutorial ini akan menggunakan your_domain sebagai contoh di seluruh tulisan ini. Anda dapat membeli nama domain dari Namecheap, mendapat nama domain gratis di Freenom, atau menggunakan registrar domain pilihan Anda.

      • Kedua catatan DNS berikut disiapkan untuk server Anda. Anda dapat mengikuti pengantar DigitalOcean DNS ini untuk detail tentang cara menambahkannya.

        • Catatan A dengan your_domain yang mengarahkan ke alamat IP publik server Anda.
        • Catatan A dengan www.your_domain yang mengarahkan ke alamat IP publik server Anda.
      • Apache yang terinstal dengan mengikuti Cara Menginstal Apache pada Ubuntu 20.04. Pastikan Anda memiliki berkas hos virtual untuk domain Anda. Tutorial ini akan menggunakann /etc/apache2/sites-available/your_domain.conf sebagai contoh.

      Langkah 1 — Menginstal Certbot

      Untuk memperoleh sertifikat SSL dengan Let’s Encrypt, kita perlu menginstal perangkat lunak Certbot pada server Anda terlebih dahulu. Kita akan menggunakan repositori paket Ubuntu asali untuk itu.

      Kita membutuhkan dua paket: certbot dan python3-certbot-apache. Paket yang disebut terakhir adalah plugin yang mengintegrasikan Certbot dengan Apache, yang memungkinkan kita untuk mengotomatiskan perolehan sertifikat dan mengonfigurasi HTTPS di dalam server web Anda dengan satu perintah.

      • sudo apt install certbot python3-certbot-apache

      Anda juga akan diminta mengonfirmasi instalasi dengan menekan Y, lalu ENTER.

      Certbot sekarang telah terinstal di server Anda. Pada langkah selanjutnya, kita akan memverifikasi konfigurasi Apache untuk memastikan hos virtual Anda telah disiapkan dengan benar. Ini akan memastikan bahwa skrip klien certbot akan mampu mendeteksi domain Anda dan mengonfigurasi ulang server web Anda untuk menggunakan sertifikat SSL yang baru saja dihasilkan secara otomatis.

      Langkah 2 — Memeriksa Konfigurasi Hos Virtual Apache Anda

      Agar dapat memperoleh dan mengonfigurasi SSL untuk server web Anda secara otomatis, Certbot perlu menemukan hos virtual yang benar yang ada di dalam berkas konfigurasi Apache Anda. Nama (atau nama-nama) domain server Anda akan diambil dari arahan ServerName dan ServerAlias yang ditetapkan di dalam blok konfigurasi VirtualHost Anda.

      Jika Anda mengikuti langkah penyiapan hos virtual dalam tutorial instalasi Apache, Anda harusnya memiliki blok VirtualHost yang disiapkan untuk domain Anda di /etc/apache2/sites-available/your_domain.conf dengan arahan ServerName dan juga ServerAlias yang sudah diatur dengan benar.

      Untuk memeriksa ini, buka berkas hos virtual untuk domain Anda dengan menggunakan nano atau editor teks yang Anda sukai:

      • sudo nano /etc/apache2/sites-available/your_domain.conf

      Temukan baris ServerName dan ServerAlias yang sudah ada. Baris itu akan terlihat seperti ini:

      /etc/apache2/sites-available/your_domain.conf

      ...
      ServerName your_domain
      ServerAlias www.your_domain
      ...
      

      Jika Anda telah menyiapkan ServerName dan ServerAlias seperti ini, Anda dapat keluar dari editor teks Anda dan melanjutkan ke langkah selanjutnya. Jika Anda menggunakan nano, Anda dapat keluar dengan mengetik CTRL+X, lalu Y, dan ENTER untuk mengonfirmasi.

      Jika konfigurasi hos virtual Anda saat ini tidak sesuai dengan contoh, perbaruilah supaya sesuai contoh. Setelah Anda selesai, simpan berkas itu dan keluar dari editor. Lalu, jalankan perintah berikut untuk memvalidasi perubahan Anda:

      • sudo apache2ctl configtest

      Anda akan mendapat pesan Syntax OK sebagai respons. Jika Anda mendapat pesan kesalahan, buka kembali berkas host virtual dan periksa adanya kesalahan tik atau karakter yang hilang. Setelah sintaks berkas konfigurasi Anda benar, muat ulang Apache supaya perubahan itu diterapkan:

      • sudo systemctl reload apache2

      Dengan perubahan ini, Certbot akan dapat menemukan blok VirtualHost yang benar dan memperbaruinya.

      Selanjutnya, mari kita perbarui firewall untuk mengizinkan lalu lintas HTTPS.

      Langkah 3 — Mengizinkan HTTPS Melewati Firewall

      Jika firewall UFW Anda sudah diaktifkan, seperti yang disarankan oleh panduan prasyarat, Anda perlu menyesuaikan pengaturan untuk mengizinkan lalu lintas HTTPS. Setelah instalasi, Apache mendaftarkan beberapa profil aplikasi UFW yang berbeda. Kita dapat memanfaatkan profil Apache Full untuk mengizinkan baik lalu lintas HTTP dan HTTPS pada server Anda.

      Untuk memverifikasi lalu lintas seperti apa yang diizinkan pada server Anda, Anda dapat menggunakan:

      Jika Anda telah mengikuti salah satu panduan instalasi Apache kami, keluaran Anda akan terlihat seperti ini, yang berarti bahwa hanya lalu lintas HTTP pada porta 80 yang diizinkan untuk saat ini:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Apache (v6) ALLOW Anywhere (v6)

      Untuk menambah lalu lintas HTTPS masuk, izinkan profil “Apache Full” dan hapus profil “Apache” yang lewah lainnya:

      • sudo ufw allow 'Apache Full'
      • sudo ufw delete allow 'Apache'

      Status Anda sekarang akan terlihat seperti ini:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Apache Full (v6) ALLOW Anywhere (v6)

      Anda sekarang siap untuk menjalankan Certbot dan memperoleh sertifikat Anda.

      Langkah 4 — Memperoleh Sertifikat SSL

      Certbot menyediakan berbagai cara untuk memperoleh sertifikat SSL melalui plugin. Plugin Apache akan menangani konfigurasi ulang Apache dan memuat ulang konfigurasi itu ketika diperlukan. Untuk menggunakan plugin ini, ketik yang berikut:

      Skrip ini akan meminta Anda menjawab serangkaian pertanyaan untuk mengonfigurasi sertifikat SSL Anda. Pertama, skrip ini akan meminta alamat surel Anda yang valid. Surel ini akan digunakan untuk pemberitahuan pembaruan dan keamanan:

      Output

      Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator apache, Installer apache Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): you@your_domain

      Setelah menyediakan alamat surel yang valid, tekan ENTER untuk melanjutkan ke langkah selanjutnya. Anda kemudian akan diminta mengonfirmasi apakah Anda menyetujui ketentuan layanan dari Let’s Encrypt. Anda dapat mengonfirmasi dengan menekan A lalu ENTER:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Please read the Terms of Service at
      https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
      agree in order to register with the ACME server at
      https://acme-v02.api.letsencrypt.org/directory
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      (A)gree/(C)ancel: A
      

      Selanjutnya, Anda akan ditanya apakah mau membagi surel Anda dengan Electronic Frontier Foundation untuk menerima berita dan informasi lainnya. Jika Anda tidak ingin berlangganan konten mereka, ketik N. Jika Anda mau, ketik Y. Lalu, tekan ENTER untuk melanjutkan ke langkah selanjutnya.

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Would you be willing to share your email address with the Electronic Frontier
      Foundation, a founding partner of the Let's Encrypt project and the non-profit
      organization that develops Certbot? We'd like to send you email about our work
      encrypting the web, EFF news, campaigns, and ways to support digital freedom.
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      (Y)es/(N)o: N
      

      Langkah selanjutnya akan meminta Anda untuk menginformasikan Certbot terkait Anda ingin mengaktifkan HTTPS untuk domain yang mana. Nama-nama domain yang terdaftar secara otomatis diperoleh dari konfigurasi hos virtual Apache Anda, itu sebabnya penting untuk memastikan bahwa Anda memiliki pengaturan ServerName dan ServerAlias yang dikonfigurasi dengan benar di dalam hos virtual Anda. Jika Anda ingin mengaktifkan HTTPS untuk semua nama domain yang terdaftar (disarankan), Anda dapat mengosongkan prompt itu dan tekan ENTER untuk melanjutkan. Jika tidak, pilih domain yang Anda ingin aktifkan HTTPS-nya dengan membuat daftar dari setiap nomor yang sesuai, yang dipisahkan dengan koma dan/atau spasi, lalu tekan ENTER.

      Which names would you like to activate HTTPS for?
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      1: your_domain
      2: www.your_domain
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Select the appropriate numbers separated by commas and/or spaces, or leave input
      blank to select all options shown (Enter 'c' to cancel):
      

      Anda akan melihat keluaran seperti ini:

      Obtaining a new certificate
      Performing the following challenges:
      http-01 challenge for your_domain
      http-01 challenge for www.your_domain
      Enabled Apache rewrite module
      Waiting for verification...
      Cleaning up challenges
      Created an SSL vhost at /etc/apache2/sites-available/your_domain-le-ssl.conf
      Enabled Apache socache_shmcb module
      Enabled Apache ssl module
      Deploying Certificate to VirtualHost /etc/apache2/sites-available/your_domain-le-ssl.conf
      Enabling available site: /etc/apache2/sites-available/your_domain-le-ssl.conf
      Deploying Certificate to VirtualHost /etc/apache2/sites-available/your_domain-le-ssl.conf
      

      Selanjutnya, Anda akan diminta memilih apakah Anda ingin lalu lintas HTTP dialihkan ke HTTPS atau tidak. Dalam praktiknya, itu berarti saat seseorang mengunjungi situs web Anda melalui saluran yang tidak terenkripsi (HTTP), dia akan secara otomatis dialihkan ke alamat HTTPS dari situs web Anda. Pilih 2 untuk mengaktifkan pengalihan, atau 1 jika Anda ingin mempertahankan baik HTTP dan HTTPS sebagai metode yang terpisah untuk mengakses situs web Anda.

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      1: No redirect - Make no further changes to the webserver configuration.
      2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
      new sites, or if you're confident your site works on HTTPS. You can undo this
      change by editing your web server's configuration.
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
      
      

      Setelah langkah ini, konfigurasi Certbot selesai, dan Anda akan melihat catatan terakhir tentang sertifikat baru Anda, di mana Anda dapat menemukan berkas yang dihasilkan, dan bagaimana cara menguji konfigurasi Anda dengan menggunakan alat eksternal yang menganalisis keaslian sertifikat Anda:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Congratulations! You have successfully enabled https://your_domain and
      https://www.your_domain
      
      You should test your configuration at:
      https://www.ssllabs.com/ssltest/analyze.html?d=your_domain
      https://www.ssllabs.com/ssltest/analyze.html?d=www.your_domain
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      
      IMPORTANT NOTES:
       - Congratulations! Your certificate and chain have been saved at:
         /etc/letsencrypt/live/your_domain/fullchain.pem
         Your key file has been saved at:
         /etc/letsencrypt/live/your_domain/privkey.pem
         Your cert will expire on 2020-07-27. To obtain a new or tweaked
         version of this certificate in the future, simply run certbot again
         with the "certonly" option. To non-interactively renew *all* of
         your certificates, run "certbot renew"
       - Your account credentials have been saved in your Certbot
         configuration directory at /etc/letsencrypt. You should make a
         secure backup of this folder now. This configuration directory will
         also contain certificates and private keys obtained by Certbot so
         making regular backups of this folder is ideal.
       - If you like Certbot, please consider supporting our work by:
      
         Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
         Donating to EFF:                    https://eff.org/donate-le
      
      

      Sertifikat Anda sekarang sudah terinstal dan dimuat ke konfigurasi Apache. Coba muat ulang situs Anda dengan menggunakan https:// dan perhatikan indikator keamanan di peramban Anda. Peramban akan menunjukkan bahwa situs Anda sudah diamankan dengan benar, biasanya dengan adanya ikon kunci di dalam bilah alamat.

      Anda dapat menggunakan SSL Labs Server Test untuk memverifikasi nilai sertifikat Anda dan memperoleh informasi mendetail tentang hal itu, dari sudut pandang layanan eksternal.

      Di langkah selanjutnya yang juga merupakan langkah terakhir, kita akan menguji fitur pembaruan otomatis Certbot, yang menjamin bahwa sertifikat Anda akan diperbarui secara otomatis sebelum tanggal kedaluwarsa.

      Langkah 5 — Memverifikasi Pembaruan Otomatis Certbot

      Sertifikat Let’s Encrypt hanya berlaku selama 90 hari. Kebijakan ini diterapkan untuk mendorong pengguna supaya mengotomatiskan proses pembaruan sertifikatnya, serta memastikan bahwa sertifikat yang disalahgunakan atau kunci yang dicari akan kedaluwarsa lebih cepat daripada seharusnya.

      Paket certbot yang kita instal menangani pembaruan dengan memasukkan skrip pembaruan ke /etc/cron.d, yang dikelola oleh layanan systemctl yang bernama certbot.timer. Skrip ini berjalan dua kali sehari dan secara otomatis memperbarui sertifikat apa pun yang berada dalam waktu 30 hari dari tanggal kedaluwarsa.

      Untuk memeriksa status layanan ini dan memastikan bahwa layanan sudah aktif dan berjalan, Anda dapat menggunakan:

      • sudo systemctl status certbot.timer

      Anda akan medapat keluaran yang mirip dengan ini:

      Output

      ● certbot.timer - Run certbot twice daily Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled) Active: active (waiting) since Tue 2020-04-28 17:57:48 UTC; 17h ago Trigger: Wed 2020-04-29 23:50:31 UTC; 12h left Triggers: ● certbot.service Apr 28 17:57:48 fine-turtle systemd[1]: Started Run certbot twice daily.

      Untuk menguji proses pembaruan, Anda dapat melakukan uji coba dengan certbot:

      • sudo certbot renew --dry-run

      Jika Anda tidak melihat kesalahan, maka Anda sudah siap. Ketika diperlukan, Certbot akan memperbarui sertifikat Anda dan memuat ulang Apache untuk menerapkan perubahan itu. Jika proses pembaruan otomatis itu terus-menerus gagal, Let’s Encrypt akan mengirim pesan ke surel yang Anda tentukan, memperingatkan Anda saat sertifikat Anda akan berakhir.

      Kesimpulan

      Dalam tutorial ini, Anda telah menginstal certbot klien Let’s Encrypt, mengonfigurasi dan menginstal sertifikat SSL untuk domain Anda, dan mengonfirmasi bahwa layanan pembaruan otomatis Certbot sudah aktif di dalam systemctl. Jika Anda memiliki pertanyaan lebih lanjut tentang cara menggunakan Certbot, dokumentasi mereka adalah tempat yang baik untuk memulai.



      Source link