← Back to list

How to Deploy a Laravel Application on Ubuntu Server (with GitLab)

A step-by-step guide for deploying a Laravel project from GitLab to an Ubuntu/Debian VPS with Apache.

Medrick Meshack · 2026-05-11 18:27 · 4 claps · 3.2 min read
#laravel-framework #web-development #git #software-development #developer
Open on Medium ↗
Wiki topics: 🌐 · Web Development ☁️ · DevOps & Cloud 🔓 · Open Source

How to Deploy a Laravel Application on Ubuntu Server (with GitLab)

mrone.inc

mrone.inc

A step-by-step guide for deploying a Laravel project from GitLab to an Ubuntu/Debian VPS with Apache.

Prerequisites

  • Ubuntu/Debian VPS with SSH access

  • PHP 8.2+

  • MySQL 8.0+

  • Apache2

  • Composer

  • Node.js 20+ & NPM

  • Git

Step 1: Set Up SSH Key for GitLab

Generate an SSH key on your server:

ssh-keygen -t ed25519 -C "your-email@example.com"

Press Enter to accept default location. Then copy the public key:

cat ~/.ssh/id_ed25519.pub

Go to GitLab > Settings > SSH Keys (https://gitlab.com/-/user_settings/ssh_keys), paste the key, and save.

Test the connection:

ssh -T git@gitlab.com

You should see: ”Welcome to GitLab, @yourusername!”

Welcome to GitLab, @yourusername!

Step 2: Clone the Repository

sudo mkdir -p /var/www/your-project
sudo chown $USER:$USER /var/www/your-project
git clone git@gitlab.com:your-group/your-project.git /var/www/your-project

Important: Never use sudo git clone — it uses root’s SSH keys instead of yours and will fail with “Permission denied (publickey)”.

Step 3: Install PHP Dependencies

cd /var/www/your-project
composer install - optimize-autoloader - no-dev

Step 4: Install Node.js & Build Frontend Assets

If your server has an older Node.js version, upgrade it first:

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v

Then install and build:

npm install
npm run build

Step 5: Configure Environment

cp .env.example .env
php artisan key:generate

Edit the .env file:

nano .env

Update these values for production:

APP_NAME="Your App Name"
APP_ENV=production
APP_DEBUG=false
APP_URL=http://your-server-ip-or-domain
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_password

Save with Ctrl+O, exit with Ctrl+X.

Step 6: Create the Database

sudo mysql
CREATE DATABASE your_database CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'your_db_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON your_database.* TO 'your_db_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Note: On Ubuntu, MySQL root often requires sudo mysql instead of mysql -u root -p

Step 7: Run Migrations & Seed

cd /var/www/your-project
php artisan migrate - force
php artisan db:seed - force # optional, if your project has seeders

The — force flag is required because Laravel blocks these commands in production as a safety measure.

Step 8: Set File Permissions

sudo chown -R www-data:www-data /var/www/your-project
sudo chmod -R 755 /var/www/your-project
sudo chmod -R 775 /var/www/your-project/storage
sudo chmod -R 775 /var/www/your-project/bootstrap/cache

Step 9: Configure Apache

Enable the rewrite module:

sudo a2enmod rewrite

Create a virtual host configuration:

sudo nano /etc/apache2/sites-available/your-project.conf

Paste the following:

<VirtualHost *:80>
    ServerAdmin admin@localhost
    DocumentRoot /var/www/your-project/public

    <Directory /var/www/your-project/public>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/your-project-error.log
    CustomLog ${APACHE_LOG_DIR}/your-project-access.log combined
</VirtualHost>

If you have a domain name, add ServerName inside the <VirtualHost> block:

ServerName yourdomain.com
ServerAlias www.yourdomain.com

Enable the site and reload Apache:

sudo a2ensite your-project.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2

Step 10: Optimize Laravel for Production

cd /var/www/your-project
php artisan config:cache
php artisan route:cache
php artisan view:cache

Step 11: Set Up Queue Worker (if your app uses queues)

Create a systemd service:

sudo nano /etc/systemd/system/laravel-queue.service

Paste:

[Unit]
Description=Laravel Queue Worker
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/your-project
ExecStart=/usr/bin/php artisan queue:work - sleep=3 - tries=3 - max-time=3600
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable laravel-queue
sudo systemctl start laravel-queue

Step 12: Set Up Cron Job (for Laravel Scheduler)

sudo crontab -u www-data -e

Add this line:

cd /var/www/your-project && php artisan schedule:run >> /dev/null 2>&1

Step 13: Set Up SSL with Let’s Encrypt (Recommended)

sudo apt install certbot python3-certbot-apache -y
sudo certbot - apache -d yourdomain.com -d www.yourdomain.com

Certbot will automatically configure HTTPS and set up auto-renewal.

Step 14: Verify

Visit http://your-server-ip (or https://yourdomain.com) in your browser. Your Laravel app should be live!

Updating the Application

When new changes are pushed to GitLab:

cd /var/www/your-project
git pull origin main
composer install - optimize-autoloader - no-dev
npm install && npm run build
php artisan migrate - force
php artisan config:cache
php artisan route:cache
php artisan view:cache
sudo systemctl restart laravel-queue

Troubleshooting

Problem

i. `Permission denied (publickey)` on git clone
   -> Don't use `sudo` with git. Use your user's SSH key
ii. `sudo mysql` doesn't work
   -> Try `mysql -u root -p` instead
iii. 500 error in browser
   -> Check `storage/logs/laravel.log` for details
iv. CSS/JS not loading
   -> Make sure you ran `npm run build`
v.  Blank page
   -> Run `php artisan config:cache` and check permissions on `storage/`
vi. Queue jobs not running
   -> Check `sudo systemctl status laravel-queue`

Useful Commands

Check Laravel logs

tail -f /var/www/your-project/storage/logs/laravel.log

Check Apache logs

tail -f /var/log/apache2/your-project-error.log

Restart queue worker after code changes

sudo systemctl restart laravel-queue

Clear all caches

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

Re-cache for production

php artisan config:cache
php artisan route:cache
php artisan view:cache

Happy deploying!


메타데이터
post_id
9af2d24398db
slug
how-to-deploy-a-laravel-application-on-ubuntu-server-with-gitlab-9af2d24398db
url
https://medium.com/@meckar21/how-to-deploy-a-laravel-application-on-ubuntu-server-with-gitlab-9af2d24398db
canonical_url
https://medium.com/@meckar21/how-to-deploy-a-laravel-application-on-ubuntu-server-with-gitlab-9af2d24398db
author_url
https://medium.com/@meckar21
status
ok
fetched_at
2026-06-09 15:37:30