Для реализации данной идеи рекомендую взять сервер c хотя бы 4Гб оперативки. В противном случае контейнер с TeamCity будет очень долго стартовать и мы нередко будем видеть в логах ООМ.
Я буду использовать Ubuntu 20.
Для начала установим докер по инструкции с офф сайта.
sudo apt-get update && apt-get upgrade –y
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo docker run hello-world # test
Теперь создадим папки, где Тимсити будет хранить логи и данные:
mkdir -p /var/teamcity/datadir /var/teamcity/logs
chown -R 1000:1000 /var/teamcity/datadir /var/teamcity/logs
Для проверки можно запустить сервер командой:
docker run -d --rm --name teamcity-server-instance –v /var/teamcity/datadir:/data/teamcity_server/datadir -v /var/teamcity/logs:/opt/teamcity/logs -p 80:8111 jetbrains/teamcity-server
Но я предлагаю сразу сделать systemd unit. Запишем в файл /etc/systemd/system/teamcity.service
[Unit]
Description=teamcity
After=network.target
[Service]
ExecStart=docker run --rm --name teamcity-server-instance \
-v /var/teamcity/datadir:/data/teamcity_server/datadir \
-v /var/teamcity/logs:/opt/teamcity/logs \
-p 8111:8111 \
jetbrains/teamcity-server
Restart=always
[Install]
WantedBy=multi-user.target
Готово. Запускаем.
systemctl daemon-reload
systemctl enable teamcity
systemctl start teamcity
Можно посмотреть логи контейнера и убедиться что все в порядке.
docker logs teamcity-server-instance
Мы должны увидеть последней строкой лога следующее:
Startup confirmation is required. Open TeamCity web page in the browser. Server is running at http://localhost:8111
Идём адресу сервера. Например, teamcity.amulin.ru:8111 .
Работает, но ещё не все. Хочется иметь перед teamcity nginx с блекджеком и сертификатом.
Создадим самоподписанный сертификат и положим его в папку /etc/ssl/teamcity.amulin.ru
mkdir -p /etc/ssl/teamcity.amulin.ru
openssl req -x509 -nodes -newkey rsa:2048 -days 3650 -keyout /etc/ssl/teamcity.amulin.ru/mykey.key -out /etc/ssl/teamcity.amulin.ru/cert.crt
Сделаем конфиг для nginx, который направит трафик на нужный контейнер. Для этого создадим папку /etc/nginx/conf.d и файл /etc/nginx/conf.d/teamcity.amulin.ru.conf следующего содержания:
server {
listen 443 ssl;
listen [::]:443 ssl ipv6only=on;
server_name teamcity.amulin.ru;
location / {
proxy_set_header Host $http_host;
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://teamcity-server-instance:8111;
}
ssl_certificate /etc/ssl/teamcity.amulin.ru/cert.crt;
ssl_certificate_key /etc/ssl/teamcity.amulin.ru/mykey.key;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name teamcity.amulin.ru;
if ($host = teamcity.amulin.ru) {
return 301 https://$host$request_uri;
}
}
Здесь я использую прокси на http://teamcity-server-instance:8111; teamcity-server-instance – это имя контейнера. Далее нам нужно будет прилинковать его к контейнеру nginx.
Теперь сделаем systemd unit под nginx /etc/systemd/system/nginx.service
[Unit]
Description=nginx
[Service]
ExecStart=docker run --rm --name nginx \
-v /etc/nginx/conf.d/teamcity.amulin.ru.conf:/etc/nginx/conf.d/default.conf \
-v /etc/ssl/teamcity.amulin.ru:/etc/ssl/teamcity.amulin.ru:ro \
-p 80:80 \
-p 443:443 \
--link teamcity-server-instance \
nginx
Restart=always
[Install]
WantedBy=multi-user.target
Как раз —link teamcity-server-instance даём nginx возможность сходить в контейнер TeamCity.
Запускаем
systemctl daemon-reload
systemctl enable nginx
systemctl start nginx
И даже не удивляемся, что все работает. Конечно браузер предупредит, что сертификат самоподписанный, но мы можем пойти на такой риск.
Теперь настраиваем БД и ждём.
И наконец лицензионное соглашение и создание админа, где мы конечно же укажем логин — admin, а пароль 12345678.
Очень хочется, чтобы после перезагрузки все само поднялось. Попробуем перезапустить машину и убедимся что все работает. Магия!
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c2d1962cb47 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginx
58bb3068be4f jetbrains/teamcity-server "/run-services.sh" About a minute ago Up About a minute 0.0.0.0:8111->8111/tcp, :::8111->8111/tcp teamcity-server-instance