HowTo: Installing and running Gitlab

I originally installed Gitlab on FreeBSD 12.4 attempting to follow the article at [1]. While this is a good starting point, things have changed over time because there were numerous things not mentioned that need to be done to get things going properly.

So I started this post with the intent to outline the whole installation procedure. It should work on a recent 12.4 and 13.2 alike.

Requirements​

Obviously, you need a recent and up-to-date FreeBSD install; you may use either everything on one box, or separate the database onto a different box, vm or jail.
  • FreeBSD 12.4 or FreeBSD 13.2
  • internet access is set up and working
  • recent patches installed

Install packages​

To install all necessary packages, run

Code:
# pkg install gitlab-ce nginx ssmtp go120

On your database system, run

Code:
# pkg install postgresql12-server postgresql12-contrib

If you are running the database on your webserver, you just add those packages to your pkg install command when installing the application packages.

You do need to install the -contrib package as well, because Gitlab requires database extensions to be installed for its database.

I won't outline how to get your PostgreSQL database up and running; I believe, there are numerous other complete How-Tos out there that outline this process in sufficient detail. Suffice it to say, you need to get your database up and running, before proceeding further.

Prepare git user​

It appears, Gitlab requires a proper home directory for the gituser:

Code:
mkdir -p /usr/home/git
chown git:git /usr/home/git
pw usermod git -d /usr/home/git

Configure outbound email​

We previously installed ssmtp to allow sending outbound emails; its setup is simpler than sendmail's. Simply do

Code:
# sysrc sendmail_enable=NONE
# service sendmail stop

Then replace /etc/mail/mailer.conf settings via

Code:
# ee /etc/mail/mailer.conf

and configure

Code:
#sendmail       /usr/libexec/sendmail/sendmail
#mailq          /usr/libexec/sendmail/sendmail
#newaliases     /usr/libexec/sendmail/sendmail
#hoststat       /usr/libexec/sendmail/sendmail
#purgestat      /usr/libexec/sendmail/sendmail

sendmail        /usr/local/sbin/ssmtp
send-mail       /usr/local/sbin/ssmtp
mailq           /usr/local/sbin/ssmtp
newaliases      /usr/local/sbin/ssmtp
hoststat        /usr/bin/true
purgestat       /usr/bin/true

To configure your mail server settings, edit

Code:
ee /usr/local/etc/ssmtp/ssmtp.conf

Test your configuration and confirm it's in working order by using

Code:
mail <emailaddress>

to write an email to a public email address.

Prepare database​

Having an up and running database server, log in on that server. You need to prepare a database account and - at least for the installation - provide it superuser permissions. Gitlab's database setup script drops any previously existing database, creates a new instance and then attempts installing extensions. The latter fails unless the user running the migration script has superuser permissions.

Once the database has been set up by Gitlab, you can of course remove superuser privileges. We'll do this in the course of this installation at a later stage, once we are done with database tables setup.

For now, switch to the postgres user and prepare a user.

Code:
$ su - postgres
# createuser -P -s gitlab

Enter a password when queried. Store that password (from now on called DB-GITLAB-SECRET) database in a safe location - you'll need it later.

If you are running your database on a separate server, you'll need to authorize your Gitlab server to access the database.

Code:
ee /var/db/postgres/data12/pg_hba.conf

Add the following lines:

Code:
host    <dbname>     gitlab     <ipaddress>/32       password
host    postgres     gitlab     <ipaddress>/32       password

You'll have to restart the daemon afterwards

Code:
service postgresql restart

Configure Redis​

Gitlab requires redis to be configured and running. So we update /usr/local/etc/redis.conf to provide a unix socket, which can be written to by the git user, because Gitlab runs under this user.

Code:
$ su
# ee /usr/local/etc/redis.conf

Look for the line with unixsocket and update to

Code:
unixsocket /var/run/redis/redis.sock
unixsocketperm 770

Be sure to use this path precisely, because it is expected to be that by Gitlab.

Now, add the git user to the redis group to allow it use redis:

Code:
# pw usermod git -G redis

Then enable redis and start the server

Code:
# sysrc redis_enable=YES
# service redis start

Configure Gitlab​

On your web server, there are a few important directories you need to keep in mind for your Gitlab installation
  • /usr/local/www/gitlab-ce is the root path for the Gitlab installation
  • /usr/local/www/gitlab-ce/config contains configuration files of all sorts
  • /usr/local/www/gitlab-ce/log contains log files, which help for troubleshooting of all sorts
  • /usr/local/etc/nginx nginx configuration directory
We need to prepare the directory for Gitlab's repository storage:

Code:
$ su
# mkdir -p /usr/local/git/repositories
# chown git:git /usr/local/git/repositories

Unless we create this directory, the gitaly git integration service won't be able to start. So, if that fails to initialize for you, make sure you created this directory.

Switch to the git user and update some of its global git settings:

Code:
# su - git
$ git config --global core.autocrlf input
$ git config --global gc.auto 0
$ git config --global repack.writeBitmaps true
$ git config --global receive.advertisePushOptions true

Then open up /usr/local/www/gitlab-ce/config/gitlab.yml and update your host and database configuration.

Code:
$ su
# ee /usr/local/www/gitlab-ce/config/gitlab.yml

Leave http and port properties as they are - we will run the web front end through nginx, which means, those port settings are obsolete anyways. Make sure to fix email_from and other relevant email_* variables however.

The actual mail transport settings are configured in /usr/local/www/gitlab-ce/config/initializers/smtp_settings.rb. Open this file now with

Code:
# ee /usr/local/www/gitlab-ce/config/initializers/smtp_settings.rb

Modify the following lines:

Code:
Rails.application.config.action_mailer.delivery_method = :sendmail
ActionMailer::Base.delivery_method = :sendmail

This saves us from troubleshooting email functionality in ruby. As long as your system mail works via ssmtp, you're good to go.

Open Gitlab's database settings file and update "production" configuration settings:

Code:
# ee /usr/local/www/gitlab-ce/config/database.yml

Use the DB-GITLAB-SECRET secret and database user you previously created.

Prepare database tables​

For database migration, we need to allow user git some write permissions on directories where it will maintain some of its secrets. We will revoke those permissions once the database setup is completed.

Code:
# chown git /usr/local/share/gitlab-shell
# su - git
$ cd /usr/local/www/gitlab-ce/
$ rake gitlab:setup RAILS_ENV=production
$ exit
# chown root /usr/local/share/gitlab-shell

This takes a while, so be patient.

Precompile frontend​

Run

Code:
$ su - git
$ cd /usr/local/www/gitlab-ce/
$ rake gettext:compile RAILS_ENV=production
$ yarn install --production --pure-lockfile
$ rake gitlab:assets:compile RAILS_ENV=production NODE_ENV=production

This takes a long time to complete. Again, be patient.

In case you run into certificate errors like

Code:
error An unexpected error occurred: "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz: unable to get local issuer certificate".

during your yarn run, you can

Code:
yarn config set "strict-ssl" false -g

rerun yarn and then

Code:
yarn config set "strict-ssl" true -g

to circumvent the issue.

Enable Gitlab service and start​

Now, we allow gitlab to actually start and ensure it will also do so after a reboot.

Code:
$ su
# sysrc gitlab_enable=YES
# service gitlab start

Enable web server​

Edit /usr/local/etc/nginx/nginx.conf and add

Code:
include       /usr/local/www/gitlab-ce/lib/support/nginx/gitlab;

into the http section. Remove the server settings for the port 80 server and instead add

Code:
http {
 ...
 server {
  listen       <ipaddress>:80;
  server_name  <fqdn>;
  return       301 https://$server_name$request_uri;
 }
 ...
 include /usr/local/www/gitlab-ce/lib/support/nginx/gitlab;
 ...
}

This will redirect all HTTP requests to HTTPS instead.

Finally, edit /usr/local/www/gitlab-ce/lib/support/nginx/gitlab to enable HTTPS instead of HTTP.

Code:
$ su
# ee /usr/local/etc/nginx/nginx.conf

In the server section add

Code:
server {
 listen <ipaddress>:443 ssl;
 ssl_certificate /usr/local/etc/ssl/<certname>;
 ssl_certificate_key /usr/local/etc/ssl/<privatekey>;
 ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
 ssl_ciphers         HIGH:!aNULL:!MD5;
 server_name <fqdn>;
}

Finally, run

Code:
$ su
# sysrc nginx_enable=YES
# service nginx start

Completion​

Once nginx is up and running, you should be able to point your browser at

Code:
https://<fqdn>

and get asked for a new root user password. Enter a secure password and proceed to login as root.

I got a 404 after login, but after once again going back to

Code:
https://<fqdn>

I was finally in. You should then - as suggested - disable public user registration unless you do want to run a public site.
 
Yeah, just follow the instructions the port's pkg-message points too. It also points to instructions in case you're upgrading gitlab (for patch updates and version upgrades). Those instructions are excellent.
 
Yeah, just follow the instructions the port's pkg-message points too. It also points to instructions in case you're upgrading gitlab (for patch updates and version upgrades). Those instructions are excellent.
THIS.

Gitlab is often very picky when it comes to upgrades with 'larger' version jumps - i.e. you should follow the patch-releases at least somewhat closely, because bigger jumps even within a major version are often a PITA, let alone jumps over one (or more) major releases which may end in a dead-end and require manual transfer of every single project, as gitlab has absolutely no mechanism/tooling for any dump/restore (been there, done that...).
Some updates also have various caveats and/or require additional steps/migrations which are taken care of in those official instructions of the port.
Huge respect and many thanks to the maintainer for that!
 
Good point on the pkg-message. When I did my pkg install, it installed so many other packages, that I failed to realize that its message went under in the sea of other messages. Go figure.

Overall, I agree - the port is really well done. I might disagree with having the log directory under /usr/local, but that's really nitpicking at the end.
 
In case you missed it when it scrolls by with a bunch of other messages: pkg info -D gitlab-ce
 
I've been following this pretty manual from the first message but failed with it:

Code:
$ rake gettext:compile RAILS_ENV=production
WARNING: The Rust extension for prometheus-client-mmap is unavailable, falling back to the legacy C extension.
  The Rust extension will be required in the next version. If you are compiling this gem from source,
  ensure your build system has a Rust compiler and clang: https://gitlab.com/gitlab-org/ruby/gems/prometheus-client-mmap
node:internal/modules/cjs/loader:1080
  throw err;
  ^

Error: Cannot find module 'commander'
Require stack:
- /usr/local/www/gitlab-ce/scripts/frontend/po_to_json.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:119:18)
    at Object.<anonymous> (/usr/local/www/gitlab-ce/scripts/frontend/po_to_json.js:175:27)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:86:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/usr/local/www/gitlab-ce/scripts/frontend/po_to_json.js' ]
}

Node.js v18.18.2
Error: Unable to convert gettext files to js.
 
Can you try this - the official documentation seems to have slightly different commands now:
Code:
su -l git -c "cd /usr/local/www/gitlab-ce && rake gitlab:env:info RAILS_ENV=production"
su -l git -c "cd /usr/local/www/gitlab-ce && yarn install --production --pure-lockfile"
su -l git -c "cd /usr/local/www/gitlab-ce && RAILS_ENV=production NODE_ENV=production USE_DB=false SKIP_STORAGE_VALIDATION=true NODE_OPTIONS='--max_old_space_size=3584' bundle exec rake gitlab:assets:compile"
 
I ran into problems with cyclic locale:
Had to manually re-symlink.
Fix found in this thread:

and in the bug report:

 
Can you try this - the official documentation seems to have slightly different commands now:
Code:
su -l git -c "cd /usr/local/www/gitlab-ce && rake gitlab:env:info RAILS_ENV=production"
su -l git -c "cd /usr/local/www/gitlab-ce && yarn install --production --pure-lockfile"
su -l git -c "cd /usr/local/www/gitlab-ce && RAILS_ENV=production NODE_ENV=production USE_DB=false SKIP_STORAGE_VALIDATION=true NODE_OPTIONS='--max_old_space_size=3584' bundle exec rake gitlab:assets:compile"

I am getting the following error:


Code:
su -l git -c "cd /usr/local/www/gitlab && rake gitlab:env:info RAILS_ENV=production"

System information
System:
Current User:   git
Using RVM:      no
Ruby Version:   3.2.6
Gem Version:    3.5.23
Bundler Version:2.5.23
Rake Version:   13.2.1
Redis Version:  7.4.1
Sidekiq Version:7.2.4
Go Version:     unknown

GitLab information
Version:        17.6.0
Revision:       Unknown
Directory:      /usr/local/www/gitlab
DB Adapter:     PostgreSQL
DB Version:     17.2
URL:            http://localhost
HTTP Clone URL: http://localhost/some-group/some-project.git
SSH Clone URL:  git@localhost:some-group/some-project.git
Using LDAP:     no
Using Omniauth: yes
Omniauth Providers:

GitLab Shell
Version:        14.39.0
Repository storages:
- default:      unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket
GitLab Shell path:              /usr/local/share/gitlab-shell

Gitaly
rake aborted!
GRPC::Unavailable: 14:connections to all backends failing; last error: FAILED_PRECONDITION: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket: connect failed: addr: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket error: No such file or directory. debug_error_string:{UNKNOWN:Error received from peer  {grpc_message:"connections to all backends failing; last error: FAILED_PRECONDITION: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket: connect failed: addr: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket error: No such file or directory", grpc_status:14, created_time:"2024-11-28T21:36:17.170801801+02:00"}} (GRPC::Unavailable)
/usr/local/www/gitlab/lib/gitlab/gitaly_client.rb:292:in `execute'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/call.rb:18:in `block in call'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/call.rb:60:in `recording_request'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/call.rb:17:in `call'
/usr/local/www/gitlab/lib/gitlab/gitaly_client.rb:281:in `call'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/server_service.rb:14:in `info'
/usr/local/www/gitlab/lib/tasks/gitlab/info.rake:99:in `block (4 levels) in <top (required)>'
/usr/local/www/gitlab/lib/tasks/gitlab/info.rake:97:in `block (3 levels) in <top (required)>'
Tasks: TOP => gitlab:env:info
(See full trace by running task with --trace)

$ ls /usr/local/www/gitlab/tmp/sockets/private/gitaly.socket
ls: /usr/local/www/gitlab/tmp/sockets/private/gitaly.socket: No such file or directory
$ ls /usr/local/www/gitlab/tmp/sockets/private/
internal


Anyone encountering it?
 
I am getting the following error:


Code:
su -l git -c "cd /usr/local/www/gitlab && rake gitlab:env:info RAILS_ENV=production"

System information
System:
Current User:   git
Using RVM:      no
Ruby Version:   3.2.6
Gem Version:    3.5.23
Bundler Version:2.5.23
Rake Version:   13.2.1
Redis Version:  7.4.1
Sidekiq Version:7.2.4
Go Version:     unknown

GitLab information
Version:        17.6.0
Revision:       Unknown
Directory:      /usr/local/www/gitlab
DB Adapter:     PostgreSQL
DB Version:     17.2
URL:            http://localhost
HTTP Clone URL: http://localhost/some-group/some-project.git
SSH Clone URL:  git@localhost:some-group/some-project.git
Using LDAP:     no
Using Omniauth: yes
Omniauth Providers:

GitLab Shell
Version:        14.39.0
Repository storages:
- default:      unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket
GitLab Shell path:              /usr/local/share/gitlab-shell

Gitaly
rake aborted!
GRPC::Unavailable: 14:connections to all backends failing; last error: FAILED_PRECONDITION: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket: connect failed: addr: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket error: No such file or directory. debug_error_string:{UNKNOWN:Error received from peer  {grpc_message:"connections to all backends failing; last error: FAILED_PRECONDITION: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket: connect failed: addr: unix:/usr/local/www/gitlab/tmp/sockets/private/gitaly.socket error: No such file or directory", grpc_status:14, created_time:"2024-11-28T21:36:17.170801801+02:00"}} (GRPC::Unavailable)
/usr/local/www/gitlab/lib/gitlab/gitaly_client.rb:292:in `execute'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/call.rb:18:in `block in call'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/call.rb:60:in `recording_request'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/call.rb:17:in `call'
/usr/local/www/gitlab/lib/gitlab/gitaly_client.rb:281:in `call'
/usr/local/www/gitlab/lib/gitlab/gitaly_client/server_service.rb:14:in `info'
/usr/local/www/gitlab/lib/tasks/gitlab/info.rake:99:in `block (4 levels) in <top (required)>'
/usr/local/www/gitlab/lib/tasks/gitlab/info.rake:97:in `block (3 levels) in <top (required)>'
Tasks: TOP => gitlab:env:info
(See full trace by running task with --trace)

$ ls /usr/local/www/gitlab/tmp/sockets/private/gitaly.socket
ls: /usr/local/www/gitlab/tmp/sockets/private/gitaly.socket: No such file or directory
$ ls /usr/local/www/gitlab/tmp/sockets/private/
internal


Anyone encountering it?
gitaly is not running.
I've installed it as a separate package and then run it as a git user, only then aforementioned check is passing.
 
gitaly is not running.
Gitaly should be started with service gitlab start. That will start a whole bunch of required components, including gitaly.

Follow the installation instructions from the pkg-message.
 
Gitaly should be started with service gitlab start. That will start a whole bunch of required components, including gitaly.

Follow the installation instructions from the pkg-message.
Yes. But eXRuLeZz had problem with some precheck that is meant to be executed before gitlab is started. Today I have experienced the same issue. And yes, later 'service gitlab start' starts also gitaly.
 
Back
Top