Ubuntu 2024 Docker-Compose部署GitLab+MySQL 8.0保姆式方案

Ubuntu 2024 Docker-Compose部署GitLab+MySQL 8.0保姆式方案

一、环境准备

1.1 系统要求

  • Ubuntu Server 24.04 LTS
  • 最低配置:4核CPU,8GB内存,50GB存储
  • 推荐配置:8核CPU,16GB内存,100GB存储

1.2 安装必要工具

bash 复制代码
# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装必要工具
sudo apt install -y \
    curl \
    wget \
    gnupg \
    lsb-release \
    apt-transport-https \
    ca-certificates \
    software-properties-common

1.3 安装Docker和Docker Compose

bash 复制代码
# 添加Docker官方GPG密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# 添加Docker仓库
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 验证安装
docker --version
docker compose version

# 将当前用户添加到docker组(避免每次使用sudo)
sudo usermod -aG docker $USER
newgrp docker

二、创建部署目录结构

bash 复制代码
# 创建项目目录
mkdir -p ~/gitlab-docker/{mysql,gitlab,redis,backup,logs}
cd ~/gitlab-docker

# 创建目录结构
mkdir -p {data,config,logs}
mkdir -p mysql/{data,config,logs,init}
mkdir -p redis/{data,logs}

三、配置MySQL 8.0

3.1 创建MySQL配置文件

bash 复制代码
# 创建MySQL配置目录
sudo mkdir -p ~/gitlab-docker/mysql/config

# 创建自定义MySQL配置文件
cat > ~/gitlab-docker/mysql/config/my.cnf << 'EOF'
[mysqld]
# 基本设置
user = mysql
port = 3306
datadir = /var/lib/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid

# 字符集设置
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
skip-character-set-client-handshake = true

# 连接设置
max_connections = 1000
connect_timeout = 60
wait_timeout = 28800
interactive_timeout = 28800

# 缓冲区设置
key_buffer_size = 256M
max_allowed_packet = 256M
thread_cache_size = 8
sort_buffer_size = 4M
read_buffer_size = 2M
read_rnd_buffer_size = 4M
join_buffer_size = 4M

# InnoDB设置
default-storage-engine = InnoDB
innodb_buffer_pool_size = 2G
innodb_log_file_size = 256M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_lock_wait_timeout = 50
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT
innodb_read_io_threads = 4
innodb_write_io_threads = 4

# 日志设置
log_error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 2
log_queries_not_using_indexes = 1

# 二进制日志
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = row
expire_logs_days = 7
max_binlog_size = 100M

# 安全设置
local-infile = 0
symbolic-links = 0

[client]
default-character-set = utf8mb4
port = 3306
socket = /var/run/mysqld/mysqld.sock

[mysql]
default-character-set = utf8mb4
EOF

3.2 创建MySQL初始化脚本

bash 复制代码
cat > ~/gitlab-docker/mysql/init/init.sql << 'EOF'
-- 创建GitLab数据库
CREATE DATABASE IF NOT EXISTS `gitlabhq_production` 
CHARACTER SET `utf8mb4` 
COLLATE `utf8mb4_unicode_ci`;

-- 创建GitLab用户并授权
CREATE USER 'gitlab'@'%' IDENTIFIED BY 'GitLabSecurePass123!';
GRANT ALL PRIVILEGES ON `gitlabhq_production`.* TO 'gitlab'@'%';

-- 创建备份用户
CREATE USER 'gitlab_backup'@'%' IDENTIFIED BY 'BackupSecurePass123!';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON `gitlabhq_production`.* TO 'gitlab_backup'@'%';

-- 刷新权限
FLUSH PRIVILEGES;

-- 性能优化:设置事务隔离级别(GitLab推荐)
SET GLOBAL transaction_isolation = 'READ-COMMITTED';
EOF

四、配置Redis

bash 复制代码
# 创建Redis配置文件
cat > ~/gitlab-docker/redis/redis.conf << 'EOF'
# Redis配置文件
bind 0.0.0.0
port 6379
protected-mode yes
daemonize no

# 内存设置
maxmemory 1gb
maxmemory-policy allkeys-lru

# 持久化设置
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data

# 日志设置
loglevel notice
logfile /var/log/redis/redis.log

# 慢日志
slowlog-log-slower-than 10000
slowlog-max-len 128

# 连接设置
timeout 0
tcp-keepalive 300
tcp-backlog 511

# 安全设置
requirepass RedisSecurePass123!
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command SHUTDOWN ""

# 集群设置(单节点)
cluster-enabled no
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
EOF

五、创建docker-compose.yml文件

yaml 复制代码
# 创建docker-compose.yml
cat > ~/gitlab-docker/docker-compose.yml << 'EOF'
version: '3.8'

services:
  # MySQL 8.0 服务
  mysql:
    image: mysql:8.0
    container_name: gitlab-mysql
    restart: unless-stopped
    command: 
      - --default-authentication-plugin=mysql_native_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --innodb-buffer-pool-size=2G
      - --transaction-isolation=READ-COMMITTED
    environment:
      MYSQL_ROOT_PASSWORD: RootSecurePass123!
      MYSQL_DATABASE: gitlabhq_production
      MYSQL_USER: gitlab
      MYSQL_PASSWORD: GitLabSecurePass123!
      TZ: Asia/Shanghai
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/config/my.cnf:/etc/mysql/my.cnf:ro
      - ./mysql/init:/docker-entrypoint-initdb.d:ro
      - ./mysql/logs:/var/log/mysql
      - ./backup/mysql:/backup
    ports:
      - "3306:3306"
    networks:
      - gitlab-network
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pRootSecurePass123!"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    ulimits:
      nofile:
        soft: 65535
        hard: 65535
    deploy:
      resources:
        limits:
          memory: 4G
        reservations:
          memory: 2G

  # Redis 服务
  redis:
    image: redis:7-alpine
    container_name: gitlab-redis
    restart: unless-stopped
    command: redis-server /usr/local/etc/redis/redis.conf
    volumes:
      - ./redis/data:/data
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
      - ./redis/logs:/var/log/redis
    ports:
      - "6379:6379"
    networks:
      - gitlab-network
    healthcheck:
      test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M

  # GitLab 服务
  gitlab:
    image: gitlab/gitlab-ce:latest
    container_name: gitlab
    restart: unless-stopped
    hostname: 'gitlab.example.com'  # 修改为你的域名或IP
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        # 数据库配置
        gitlab_rails['db_adapter'] = 'mysql2'
        gitlab_rails['db_encoding'] = 'utf8mb4'
        gitlab_rails['db_host'] = 'mysql'
        gitlab_rails['db_port'] = '3306'
        gitlab_rails['db_database'] = 'gitlabhq_production'
        gitlab_rails['db_username'] = 'gitlab'
        gitlab_rails['db_password'] = 'GitLabSecurePass123!'
        
        # Redis配置
        gitlab_rails['redis_host'] = 'redis'
        gitlab_rails['redis_port'] = '6379'
        gitlab_rails['redis_password'] = 'RedisSecurePass123!'
        
        # 基础配置
        external_url 'http://gitlab.example.com'  # 修改为你的域名或IP
        gitlab_rails['gitlab_email_from'] = 'gitlab@example.com'
        gitlab_rails['gitlab_email_display_name'] = 'GitLab'
        gitlab_rails['gitlab_email_reply_to'] = 'noreply@example.com'
        
        # 时区设置
        gitlab_rails['time_zone'] = 'Asia/Shanghai'
        
        # 备份配置
        gitlab_rails['backup_path'] = '/var/opt/gitlab/backups'
        gitlab_rails['backup_keep_time'] = 604800
        
        # 性能优化
        puma['worker_processes'] = 2
        sidekiq['concurrency'] = 10
        gitlab_rails['gitlab_default_projects_limit'] = 1000
        
        # 存储配置
        gitlab_rails['uploads_storage_path'] = '/var/opt/gitlab/gitlab-rails/uploads'
        gitlab_rails['rate_limit_requests_per_period'] = 1000
        gitlab_rails['rate_limit_period'] = 60
        
        # SMTP配置(根据实际情况修改)
        # gitlab_rails['smtp_enable'] = true
        # gitlab_rails['smtp_address'] = "smtp.example.com"
        # gitlab_rails['smtp_port'] = 465
        # gitlab_rails['smtp_user_name'] = "gitlab@example.com"
        # gitlab_rails['smtp_password'] = "password"
        # gitlab_rails['smtp_domain'] = "example.com"
        # gitlab_rails['smtp_authentication'] = "login"
        # gitlab_rails['smtp_enable_starttls_auto'] = true
        # gitlab_rails['smtp_tls'] = true
        
        # LDAP配置(可选)
        # gitlab_rails['ldap_enabled'] = true
        # gitlab_rails['ldap_servers'] = {...}
        
        # 监控配置
        gitlab_rails['monitoring_whitelist'] = ['0.0.0.0/0']
        
        # 日志配置
        logging['svlogd_size'] = 200 * 1024 * 1024
        
        # Docker仓库(可选)
        # registry_external_url 'https://registry.example.com'
        
        # Pages配置(可选)
        # gitlab_pages['enable'] = true
        
        # Mattermost配置(可选)
        # mattermost_external_url 'http://mattermost.example.com'
    volumes:
      - ./config:/etc/gitlab
      - ./data:/var/opt/gitlab
      - ./logs:/var/log/gitlab
      - ./backup/gitlab:/var/opt/gitlab/backups
    ports:
      - "80:80"
      - "443:443"
      - "22:22"
    networks:
      - gitlab-network
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_started
    deploy:
      resources:
        limits:
          memory: 8G
        reservations:
          memory: 4G
    healthcheck:
      test: ["CMD", "/opt/gitlab/bin/gitlab-healthcheck", "--fail"]
      interval: 1m
      timeout: 10s
      retries: 3
      start_period: 2m
    ulimits:
      nproc:
        soft: 65535
        hard: 65535
      nofile:
        soft: 65535
        hard: 65535

networks:
  gitlab-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
EOF

六、修改目录权限

bash 复制代码
# 设置目录权限
sudo chown -R 1000:1000 ~/gitlab-docker/{data,config,logs,backup}
sudo chown -R 999:999 ~/gitlab-docker/mysql
sudo chown -R 1001:1001 ~/gitlab-docker/redis

# 创建必要的日志目录
mkdir -p ~/gitlab-docker/logs/{mysql,redis,gitlab}
mkdir -p ~/gitlab-docker/mysql/logs
mkdir -p ~/gitlab-docker/redis/logs

# 设置日志目录权限
sudo chmod -R 755 ~/gitlab-docker/logs
sudo chmod -R 755 ~/gitlab-docker/mysql/logs
sudo chmod -R 755 ~/gitlab-docker/redis/logs

七、启动服务

bash 复制代码
# 进入项目目录
cd ~/gitlab-docker

# 启动所有服务(后台运行)
docker compose up -d

# 查看服务状态
docker compose ps

# 查看启动日志
docker compose logs -f gitlab

# 查看所有容器日志
docker compose logs -f

# 检查各服务健康状态
docker compose exec mysql mysqladmin ping -h localhost -u root -pRootSecurePass123!
docker compose exec redis redis-cli -a RedisSecurePass123! ping

八、初始配置和优化

8.1 等待GitLab完全启动

bash 复制代码
# 监控GitLab启动过程(大约需要5-10分钟)
watch -n 10 "docker compose logs gitlab --tail=20"

# 检查GitLab状态
docker compose exec gitlab gitlab-ctl status

# 获取初始root密码
docker compose exec gitlab grep 'Password:' /etc/gitlab/initial_root_password

8.2 修改GitLab配置(可选)

bash 复制代码
# 进入GitLab容器
docker compose exec gitlab bash

# 重新配置GitLab
gitlab-ctl reconfigure

# 重启GitLab服务
gitlab-ctl restart

# 检查服务状态
gitlab-ctl status

# 退出容器
exit

8.3 备份配置

bash 复制代码
# 创建备份脚本
cat > ~/gitlab-docker/backup/backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)

echo "开始备份 $(date)"

# 备份MySQL
echo "备份MySQL数据库..."
docker compose exec mysql mysqldump -u root -pRootSecurePass123! \
    --single-transaction \
    --routines \
    --triggers \
    --events \
    --all-databases \
    > ${BACKUP_DIR}/mysql/mysql_full_${DATE}.sql

# 压缩MySQL备份
gzip ${BACKUP_DIR}/mysql/mysql_full_${DATE}.sql

# 备份GitLab
echo "备份GitLab..."
docker compose exec gitlab gitlab-backup create STRATEGY=copy

# 备份GitLab配置文件
tar -czf ${BACKUP_DIR}/gitlab/gitlab_config_${DATE}.tar.gz \
    ~/gitlab-docker/config/gitlab.rb \
    ~/gitlab-docker/config/gitlab-secrets.json

# 清理旧备份(保留7天)
find ${BACKUP_DIR}/mysql -name "*.gz" -mtime +7 -delete
find ${BACKUP_DIR}/gitlab -name "*.tar" -mtime +7 -delete
find ${BACKUP_DIR}/gitlab -name "*.tar.gz" -mtime +7 -delete

echo "备份完成 $(date)"
EOF

# 赋予执行权限
chmod +x ~/gitlab-docker/backup/backup.sh

# 设置定时备份(每天凌晨2点)
(crontab -l 2>/dev/null; echo "0 2 * * * /bin/bash ~/gitlab-docker/backup/backup.sh >> ~/gitlab-docker/backup/backup.log 2>&1") | crontab -

九、监控和维护

9.1 常用维护命令

bash 复制代码
# 重启所有服务
docker compose restart

# 重启单个服务
docker compose restart gitlab

# 停止所有服务
docker compose down

# 停止并删除所有数据(谨慎使用)
docker compose down -v

# 查看容器资源使用情况
docker stats

# 进入容器
docker compose exec gitlab bash
docker compose exec mysql mysql -u root -pRootSecurePass123!
docker compose exec redis redis-cli -a RedisSecurePass123!

# 更新所有镜像
docker compose pull
docker compose up -d

# 查看日志
docker compose logs -f gitlab
docker compose logs -f mysql
docker compose logs -f redis

# 清理无用镜像
docker image prune -a

9.2 健康检查脚本

bash 复制代码
cat > ~/gitlab-docker/check-health.sh << 'EOF'
#!/bin/bash
echo "=== GitLab 系统健康检查 ==="
echo "检查时间: $(date)"

echo -e "\n1. 容器状态:"
docker compose ps

echo -e "\n2. 资源使用情况:"
docker stats --no-stream

echo -e "\n3. MySQL连接测试:"
if docker compose exec mysql mysqladmin ping -h localhost -u root -pRootSecurePass123! --silent; then
    echo "✓ MySQL运行正常"
else
    echo "✗ MySQL连接失败"
fi

echo -e "\n4. Redis连接测试:"
if docker compose exec redis redis-cli -a RedisSecurePass123! ping | grep -q PONG; then
    echo "✓ Redis运行正常"
else
    echo "✗ Redis连接失败"
fi

echo -e "\n5. GitLab服务状态:"
docker compose exec gitlab gitlab-ctl status | head -20

echo -e "\n6. 磁盘空间检查:"
df -h ~/gitlab-docker

echo -e "\n7. 内存使用情况:"
free -h

echo -e "\n检查完成"
EOF

chmod +x ~/gitlab-docker/check-health.sh

十、故障排查

10.1 常见问题解决

bash 复制代码
# 1. GitLab启动缓慢
# 增加内存或调整配置
docker compose stop gitlab
docker compose up -d gitlab

# 2. MySQL连接问题
# 检查MySQL日志
docker compose logs mysql --tail=50

# 重启MySQL服务
docker compose restart mysql

# 3. Redis连接问题
docker compose restart redis

# 4. 端口冲突
# 检查端口占用
sudo netstat -tulpn | grep -E ':(80|443|22|3306|6379)'

# 5. 磁盘空间不足
# 清理无用镜像和容器
docker system prune -a

10.2 日志位置

  • GitLab日志:~/gitlab-docker/logs/gitlab/
  • MySQL日志:~/gitlab-docker/mysql/logs/
  • Redis日志:~/gitlab-docker/redis/logs/
  • Docker日志:journalctl -u docker.service

十一、安全建议

  1. 修改默认密码:首次登录后立即修改root密码
  2. 启用HTTPS:配置SSL证书
  3. 防火墙配置
bash 复制代码
# 配置UFW防火墙
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
  1. 定期更新
bash 复制代码
# 更新所有容器
docker compose pull
docker compose up -d

# 更新系统
sudo apt update && sudo apt upgrade -y

十二、访问GitLab

  1. 获取初始密码
bash 复制代码
docker compose exec gitlab cat /etc/gitlab/initial_root_password
  1. 访问地址

  2. 首次登录

    • 用户名:root
    • 密码:从initial_root_password文件获取
    • 登录后立即修改密码

注意事项

  1. 备份重要数据:定期备份数据库和配置文件
  2. 监控资源使用:确保有足够的内存和磁盘空间
  3. 安全更新:定期更新Docker镜像和系统补丁
  4. 配置备份:备份docker-compose.yml和所有配置文件
  5. 网络配置:根据实际网络环境调整端口和防火墙设置

这个方案提供了完整的GitLab + MySQL 8.0部署方案,包含了生产环境的最佳实践和安全配置。请根据实际需求调整资源配置和域名设置。

相关推荐
Byte Beat11 小时前
ubuntu安装docker
linux·ubuntu·docker
HIT_Weston11 小时前
88、【Ubuntu】【Hugo】搭建私人博客:侧边导航栏(二)
linux·运维·ubuntu
七七powerful11 小时前
docker28.1.1和docker-compose v.2.35.1安装
java·docker·eureka
single-life11 小时前
不借助docker desktop 本地windows安装nabula
windows·docker·容器·nebula
liulilittle11 小时前
AF_XDP开发环境(Ubuntu24.04.3)
linux·运维·服务器·ubuntu
liulilittle12 小时前
Windows WSL部署Ubuntu子系统到其它磁盘上
linux·运维·服务器·网络·windows·ubuntu·wsl
阿豪只会阿巴12 小时前
【多喝热水系列】从零开始的ROS2之旅——Day5
c++·笔记·python·ubuntu·ros2
susu108301891112 小时前
docker部署 Java 项目jar
java·docker·jar
派大鑫wink12 小时前
DevOps与AIOps融合:智能化运维体系构建与实战
docker·容器·kubernetes
工程师老罗13 小时前
Ubuntu下怎么将u盘格式化为ext4?
linux·运维·ubuntu