Build Apache HTTP Server on Ubuntu 24 and Configure It as a Git Server

5 days ago 1

Overview

This brief article shows by example how to build the Apache HTTP Server from source on Ubuntu 24.04 LTS and configure it as an HTTP GIT server to support operations like git clone and git push via HTTP. There are many options to choose from when setting up an Apache HTTP Server; however, creating a server on an internal LAN for the purpose of acting as a Git server is fairly straightforward.

Building the HTTP Server from the Apache SVN is surprisingly simple, and the server configuration from source has a different, more straightforward approach than the Ubuntu package version, which splits the server configuration into multiple files, folders, and helpers. If you're new to Apache on Ubuntu, you may find you like working with the upstream version better.

Note that the steps shown below may be suitable for internal development on a private network, but additional research and care should be applied before hosting an HTTP (Git) server on a public port accessible via the Internet. Fortunately, Apache has great documentation, and many good references are provided at the end of this article.

Configure, Build, and Install Apache HTTP

Our first step is to use SVN to check out the latest 2.4.x version:

# install some dependencies $ sudo apt install subversion libtool-bin autoconf libpcre2-dev $ cd /build $ svn co https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x/ httpd-2.4.x ... A http-2.4.x/InstallBin.dsp A http-2.4.x/httpd.dsp U http-2.4.x Checked out revision 1925633. $ cd /build/httpd-2.4.x # Build the APR from source along with httpd $ svn co http://svn.apache.org/repos/asf/apr/apr/trunk srclib/apr # configure doesn't exist after svn checkout $ ./buildconf found apr source: srclib/apr rebuilding srclib/apr/configure buildconf: checking installation... buildconf: python version 3.12.0a1+ (ok) buildconf: autoconf version 2.69 (ok) buildconf: libtool version 2.4.6 (ok) buildconf: copying libtool helper files using /usr/bin/libtoolize buildconf: creating include/arch/unix/apr_private.h.in ... buildconf: creating configure ... buildconf: generating 'make' outputs ... buildconf: rebuilding rpm spec file copying build files rebuilding include/ap_config_auto.h.in rebuilding configure rebuilding rpm spec file buildconf: Fixing timestamps for ap_expr sources to prevent regeneration

Our next step is to configure and build httpd. Note that we'll be installing the server into /opt/apache2/:

$ CFLAGS="-Og" ./configure --prefix=/opt/apache2 --enable-debugger-mode --enable-rewrite --enable-log-debug configure: summary of build options: Server Version: 2.4.64 Install prefix: /opt/apache2 C compiler: gcc CFLAGS: -Og -O0 -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -Werror=declaration-after-statement -Wpointer-arith -Wformat -Wformat-security -Werror=format-security CPPFLAGS: -DLINUX -D_REENTRANT -D_GNU_SOURCE -DAP_DEBUG LDFLAGS: LIBS: C preprocessor: gcc -E $ make $ make install ... Installing configuration files mkdir /opt/apache2/conf mkdir /opt/apache2/conf/extra mkdir /opt/apache2/conf/original mkdir /opt/apache2/conf/original/extra Installing HTML documents mkdir /opt/apache2/htdocs Installing error documents mkdir /opt/apache2/error Installing icons mkdir /opt/apache2/icons mkdir /opt/apache2/logs Installing CGIs mkdir /opt/apache2/cgi-bin Installing header files Installing build system files Installing man pages and online manual mkdir /opt/apache2/man mkdir /opt/apache2/man/man1 mkdir /opt/apache2/man/man8 mkdir /opt/apache2/manual make[1]: Leaving directory '/build/httpd-2.4.x'

Let's perform some introspection of our installation:

$ ls /opt/apache2 bin build cgi-bin conf error htdocs icons include lib logs man manual modules state $ ls /opt/apache2/bin/ ab apxs envvars htcacheclean htpasswd logresolve apachectl checkgid envvars-std htdbm httpd rotatelogs apr-2-config dbmmanage fcgistarter htdigest httxt2dbm $ ldd /opt/apache2/bin/httpd linux-vdso.so.1 (0x00007104a07b3000) libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007104a064b000) libapr-2.so.0 => /opt/apache2/lib/libapr-2.so.0 (0x00007104a05da000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007104a0200000) libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007104a05a0000) libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007104a0574000) /lib64/ld-linux-x86-64.so.2 (0x00007104a07b5000) $ ls /opt/apache2/lib/ apr.exp libapr-2.a libapr-2.la libapr-2.so libapr-2.so.0 libapr-2.so.0.0.0 pkgconfig $ /opt/apache2/bin/apachectl -V Server version: Apache/2.4.64-dev (Unix) Server built: May 17 2025 10:37:02 Server's Module Magic Number: 20120211:138 Server loaded: APR 2.0.0-dev, PCRE 10.42 2022-12-11 Compiled using: APR 2.0.0-dev, PCRE 10.42 2022-12-11 Architecture: 64-bit Server MPM: event threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_PROC_PTHREAD_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/opt/apache2" -D SUEXEC_BIN="/opt/apache2/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"

Next we make a couple of tweaks to the configuration file (/opt/apache2/conf/httpd.conf) so we don't run as root:

Listen 8001 ServerName <hostname>:8001

Let's give it a quick try - httpd should serve up /opt/apache2/htdocs/index.html as shown below:

$ /opt/apache2/bin/apachectl -k start $ ps -e | grep httpd 14056 ? 00:00:00 httpd ... $ wget localhost:8001 ... HTTP request sent, awaiting response... 200 OK Length: 45 [text/html] Saving to: ‘index.html’ ... $ more index.html <html><body><h1>It works!</h1></body></html>

Configure Apache to work with Git

For this step, we'll follow the guidance provided by the Pro Git ebook to set up a Smart HTTP server that supports authentication and operations like git push. From the reference: "The idea is that Git comes with a CGI called git-http-backend that when invoked will do all the negotiation to send and receive data over HTTP."

Make sure mod_cgi, mod_alias and mod_env modules are being loaded:

LoadModule cgid_module modules/mod_cgid.so LoadModule alias_module modules/mod_alias.so LoadModule env_module modules/mod_env.so

Below, we modify httpd.conf to configure the ScriptAlias directive and environment variables to assoiate our file path /opt/depot with our Ubuntu Git CGI. The environment variables are passed to the git-http-backend CGI.

ScriptAlias /git/ /usr/lib/git-core/git-http-backend/ SetEnv GIT_PROJECT_ROOT /opt/depot SetEnv GIT_HTTP_EXPORT_ALL

Below we continue to follow the aforementioned Pro Git refernece and setup basic authentication using .htpasswd with the following additions to our httpd.conf conf file.

<Files "git-http-backend"> AuthType Basic AuthName "Git Access" AuthUserFile /opt/depot/.htpasswd Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#) Require valid-user </Files>

Our last step before trying to clone, modify, commit, and push via HTTP is to set up our username and password:

$ htpasswd -c /opt/depot/.htpasswd <username>

Now we should be able to interact with our Git repo (server) using HTTP:

$ git clone http://<hostname>:8001/git/privateisland.git Cloning into 'privateisland'...

Troubleshooting

If you see the error log below, it may be due to your permissions. If your Git repo is owned by you while testing, then set the User in httpd.conf to your username instead of the default "daemon". However, you will want to change this back once you're done your initial testing and configuration.

/usr/lib/git-core/git-http-backend: unable to connect to cgi daemon after multiple tries

And if you see the error shown below when trying to perform a push (write), again make sure your permissions are set up properly so the daemon process can perform writes:

client:

$ git push ... error: remote unpack failed: unable to create temporary object directory

server:

$ ps -ef | grep httpd root 18715 1 0 16:43 ? 00:00:00 /opt/apache2/bin/httpd -k start daemon 18716 18715 0 16:43 ? 00:00:00 /opt/apache2/bin/httpd -k start $ chmod -R 774 <path to repo> $ chgrp -R daemon <path to repo>

If you get into a state where apachectl can't start or restart, but the httpd processes are still running, you may want to kill all httpd processes and start again:

# apachectl -k restart error.... # ps -e | grep httpd 4335 ? 00:00:00 httpd 4452 ? 00:00:00 httpd 4453 ? 00:00:00 httpd ... # killall httpd # ps -e | grep httpd # apachectl -k start

apachectl

apachectl is a front-end command-line interface to the Apache HTTP server. Below we show various examples with the server we just built.

# Parse the configuration file $ apachectl -S ... ServerRoot: "/opt/apache2" Main DocumentRoot: "/opt/apache2/htdocs" Main ErrorLog: "/opt/apache2/logs/error_log" ... # Is our configuration syntax OK? $ apachectl -t Syntax OK

Terms and Acronyms

  • APXS: Apache Extension Tool is a "is a tool for building and installing extension modules for the Apache HTTP server".
  • APR: Apache Portable Runtime "create and maintain software libraries that provide a predictable and consistent interface to underlying platform-specific implementations"
  • CGI: Common Gateway Interface
  • DSO: Dynamic Shared Objects: Modules are ""compiled as DSOs that exist separately from the main httpd binary file"
  • MPM: Multi-Processing Modules "implement the basic behavior of the server. A single MPM must be active in order for the server to function."
  • PCRE: Perl-Compatible Regular Expressions Library
  • VHOST: Virtual Host is the practice of running more than one web site on a single PC / machine.

References

Didn't find an answer to your question? Post your issue below or in our new FORUM, and we'll try our best to help you find a solution.

And please note that we update our site daily with new content related to our open source approach to network security and system design. If you would like to be notified about these changes, then please join our mailing list.

Read Entire Article