5.7 KiB
5.7 KiB
Рекап успешной конфигурации
1. GitLab в Docker
Запуск контейнера (уже был настроен, ключевое — порты):
docker run -d \
--hostname gitlab.local \
--publish 85:80 \
--publish 443:443 \
--publish 2223:22 \
--name gitlab \
--restart always \
-v /srv/gitlab/config:/etc/gitlab \
-v /srv/gitlab/logs:/var/log/gitlab \
-v /srv/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest
Критическая настройка внутри контейнера (чтобы nginx слушал на всех интерфейсах):
docker exec -it gitlab bash
cat > /etc/gitlab/gitlab.rb << 'EOF'
external_url 'http://10.0.2.15:85'
nginx['listen_addresses'] = ['0.0.0.0']
nginx['listen_port'] = 80
EOF
gitlab-ctl reconfigure
exit
docker restart gitlab
2. GitLab Runner
Установка:
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
Регистрация (http://172.17.0.1:85 — IP docker bridge, доступный изнутри контейнеров):
sudo gitlab-runner register
# URL: http://172.17.0.1:85
# Token: [из GitLab → Settings → CI/CD → Runners]
# Executor: docker
# Default image: docker:latest
Конфиг /etc/gitlab-runner/config.toml (главное — url и clone_url на IP docker bridge):
[[runners]]
name = "gitlab-runner"
url = "http://172.17.0.1:85"
token = "..."
executor = "docker"
clone_url = "http://172.17.0.1:85"
[runners.docker]
image = "docker:latest"
privileged = true
Разрешить untagged jobs в GitLab → Settings → CI/CD → Runners → Edit → ☑️ Run untagged jobs.
3. Структура проекта
myapp/
├── main.go
├── go.mod
├── Dockerfile
└── .gitlab-ci.yml
main.go — минимальный HTTP-сервер:
package main
import (
"fmt"
"net/http"
"os"
"time"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from CI/CD!\nVersion: 1.0.0\nTime: %s\n", time.Now().Format(time.RFC3339))
})
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprintln(w, `{"status":"ok"}`)
})
fmt.Printf("Server starting on :%s\n", port)
http.ListenAndServe(":"+port, nil)
}
go.mod:
module myapp
go 1.23
Dockerfile — копирует уже собранный бинарник (не собирает заново):
FROM alpine:latest
COPY server /server
RUN chmod +x /server
ENV PORT=8080
EXPOSE 8080
ENTRYPOINT ["/server"]
4. CI/CD Pipeline (.gitlab-ci.yml)
stages:
- build
- deploy
build:
stage: build
image: golang:1.23-alpine
script:
- CGO_ENABLED=0 go build -ldflags="-s -w" -o server main.go
artifacts:
paths:
- server
deploy:
stage: deploy
image: alpine:latest
dependencies:
- build
before_script:
- apk add --no-cache openssh-client
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -H $DEPLOY_HOST >> ~/.ssh/known_hosts
script:
- |
ssh $DEPLOY_USER@$DEPLOY_HOST "mkdir -p ~/myapp"
scp server Dockerfile $DEPLOY_USER@$DEPLOY_HOST:~/myapp/
ssh $DEPLOY_USER@$DEPLOY_HOST << EOF
set -e
cd ~/myapp
docker stop myapp || true
docker rm myapp || true
docker build -t myapp:latest .
docker run -d --name myapp --restart unless-stopped -p 8080:8080 myapp:latest
docker image prune -f
docker ps | grep myapp
EOF
only:
- master
5. Целевой сервер (деплой)
SSH-ключи (генерируем на сервере с GitLab):
ssh-keygen -t ed25519 -C "gitlab-deploy" -f ~/.ssh/gitlab_deploy
На целевом сервере:
sudo useradd -m -s /bin/bash deploy
sudo usermod -aG docker deploy
sudo mkdir -p /home/deploy/.ssh
sudo nano /home/deploy/.ssh/authorized_keys
# Вставить содержимое ~/.ssh/gitlab_deploy.pub
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo reboot
6. GitLab Variables
Project → Settings → CI/CD → Variables:
| Variable | Значение |
|---|---|
SSH_PRIVATE_KEY |
Содержимое ~/.ssh/gitlab_deploy (приватный ключ) |
DEPLOY_HOST |
IP целевого сервера |
DEPLOY_USER |
deploy |
7. Проверка деплоя
ssh deploy@<IP_сервера>
docker ps
curl http://localhost:8080
curl http://localhost:8080/health
Итоговые цифры
| Параметр | Значение |
|---|---|
| Размер Docker-образа приложения | ~10 МБ |
| Внешних зависимостей | 0 |
| Этапов CI/CD | 2 (build → deploy) |
| Размер runner-образа | не критичен (используется стандартный alpine) |
Push в master → build → scp на сервер → docker build → docker run → приложение доступно на порту 8080.