ในบทความนี้ผมจะพูดถึงการ Deploy Symfony ไปยัง Droplet บน DigitalOcean โดย OS ที่ใช้จะเป็น ubuntu เพราะน่าจะง่ายที่สุดละ (จริงๆ มันมี tutorials เยอะดี 😀) และใช้ nginx เป็น Web Server สาเหตุที่ไม่ใช้ apache เพราะผมไม่ชอบ syntax มันเลย ค่อนข้างชอบ syntax ของ nginx มากกว่า รู้สึกอ่านง่ายดี
มาพูดถึง Symfony กันหน่อยเผื่อใครไม่รู้จัก ตัว Symfony ก็เป็น Framework นึงจากฝั่ง PHP ส่วน ซึ่งผมก็มีบางงานที่ต้อง Deploy ก็เลยถือโอกาสมาเขียนเป็นบทความไว้ เผื่อใครกำลังจะหาวิธีการ Deploy อยู่พอดี อาจจะนำวิธีการที่ผมนำเสนอในบทความนี้ไปใช้ต่อได้ บวกกับผมก็จดไว้กันลืมอะแหละ ก็เลยมาเขียนเป็นบทความซะเลย
วิธีการนี้ก็อาจจะดูเป็นวิธีการที่ tranditional สักหน่อย (ใช้คำซะหรูเชียว) ยุคนี้มันต้อง Deploy ด้วย Container กันแล้ว ก็เอาไว้ก่อนละกัน เอาแบบบ้านๆ ไปก่อนนะ 😅
ผมขอข้ามวิธีการสมัครและสร้าง Droplet ใน DigitalOcean ไปเลยนะครับ เราเข้าสู่ขั้นตอนการ remote เข้าเครื่องเพื่อจัดการ server กันเลย
Setup Server
เริ่มด้วยการ remote เข้าไปที่ server ด้วย ssh
Remote to server
ใช้คำสั่ง ssh
เพื่อเชื่อมต่อกับ server โดยวิธีการก็จะเป็น
ssh root@your_server_ip
![ssh connection to server](/images/posts/symfony-deploy-digitalocean/01-connect-to-server.png)
เมื่อเข้ามาแล้ว ก็จะได้หน้าตาแบบนี้
![ssh connection to server](/images/posts/symfony-deploy-digitalocean/02-on-server.png)
Create new user
ผมจะมาสร้าง user ใหม่ไว้ใช้ใน server กันก่อน เพราะไม่อยากจะใช้ root ตลอดเวลาขนาดนั้น
สร้าง user ใหม่ ด้วยคำสั่ง
adduser bandit
![add user](/images/posts/symfony-deploy-digitalocean/03-add-user.png)
กรอก password
![add password](/images/posts/symfony-deploy-digitalocean/04-add-user.png)
กรอก password อีกครั้ง
![retype password](/images/posts/symfony-deploy-digitalocean/05-add-user-password.png)
เพิ่ม fullname ให้กับ user
![add fullname](/images/posts/symfony-deploy-digitalocean/06-add-user-fullname.png)
ตอบ y เพื่อยืนยันความถูกต้องของข้องมูล user
![confirm information](/images/posts/symfony-deploy-digitalocean/07-add-user.png)
Add privileges to user
เพิ่มสิทธิ์ให้ user ใหม่ มีสิทธิ์เทียบเท่ากับ root
usermod -aG sudo bandit
![add user sudo](/images/posts/symfony-deploy-digitalocean/08-add-user-sudo.png)
Copy ssh key
คัดลอกไฟล์ .ssh จาก user root ไปยัง user ที่เราสร้างใหม่ด้วย เพื่อจะได้ remote เข้าเครื่องโดยใช้ user ที่เราสร้างใหม่
rsync --archive --chown=bandit:bandit ~/.ssh /home/bandit
![copy .ssh](/images/posts/symfony-deploy-digitalocean/09-copy-ssh.png)
Enable Firewall
allow ssh ด้วยคำสั่ง ufw allow OpenSSH
![ufw allow OpenSSH](/images/posts/symfony-deploy-digitalocean/10-allow-firewall-openssh.png)
เปิดใช้งาน firewall ด้วยคำสั่ง ufw enable
![ufw enable](/images/posts/symfony-deploy-digitalocean/11-allow-firewall-openssh.png)
ดูสถานะ firewall ด้วยคำสั่ง ufw status
![ufw status](/images/posts/symfony-deploy-digitalocean/12-firewall-status.png)
![ufw status](/images/posts/symfony-deploy-digitalocean/13-firewall-status.png)
จากนั้นก็พิมพ์คำสั่ง exit
เพื่อตัดการเชื่อมต่อกับ server
![disconnect from server](/images/posts/symfony-deploy-digitalocean/14-exit.png)
ssh by new user
ต่อมาเราจะมาลอง Remote เข้า server ด้วย user ใหม่ ที่เราเพิ่งสร้างไป
ssh bandit@your_server_ip
![ssh connection to server](/images/posts/symfony-deploy-digitalocean/15-ssh-new-user.png)
![login with new user](/images/posts/symfony-deploy-digitalocean/16-login-with-new-user.png)
Upgrade package
หลังจากสร้าง user ใหม่เรียบร้อยแล้ว ก็ update package ซะหน่อย ด้วยคำสั่งที่คุ้นเคย
sudo apt-get update -y && sudo apt-get upgrade -y
![update apt package](/images/posts/symfony-deploy-digitalocean/17-apt-update.png)
![update apt package successful](/images/posts/symfony-deploy-digitalocean/18-apt-update-successful.png)
Install Nginx and PHP
ต่อมาถึงขั้นตอนการติดตั้ง nginx กับ PHP
Add ondrej/php repository
เราจำเป็นต้อง add ppa:ondrej/php
เพราะ ubuntu ไม่มี php 8.3 แบบ official
โดยเริ่มจากการพิมพ์คำสั่ง sudo add-apt-repository ppa:ondrej/php
เพื่อเพิ่ม ppa:ondrej/php
![add ppa:ondrej/php](/images/posts/symfony-deploy-digitalocean/19-add-ppa.png)
![add ppa:ondrej/php](/images/posts/symfony-deploy-digitalocean/20-add-ppa.png)
![add ppa:ondrej/php successful](/images/posts/symfony-deploy-digitalocean/21-add-ppa-successful.png)
จากนั้น พิมพ์คำสั่ง sudo apt update
เพื่อ update package
![add ppa:ondrej/php successful](/images/posts/symfony-deploy-digitalocean/22-apt-update.png)
![add ppa:ondrej/php successful](/images/posts/symfony-deploy-digitalocean/23-apt-update.png)
จากนั้นติดตั้ง nginx กับ PHP
sudo apt install nginx zip unzip php-zip php8.3-common php8.3-cli php8.3-fpm php8.3-{curl,bz2,mbstring,intl,xml,mysql,zip,intl}
![install nginx and php](/images/posts/symfony-deploy-digitalocean/24-install-nginx-php.png)
ตอบ y เพื่อยืนยันการติดตั้ง
![install nginx and php](/images/posts/symfony-deploy-digitalocean/25-install-nginx-php.png)
จากนั้นก็รอ
![installing nginx and php](/images/posts/symfony-deploy-digitalocean/26-install-nginx-php.png)
ติดตั้งเรียบร้อย
![installing nginx and php successful](/images/posts/symfony-deploy-digitalocean/27-install-nginx-php-successful.png)
allow nginx on firewall
หลังจากที่ติดตั้งเสร็จ เราจำเป็นต้องเปิด firewall สำหรับ nginx ด้วย ทำได้ด้วยการพิมพ์คำสั่ง sudo ufw allow 'Nginx HTTP'
![ufw allow 'Nginx HTTP'](/images/posts/symfony-deploy-digitalocean/28-ufw-allow-nginx.png)
ถ้าเราลองเปิด browser แล้วเข้าที่ IP ของ server ก็จะเห็นว่า nginx สามารถใช้งานได้แล้ว
![nginx is work!](/images/posts/symfony-deploy-digitalocean/29-nginx-is-work.png)
config nginx
มาถึงขั้นตอนการ config site สำหรับ nginx
เริ่มด้วยการ copy ไฟล์ default
ไปเป็นอีกชื่อนึงที่เราอยากได้ ในที่นี้ผมตั้งชื่อว่า demo-symfony.9mza.net
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/demo-symfony.9mza.net
![cp config sites-available default to demo-symfony.9mza.net](/images/posts/symfony-deploy-digitalocean/30-copy-config-sites-available-default.png)
จากนั้นทำการแก้ไขไฟล์ที่เราเพิ่ง copy มา
sudo vim /etc/nginx/sites-available/demo-symfony.9mza.net
![edit config demo-symfony.9mza.net](/images/posts/symfony-deploy-digitalocean/31.png)
ผมแก้ไขไฟล์ประมาณนี้ มีแค่เพิ่ม php เข้าไป
![demo-symfony.9mza.net](/images/posts/symfony-deploy-digitalocean/32-config-demo.png)
ไฟล์เต็มๆ
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name demo-symfony.9mza.net;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
จากนั้นทำการ unlink sites-available default
sudo unlink /etc/nginx/sites-enabled/default
![unlink default config](/images/posts/symfony-deploy-digitalocean/34-unlink-default-config.png)
ทำการลิงก์ sites-available เป็น sites-enabled
sudo ln -s /etc/nginx/sites-available/demo-symfony.9mza.net /etc/nginx/sites-enabled/
![link new config](/images/posts/symfony-deploy-digitalocean/33-link-config.png)
sudo nginx -t
เพื่อตรวจสอบ syntax
![nginx syntax is ok](/images/posts/symfony-deploy-digitalocean/35-test-nginx-syntax.png)
sudo systemctl reload nginx
เพื่อทำการ reload nginx
![reload nginx](/images/posts/symfony-deploy-digitalocean/36-reload-nginx.png)
เปลี่ยน permission ของ directory html
ให้เป็น 775
![chmod html](/images/posts/symfony-deploy-digitalocean/37-chmod-html.png)
สร้างไฟล์ index.php ขึ้นมาเพื่อทดสอบ
![create index.php](/images/posts/symfony-deploy-digitalocean/38-test-with-phpinfo().png)
![create index.php](/images/posts/symfony-deploy-digitalocean/39-test-with-phpinfo().png)
เมื่อสร้าง เมื่อบันทึกเสร็จแล้ว มาลองทดสอบใน browser
ถ้าขึ้นแบบนี้ก็เป็นอันใช้ได้
![phpinfo()](/images/posts/symfony-deploy-digitalocean/40-show-phpinfo().png)
สำหรับบทความนี้ขอจบไว้ที่ตรงนี้ก่อน เพราะรู้สึกว่าเหมือนจะยาวละ ไว้เรามาต่ออีกทีใน Part 2 โดยจะมาลุยกันต่อในเรื่อง Composer, Database, Symfony ละ แล้วเจอกันครับ