1 准备

1.1 服务器配置:

  • Ubuntu 16.04 LTS
  • 2核 4G 及以上
  • 1M 带宽及以上

NOTE:gitlab 非常占内存,最好用单独的服务器!

1.2 约定

  • 需要将gitlab.example.com替换成你自己的域名。
  • NOTE:是一些提示。

2 安装

#  添加包的key
curl https://packages.gitlab.com/gpg.key 2> /dev/null | sudo apt-key add - &>/dev/null

# 写入
sudo sh -c 'echo deb https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu xenial main > /etc/apt/sources.list.d/gitlab-ce.list'

# 更新
sudo apt update

sudo apt install gitlab-ce

3 修改 gitlab 配置

sudo vi /etc/gitlab/gitlab.rb
# 修改
external_url 'https://gitlab.example.com'
## My Conf
# close nginx
nginx['enable'] = false
# Set the internal API URL
gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
# Define the web server process user (ubuntu/nginx)
web_server['external_users'] = ['www-data']

sudo gitlab-ctl reconfigure

4 添加 https 证书

4.1 安装 letsencrypt

sudo apt install letsencrypt

4.2 生成 key

sudo letsencrypt certonly --standalone -d gitlab.example.com

4.3 第2步可能碰到的问题

  • 问题1:

    domain names was not valid, has an _ (underscore) in the name or equested domain domain is not a FQDN.

    解决方案:二级域名中不能包含下划线_,请修改二级域名。

  • 问题2:

    Problem binding to port 443: Could not bind to IPv4 or IPv6.

    解决方案:先关闭 Nginx,再生成 key。

4.4 自动续期

letsencrypt 的有效期只有两个月。 使用 Linux 定时任务 corntab 完成每月1日自动检查续期。

sudo crontab -e
0 0 1 * * service nginx stop && letsencrypt renew && service nginx reload

5 Nginx 配置

cd /etc/nginx/sites-available
sudo vi gitlab.example.com.conf

# 写入
upstream gitlab-workhorse {
  server unix://var/opt/gitlab/gitlab-workhorse/socket fail_timeout=0;
}

server {
  listen *:80;
  server_name gitlab.example.com;
  rewrite  ^/(.*)$ https://gitlab.example.com:443/$1 permanent;
}

server {
  listen 443 ssl;
  ssl_certificate /etc/letsencrypt/live/gitlab.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/gitlab.example.com/privkey.pem;
  keepalive_timeout   70;
  server_name gitlab.example.com;
  server_tokens off;
  root /opt/gitlab/embedded/service/gitlab-rails/public;

  client_max_body_size 250m;

  access_log  /var/log/gitlab/nginx/gitlab_access.log;
  error_log   /var/log/gitlab/nginx/gitlab_error.log;

  # Ensure Passenger uses the bundled Ruby version
  passenger_ruby /opt/gitlab/embedded/bin/ruby;

  # Correct the $PATH variable to included packaged executables
  passenger_env_var PATH "/opt/gitlab/bin:/opt/gitlab/embedded/bin:/usr/local/bin:/usr/bin:/bin";

  # Make sure Passenger runs as the correct user and group to
  # prevent permission issues
  passenger_user git;
  passenger_group git;

  # Enable Passenger & keep at least one instance running at all times
  passenger_enabled on;
  passenger_min_instances 1;

  location ~ ^/[\w\.-]+/[\w\.-]+/(info/refs|git-upload-pack|git-receive-pack)$ {
    # 'Error' 418 is a hack to re-use the @gitlab-workhorse block
    error_page 418 = @gitlab-workhorse;
    return 418;
  }

  location ~ ^/[\w\.-]+/[\w\.-]+/repository/archive {
    # 'Error' 418 is a hack to re-use the @gitlab-workhorse block
    error_page 418 = @gitlab-workhorse;
    return 418;
  }

  location ~ ^/api/v3/projects/.*/repository/archive {
    # 'Error' 418 is a hack to re-use the @gitlab-workhorse block
    error_page 418 = @gitlab-workhorse;
    return 418;
  }

  # Build artifacts should be submitted to this location
  location ~ ^/[\w\.-]+/[\w\.-]+/builds/download {
      client_max_body_size 0;
      # 'Error' 418 is a hack to re-use the @gitlab-workhorse block
      error_page 418 = @gitlab-workhorse;
      return 418;
  }

  # Build artifacts should be submitted to this location
  location ~ /ci/api/v1/builds/[0-9]+/artifacts {
      client_max_body_size 0;
      # 'Error' 418 is a hack to re-use the @gitlab-workhorse block
      error_page 418 = @gitlab-workhorse;
      return 418;
  }

  # Build artifacts should be submitted to this location
  location ~ /api/v4/jobs/[0-9]+/artifacts {
      client_max_body_size 0;
      # 'Error' 418 is a hack to re-use the @gitlab-workhorse block
      error_page 418 = @gitlab-workhorse;
      return 418;
  }


  # For protocol upgrades from HTTP/1.0 to HTTP/1.1 we need to provide Host header if its missing
  if ($http_host = "") {
  # use one of values defined in server_name
    set $http_host_with_default "gitlab.example.com";
  }

  if ($http_host != "") {
    set $http_host_with_default $http_host;
  }

  location @gitlab-workhorse {

    ## https://github.com/gitlabhq/gitlabhq/issues/694
    ## Some requests take more than 30 seconds.
    proxy_read_timeout      3600;
    proxy_connect_timeout   300;
    proxy_redirect          off;

    # Do not buffer Git HTTP responses
    proxy_buffering off;

    proxy_set_header    Host                $http_host_with_default;
    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;

    proxy_pass http://gitlab-workhorse;

    ## The following settings only work with NGINX 1.7.11 or newer
    #
    ## Pass chunked request bodies to gitlab-workhorse as-is
    # proxy_request_buffering off;
    # proxy_http_version 1.1;
  }

  ## Enable gzip compression as per rails guide:
  ## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression
  ## WARNING: If you are using relative urls remove the block below
  ## See config/application.rb under "Relative url support" for the list of
  ## other files that need to be changed for relative url support
  location ~ ^/(assets)/ {
    root /opt/gitlab/embedded/service/gitlab-rails/public;
    gzip_static on; # to serve pre-gzipped version
    expires max;
    add_header Cache-Control public;
  }

  error_page 502 /502.html;
}

# 最后激活服务
sudo nginx_ensite git.example.com.conf
sudo service nginx reload

尝试访问 https://gitlab.example.com