<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://dev1galaxy.org/extern.php?action=feed&amp;tid=7889&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Dev1 Galaxy Forum / [HowTo] Install Forgejo with self signed cert on Devuan 6]]></title>
		<link>https://dev1galaxy.org/viewtopic.php?id=7889</link>
		<description><![CDATA[The most recent posts in [HowTo] Install Forgejo with self signed cert on Devuan 6.]]></description>
		<lastBuildDate>Mon, 06 Apr 2026 19:05:49 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[[HowTo] Install Forgejo with self signed cert on Devuan 6]]></title>
			<link>https://dev1galaxy.org/viewtopic.php?pid=63080#p63080</link>
			<description><![CDATA[<p>Forgejo, an alternative to Gitea.<br /><a href="https://forgejo.org" rel="nofollow">https://forgejo.org</a></p><p>Kernel version: 6.12.48+deb13-amd64<br />Binary file: forgejo-13.0.3-linux-amd64<br />Partition scheme: / 12%, swap 12%, /home -1<br />Does these matters? I don&#039;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&#039;t know what to tell you but create a swap partition and try again.</p><p># First, make sure the domain/host name on /etc/hosts it&#039;s like: IP &lt;FQDN&gt; &lt;hostname&gt;, for example for a local domain /etc/hosts should be like:<br />127.0.0.1&#160; &#160; localhost<br />192.168.1.10 myhost.mydomain.home myhost<br /># Where 192.168.1.10 is the local network IP for your local forgejo host, to verify it then execute:</p><div class="codebox"><pre><code>hostname -f</code></pre></div><p># The result should be for example:<br /><span class="bbc">myhost.mydomain.home</span><br /># This is a must since later we will use the variables FQDN and HOSTNAME to retreive those values automatically <br /># to generate the self signed cert and to avoid mistyping errors that could make the setup completely fail.</p><p># Install dependencies</p><div class="codebox"><pre><code>sudo apt install -y git git-lfs nginx openssl</code></pre></div><p># Download and install binary</p><div class="codebox"><pre><code>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</code></pre></div><p># Create git user on the system. Forgejo will run as that user, and when accessing git through <br /># SSH (which is the default), this user is part of the URL (for example <br /># in: git clone git@git.example.com:YourOrg/YourRepo.git the &quot;git&quot; at the left of @ is the user you’ll create now).</p><div class="codebox"><pre><code>sudo adduser --system --shell /bin/bash --gecos &#039;Git Version Control&#039; \
  --group --disabled-password --home /home/git git</code></pre></div><p># Create the directory where Forgejo’s config, called app.ini it&#039;s stored in. Initially it needs to be writable by Forgejo, <br /># but after the installation you can make it read-only even for Forgejo because then it shouldn’t modify it anymore.</p><div class="codebox"><pre><code>sudo mkdir -p /etc/forgejo/{ssl}
sudo chown -R root:git /etc/forgejo &amp;&amp; sudo chmod -R 770 /etc/forgejo</code></pre></div><p># In this case, below will use the path &quot;/home/git/&quot; where Forgejo will store its data, including your repositories,&#160; <br /># this in order to make it easier to preserve and backup when ussing separated /home partition and SQLite database, <br /># but that value can be modified to anything that suits best for you if you know what are you doing.</p><p># Create Forgejo service file, copy and paste from #!/bin/sh line to &quot;exit 0&quot; line and save.</p><div class="codebox"><pre><code>sudo nano /etc/init.d/forgejo</code></pre></div><p><span class="bbc">#!/bin/sh<br />### BEGIN INIT INFO<br /># Provides:&#160; &#160; &#160; &#160; &#160; forgejo<br /># Required-Start:&#160; &#160; $remote_fs $network $syslog<br /># Required-Stop:&#160; &#160; &#160;$remote_fs $network $syslog<br /># Should-Start:&#160; &#160; &#160; $local_fs<br /># Should-Stop:&#160; &#160; &#160; &#160;$local_fs<br /># Default-Start:&#160; &#160; &#160;2 3 4 5<br /># Default-Stop:&#160; &#160; &#160; 0 1 6<br /># Short-Description: Forgejo Git server daemon<br /># Description:&#160; &#160; &#160; &#160;Starts, stops, and manages the Forgejo service.<br />### END INIT INFO</span></p><p><span class="bbc"># Where Forgejo lives (binary, config, data)<br />FORGEJO_ROOT=&quot;/home/git/lib/forgejo&quot;<br />FORGEJO_BINARY=&quot;/usr/local/bin/forgejo&quot;<br />FORGEJO_WORK_DIR=&quot;/home/git/lib/forgejo&quot;<br />FORGEJO_USER=&quot;git&quot;<br />FORGEJO_GROUP=&quot;git&quot;</span></p><p><span class="bbc"># Config file<br />FORGEJO_CONFIG=&quot;/etc/forgejo/app.ini&quot;</span></p><p><span class="bbc"># Log files – same locations used by the systemd unit<br />FORGEJO_LOG_DIR=&quot;${FORGEJO_ROOT}/log&quot;<br />STDOUT_LOG=&quot;${FORGEJO_LOG_DIR}/stdout.log&quot;<br />STDERR_LOG=&quot;${FORGEJO_LOG_DIR}/stderr.log&quot;</span></p><p><span class="bbc"># PID file – used for status checks and clean shutdowns<br />PIDFILE=&quot;/var/run/forgejo.pid&quot;</span></p><p><span class="bbc"># Extra flags you might want to pass (e.g., --config)<br />DAEMON_OPTS=&quot;web --config ${FORGEJO_CONFIG}&quot;</span></p><p><span class="bbc">log_msg() {<br />&#160; &#160; echo &quot;[forgejo] $*&quot;<br />}</span></p><p><span class="bbc"># Ensure the binary exists before we try anything<br />[ -x &quot;${FORGEJO_BINARY}&quot; ] || {<br />&#160; &#160; log_msg &quot;Executable not found at ${FORGEJO_BINARY}. Aborting.&quot;<br />&#160; &#160; exit 1<br />}</span></p><p><span class="bbc"># Create log directory if missing<br />[ -d &quot;${FORGEJO_LOG_DIR}&quot; ] || mkdir -p &quot;${FORGEJO_LOG_DIR}&quot;<br />chown ${FORGEJO_USER}:${FORGEJO_GROUP} &quot;${FORGEJO_LOG_DIR}&quot;</span></p><p><span class="bbc">do_start() {<br />&#160; &#160; log_msg &quot;Starting Forgejo…&quot;<br />&#160; &#160; # Run as the dedicated user, detach, and capture PID<br />&#160; &#160; start-stop-daemon --start \<br />&#160; &#160; &#160; &#160; --quiet \<br />&#160; &#160; &#160; &#160; --background \<br />&#160; &#160; &#160; &#160; --make-pidfile \<br />&#160; &#160; &#160; &#160; --pidfile &quot;${PIDFILE}&quot; \<br />&#160; &#160; &#160; &#160; --chuid &quot;${FORGEJO_USER}:${FORGEJO_GROUP}&quot; \<br />&#160; &#160; &#160; &#160; --exec &quot;${FORGEJO_BINARY}&quot; \<br />&#160; &#160; &#160; &#160; -- ${DAEMON_OPTS} &gt;&gt;&quot;${STDOUT_LOG}&quot; 2&gt;&gt;&quot;${STDERR_LOG}&quot;<br />&#160; &#160; RET=$?<br />&#160; &#160; [ $RET -eq 0 ] &amp;&amp; log_msg &quot;Forgejo started (PID $(cat ${PIDFILE}))&quot;<br />&#160; &#160; return $RET<br />}</span></p><p><span class="bbc">do_stop() {<br />&#160; &#160; log_msg &quot;Stopping Forgejo…&quot;<br />&#160; &#160; if [ -f &quot;${PIDFILE}&quot; ]; then<br />&#160; &#160; &#160; &#160; PID=$(cat &quot;${PIDFILE}&quot;)<br />&#160; &#160; &#160; &#160; start-stop-daemon --stop --quiet --pid &quot;${PID}&quot; --retry=TERM/30/KILL/5<br />&#160; &#160; &#160; &#160; RET=$?<br />&#160; &#160; &#160; &#160; [ $RET -eq 0 ] &amp;&amp; rm -f &quot;${PIDFILE}&quot; &amp;&amp; log_msg &quot;Forgejo stopped&quot;<br />&#160; &#160; else<br />&#160; &#160; &#160; &#160; log_msg &quot;No PID file found – is Forgejo already stopped?&quot;<br />&#160; &#160; &#160; &#160; RET=1<br />&#160; &#160; fi<br />&#160; &#160; return $RET<br />}</span></p><p><span class="bbc">do_restart() {<br />&#160; &#160; do_stop &amp;&amp; do_start<br />}</span></p><p><span class="bbc">do_status() {<br />&#160; &#160; if [ -f &quot;${PIDFILE}&quot; ]; then<br />&#160; &#160; &#160; &#160; PID=$(cat &quot;${PIDFILE}&quot;)<br />&#160; &#160; &#160; &#160; if kill -0 &quot;$PID&quot; 2&gt;/dev/null; then<br />&#160; &#160; &#160; &#160; &#160; &#160; echo &quot;Forgejo is running (PID $PID)&quot;<br />&#160; &#160; &#160; &#160; &#160; &#160; return 0<br />&#160; &#160; &#160; &#160; else<br />&#160; &#160; &#160; &#160; &#160; &#160; echo &quot;Forgejo PID file exists but process is dead&quot;<br />&#160; &#160; &#160; &#160; &#160; &#160; return 1<br />&#160; &#160; &#160; &#160; fi<br />&#160; &#160; else<br />&#160; &#160; &#160; &#160; echo &quot;Forgejo is not running&quot;<br />&#160; &#160; &#160; &#160; return 3<br />&#160; &#160; fi<br />}</span></p><p><span class="bbc">case &quot;$1&quot; in<br />&#160; &#160; start)<br />&#160; &#160; &#160; &#160; do_start<br />&#160; &#160; &#160; &#160; ;;<br />&#160; &#160; stop)<br />&#160; &#160; &#160; &#160; do_stop<br />&#160; &#160; &#160; &#160; ;;<br />&#160; &#160; restart|force-reload)<br />&#160; &#160; &#160; &#160; do_restart<br />&#160; &#160; &#160; &#160; ;;<br />&#160; &#160; status)<br />&#160; &#160; &#160; &#160; do_status<br />&#160; &#160; &#160; &#160; ;;<br />&#160; &#160; *)<br />&#160; &#160; &#160; &#160; echo &quot;Usage: $0 {start|stop|restart|status}&quot;<br />&#160; &#160; &#160; &#160; exit 2<br />&#160; &#160; &#160; &#160; ;;<br />esac</span></p><p><span class="bbc">exit 0</span></p><p># Make it executable</p><div class="codebox"><pre><code>sudo chmod +x /etc/init.d/forgejo</code></pre></div><p># Enable the service auto-start at boot</p><div class="codebox"><pre><code>sudo update-rc.d forgejo defaults</code></pre></div><p># Generate self signed cert and key</p><div class="codebox"><pre><code>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 &quot;/CN=$(hostname -f)&quot; -reqexts v3_req -extensions v3_ca -out /etc/nginx/ssl/$(hostname).crt</code></pre></div><p># Change cert and key group permissions but maintaining root ownership</p><div class="codebox"><pre><code>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</code></pre></div><p># Prevent git error: server verification failed: certificate signer not trusted for your local repo/server</p><div class="codebox"><pre><code>git config --global http.&quot;https://$(hostname -f)/&quot;.sslCAInfo /etc/nginx/ssl/$(hostname).crt</code></pre></div><p># Copy the new certificate system wide (optional):</p><div class="codebox"><pre><code>sudo cp /etc/nginx/ssl/$(hostname).crt /usr/local/share/ca-certificates/
sudo update-ca-certificates</code></pre></div><p># To prevent error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413</p><div class="codebox"><pre><code>sudo nano /etc/nginx/nginx.conf</code></pre></div><p># Add this line inside the &quot;http {&quot; block</p><p><span class="bbc">&#160; &#160; &#160; &#160; # To prevent error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 41<br />&#160; &#160; &#160; &#160; client_max_body_size 500M;&#160; # Increase limit from default 1MB to 500M</span></p><p># Create the initial forgejo settings: copy, paste and enter (to pass the hostname values).</p><div class="codebox"><pre><code>sudo tee /etc/forgejo/app.ini &gt; /dev/null &lt;&lt;&#039;EOF&#039;
[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</code></pre></div><p># Change /etc/forgejo/app.ini ownership</p><div class="codebox"><pre><code>sudo chown git:git /etc/forgejo/app.ini
sudo chmod 644 /etc/forgejo/app.ini</code></pre></div><p># Create the NGINX site configuration: copy, paste, press enter.</p><div class="codebox"><pre class="vscroll"><code>sudo tee /etc/nginx/sites-available/forgejo.conf &gt; /dev/null &lt;&lt;&#039;EOF&#039;
# --------------------------------------------------------------
# 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 &quot;max-age=31536000; includeSubDomains; preload&quot; 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 &quot;public, immutable&quot;;
        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</code></pre></div><p># Enable the site &amp; test the NGINX config</p><div class="codebox"><pre><code>sudo ln -sf /etc/nginx/sites-available/forgejo.conf /etc/nginx/sites-enabled/</code></pre></div><p># Test syntax (very important!)</p><div class="codebox"><pre><code>sudo nginx -t</code></pre></div><p># You should see:<br /><span class="bbc">nginx: the configuration file /etc/nginx/nginx.conf syntax is ok<br />nginx: configuration file /etc/nginx/nginx.conf test is successful</span></p><p># Open firewall ports (if applicable)<br /># If you have ufw, firewalld, or a cloud‑provider security group, allow only 80 and 443 inbound:</p><p># UFW example</p><div class="codebox"><pre><code>sudo ufw allow 80/tcp
sudo ufw allow 443/tcp</code></pre></div><p># (Optionally deny direct access to 3000 from outside)</p><div class="codebox"><pre><code>sudo ufw deny 3000/tcp</code></pre></div><p># For firewalld:</p><div class="codebox"><pre><code>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</code></pre></div><p># Start both services </p><div class="codebox"><pre><code>sudo service forgejo start
sudo service nginx start</code></pre></div><p># Finally, open your browser and go to http://&lt;FQDN_here&gt; to finish the setup.<br /># Yes, of course you will get the warning of self signed cert but other than that everything will work as intended.</p>]]></description>
			<author><![CDATA[dummy@example.com (joser)]]></author>
			<pubDate>Mon, 06 Apr 2026 19:05:49 +0000</pubDate>
			<guid>https://dev1galaxy.org/viewtopic.php?pid=63080#p63080</guid>
		</item>
	</channel>
</rss>
