In this article, we will explain how to install a GitLab server on FreeBSD. For greater flexibility, I will install it in a jail using Bastille Before we begin, it should be noted that GitLab is an application written in Ruby, so we will have the Ruby server that incorporates GitLab and the web server of our choice that will forward requests to GitLab and serve static content.
We create the jail:
We enable and start the SSH service:
We access the jail:
According to the
documentation
, we must use the latest repositories:
FreeBSD: {
url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/keys/pkg",
enabled: yes
We install GitLab:
We install the latest version of PostgreSQL that is compatible with the version of GitLab we are installing, in my case:
gitlab-ce-15.5.6_1
The only way I have found to find out the correct version is to install the highest version and descend until the installer does not try to uninstall GitLab:
Installed packages to be REMOVED:
gitlab-ce: 15.5.6_1
postgresql13-client: 13.9
rubygem-activerecord-explain-analyze: 0.1.0_4
rubygem-pg: 1.4.4
New packages to be INSTALLED:
postgresql15-client: 15.1
postgresql15-contrib: 15.1
postgresql15-server: 15.1_1
We install PostgreSQL:
PostgreSQL requires access to sysvipc, but jails are restricted by default.
We allow access per jail, it can also be allowed globally on the parent host for all jails, but it is preferable to be more granular:
NOTE: Do not use allow.sysvipc as it is considered deprecated and grants more permissions than strictly necessary.
Restart the jail:
Initialize and start the database:
Create the git user in the database:
Create the database that GitLab will use:
Check that it has been created:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------------+----------+----------+---------+---------+-----------------------
gitlabhq_production | git | UTF8 | C | C.UTF-8 |
postgres | postgres | UTF8 | C | C.UTF-8 |
template0 | postgres | UTF8 | C | C.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C | C.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
Allow access from the server’s own IP:
# GitLab:
host all git 192.168.69.16/32 md5
Restart the service:
Check that we can connect with the git user:
Enable the pg_trgm and btree_gist extensions:
GitLab will have installed a Redis as a dependency, enable socket access:
Indicate the socket permissions:
Enable and start Redis:
Add the git user to the redis group:
We dont configure GitLab to use SSL because I use an HTTP balancer where the SSL tunnel is finished, I must indicate the IP of said balancer in trusted_proxies. Finally, I need to specify the email account to use for sending notifications:
We create an email user on the email server:
[email protected]
adduser
We copy the example SMTP configuration and adapt it:
if Rails.env.production?
Rails.application.config.action_mailer.delivery_method = :smtp
secrets = Gitlab::Email::SmtpConfig.secrets
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
address: "192.168.69.17",
port: 25,
user_name: "[email protected]",
password: "XXXXXXXXXXX",
## If you are using encrypted smtp credentials then you should instead use the secrets user_name/password
## See: https://docs.gitlab.com/ee/administration/raketasks/smtp.html#secrets
# user_name: secrets.username,
# password: secrets.password,
domain: "flatland.alfaexploit.com",
authentication: :login,
enable_starttls_auto: true,
openssl_verify_mode: 'peer' # See ActionMailer documentation for other possible options
We configure the key with which the database will be encrypted:
db_key_base: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
We check the number of cores the server has:
hw.ncpu: 2
For a server with 2GB of RAM, 3 workers usually work well, but workers>=hw.ncpu must always be met:
workers 3
We configure some options for the git user so that GitLab works correctly:
We make sure that the .ssh directory exists:
We make sure that the repository directory exists and has the necessary permissions:
We configure the access credentials to PostgreSQL:
production:
main:
adapter: postgresql
encoding: unicode
database: gitlabhq_production
username: git
password: "XXXXXXXXXXXXXXX"
host: localhost
adapter: postgresql
encoding: unicode
database: gitlabhq_production
database_tasks: false
username: git
password: "XXXXXXXXXXXXXXX"
host: localhost
We adjust the permissions of the /usr/local/share/gitlab-shell directory so that the git user has access while initializing the database and performing the initial configuration:
We initialize the database indicating the access password for root. The first time, RSA keys are generated based on the indicated db_key_base. For this reason, it will say missing Rails.application.secrets.secret_key_base, but it refers to the RSA key, not the password, so everything is fine:
Missing Rails.application.secrets.secret_key_base for production environment. The secret will be generated and stored in config/secrets.yml.
Missing Rails.application.secrets.otp_key_base for production environment. The secret will be generated and stored in config/secrets.yml.
Missing Rails.application.secrets.openid_connect_signing_key for production environment. The secret will be generated and stored in config/secrets.yml.
This will create the necessary database tables and seed the database.
You will lose any previous data stored in the database.
Do you want to continue (yes/no)? yes
Dropped database 'gitlabhq_production'
Created database 'gitlabhq_production'
== Seed from /usr/local/www/gitlab-ce/db/fixtures/production/001_application_settings.rb
Creating the default ApplicationSetting record.
== Seed from /usr/local/www/gitlab-ce/db/fixtures/production/002_admin.rb
Administrator account created:
login: root
password: ******
Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead.(called from: /usr/local/lib/ruby/gems/3.0/gems/redis-namespace-1.9.0/lib/redis/namespace.rb:479:in `call_with_namespace')
== Seed from /usr/local/www/gitlab-ce/db/fixtures/production/003_create_base_work_item_types.rb
== Seed from /usr/local/www/gitlab-ce/db/fixtures/production/004_add_security_training_providers.rb
== Seed from /usr/local/www/gitlab-ce/db/fixtures/production/010_settings.rb
Saved CI JWT signing key
== Seed from /usr/local/www/gitlab-ce/db/fixtures/production/998_gitlab_instance_administration_project.rb
Successfully created self monitoring project.
Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead.(called from: /usr/local/lib/ruby/gems/3.0/gems/redis-namespace-1.9.0/lib/redis/namespace.rb:479:in `call_with_namespace')
Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead.(called from: /usr/local/lib/ruby/gems/3.0/gems/redis-namespace-1.9.0/lib/redis/namespace.rb:479:in `call_with_namespace')
== Seed from /usr/local/www/gitlab-ce/db/fixtures/production/999_common_metrics.rb
If it complains about unsupported database names: embedding, we should comment the embedding section:
ERROR: This installation of GitLab uses unsupported database names in 'config/database.yml': embedding. The only supported ones are main, ci, main_clusterwide.
test: &test
# embedding:
# adapter: postgresql
# encoding: unicode
# database: gitlabhq_embedding_test
# username: postgres
# password:
# host: localhost
We backup the secrets:
Now that we have initialized the database, we can revert the assigned permissions:
We check that the entire GitLab environment is working correctly. The Go version can be ignored:
System information
System:
Current User: git
Using RVM: no
Ruby Version: 3.0.5p211
Gem Version: 3.3.23
Bundler Version:2.3.23
Rake Version: 13.0.6
Redis Version: 7.0.7
Sidekiq Version:6.4.2
Go Version: unknown
GitLab information
Version: 15.5.6
Revision: Unknown
Directory: /usr/local/www/gitlab-ce
DB Adapter: PostgreSQL
DB Version: 13.9
URL: http://flatland.alfaexploit.com
HTTP Clone URL: http://flatland.alfaexploit.com/some-group/some-project.git
SSH Clone URL: [email protected]:some-group/some-project.git
Using LDAP: no
Using Omniauth: yes
Omniauth Providers:
GitLab Shell
Version: 14.12.0
Repository storage paths:
- default: /usr/local/git/repositories
GitLab Shell path: /usr/local/share/gitlab-shell
We compile the assets:
NOTE: This will take a while: Done in 1134.20s.
We remove superuser permissions from the database:
We enable and start GitLab:
We install Nginx:
We include the GitLab configuration:
We modify the Nginx configuration to determine the real IP of the requests using proxy protocol:
We check that there are no errors:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
We enable and start the service:
We check that everything is correctly configured. We can ignore all errors related to sidekiq, mailroom, and systemD. Also, on the first run, it will complain that the authorized keys file is not accessible. Running the check a second time will work:
Checking GitLab subtasks ...
Checking GitLab Shell ...
GitLab Shell: ... GitLab Shell version >= 14.12.0 ? ... OK (14.12.0)
Running /usr/local/share/gitlab-shell/bin/check
Internal API available: OK
Redis available via internal API: OK
gitlab-shell self-check successful
Checking GitLab Shell ... Finished
Checking Gitaly ...
Gitaly: ... default ... OK
Checking Gitaly ... Finished
Checking Sidekiq ...
Sidekiq: ... Running? ... no
Try fixing it:
sudo -u git -H RAILS_ENV=production bin/background_jobs start
For more information see:
doc/install/installation.md in section "Install Init Script"
see log/sidekiq.log for possible errors
Please fix the error above and rerun the checks.
Checking Sidekiq ... Finished
Checking Incoming Email ...
Incoming Email: ... Reply by email is disabled in config/gitlab.yml
Checking Incoming Email ... Finished
Checking LDAP ...
LDAP: ... LDAP is disabled in config/gitlab.yml
Checking LDAP ... Finished
Checking GitLab App ...
Database config exists? ... yes
All migrations up? ... yes
Database contains orphaned GroupMembers? ... no
GitLab config exists? ... yes
GitLab config up to date? ... yes
Log directory writable? ... yes
Tmp directory writable? ... yes
Uploads directory exists? ... yes
Uploads directory has correct permissions? ... yes
Uploads directory tmp has correct permissions? ... skipped (no tmp uploads folder yet)
Systemd unit files or init script exist? ... no
Try fixing it:
Install the Service
For more information see:
doc/install/installation.md in section "Install the Service"
Please fix the error above and rerun the checks.
Systemd unit files or init script up-to-date? ... can't check because of previous errors
Projects have namespace: ...
GitLab Instance / Monitoring ... yes
Redis version >= 6.0.0? ... yes
Ruby version >= 2.7.2 ? ... yes (3.0.5)
Git user has default SSH configuration? ... yes
Active users: ... 1
Is authorized keys file accessible? ... yes
GitLab configured to store new projects in hashed storage? ... yes
All projects are in hashed storage? ... yes
Checking GitLab App ... Finished
Checking GitLab subtasks ... Finished
Finally, we access GitLab:
https://flatland.alfaexploit.com
Check GitLab configuration:
gitlab:
## Web server settings (note: host is the FQDN, do not include http://)
host: gitlab.alfaexploit.com
port: 80 # Set to 443 if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
https: false # Set to true if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
Check Nginx configuration:
Recompile assets:
Repository directory:
RAKE tasks:
Version information:
Execution environment information:
View logs:
Restart services:
Import repositories:
In GitLab we have to create the new repository and then push old repository content to the new one.
Clone the old repository:
git clone [email protected]:gitlab-instance-0a98b435/bastille-basicconfiguration.git
Remove repository origin:
Add new repository remote:
git remote add origin [email protected]\:root/bastille-basicconfiguration.git
Upload content:
Frankly, if all we need is a Git server, I recommend GitOlite over GitLab. GitOlite simply works without issues compiling assets or dealing with Ruby gems, and it is also a much lighter system.