{"id":310,"date":"2020-10-29T07:39:45","date_gmt":"2020-10-29T07:39:45","guid":{"rendered":"https:\/\/www.hort.net\/techblog\/?p=310"},"modified":"2020-11-02T23:56:04","modified_gmt":"2020-11-02T23:56:04","slug":"setting-up-gitlab-as-a-docker-container-behind-a-secure-reverse-proxy-on-centos-7-x","status":"publish","type":"post","link":"https:\/\/www.hort.net\/techblog\/2020\/10\/29\/setting-up-gitlab-as-a-docker-container-behind-a-secure-reverse-proxy-on-centos-7-x\/","title":{"rendered":"Setting up GitLab as a docker container behind a secure reverse proxy on CentOS 7.x"},"content":{"rendered":"<div class=\"share_buttons_simple_use_buttons\" style=\"padding: 10px 0; display: inline-block\"><div class=\"tweet_button\" style=\"float: left; vertical-align: top\"><a href=\"https:\/\/twitter.com\/share\" class=\"twitter-share-button\" data-url=\"https:\/\/www.hort.net\/techblog\/2020\/10\/29\/setting-up-gitlab-as-a-docker-container-behind-a-secure-reverse-proxy-on-centos-7-x\/\" data-text=\"Setting up GitLab as a docker container behind a secure reverse proxy on CentOS 7.x\" data-count=\"none\">Tweet<\/a><script type=\"text\/javascript\" src=\"https:\/\/platform.twitter.com\/widgets.js\"><\/script><\/div><div class=\"facebook_like_button\" style=\"float: left; vertical-align: top; margin-left: 10px; max-width: 255px\"><iframe src=\"https:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Fwww.hort.net%2Ftechblog%2F2020%2F10%2F29%2Fsetting-up-gitlab-as-a-docker-container-behind-a-secure-reverse-proxy-on-centos-7-x%2F&amp;layout=button_count&amp;show_faces=false&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=25\" scrolling=\"no\" frameborder=\"0\" style=\"border:none; overflow:hidden; width:450px; height:25px;\" allowTransparency=\"true\"><\/iframe><\/div><\/div><p>Last weekend I decided to install GitLab for Mallorn Computing.  I&#8217;d been meaning to do it for ages, but I never really got around to it.  Surprisingly, I couldn&#8217;t find much about the process online, so I thought I&#8217;d document and share it.<\/p>\n<p>I dutifully downloaded the installation package to a fairly empty server, ran it, and immediately freaked out.  My server wasn&#8217;t just going to run GitLab; it was going to have Apache on it, other Redis databases, MariaDB, etc.  GitLab didn&#8217;t seem to play nice with other applications and took over all kinds of ports.  The install eventually failed when it realized it couldn&#8217;t bind to port 80 since Apache was already installed, and I was left with a mess (hint: the command to clean things up is <code class=\"preserve-code-formatting\">gitlab-ctl cleanse<\/code>).<\/p>\n<p>I really didn&#8217;t want to set up a new dedicated server, so I hoped there was a Docker container I could install instead.  Thankfully, a quick Google search <a href=\"https:\/\/docs.gitlab.com\/omnibus\/docker\/\" rel=\"noopener noreferrer\" target=\"_blank\">showed there was<\/a>.<\/p>\n<p>The first thing I did was to install the Docker container:<\/p>\n<p><code class=\"preserve-code-formatting\">docker run --detach --hostname git.mallorn.com --publish 4443:4443 --publish 2211:2211 --name gitlab --restart always gitlab\/gitlab-ee:latest<\/code><\/p>\n<p>Then I edited the GitLab config file and tried a bunch of settings for a few hours.  Ultimately, I figured out which ones worked.  Running <code class=\"preserve-code-formatting\">docker exec -it gitlab vi \/etc\/gitlab\/gitlab.rb<\/code> opened a vi session editing the configuration file for GitLab.  I had to change the variables below to the values you see.<br \/>\n<pre><code class=\"preserve-code-formatting\">&nbsp;&nbsp; \n&nbsp;&nbsp; external_url &#039;https:\/\/git.mallorn.com:4443&#039;\n&nbsp;&nbsp; nginx[&#039;ssl_client_certificate&#039;] = &quot;\/etc\/gitlab\/trusted-certs\/cert.pem&quot;\n&nbsp;&nbsp; nginx[&#039;ssl_certificate&#039;] = &quot;\/etc\/gitlab\/trusted-certs\/fullchain.pem&quot;\n&nbsp;&nbsp; nginx[&#039;ssl_certificate_key&#039;] = &quot;\/etc\/gitlab\/trusted-certs\/privkey.pem&quot;\n&nbsp;&nbsp; gitlab_rails[&#039;trusted_proxies&#039;] = [&quot;172.16.1.10&quot;]\n&nbsp;&nbsp; nginx[&#039;proxy_set_headers&#039;] = {\n&nbsp;&nbsp;&nbsp;&nbsp; &quot;X-Forwarded-Proto&quot; =&gt; &quot;https&quot;,\n&nbsp;&nbsp;&nbsp;&nbsp; &quot;X-Forwarded-Ssl&quot; =&gt; &quot;on&quot;\n&nbsp;&nbsp; }\n<\/code><\/pre><\/p>\n<p>Note that <code class=\"preserve-code-formatting\">trusted_proxies<\/code> is my internal network; set it to the IP of the interface on your proxy server that will talk to your GitLab installation.<\/p>\n<p>Once that was done, I had to edit the ssh configuration file to tell it to listen on port 2211 (I now realize I could have just changed my startup parameters when I started the container, but too late now):  I had to run <code class=\"preserve-code-formatting\">docker exec -it gitlab vi \/assets\/sshd_config<\/code> and change the port to 2211, then save the file.  The last step was to restart the sshd process with <code class=\"preserve-code-formatting\">docker exec -it gitlab \/etc\/init.d\/sshd restart<\/code>.<\/p>\n<p>At this point I needed to import my SSL certificates because I had told GitLab to use certs that didn&#8217;t exist yet.  I used <a href=\"https:\/\/letsencrypt.org\/getting-started\/\" rel=\"noopener noreferrer\" target=\"_blank\">letsencrypt<\/a> to generate a certificate, then copied it into my Docker container:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">\n&nbsp;&nbsp; cd \/etc\/letsencrypt\/live\/git.mallorn.com\n&nbsp;&nbsp; docker cp -a -L cert.pem gitlab:\/etc\/gitlab\/trusted-certs\n&nbsp;&nbsp; docker cp -a -L privkey.pem gitlab:\/etc\/gitlab\/trusted-certs\n&nbsp;&nbsp; docker cp -a -L fullchain.pem gitlab:\/etc\/gitlab\/trusted-certs\n<\/code><\/pre><\/p>\n<p>Your directory will be different; change into the one for your server.  After this is done, restart your container by running <code class=\"preserve-code-formatting\">sudo docker restart gitlab<\/code>.<\/p>\n<p>The last step was to create <code class=\"preserve-code-formatting\">\/etc\/httpd\/conf.d\/git.mallorn.com.conf<\/code>:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">\n&nbsp;&nbsp; &lt;VirtualHost *:80 *:443&gt;\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerName git.mallorn.com\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RewriteCond %{HTTPS} !=on\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RewriteRule ^\/?(.*) https:\/\/%{SERVER_NAME}\/$1 [R,L]\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLEngine on\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLHonorCipherOrder on\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLCipherSuite &quot;EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA!RC4:EECDH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS&quot;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLCompression off\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLSessionTickets off\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLCertificateFile \/etc\/letsencrypt\/live\/git.mallorn.com\/cert.pem\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLCertificateKeyFile \/etc\/letsencrypt\/live\/git.mallorn.com\/privkey.pem\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLCertificateChainFile \/etc\/letsencrypt\/live\/git.mallorn.com\/chain.pem\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Proxy *&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Require all granted\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/Proxy&gt;\n&nbsp;&nbsp; \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProxyPreserveHost on\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLProxyEngine on\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLProxyVerify none\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLProxyCheckPeerCN off\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLProxyCheckPeerName off\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSLProxyCheckPeerExpire off\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProxyRequests Off\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProxyPass \/ https:\/\/git.mallorn.com:4443\/ nocanon\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProxyPassReverse \/ https:\/\/git.mallorn.com:4443\/ nocanon\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AllowEncodedSlashes NoDecode\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Header edit Location ^http:\/\/git.mallorn.com\/ https:\/\/git.mallorn.com\/\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RequestHeader unset Accept-Encoding\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RequestHeader set Host &quot;git.mallorn.com&quot;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RequestHeader add X-Forwarded-Ssl on\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RequestHeader set X-Forwarded-Proto &quot;https&quot;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFormat &quot;%h %l %u %t \\&quot;%r\\&quot; %s %b \\&quot;%{Referer}i\\&quot; \\&quot;%{User-agent}i\\&quot;&quot;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ErrorLog \/var\/log\/httpd\/git.mallorn.com\/error\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TransferLog \/var\/log\/httpd\/git.mallorn.com\/access\n&nbsp;&nbsp; &lt;\/VirtualHost&gt;\n<\/code><\/pre><br \/>\nI ran <code class=\"preserve-code-formatting\">apachectl graceful<\/code> to reload Apache, and from that point forward git.mallorn.com answered HTTP requests.<\/p>\n<p>Next I had to make ssh work.  Create an ssh key:<\/p>\n<p>   <code class=\"preserve-code-formatting\">ssh-keygen -t rsa -b 4096 -f ~\/.ssh\/gitlab.id_rsa<\/code><\/p>\n<p>Then set up <code class=\"preserve-code-formatting\">~\/.ssh\/config<\/code> to reflect that key:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">\n&nbsp;&nbsp; host git.mallorn.com\n&nbsp;&nbsp;&nbsp;&nbsp;HostName git.mallorn.com\n&nbsp;&nbsp;&nbsp;&nbsp;Port 2211\n&nbsp;&nbsp;&nbsp;&nbsp;IdentityFile ~\/.ssh\/mallorn-git.id_rsa\n&nbsp;&nbsp;&nbsp;&nbsp;User [your login in GitLab]\n<\/code><\/pre><\/p>\n<p>Paste the contents of your <code class=\"preserve-code-formatting\">~\/.ssh\/gitlab.id_rsa.pub<\/code> file into your key settings in GitLab and you will now be able to check files in and out via ssh.<\/p>\n<p>Finally, set up a cron job to copy your SSL certs into the container regularly.  This cron entry (saved as <code class=\"preserve-code-formatting\">\/etc\/cron.d\/gitlab<\/code>) copies the certificates in and restarts the container if they have changed.<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&nbsp;&nbsp; 5 30 * * * root (cd \/etc\/letsencrypt\/live\/git.mallorn.com ; find . -mmin 2 -exec &quot;docker cp -a -L cert.pem gitlab:\/etc\/gitlab\/trusted-certs; docker cp -a -L privkey.pem gitlab:\/etc\/gitlab\/trusted-certs; docker cp -a -L fullchain.pem gitlab:\/etc\/gitlab\/trusted-certs; docker restart gitlab)\n<\/code><\/pre><\/p>\n<p>Note that you could make the certs available directly to the container instead by starting it with the -v option, and that may ultimately be the route that I take.  <\/p>\n<p>Lastly, don&#8217;t forget to <a href=\"https:\/\/docs.gitlab.com\/omnibus\/settings\/backups.html\">setup backups<\/a>! <\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"share_buttons_simple_use_buttons\" style=\"padding: 10px 0; display: inline-block\"><div class=\"tweet_button\" style=\"float: left; vertical-align: top\"><a href=\"https:\/\/twitter.com\/share\" class=\"twitter-share-button\" data-url=\"https:\/\/www.hort.net\/techblog\/2020\/10\/29\/setting-up-gitlab-as-a-docker-container-behind-a-secure-reverse-proxy-on-centos-7-x\/\" data-text=\"Setting up GitLab as a docker container behind a secure reverse proxy on CentOS 7.x\" data-count=\"none\">Tweet<\/a><script type=\"text\/javascript\" src=\"https:\/\/platform.twitter.com\/widgets.js\"><\/script><\/div><div class=\"facebook_like_button\" style=\"float: left; vertical-align: top; margin-left: 10px; max-width: 255px\"><iframe src=\"https:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Fwww.hort.net%2Ftechblog%2F2020%2F10%2F29%2Fsetting-up-gitlab-as-a-docker-container-behind-a-secure-reverse-proxy-on-centos-7-x%2F&amp;layout=button_count&amp;show_faces=false&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=25\" scrolling=\"no\" frameborder=\"0\" style=\"border:none; overflow:hidden; width:450px; height:25px;\" allowTransparency=\"true\"><\/iframe><\/div><\/div><p>TweetLast weekend I decided to install GitLab for Mallorn Computing. I&#8217;d been meaning to do it for ages, but I never really got around to it. Surprisingly, I couldn&#8217;t find much about the process online, so I thought I&#8217;d document and share it. I dutifully downloaded the installation package to a fairly empty server, ran [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23],"tags":[24,25,26],"class_list":["post-310","post","type-post","status-publish","format-standard","hentry","category-system-administration","tag-gitlab","tag-proxy","tag-ssl"],"_links":{"self":[{"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/posts\/310","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/comments?post=310"}],"version-history":[{"count":13,"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/posts\/310\/revisions"}],"predecessor-version":[{"id":324,"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/posts\/310\/revisions\/324"}],"wp:attachment":[{"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/media?parent=310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/categories?post=310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hort.net\/techblog\/wp-json\/wp\/v2\/tags?post=310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}