Last active
March 9, 2026 20:46
-
-
Save TheyCallMeLinux/e0d8669b5fe576176a89ecaacc929504 to your computer and use it in GitHub Desktop.
Alma 9 install snipe-it with self signed certificates
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
| #!/bin/bash | |
| set -euo pipefail | |
| ############################ | |
| # VARIABLES | |
| ############################ | |
| # DB MODE: "local" or "remote" | |
| DB_MODE="local" | |
| # Local DB defaults (ignored if DB_MODE=remote) | |
| DB_HOST="127.0.0.1" | |
| DB_SOCKET="/var/lib/mysql/mysql.sock" | |
| DB_NAME="snipeit" | |
| DB_USER="snipeit_dbuser" | |
| DB_PASS="CHANGE_ME_STRONG_PASSWORD" | |
| # Remote DB settings (if DB_MODE="remote", override DB_HOST) | |
| # DB_HOST="db.example.com" | |
| APP_URL="https://snipeit.example.com" | |
| SERVER_NAME="snipeit.example.com" | |
| SNIPE_VERSION="v8.4.0" | |
| INSTALL_DIR="/var/www/html/snipeit" | |
| # SELinux: enforcing | permissive | disabled | |
| SELINUX_MODE="enforcing" | |
| CERT_COUNTRY="CA" | |
| CERT_STATE="ON" | |
| CERT_CITY="Toronto" | |
| CERT_ORG="exampleCorp" | |
| CERT_UNIT="IT" | |
| ############################ | |
| # SELINUX CONFIG | |
| ############################ | |
| echo "[DEPLOY] Configuring SELinux" | |
| if [ "$SELINUX_MODE" = "disabled" ]; then | |
| sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config | |
| setenforce 0 || true | |
| elif [ "$SELINUX_MODE" = "permissive" ]; then | |
| sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config | |
| setenforce 0 || true | |
| else | |
| sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config | |
| setenforce 1 || true | |
| fi | |
| ############################ | |
| # SYSTEM UPDATE | |
| ############################ | |
| echo "[DEPLOY] Updating system packages" | |
| dnf -y update | |
| ############################ | |
| # SWAP + MEMORY TUNING | |
| ############################ | |
| if [ ! -f /swapfile ]; then | |
| echo "[DEPLOY] Creating swap" | |
| fallocate -l 4G /swapfile | |
| chmod 600 /swapfile | |
| mkswap /swapfile | |
| swapon /swapfile | |
| echo '/swapfile none swap sw 0 0' >> /etc/fstab | |
| cat > /etc/sysctl.d/99-memory.conf <<EOF | |
| vm.swappiness=10 | |
| vm.vfs_cache_pressure=50 | |
| EOF | |
| sysctl --system | |
| fi | |
| ############################ | |
| # INSTALL BASE PACKAGES | |
| ############################ | |
| echo "[DEPLOY] Installing base packages" | |
| dnf -y install epel-release | |
| dnf -y install \ | |
| git curl unzip nano \ | |
| firewalld fail2ban \ | |
| httpd mod_ssl \ | |
| policycoreutils-python-utils | |
| ############################ | |
| # FIREWALL HARDENING | |
| ############################ | |
| echo "[DEPLOY] Configuring firewall" | |
| systemctl enable --now firewalld httpd | |
| firewall-cmd --permanent --add-service=http || true | |
| firewall-cmd --permanent --add-service=https || true | |
| firewall-cmd --reload | |
| ############################ | |
| # FAIL2BAN SSH PROTECTION | |
| ############################ | |
| echo "[DEPLOY] Installing fail2ban" | |
| cat > /etc/fail2ban/jail.local <<EOF | |
| [sshd] | |
| enabled = true | |
| port = ssh | |
| maxretry = 5 | |
| findtime = 10m | |
| bantime = 1h | |
| EOF | |
| systemctl enable --now fail2ban | |
| ############################ | |
| # INSTALL PHP 8.2 | |
| ############################ | |
| echo "[DEPLOY] Installing PHP" | |
| dnf -y install \ | |
| https://rpms.remirepo.net/enterprise/remi-release-9.rpm | |
| dnf -y module reset php | |
| dnf -y module enable php:remi-8.2 | |
| dnf -y install \ | |
| php php-cli php-fpm php-mysqlnd \ | |
| php-gd php-mbstring php-xml php-bcmath \ | |
| php-zip php-curl php-intl php-ldap \ | |
| php-sodium composer | |
| ############################ | |
| # PHP OPCACHE TUNING | |
| ############################ | |
| echo "[DEPLOY] Configuring OPcache" | |
| cat > /etc/php.d/10-opcache.ini <<EOF | |
| opcache.enable=1 | |
| opcache.enable_cli=1 | |
| opcache.memory_consumption=192 | |
| opcache.interned_strings_buffer=16 | |
| opcache.max_accelerated_files=20000 | |
| opcache.revalidate_freq=60 | |
| opcache.fast_shutdown=1 | |
| opcache.jit=off | |
| EOF | |
| ############################ | |
| # ENABLE SERVICES | |
| ############################ | |
| systemctl enable --now httpd | |
| ############################ | |
| # LOCAL DATABASE | |
| ############################ | |
| if [ "$DB_MODE" = "local" ]; then | |
| echo "[DEPLOY] Installing MariaDB" | |
| dnf -y install mariadb-server | |
| systemctl enable --now mariadb | |
| echo "[DEPLOY] Waiting for MariaDB" | |
| until mysqladmin ping --silent; do | |
| sleep 2 | |
| done | |
| mysql -e "DELETE FROM mysql.user WHERE User='';" | |
| mysql -e "DROP DATABASE IF EXISTS test;" | |
| mysql -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';" | |
| mysql -e "FLUSH PRIVILEGES;" | |
| mysql -e "CREATE DATABASE IF NOT EXISTS ${DB_NAME};" | |
| mysql -e "CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';" | |
| mysql -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';" | |
| mysql -e "FLUSH PRIVILEGES;" | |
| fi | |
| ############################ | |
| # INSTALL SNIPE-IT | |
| ############################ | |
| echo "[DEPLOY] Installing Snipe-IT" | |
| if [ ! -d "${INSTALL_DIR}" ]; then | |
| git clone --branch "${SNIPE_VERSION}" --single-branch https://github.com/grokability/snipe-it.git /tmp/snipe-it | |
| mv /tmp/snipe-it "${INSTALL_DIR}" | |
| fi | |
| cd "${INSTALL_DIR}" | |
| chown -R apache:apache "${INSTALL_DIR}" | |
| sudo -u apache composer install \ | |
| --no-dev --prefer-dist --no-interaction | |
| ############################ | |
| # CONFIGURE ENV | |
| ############################ | |
| cp -n .env.example .env | |
| sed -i "s|APP_ENV=.*|APP_ENV=production|" .env | |
| sed -i "s|APP_DEBUG=.*|APP_DEBUG=false|" .env | |
| sed -i "s|APP_URL=.*|APP_URL=${APP_URL}|" .env | |
| sed -i "s|DB_HOST=.*|DB_HOST=${DB_HOST}|" .env | |
| sed -i "s|DB_DATABASE=.*|DB_DATABASE=${DB_NAME}|" .env | |
| sed -i "s|DB_USERNAME=.*|DB_USERNAME=${DB_USER}|" .env | |
| sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=${DB_PASS}|" .env | |
| sed -i "s|DB_SOCKET=.*|DB_SOCKET=${DB_SOCKET}|" .env | |
| ############################ | |
| # PERMISSIONS & SELINUX | |
| ############################ | |
| echo "[DEPLOY] Setting permissions & SELinux" | |
| find "${INSTALL_DIR}" -type d -exec chmod 755 {} \; | |
| find "${INSTALL_DIR}" -type f -exec chmod 644 {} \; | |
| chmod -R 775 "${INSTALL_DIR}/storage" | |
| chmod -R 775 "${INSTALL_DIR}/bootstrap/cache" | |
| chown -R apache:apache "${INSTALL_DIR}" | |
| restorecon -Rv /var/www/html/snipeit | |
| chcon -R -t httpd_sys_rw_content_t /var/www/html/snipeit/storage /var/www/html/snipeit/bootstrap/cache | |
| ############################ | |
| # LARAVEL SETUP | |
| ############################ | |
| echo "[DEPLOY] Configuring Laravel" | |
| sudo -u apache php artisan key:generate --force | |
| sudo -u apache php artisan config:clear | |
| sudo -u apache php artisan cache:clear | |
| sudo -u apache php artisan migrate --force | |
| ############################ | |
| # SSL CERTIFICATE | |
| ############################ | |
| echo "[DEPLOY] Generating SSL certificate" | |
| if [ ! -f /etc/pki/tls/private/snipeit.key ]; then | |
| openssl req -x509 -nodes -days 825 -newkey rsa:2048 \ | |
| -keyout /etc/pki/tls/private/snipeit.key \ | |
| -out /etc/pki/tls/certs/snipeit.crt \ | |
| -subj "/C=${CERT_COUNTRY}/ST=${CERT_STATE}/L=${CERT_CITY}/O=${CERT_ORG}/OU=${CERT_UNIT}/CN=${SERVER_NAME}" | |
| chmod 600 /etc/pki/tls/private/snipeit.key | |
| fi | |
| ############################ | |
| # APACHE CONFIG | |
| ############################ | |
| echo "[DEPLOY] Configuring Apache" | |
| cat > /etc/httpd/conf.d/snipeit.conf <<EOF | |
| <VirtualHost *:80> | |
| ServerName ${SERVER_NAME} | |
| Redirect permanent / https://${SERVER_NAME}/ | |
| </VirtualHost> | |
| <VirtualHost *:443> | |
| ServerName ${SERVER_NAME} | |
| DocumentRoot ${INSTALL_DIR}/public | |
| SSLEngine on | |
| SSLCertificateFile /etc/pki/tls/certs/snipeit.crt | |
| SSLCertificateKeyFile /etc/pki/tls/private/snipeit.key | |
| <Directory ${INSTALL_DIR}/public> | |
| AllowOverride All | |
| Require all granted | |
| </Directory> | |
| Header always set X-Frame-Options "SAMEORIGIN" | |
| Header always set X-Content-Type-Options "nosniff" | |
| Header always set X-XSS-Protection "1; mode=block" | |
| Header always set Referrer-Policy "strict-origin-when-cross-origin" | |
| Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" | |
| Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()" | |
| </VirtualHost> | |
| EOF | |
| systemctl restart httpd | |
| ############################ | |
| # CRON HEALTH TASKS | |
| ############################ | |
| echo "[DEPLOY] Installing cron tasks" | |
| cat > /etc/cron.d/snipeit-health <<EOF | |
| */5 * * * * apache php ${INSTALL_DIR}/artisan schedule:run >> /dev/null 2>&1 | |
| 0 2 * * * root dnf -y update --security | |
| EOF | |
| chmod 644 /etc/cron.d/snipeit-health | |
| ############################ | |
| # FINISHED | |
| ############################ | |
| echo "======================================" | |
| echo " Snipe-IT installation completed!" | |
| echo " DB Mode: ${DB_MODE}" | |
| echo " SELinux Mode: ${SELINUX_MODE}" | |
| echo " URL: ${APP_URL}" | |
| echo "======================================" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment