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
十一、安全建议
- 修改默认密码:首次登录后立即修改root密码
- 启用HTTPS:配置SSL证书
- 防火墙配置:
bash
# 配置UFW防火墙
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
- 定期更新:
bash
# 更新所有容器
docker compose pull
docker compose up -d
# 更新系统
sudo apt update && sudo apt upgrade -y
十二、访问GitLab
- 获取初始密码:
bash
docker compose exec gitlab cat /etc/gitlab/initial_root_password
-
访问地址:
- 本地访问:http://localhost
- 远程访问:http://服务器IP
- 自定义域名:http://gitlab.example.com(需配置DNS)
-
首次登录:
- 用户名:root
- 密码:从initial_root_password文件获取
- 登录后立即修改密码
注意事项
- 备份重要数据:定期备份数据库和配置文件
- 监控资源使用:确保有足够的内存和磁盘空间
- 安全更新:定期更新Docker镜像和系统补丁
- 配置备份:备份docker-compose.yml和所有配置文件
- 网络配置:根据实际网络环境调整端口和防火墙设置
这个方案提供了完整的GitLab + MySQL 8.0部署方案,包含了生产环境的最佳实践和安全配置。请根据实际需求调整资源配置和域名设置。