Deploy on Virtual Machine
How to deploy some tech stack in virtual machine
Deploy Laravel
- Get in into root user
sudo su
- Update the ubuntu repository
sudo apt update -y
- Install NGINX Proxy
sudo apt install nginx -y
- Add Ondrej PPA Repository
sudo add-apt-repository ppa:ondrej/php
- Do the repository update again
sudo apt update
- Install PHP8.2
sudo apt install php8.2 -y
- Install PHP module
sudo apt install php8.2-{fpm,imap,ldap,xml,curl,mbstring,zip,mongodb,gd,dev}
- Remove Apache2 from the systemctl (because it will conflicted with NGINX)
sudo systemctl stop apache2
sudo systemctl disable apache2
- Install Composer
wget -O composer-setup.php https://getcomposer.org/installer
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
- Clone the repository in
/var/www
folder
cd /var/www
git clone https://gitlab.com/user/laravel-repo.git
- Install the vendor package
composer install
- Copy the .env.example into .env file and fill the .env file
cp .env.example .env
- Do the artisan things
php artisan jwt:secret
php artisan key:generate
- Seed database
php artisan db:seed
- Create file inside /etc/nginx/sites-available
vim /etc/nginx/sites-available/laravel-repo
Fill it with this value:
server {
listen 80;
index index.php index.html index.htm;
error_log /var/log/nginx/backend-error.log;
access_log /var/log/nginx/backend-access.log;
root /var/www/laravel-repo/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /.well-known {
allow all;
}
location = /.env {
deny all;
return 404;
}
}
- Symlink it into /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/laravel-repo /etc/nginx/sites-enabled/laravel-repo
- Unlink default file inside sites-enabled folder
unlink /etc/nginx/sites-enabled/default
- Test the nginx configuration
nginx -t
- Reload the nginx
nginx -s reload
Deploy Wordpress MySQL and NGINX
- Install common software
sudo apt-get update
sudo apt -y install software-properties-common
- Install NGINX
sudo apt install nginx -y
- Add PHP Repository
sudo add-apt-repository ppa:ondrej/php
- Install PHP and basic extension
sudo apt install php8.2 php8.2-fpm php8.2-common php8.2-gmp php8.2-curl php8.2-intl php8.2-mbstring php8.2-xmlrpc php8.2-gd php8.2-xml php8.2-cli php8.2-zip php8.2-mysql
- Purge Apache Web Server
sudo apt purge apache2
- Download and unzip wordpress latest
wget https://wordpress.org/latest.tar.gz
tar -xvzf latest.tar.gz
- Move to NGINX folder
sudo mv wordpress /var/www && cd /var/www/<folder-name>
- Install MySQL or MariaDB
sudo apt install mariadb-server # MariaDB
sudo apt install mysql-server # MySQL
- Secure install MySQL
mysql_secure_installation
- Create wordpress database
mysql -u root
CREATE DATABASE <db-name>;
CREATE USER '<user-name>'@'localhost' IDENTIFIED BY '<password>';
GRANT ALL ON <db-name>.* TO '<user-name>'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
- Configure
wp-config.php
sudo cp wp-config-sample.php wp-config.php
sudo vim wp-config.php
- Change owner wordpress folder
sudo chown -R www-data:www-data /var/www/<folder-name>
- Change mode wordpress folder
sudo find . -type d -exec chmod 755 {} \;
sudo find . -type f -exec chmod 644 {} \;
Deploy NodeJS using Node Version Manager (NVM)
- Curl installation shell from github
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
- Source the changed data in bash
source ~/.bashrc
- Check node version in terminal
nvm list-remote
- Install required node version
nvm install <node_version>
For example:
nvm install v16.13.0
- Check your node inside terminal
node -v
- Install package manager
If you use pnpm:
npm i -g pnpm
If you use yarn:
npm i -g yarn
- Install NGINX Proxy
sudo apt install nginx -y
- Use SuperUser to access root folder
sudo su
- Go to destination folder for your repository, and clone it
cd /var/www
git clone https://gitlab.com/user/node-repo.git
cd node-repo
- Install node_modules
pnpm install
- Build the code
pnpm run build
Static File
- Create file inside /etc/nginx/sites-available
vim /etc/nginx/sites-available/node-static-conf
Fill it with this value:
server {
listen 80;
root /var/www/node-repo/dist; # Build code static files are often found in the dist folder.
index index.html;
location / {
try_files $uri $uri/ @rewrites;
include /etc/nginx/mime.types;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
}
location @rewrites {
rewrite ^(.+)$ /index.html last;
}
location = /.env {
deny all;
return 404;
}
}
- Symlink it into /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/node-static-conf /etc/nginx/sites-enabled/node-static-conf
- Unlink default file inside sites-enabled folder
unlink /etc/nginx/sites-enabled/default
- Test the nginx configuration
nginx -t
- Reload the nginx
nginx -s reload
Upstream Port
- Install pm2 to run the app in background
npm i -g pm2
- Run the app using pm2
PORT=3000 NODE_PORT=3000 pm2 start pnpm --name "node-upstream:3000" -- start
- Check the app if it's already running
curl -X GET -I http://127.0.0.1:3000
The stdout should print this:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: text/html
Cache-Control: no-cache
Etag: W/"63f-nngLMxQfvLPukzBwkH36P2K460M"
Date: Mon, 24 Jun 2024 15:52:06 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 1599
- Create file inside /etc/nginx/sites-available
vim /etc/nginx/sites-available/node-upstream
Fill it with this value:
upstream node-upstream {
server 127.0.0.1:3000;
}
server {
listen 80;
location / {
proxy_pass http://node-upstream;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = /.env {
deny all;
return 404;
}
}
- Symlink it into /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/node-upstream /etc/nginx/sites-enabled/node-upstream
- Unlink default file inside sites-enabled folder
unlink /etc/nginx/sites-enabled/default
- Test the nginx configuration
nginx -t
- Reload the nginx
nginx -s reload
Deploy Golang using goenv
- Check out goenv where you want it installed. Usually it's in
$HOME/.goenv
git clone https://github.com/go-nv/goenv.git ~/.goenv
- Define environment variable
GOENV_ROOT
to point to the path where goenv repo is cloned and add$GOENV_ROOT/bin
to your$PATH
for access to the goenv command-line utility
echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.bashrc
echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.bashrc
- Add
goenv init
to your shell to enable shims, management ofGOPATH
andGOROOT
and auto-completion. Please make sureeval "$(goenv init -)"
is placed toward the end of the shell configuration file since it manipulatesPATH
during the initialization
echo 'eval "$(goenv init -)"' >> ~/.bashrc
- If you want
goenv
to manageGOPATH
andGOROOT
(recommended), addGOPATH
andGOROOT
to your shell aftereval "$(goenv init -)"
echo 'export PATH="$GOROOT/bin:$PATH"' >> ~/.bashrc
echo 'export PATH="$PATH:$GOPATH/bin"' >> ~/.bashrc
- Restart your shell so the path changes take effect
exec $SHELL
or
source ~/.bashrc
- Install Go versions into
$GOENV_ROOT/versions
goenv install v1.22.2
- Set
goenv
global version
goenv global v1.22.2
- Install NGINX proxy
sudo apt install nginx -y
- Use SuperUser to access root folder
sudo su
- Go to destination folder for your repository, and clone it
cd /var/www
git clone https://gitlab.com/user/go-repo.git
cd go-repo
- Install go modules
go mod download && go mod tidy
- Copy the env.example file into .env
cp .env.example .env
- Build golang app into binary executable file
go build -o <output-file> <main.go-file-path>
Example:
go build -o app.sh cmd/main.go
- Create file service for running golang app in background
cd /etc/systemd/system
vim golang-app.service
Fill the file with this config:
[Unit]
Description=golang-app
[Service]
Type=simple
User=root
Group=root
LimitNOFILE=1024
Restart=on-failure
RestartSec=10
startLimitIntervalSec=60
WorkingDirectory=/var/www/go-repo
ExecStart=/var/www/go-repo/app.sh
[Install]
WantedBy=multi-user.target
- Restart the daemon and check the service status
systemctl daemon-reload
systemctl status golang-app.service
- Start the app and enable the service (to make the app autostart)
systemctl start golang-app.service
systemctl enable golang-app.service
- Check the app if it's already running
curl -X GET -I http://127.0.0.1:8000
The stdout should print this:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: text/html
Cache-Control: no-cache
Etag: W/"63f-nngLMxQfvLPukzBwkH36P2K460M"
Date: Mon, 24 Jun 2024 15:52:06 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 1599
- Create file inside /etc/nginx/sites-available
vim /etc/nginx/sites-available/golang-app
Fill it with this value:
upstream golang-app {
server 127.0.0.1:8000;
}
server {
listen 80;
location / {
proxy_pass http://golang-app;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = /.env {
deny all;
return 404;
}
}
- Symlink it into /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/golang-app /etc/nginx/sites-enabled/golang-app
- Unlink default file inside sites-enabled folder
unlink /etc/nginx/sites-enabled/default
- Test the nginx configuration
nginx -t
- Reload the nginx
nginx -s reload