Last active
November 18, 2025 12:36
-
-
Save privyreza/d54bfee09cb7e8f2317df36b8ca5f879 to your computer and use it in GitHub Desktop.
Setup Laravel Env on Ubuntu and Install Laravel app from gitlab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -e | |
| set -o pipefail | |
| # ------------------------------- | |
| # Ensure screen is installed | |
| # ------------------------------- | |
| export DEBIAN_FRONTEND=noninteractive | |
| apt-get update -y | |
| apt-get install -y screen | |
| # ------------------------------- | |
| # If not already inside a screen session, re-launch script inside screen | |
| # ------------------------------- | |
| # $STY is set when inside a screen session :contentReference[oaicite:1]{index=1} | |
| if [ -z "${STY}" ]; then | |
| SESSION_NAME="laravel-setup" | |
| echo "Not inside screen. Starting a detached screen session called '${SESSION_NAME}'..." | |
| # -dmS: start detached, name session | |
| screen -dmS "${SESSION_NAME}" bash -c "$0 \"$@\"" | |
| echo "Setup is now running inside screen session '${SESSION_NAME}'." | |
| echo "You can reattach using: screen -r ${SESSION_NAME}" | |
| exit 0 | |
| fi | |
| # ------------------------------- | |
| # Main setup logic (inside screen) | |
| # ------------------------------- | |
| echo "=== Laravel Server Auto Setup with SSL and DB (running inside screen) ===" | |
| # Support interactive or env variable input | |
| DOMAIN=${DOMAIN:-$(read -p "Enter your domain name (e.g. example.com): " input && echo $input)} | |
| REPO_URL=${REPO_URL:-$(read -p "Enter your GitLab SSH repo URL ([email protected]:user/repo.git): " input && echo $input)} | |
| BRANCH=${BRANCH:-main} | |
| # Detect server public IP | |
| SERVER_IP=$(curl -s https://ipinfo.io/ip) | |
| echo "Detected server public IP: $SERVER_IP" | |
| # Generate random system user and DB credentials | |
| USERNAME="u$(openssl rand -hex 3)" | |
| PASSWORD=$(openssl rand -base64 12) | |
| DB_NAME=$(openssl rand -hex 4) | |
| DB_USER=$(openssl rand -hex 4) | |
| DB_PASS=$(openssl rand -base64 12) | |
| echo | |
| echo " Generated credentials:" | |
| echo " → System user: ${USERNAME}" | |
| echo " → System pass: ${PASSWORD}" | |
| echo " → DB name: ${DB_NAME}" | |
| echo " → DB user: ${DB_USER}" | |
| echo " → DB password: ${DB_PASS}" | |
| echo | |
| # Create system user for Laravel app (no sudo) | |
| adduser --disabled-password --gecos "" "$USERNAME" | |
| echo "$USERNAME:$PASSWORD" | chpasswd | |
| # Install required packages | |
| apt-get update -y | |
| apt-get upgrade -y | |
| apt-get install -y software-properties-common curl unzip git apache2 mysql-server certbot python3-certbot-apache ufw | |
| # Install PHP 8.4 + extensions | |
| add-apt-repository ppa:ondrej/php -y | |
| apt-get update -y | |
| apt-get install -y \ | |
| php8.4 php8.4-cli php8.4-common php8.4-mysql php8.4-xml php8.4-mbstring \ | |
| php8.4-curl php8.4-zip php8.4-bcmath php8.4-gd libapache2-mod-php8.4 | |
| # Install Composer | |
| curl -sS https://getcomposer.org/installer | php | |
| mv composer.phar /usr/local/bin/composer | |
| # Install Node.js LTS | |
| curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - | |
| apt-get install -y nodejs | |
| # Enable Apache rewrite module | |
| a2enmod rewrite | |
| systemctl enable apache2 | |
| systemctl start apache2 | |
| # Setup firewall | |
| ufw allow OpenSSH | |
| ufw allow 'Apache Full' | |
| ufw --force enable | |
| # Generate SSH key for GitLab (2048-bit) | |
| sudo -u "$USERNAME" mkdir -p "/home/${USERNAME}/.ssh" | |
| sudo -u "$USERNAME" ssh-keygen -t rsa -b 2048 -C "${USERNAME}@server" -f "/home/${USERNAME}/.ssh/id_rsa" -N "" | |
| sudo -u "$USERNAME" chmod 700 "/home/${USERNAME}/.ssh" | |
| sudo -u "$USERNAME" chmod 600 "/home/${USERNAME}/.ssh/id_rsa" | |
| sudo -u "$USERNAME" chmod 644 "/home/${USERNAME}/.ssh/id_rsa.pub" | |
| echo "=== Copy this SSH key to GitLab ===" | |
| sudo -u "$USERNAME" cat "/home/${USERNAME}/.ssh/id_rsa.pub" | |
| echo "==================================" | |
| read -p "Press Enter after adding the SSH key to GitLab..." | |
| # Prepare folder for Laravel app and fix permissions | |
| APP_PATH="/var/www/${DOMAIN}" | |
| mkdir -p "$APP_PATH" | |
| chown -R "$USERNAME":"$USERNAME" "$APP_PATH" | |
| # Clone Laravel repo as app user | |
| sudo -u "$USERNAME" git clone -b "$BRANCH" "$REPO_URL" "$APP_PATH" | |
| # Set permissions | |
| chown -R "$USERNAME":www-data "$APP_PATH" | |
| chmod -R 775 "$APP_PATH/storage" "$APP_PATH/bootstrap/cache" | |
| # MySQL setup | |
| mysql -e "CREATE DATABASE \`${DB_NAME}\`;" | |
| mysql -e "CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';" | |
| mysql -e "GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'localhost';" | |
| mysql -e "FLUSH PRIVILEGES;" | |
| # Configure Laravel environment | |
| ENV_FILE="$APP_PATH/.env" | |
| if [ ! -f "$ENV_FILE" ]; then | |
| sudo -u "$USERNAME" cp "$APP_PATH/.env.example" "$ENV_FILE" | |
| fi | |
| sudo -u "$USERNAME" sed -i "s/APP_ENV=.*/APP_ENV=production/" "$ENV_FILE" | |
| sudo -u "$USERNAME" sed -i "s/APP_DEBUG=.*/APP_DEBUG=false/" "$ENV_FILE" | |
| sudo -u "$USERNAME" sed -i "s/DB_DATABASE=.*/DB_DATABASE=${DB_NAME}/" "$ENV_FILE" | |
| sudo -u "$USERNAME" sed -i "s/DB_USERNAME=.*/DB_USERNAME=${DB_USER}/" "$ENV_FILE" | |
| sudo -u "$USERNAME" sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=${DB_PASS}/" "$ENV_FILE" | |
| # Install Laravel dependencies inside app folder | |
| sudo -u "$USERNAME" bash -c "cd $APP_PATH && composer install --no-interaction --optimize-autoloader" | |
| # Laravel key & migration | |
| sudo -u "$USERNAME" bash -c "cd $APP_PATH && php artisan key:generate" | |
| sudo -u "$USERNAME" bash -c "cd $APP_PATH && php artisan migrate --force || echo '⚠️ Migration skipped (check manually)'" | |
| sudo -u "$USERNAME" bash -c "cd $APP_PATH && php artisan storage:link" | |
| # Apache virtual host | |
| cat > /etc/apache2/sites-available/${DOMAIN}.conf <<EOF | |
| <VirtualHost *:80> | |
| ServerName ${DOMAIN} | |
| ServerAlias www.${DOMAIN} | |
| DocumentRoot ${APP_PATH}/public | |
| <Directory ${APP_PATH}/public> | |
| AllowOverride All | |
| Require all granted | |
| </Directory> | |
| ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}-error.log | |
| CustomLog \${APACHE_LOG_DIR}/${DOMAIN}-access.log combined | |
| </VirtualHost> | |
| EOF | |
| a2ensite "${DOMAIN}.conf" | |
| systemctl reload apache2 | |
| # Ensure user sets DNS A record | |
| echo "✅ Make sure your domain A record points to ${SERVER_IP} before continuing" | |
| read -p "Press Enter when the DNS A record is set..." | |
| # Setup HTTPS with Certbot | |
| certbot --apache -d "$DOMAIN" -d "www.${DOMAIN}" --non-interactive --agree-tos -m "admin@${DOMAIN}" | |
| echo | |
| echo "✅ Laravel server with SSL setup complete!" | |
| echo "User: ${USERNAME}" | |
| echo "Password: ${PASSWORD}" | |
| echo "Database: ${DB_NAME} / ${DB_USER} / ${DB_PASS}" | |
| echo "Domain: https://${DOMAIN}" | |
| echo "SSH key above must be added to GitLab before git clone." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment