Skip to content

Instantly share code, notes, and snippets.

@TheyCallMeLinux
Created April 26, 2026 18:30
Show Gist options
  • Select an option

  • Save TheyCallMeLinux/7292b4ffd64dfbf725358bf7edef0012 to your computer and use it in GitHub Desktop.

Select an option

Save TheyCallMeLinux/7292b4ffd64dfbf725358bf7edef0012 to your computer and use it in GitHub Desktop.
Deploy Forgejo on Alma Linux 9 (sqlite3)
#!/bin/bash
set -euo pipefail
############################
# VARIABLES
############################
APP_URL="https://forgejo.example.com"
SERVER_NAME="forgejo.example.com"
HTTP_BIND="127.0.0.1"
HTTP_PORT="3000"
SSH_PORT="22"
APP_NAME="example Forgejo"
FORGEJO_VERSION="15.0.0"
DISABLE_REGISTRATION="true"
REQUIRE_SIGNIN_VIEW="true"
ENABLE_CAPTCHA="true"
RUN_MODE="prod"
SELINUX_MODE="permissive"
CERT_COUNTRY="CA"
CERT_STATE="ON"
CERT_CITY="Toronto"
CERT_ORG="exampleCorp"
CERT_UNIT="IT"
MAIL_ENABLED="true"
SMTP_ADDR="smtp.gmail.com"
SMTP_PORT="465"
SMTP_USER="example@gmail.com"
SMTP_PASS="APP PASS WORD"
MAIL_FROM="example@gmail.com"
SMTP_PROTOCOL="smtps"
SSL_CERT="/etc/pki/tls/certs/forgejo.crt"
SSL_KEY="/etc/pki/tls/private/forgejo.key"
############################
# LOGGING
############################
log() {
echo "[DEPLOY] $1"
}
trap 'log "Deployment failed at line $LINENO"' ERR
############################
# SELINUX
############################
log "Configuring SELinux"
case "$SELINUX_MODE" in
disabled)
setenforce 0 || true
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
;;
permissive)
setenforce 0 || true
sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config
;;
enforcing)
setenforce 1 || true
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
;;
esac
############################
# SYSTEM UPDATE
############################
log "Updating system"
dnf -y update
############################
# PACKAGES
############################
log "Installing packages"
dnf -y install epel-release
dnf -y install git curl wget unzip nano tar sqlite httpd mod_ssl policycoreutils-python-utils firewalld
systemctl daemon-reexec
systemctl enable --now httpd firewalld
############################
# FIREWALL
############################
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-port=3000/tcp
firewall-cmd --reload
############################
# FORGEJO INSTALL
############################
log "Installing Forgejo"
cd /tmp
wget https://codeberg.org/forgejo/forgejo/releases/download/v${FORGEJO_VERSION}/forgejo-${FORGEJO_VERSION}-linux-amd64
install -m 0755 forgejo-${FORGEJO_VERSION}-linux-amd64 /usr/local/bin/forgejo
############################
# USER + DIRS
############################
groupadd --system forgejo || true
useradd --system \
--home /var/lib/forgejo \
--gid forgejo \
--shell /bin/bash \
forgejo || true
mkdir -p /var/lib/forgejo/{custom,data,log}
chown -R forgejo:forgejo /var/lib/forgejo
############################
# CONFIG
############################
log "Creating Forgejo config"
mkdir -p /var/lib/forgejo/custom/conf
SECRET_KEY=$(openssl rand -hex 32)
INTERNAL_TOKEN=$(openssl rand -hex 32)
cat > /var/lib/forgejo/custom/conf/app.ini <<EOF
APP_NAME = ${APP_NAME}
RUN_MODE = ${RUN_MODE}
[server]
DOMAIN = ${SERVER_NAME}
ROOT_URL = ${APP_URL}/
HTTP_ADDR = ${HTTP_BIND}
HTTP_PORT = ${HTTP_PORT}
DISABLE_SSH = false
SSH_PORT = ${SSH_PORT}
START_SSH_SERVER = false
[database]
DB_TYPE = sqlite3
PATH = /var/lib/forgejo/data/forgejo.db
[mailer]
ENABLED = ${MAIL_ENABLED}
PROTOCOL = ${SMTP_PROTOCOL}
SMTP_ADDR = ${SMTP_ADDR}
SMTP_PORT = ${SMTP_PORT}
FROM = ${MAIL_FROM}
USER = ${SMTP_USER}
PASSWD = ${SMTP_PASS}
[security]
INSTALL_LOCK = false
SECRET_KEY = ${SECRET_KEY}
INTERNAL_TOKEN = ${INTERNAL_TOKEN}
PASSWORD_HASH_ALGO = argon2
[service]
DISABLE_REGISTRATION = ${DISABLE_REGISTRATION}
REQUIRE_SIGNIN_VIEW = ${REQUIRE_SIGNIN_VIEW}
ENABLE_CAPTCHA = ${ENABLE_CAPTCHA}
[repository]
DEFAULT_PRIVATE = private
[session]
PROVIDER = file
[log]
MODE = file
LEVEL = Info
ROOT_PATH = /var/lib/forgejo/log
EOF
chown -R forgejo:forgejo /var/lib/forgejo/custom
chmod 750 /var/lib/forgejo/custom
chmod 640 /var/lib/forgejo/custom/conf/app.ini
############################
# SYSTEMD
############################
log "Creating service"
cat > /etc/systemd/system/forgejo.service <<EOF
[Unit]
Description=Forgejo
After=network.target
[Service]
User=forgejo
Group=forgejo
WorkingDirectory=/var/lib/forgejo
ExecStart=/usr/local/bin/forgejo web
Restart=always
RestartSec=2s
Environment=USER=forgejo
Environment=HOME=/var/lib/forgejo
Environment=GITEA_WORK_DIR=/var/lib/forgejo
Environment=APP_DATA_PATH=/var/lib/forgejo/data
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable forgejo
systemctl start forgejo
############################
# SSL
############################
log "Generating self-signed cert"
openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout ${SSL_KEY} \
-out ${SSL_CERT} \
-subj "/C=${CERT_COUNTRY}/ST=${CERT_STATE}/L=${CERT_CITY}/O=${CERT_ORG}/OU=${CERT_UNIT}/CN=${SERVER_NAME}"
chmod 600 ${SSL_KEY}
############################
# APACHE PROXY
############################
log "Configuring Apache"
cat > /etc/httpd/conf.d/forgejo.conf <<EOF
<VirtualHost *:80>
ServerName ${SERVER_NAME}
Redirect / https://${SERVER_NAME}/
</VirtualHost>
<VirtualHost *:443>
ServerName ${SERVER_NAME}
SSLEngine on
SSLCertificateFile ${SSL_CERT}
SSLCertificateKeyFile ${SSL_KEY}
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
EOF
setsebool -P httpd_can_network_connect 1
systemctl restart httpd
############################
# DONE
############################
log "Deployment complete"
echo "======================================"
echo " Forgejo is ready"
echo " URL: ${APP_URL}"
echo "======================================"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment