The officially official Devuan Forum!

You are not logged in.

#1 Yesterday 19:05:49

joser
Member
Registered: 2024-05-20
Posts: 7  

[HowTo] Install Forgejo with self signed cert on Devuan 6

Forgejo, an alternative to Gitea.
https://forgejo.org

Kernel version: 6.12.48+deb13-amd64
Binary file: forgejo-13.0.3-linux-amd64
Partition scheme: / 12%, swap 12%, /home -1
Does these matters? I don't know but I have tried this steps only on systems having exactly the same specs like above, so if you get any error message related for example to swap memory and you have no swap then I won't know what to tell you but create a swap partition and try again.

# First, make sure the domain/host name on /etc/hosts it's like: IP <FQDN> <hostname>, for example for a local domain /etc/hosts should be like:
127.0.0.1    localhost
192.168.1.10 myhost.mydomain.home myhost
# Where 192.168.1.10 is the local network IP for your local forgejo host, to verify it then execute:

hostname -f

# The result should be for example:
myhost.mydomain.home
# This is a must since later we will use the variables FQDN and HOSTNAME to retreive those values automatically
# to generate the self signed cert and to avoid mistyping errors that could make the setup completely fail.

# Install dependencies

sudo apt install -y git git-lfs nginx openssl

# Download and install binary

wget https://codeberg.org/forgejo/forgejo/releases/download/v13.0.3/forgejo-13.0.3-linux-amd64
chmod +x forgejo-13.0.3-linux-amd64
sudo cp forgejo-13.0.3-linux-amd64 /usr/local/bin/forgejo
sudo chmod 755 /usr/local/bin/forgejo

# Create git user on the system. Forgejo will run as that user, and when accessing git through
# SSH (which is the default), this user is part of the URL (for example
# in: git clone git@git.example.com:YourOrg/YourRepo.git the "git" at the left of @ is the user you’ll create now).

sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' \
  --group --disabled-password --home /home/git git

# Create the directory where Forgejo’s config, called app.ini it's stored in. Initially it needs to be writable by Forgejo,
# but after the installation you can make it read-only even for Forgejo because then it shouldn’t modify it anymore.

sudo mkdir -p /etc/forgejo/{ssl}
sudo chown -R root:git /etc/forgejo && sudo chmod -R 770 /etc/forgejo

# In this case, below will use the path "/home/git/" where Forgejo will store its data, including your repositories, 
# this in order to make it easier to preserve and backup when ussing separated /home partition and SQLite database,
# but that value can be modified to anything that suits best for you if you know what are you doing.

# Create Forgejo service file, copy and paste from #!/bin/sh line to "exit 0" line and save.

sudo nano /etc/init.d/forgejo

#!/bin/sh
### BEGIN INIT INFO
# Provides:          forgejo
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Should-Start:      $local_fs
# Should-Stop:       $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Forgejo Git server daemon
# Description:       Starts, stops, and manages the Forgejo service.
### END INIT INFO

# Where Forgejo lives (binary, config, data)
FORGEJO_ROOT="/home/git/lib/forgejo"
FORGEJO_BINARY="/usr/local/bin/forgejo"
FORGEJO_WORK_DIR="/home/git/lib/forgejo"
FORGEJO_USER="git"
FORGEJO_GROUP="git"

# Config file
FORGEJO_CONFIG="/etc/forgejo/app.ini"

# Log files – same locations used by the systemd unit
FORGEJO_LOG_DIR="${FORGEJO_ROOT}/log"
STDOUT_LOG="${FORGEJO_LOG_DIR}/stdout.log"
STDERR_LOG="${FORGEJO_LOG_DIR}/stderr.log"

# PID file – used for status checks and clean shutdowns
PIDFILE="/var/run/forgejo.pid"

# Extra flags you might want to pass (e.g., --config)
DAEMON_OPTS="web --config ${FORGEJO_CONFIG}"

log_msg() {
    echo "[forgejo] $*"
}

# Ensure the binary exists before we try anything
[ -x "${FORGEJO_BINARY}" ] || {
    log_msg "Executable not found at ${FORGEJO_BINARY}. Aborting."
    exit 1
}

# Create log directory if missing
[ -d "${FORGEJO_LOG_DIR}" ] || mkdir -p "${FORGEJO_LOG_DIR}"
chown ${FORGEJO_USER}:${FORGEJO_GROUP} "${FORGEJO_LOG_DIR}"

do_start() {
    log_msg "Starting Forgejo…"
    # Run as the dedicated user, detach, and capture PID
    start-stop-daemon --start \
        --quiet \
        --background \
        --make-pidfile \
        --pidfile "${PIDFILE}" \
        --chuid "${FORGEJO_USER}:${FORGEJO_GROUP}" \
        --exec "${FORGEJO_BINARY}" \
        -- ${DAEMON_OPTS} >>"${STDOUT_LOG}" 2>>"${STDERR_LOG}"
    RET=$?
    [ $RET -eq 0 ] && log_msg "Forgejo started (PID $(cat ${PIDFILE}))"
    return $RET
}

do_stop() {
    log_msg "Stopping Forgejo…"
    if [ -f "${PIDFILE}" ]; then
        PID=$(cat "${PIDFILE}")
        start-stop-daemon --stop --quiet --pid "${PID}" --retry=TERM/30/KILL/5
        RET=$?
        [ $RET -eq 0 ] && rm -f "${PIDFILE}" && log_msg "Forgejo stopped"
    else
        log_msg "No PID file found – is Forgejo already stopped?"
        RET=1
    fi
    return $RET
}

do_restart() {
    do_stop && do_start
}

do_status() {
    if [ -f "${PIDFILE}" ]; then
        PID=$(cat "${PIDFILE}")
        if kill -0 "$PID" 2>/dev/null; then
            echo "Forgejo is running (PID $PID)"
            return 0
        else
            echo "Forgejo PID file exists but process is dead"
            return 1
        fi
    else
        echo "Forgejo is not running"
        return 3
    fi
}

case "$1" in
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    restart|force-reload)
        do_restart
        ;;
    status)
        do_status
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status}"
        exit 2
        ;;
esac

exit 0

# Make it executable

sudo chmod +x /etc/init.d/forgejo

# Enable the service auto-start at boot

sudo update-rc.d forgejo defaults

# Generate self signed cert and key

sudo openssl genrsa -out /etc/nginx/ssl/$(hostname).key 4096
sudo openssl req -x509 -new -nodes -key /etc/nginx/ssl/$(hostname).key -sha256 -days 365 -subj "/CN=$(hostname -f)" -reqexts v3_req -extensions v3_ca -out /etc/nginx/ssl/$(hostname).crt

# Change cert and key group permissions but maintaining root ownership

sudo chgrp git /etc/nginx/ssl/$(hostname).crt
sudo chmod 644 /etc/nginx/ssl/$(hostname).crt
sudo chgrp git /etc/nginx/ssl/$(hostname).key
sudo chmod 600 /etc/nginx/ssl/$(hostname).key

# Prevent git error: server verification failed: certificate signer not trusted for your local repo/server

git config --global http."https://$(hostname -f)/".sslCAInfo /etc/nginx/ssl/$(hostname).crt

# Copy the new certificate system wide (optional):

sudo cp /etc/nginx/ssl/$(hostname).crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

# To prevent error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413

sudo nano /etc/nginx/nginx.conf

# Add this line inside the "http {" block

        # To prevent error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 41
        client_max_body_size 500M;  # Increase limit from default 1MB to 500M

# Create the initial forgejo settings: copy, paste and enter (to pass the hostname values).

sudo tee /etc/forgejo/app.ini > /dev/null <<'EOF'
[server]
PROTOCOL                   = http
DOMAIN                     = $(hostname -d)
ROOT_URL                   = https://$(hostname -f)
APP_DATA_PATH              = /home/git/data
LOCAL_ROOT_URL             =

[session]
COOKIE_SECURE              = true
EOF

# Change /etc/forgejo/app.ini ownership

sudo chown git:git /etc/forgejo/app.ini
sudo chmod 644 /etc/forgejo/app.ini

# Create the NGINX site configuration: copy, paste, press enter.

sudo tee /etc/nginx/sites-available/forgejo.conf > /dev/null <<'EOF'
# --------------------------------------------------------------
# HTTP → HTTPS redirect (listen on port 80)
# --------------------------------------------------------------
server {
    listen 80;
    listen [::]:80;
    server_name $(hostname -f);
    
    # Redirect every request to the same URL but with https
    return 301 https://$host$request_uri;
}

# --------------------------------------------------------------
# TLS termination + reverse‑proxy to Forgejo (listen on 443)
# --------------------------------------------------------------
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name $(hostname -f);

    # ----- TLS certificates -----
    ssl_certificate     /etc/nginx/ssl/$(hostname).crt;
    ssl_certificate_key /etc/nginx/ssl/$(hostname).key;

    # ----- Recommended SSL settings (Mozilla intermediate profile) -----
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_timeout 1d;
    ssl_session_cache   shared:SSL:10m;

    # ----- HSTS (force browsers to stay on HTTPS) -----
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # ----- Proxy settings -----
    location / {
        # Forgejo runs internally on HTTP port 3000 (unchanged)
        proxy_pass http://127.0.0.1:3000;

        # Preserve original host and scheme for Forgejo’s own link generation
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Optional: increase timeout for large git pushes
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    # ----- Optional: static assets cache (speed up UI) -----
    location ~* \.(css|js|png|jpg|jpeg|svg|ico|woff2?)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        try_files $uri @forgejo;
    }

    # Fallback to the main proxy block if the static file isn’t found
    location @forgejo {
        proxy_pass http://127.0.0.1:3000;
    }
}
EOF

# Enable the site & test the NGINX config

sudo ln -sf /etc/nginx/sites-available/forgejo.conf /etc/nginx/sites-enabled/

# Test syntax (very important!)

sudo nginx -t

# You should see:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# Open firewall ports (if applicable)
# If you have ufw, firewalld, or a cloud‑provider security group, allow only 80 and 443 inbound:

# UFW example

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# (Optionally deny direct access to 3000 from outside)

sudo ufw deny 3000/tcp

# For firewalld:

sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --remove-port=3000/tcp --permanent   # optional
sudo firewall-cmd --reload

# Start both services

sudo service forgejo start
sudo service nginx start

# Finally, open your browser and go to http://<FQDN_here> to finish the setup.
# Yes, of course you will get the warning of self signed cert but other than that everything will work as intended.

Last edited by joser (Yesterday 19:34:27)

Offline

Board footer