├── README.md ├── base ├── centos.md ├── docker.md ├── mariadb.md ├── nginx.md ├── postgresql.md └── redis.md ├── deploy ├── passenger.md ├── python.md ├── rails.md └── supervisor.md ├── gitlab ├── gitlab-ci-usage.md ├── gitlab-ci.md └── gitlab.md ├── languages ├── java.md ├── nodejs.md ├── php.md ├── python.md └── ruby.md └── others ├── certbot.md ├── emqttd.md ├── nexus.md └── shadowsoccks.md /README.md: -------------------------------------------------------------------------------- 1 | # CentOS 7 运维 2 | 3 | CentOS 7 下服务器配置,各类应用部署等文档 4 | 5 | * [基本配置](./base/centos.md) 6 | 7 | * 常用软件 8 | * [Nginx](./base/nginx.md) 9 | * [MariaDB](./base/mariadb.md) 10 | * [PostgreSQL](./base/postgresql.md) 11 | * [Redis](./base/redis.md) 12 | * [Docker](./base/docker.md) 13 | 14 | * GitLab 15 | * [GitLab 安装与维护](./gitlab/gitlab.md) 16 | * [GitLab-CI 安装与维护](./gitlab/gitlab-ci.md) 17 | * [GitLab-CI 用法](./gitlab/gitlab-ci-usage.md) 18 | 19 | * 各语言环境配置 20 | * [Java](./languages/java.md) 21 | * [PHP](./languages/php.md) 22 | * [Ruby](./languages/ruby.md) 23 | * [Node.js](./languages/nodejs.md) 24 | * [Python](./languages/python.md) 25 | 26 | * 各类应用部署 27 | * PHP 28 | * [Rails](./deploy/rails.md) 29 | * [Python](./deploy/python.md) 30 | 31 | * 进程管理工具 32 | * [Supervisor](./deploy/supervisor.md) 33 | * [Passenger](./deploy/passenger.md) 34 | 35 | * 其它 36 | * [Emqttd](./others/emqttd.md) 37 | * [Nexus Repository Manager OSS](./others/nexus.md) 38 | * [Certbot - Let's Encrypt SSL 证书](./others/certbot.md) 39 | * [Shadowsocks](./others/shadowsocks.md) 40 | -------------------------------------------------------------------------------- /base/centos.md: -------------------------------------------------------------------------------- 1 | # 服务器基本配置 2 | 3 | 以下配置过程需使用 root 用户执行 4 | 5 | ## 基本配置 6 | 7 | ### 主机名称 8 | 9 | ``` 10 | echo example.com > /etc/hostname 11 | ``` 12 | 13 | ### 语言 14 | 15 | 语言不正确可能会导致无法正常显示中文 16 | 17 | ``` 18 | echo LANG=en_US.UTF-8 > /etc/locale.conf 19 | ``` 20 | 21 | ### 时区 22 | 23 | ``` 24 | ln -sf ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime 25 | ``` 26 | 27 | ## 常用软件、软件源 28 | 29 | ``` 30 | yum update -y 31 | yum group install -y development 32 | yum install -y vim bash-completion git mailx deltarpm bind-utils yum-utils 33 | yum install -y epel-release 34 | yum-config-manager --enable epel 35 | ``` 36 | 37 | 若默认的软件源(云服务厂商一般都使用他们自己维护的软件源)中软件版本较旧或速度较慢,可替换为[中科大源](https://lug.ustc.edu.cn/wiki/mirrors/help/centos)或[清华大学源](https://mirror.tuna.tsinghua.edu.cn/help/centos/) 38 | 39 | EPEL 也可改用[中科大源](https://lug.ustc.edu.cn/wiki/mirrors/help/epel)或[清华大学源](https://mirror.tuna.tsinghua.edu.cn/help/epel/) 40 | 41 | ## sshd 42 | 43 | sshd 配置文件为`/etc/ssh/sshd_config` 44 | 45 | ``` 46 | # 禁止root登录 47 | PermitRootLogin no 48 | 49 | # 禁止密码登录 50 | PasswordAuthentication no 51 | 52 | # 避免长时间无操作后断线 53 | ClientAliveInterval 10 54 | ClientAliveCountMax 5 55 | ``` 56 | 57 | 重启 sshd 使配置生效 58 | 59 | ``` 60 | systemctl restart sshd 61 | ``` 62 | 63 | ## 防火墙 64 | 65 | ``` 66 | # 有些云服务商提供的 CentOS 镜像可能默认没有安装 67 | yum install -y firewalld 68 | 69 | # 检查是否正在运行 70 | systemctl status firewalld 71 | 72 | # 若未运行,运行并自启动 73 | systemctl start firewalld 74 | systemctl enable firewalld 75 | 76 | # 查看默认的zone 77 | firewall-cmd --get-default-zone 78 | 79 | # 查看当前使用的zone 80 | firewall-cmd --get-active-zones 81 | 82 | # 设置默认使用的zone 83 | firewall-cmd --set-default-zone=dmz 84 | 85 | # 允许对外开放的服务。执行 ls /usr/lib/firewalld/services/ 以查看支持的服务列表 86 | firewall-cmd --permanent --add-service=http 87 | firewall-cmd --permanent --add-service=https 88 | firewall-cmd --permanent --add-service=ssh 89 | 90 | # 允许对外开放的端口 91 | # firewall-cmd --permanent --add-port=3306/tcp 92 | 93 | # 重载配置以生效 94 | firewall-cmd --reload 95 | 96 | # 查看配置 97 | firewall-cmd --list-all 98 | ``` 99 | 100 | __注意:__ 101 | 102 | 若修改了所添加service(如ssh)的端口号,需修改 `/usr/lib/firewalld/services/` 目录下相应配置文件中的端口号,并在修改后执行 `firewall-cmd --reload` 重载配置 103 | 104 | ## SELinux 105 | 106 | [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) 是一种安全机制,但容易导致权限问题,最好禁用 107 | 108 | ``` 109 | # 查看状态 110 | sestatus 111 | ``` 112 | 113 | 修改配置文件 `/etc/sysconfig/selinux`: 114 | 115 | ``` 116 | SELINUX=disabled 117 | ``` 118 | 119 | 重启系统以生效 120 | 121 | ## Ulimit 122 | 123 | Ulimit (User Limits) 对用户能够使用的系统资源(如最大文件描述符数量)进行限制 124 | 125 | 若默认值较小,易导致 "Too many open files" 等错误 126 | 127 | 在 `/etc/security/limits.conf` 中加入: 128 | 129 | ``` 130 | * soft nofile 65535 131 | * hard nofile 65535 132 | ``` 133 | 134 | 修改后重启系统 135 | 136 | ## Yum 配置 137 | 138 | 修改 `/etc/yum.conf`: 139 | 140 | ``` 141 | # 缓存安装包 142 | keepcache=1 143 | 144 | # 内核数量 145 | # 默认会保留 5 个旧内核,为减少空间占用,可改为两个 146 | installonly_limit=2 147 | ``` 148 | 149 | 立即删除旧内核: 150 | 151 | ``` 152 | yum install yum-utils 153 | package-cleanup --oldkernels --count=2 154 | ``` 155 | 156 | ## 数据存储 157 | 158 | 为便于管理、扩展,所有数据保存到 `/data` 目录 159 | 160 | ``` 161 | mkdir /data 162 | ``` 163 | 164 | 若有额外的数据盘,将其挂载到 /data 目录 165 | 166 | ``` 167 | # 格式化硬盘。可不分区 168 | mkfs.ext4 /dev/vdb 169 | 170 | # 挂载 171 | mount /dev/vdb /data 172 | ``` 173 | 174 | 编辑 `/etc/fstab`,配置开机自动挂载: 175 | 176 | ``` 177 | /dev/vdb /data ext4 defaults 0 0 178 | ``` 179 | 180 | 按需要创建子目录 181 | 182 | ``` 183 | # web 服务器根目录 184 | mkdir /data/www 185 | 186 | # 应用(如 rails 应用)目录 187 | mkdir /data/app 188 | ``` 189 | 190 | __注意子目录的用户/组。__ Web 服务器根目录的用户/组应为 web 服务器运行时的用户/组 191 | 192 | ## 交换空间 193 | 194 | 若内存较大,可不设置交换空间 195 | 196 | ``` 197 | # 查看 198 | swapon -s 199 | free -m 200 | 201 | # 创建交换空间文件 202 | dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress 203 | chmod 600 /swapfile 204 | mkswap /swapfile 205 | 206 | # 启用 207 | swapon /swapfile 208 | 209 | # 禁用 210 | swapoff /swapfile 211 | ``` 212 | 213 | 编辑 `/etc/fstab`,以开机自动挂载交换空间: 214 | 215 | ``` 216 | /swapfile swap swap sw 0 0 217 | ``` 218 | 219 | ## logrotate 220 | 221 | logrotate 用于日志文件的自动切割,避免日志文件过大而影响应用性能 222 | 223 | 其基本原理是通过 crontab 配置定时任务,每日执行一次,执行时读取各应用的配置文件,根据配置进行日志文件的切割、应用的重启等 224 | 225 | 各应用的配置文件在 `/etc/logrotate.d/` 目录下,可按需修改 226 | 227 | ## sudo 228 | 229 | 执行 `visudo` 修改配置: 230 | 231 | ``` 232 | # 增加 /usr/local/bin 233 | Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin 234 | 235 | # 取消注释 236 | %wheel ALL=(ALL) ALL 237 | ``` 238 | 239 | ## 用户 240 | 241 | 出于安全考虑,新增一个非 root 用户用于日常管理 242 | 243 | ``` 244 | useradd -m -G wheel username 245 | passwd username 246 | ``` 247 | 248 | 切换到新添加的用户,配置密钥, .bashrc, .vimrc, .gitconfig 等 249 | 250 | 注意,`.ssh` 权限需为 700,`.ssh/authorized_keys` 权限需为 600,否则无效 251 | -------------------------------------------------------------------------------- /base/docker.md: -------------------------------------------------------------------------------- 1 | # Docker 2 | 3 | ## 安装 4 | 5 | 添加 docker 镜像源: 6 | 7 | ```bash 8 | # 官方源 9 | sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 10 | 11 | # 清华大学源 12 | sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 13 | sudo sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo 14 | ``` 15 | 16 | ```bash 17 | sudo yum install docker-ce docker-ce-cli containerd.io 18 | 19 | sudo systemctl start docker 20 | sudo systemctl enable docker 21 | 22 | # 将自己添加到 docker 组以便无需 sudo 权限执行 docker 命令。需要重新登录 23 | sudo usermod -aG docker `whoami` 24 | ``` 25 | 26 | ## 配置 27 | 28 | Docker 守护进程的配置文件为 `/etc/docker/daemon.json` 29 | 30 | 参考 [Daemon configuration file](https://docs.docker.com/engine/reference/commandline/dockerd/#/daemon-configuration-file) 31 | 32 | ## 存储位置 33 | 34 | Docker 镜像等数据默认保存在 `/var/lib/docker`,若系统盘空间较小,可改为其它目录 35 | 36 | 创建或修改配置文件 `/etc/docker/daemon.json`,添加: 37 | 38 | ```json 39 | { 40 | "data-root": "/data/docker" 41 | } 42 | ``` 43 | 44 | 注意配置文件为 JSON 格式,花括号、逗号不要漏掉或多余 45 | 46 | ```bash 47 | # 将原目录的数据移动到新目录: 48 | sudo mv /var/lib/docker /data/docker 49 | 50 | # 重启 docker daemon 51 | sudo systemctl restart docker 52 | ``` 53 | 54 | ### 镜像加速 55 | 56 | 国内拉取 docker 镜像很慢且失败率很高,可使用阿里云镜像加速器 57 | 58 | 登录 [阿里云](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors) 获取加速地址(需认证为开发者),添加到 `/etc/docker/daemon.json` 中: 59 | 60 | ```json 61 | { 62 | "registry-mirrors": ["your_mirror_address"] 63 | } 64 | ``` 65 | 66 | 也可考虑使用其它加速服务: 67 | 68 | * [七牛镜像加速](https://kirk-enterprise.github.io/hub-docs/#/user-guide/mirror) 69 | * 网易加速器: https://hub-mirror.c.163.com/ 70 | * [Daocloud 加速器](https://www.daocloud.io/mirror) 71 | 72 | ## 参考资料 73 | 74 | * [Docker Documentation](https://docs.docker.com/) 75 | * [Install Docker Engine on CentOS](https://docs.docker.com/engine/install/centos/) 76 | * [清华大学 docker 源](https://mirror.tuna.tsinghua.edu.cn/help/docker-ce/) 77 | * [Daemon configuration file](https://docs.docker.com/engine/reference/commandline/dockerd/#/daemon-configuration-file) 78 | -------------------------------------------------------------------------------- /base/mariadb.md: -------------------------------------------------------------------------------- 1 | # MariaDB 2 | 3 | MariaDB 是 MySQL 的主要分支之一,推荐替代 MySQL 使用 4 | 5 | ## 安装 6 | 7 | CentOS 官方源版本较旧,使用 MariaDB 官方源 8 | 9 | ```bash 10 | # 官方镜像 11 | curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash 12 | 13 | # 手动配置官方镜像 14 | # 注意修改 MariaDB 版本号 15 | sudo tee /etc/yum.repos.d/mariadb.repo <<-'EOF' 16 | [mariadb] 17 | name = MariaDB 18 | baseurl = http://yum.mariadb.org/10.5/centos7-amd64 19 | gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB 20 | gpgcheck=1 21 | EOF 22 | 23 | # 中科大镜像 24 | sudo tee /etc/yum.repos.d/mariadb.repo <<-'EOF' 25 | [mariadb] 26 | name = MariaDB 27 | baseurl = https://mirrors.ustc.edu.cn/mariadb/yum/10.5/centos7-amd64 28 | gpgkey=https://mirrors.ustc.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB 29 | gpgcheck=1 30 | EOF 31 | 32 | sudo yum makecache 33 | sudo yum install MariaDB-client MariaDB-server MariaDB-devel 34 | 35 | sudo systemctl enable mariadb 36 | sudo systemctl start mariadb 37 | 38 | sudo mysql_secure_installation 39 | ``` 40 | 41 | ## 配置 42 | 43 | 将默认字符集改为 utf8mb4,避免意外的问题: 44 | 45 | `/etc/my.cnf.d/mysql-clients.cnf`: 46 | 47 | ```ini 48 | [mysql] 49 | default-character-set = utf8mb4 50 | 51 | [mysqldump] 52 | default-character-set = utf8mb4 53 | ``` 54 | 55 | `/etc/my.cnf.d/server.cnf`: 56 | 57 | ```ini 58 | [mysqld] 59 | character-set-server = utf8mb4 60 | log-error = /var/log/mariadb/error.log 61 | #general_log = 1 62 | #general_log_file = /var/log/mariadb/general.log 63 | slow_query_log = 1 64 | slow_query_log_file = /var/log/mariadb/slow.log 65 | ``` 66 | 67 | 创建日志目录: 68 | 69 | ```bash 70 | sudo mkdir /var/log/mariadb 71 | sudo chown mysql: /var/log/mariadb 72 | ``` 73 | 74 | 日志轮滚配置: 75 | 76 | ```bash 77 | sudo tee /etc/logrotate.d/mysql <<-'EOF' 78 | /var/log/mariadb/*log /var/lib/mysql/mysqld.log { 79 | su mysql mysql 80 | missingok 81 | daily 82 | minsize 300M 83 | rotate 10 84 | compress 85 | delaycompress 86 | copytruncate 87 | } 88 | EOF 89 | ``` 90 | 91 | ## 参考资料 92 | 93 | * [官方主页](https://mariadb.org/) 94 | * [MariaDB Package Repository Setup and Usage](https://mariadb.com/kb/en/library/mariadb-package-repository-setup-and-usage/) 95 | * [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories) 96 | * [中科大镜像源配置](https://lug.ustc.edu.cn/wiki/mirrors/help/mariadb) 97 | -------------------------------------------------------------------------------- /base/nginx.md: -------------------------------------------------------------------------------- 1 | # Nginx 2 | 3 | 使用 Nginx 作为 Web server 4 | 5 | ## 安装 6 | 7 | __若需使用 Passenger,请使用 [Passenger 文档](../deploy/passenger.md)中的方式安装 Nginx__ 8 | 9 | EPEL 源中版本过旧,使用 Nginx 官方源 10 | 11 | ``` 12 | sudo tee /etc/yum.repos.d/nginx.repo <<-'EOF' 13 | [nginx] 14 | name=nginx stable repo 15 | baseurl=https://nginx.org/packages/centos/$releasever/$basearch/ 16 | gpgcheck=1 17 | enabled=1 18 | gpgkey=https://nginx.org/keys/nginx_signing.key 19 | module_hotfixes=true 20 | EOF 21 | 22 | sudo yum makecache 23 | sudo yum install -y nginx 24 | 25 | sudo systemctl enable nginx 26 | sudo systemctl start nginx 27 | ``` 28 | 29 | ## 配置 30 | 31 | 修改配置文件 `/etc/nginx/nginx.conf`: 32 | 33 | ``` 34 | user nginx; 35 | worker_processes auto; 36 | pid /var/run/nginx.pid; 37 | error_log /var/log/nginx/error.log warn; 38 | 39 | worker_rlimit_nofile 65535; 40 | events { 41 | worker_connections 65535; 42 | } 43 | 44 | http { 45 | include /etc/nginx/mime.types; 46 | include /etc/nginx/conf.d/*.conf; 47 | default_type application/octet-stream; 48 | 49 | log_format main '$remote_addr [$time_local] "$request" ' 50 | '$status $body_bytes_sent $request_time "$http_referer" ' 51 | '"$http_user_agent" $http_x_forwarded_for'; 52 | 53 | access_log /var/log/nginx/access.log main; 54 | 55 | # 域名较多时需设置 56 | server_names_hash_bucket_size 64; 57 | 58 | # 不把 404 请求记录到错误日志中 59 | log_not_found off; 60 | 61 | sendfile on; 62 | tcp_nopush on; 63 | tcp_nodelay on; 64 | keepalive_timeout 65; 65 | types_hash_max_size 2048; 66 | 67 | # 限制了上传文件大小。根据应用需求相应修改 68 | client_max_body_size 10m; 69 | 70 | # 启用 gzip 71 | gzip on; 72 | gzip_min_length 1k; 73 | gzip_comp_level 5; 74 | gzip_http_version 1.0; 75 | gzip_types text/plain application/x-javascript application/javascript text/css text/xml application/xml application/json; 76 | gzip_proxied any; 77 | gzip_vary on; 78 | gzip_disable msie6; 79 | 80 | # 须放在最后,否则上面的配置可能无效 81 | include /etc/nginx/sites/*.conf; 82 | } 83 | ``` 84 | 85 | 为便于管理,每个 server 的配置保存为一个文件,放在 `/etc/nginx/sites/` 目录下 86 | 87 | ``` 88 | sudo mkdir /etc/nginx/sites 89 | sudo touch /etc/nginx/sites/default.conf 90 | ``` 91 | 92 | `/etc/nginx/sites/default.conf`: 93 | 94 | ``` 95 | server { 96 | listen 80 default_server; 97 | server_name _; 98 | return 404; 99 | } 100 | ``` 101 | 102 | Nginx 的 logratete 配置文件为 `/etc/logrotate.d/nginx`,默认每日一次,为避免过于频繁,建议修改频率,或加入文件大小限制: 103 | 104 | ``` 105 | minsize 300M 106 | ``` 107 | 108 | ## HTTPS 109 | 110 | ``` 111 | # 默认是 1024 位,不够安全 112 | sudo openssl dhparam -out /etc/ssl/dhparam.pem 2048 113 | 114 | sudo mkdir -p /etc/nginx/includes 115 | 116 | # 添加配置文件 117 | sudo tee /etc/nginx/includes/https.conf <<-'EOF' 118 | # certs 119 | #ssl_certificate /path/to/fullchain.pem; 120 | #ssl_certificate_key /path/to/private_key; 121 | #ssl_trusted_certificate /path/to/chain.pem; 122 | 123 | ssl_session_timeout 1d; 124 | ssl_session_cache shared:MozSSL:10m; # about 40000 sessions 125 | ssl_session_tickets off; 126 | 127 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits 128 | ssl_dhparam /etc/ssl/dhparam.pem; 129 | 130 | # intermediate configuration 131 | ssl_protocols TLSv1.2 TLSv1.3; 132 | ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; 133 | ssl_prefer_server_ciphers off; 134 | 135 | 136 | # OCSP Stapling --- 137 | # fetch OCSP records from URL in ssl_certificate and cache them 138 | ssl_stapling on; 139 | ssl_stapling_verify on; 140 | 141 | # name servers used to resolve names of upstream servers into addresses 142 | # 国内使用 DNSPod Public DNS, 阿里 DNS 143 | resolver 119.29.29.29 182.254.116.116 223.5.5.5 223.6.6.6; 144 | # resolver 8.8.8.8 8.8.4.4; 145 | EOF 146 | 147 | sudo tee /etc/nginx/includes/https-hsts.conf <<-'EOF' 148 | include /etc/nginx/includes/https.conf; 149 | 150 | # HSTS 151 | add_header Strict-Transport-Security "max-age=63072000" always; 152 | EOF 153 | ``` 154 | 155 | 网站配置示例: 156 | 157 | ``` 158 | server { 159 | listen 80; 160 | server_name example.com; 161 | return 301 https://example.com$request_uri; 162 | 163 | access_log /var/log/nginx/example-http.access.log main; 164 | error_log /var/log/nginx/example-http.error.log warn; 165 | } 166 | 167 | server { 168 | listen 443 ssl http2; 169 | server_name example.com; 170 | root /data/app/example; 171 | 172 | include /etc/nginx/includes/https.conf; 173 | # if want to enable hsts 174 | # include /etc/nginx/includes/https-hsts.conf; 175 | 176 | ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; 177 | ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; 178 | ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; 179 | 180 | access_log /var/log/nginx/example.access.log main; 181 | error_log /var/log/nginx/example.error.log warn; 182 | } 183 | ``` 184 | 185 | ## 参考资料 186 | 187 | * [Nginx Linux packages](http://nginx.org/en/linux_packages.html) 188 | * [Mozilla SSL Configuration Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/) 189 | -------------------------------------------------------------------------------- /base/postgresql.md: -------------------------------------------------------------------------------- 1 | # PostgreSQL 2 | 3 | The world's most advanced open source database. 4 | 5 | ## 安装 6 | 7 | 官方源中版本过旧,使用 PostgreSQL 官方源 8 | 9 | ``` 10 | sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm 11 | 12 | # 禁用不需要的仓库 13 | sudo yum-config-manager --disable pgdg* 14 | sudo yum-config-manager --enable pgdg-common pgdg12 15 | 16 | sudo yum install -y postgresql12-server 17 | 18 | # Initialize the database 19 | sudo /usr/pgsql-12/bin/postgresql-12-setup initdb 20 | 21 | sudo systemctl enable postgresql-12 22 | sudo systemctl start postgresql-12 23 | ``` 24 | 25 | ## 创建用户 26 | 27 | 默认只有一个 `postgres` 用户,为方便使用,可添加一个与系统用户同名的新用户 28 | 29 | ``` 30 | sudo -u postgres -i 31 | createuser --interactive 32 | 33 | # 创建普通用户 34 | createuser --no-createdb --no-createrole --no-superuser --pwprompt --interactive 35 | # 创建数据库 36 | createdb --owner USER_NAME DATABASE_NAME 37 | ``` 38 | 39 | ## 配置 40 | 41 | ### 允许远程连接 42 | 43 | 修改 `/var/lib/pgsql/12/data/postgresql.conf`: 44 | 45 | ``` 46 | listen_addresses = '*' 47 | ``` 48 | 49 | ### trust 认证 50 | 51 | 默认的验证方式是 ident,为方便本地应用连接,可考虑改为 trust 52 | 53 | 修改 `/var/lib/pgsql/12/data/pg_hba.conf`: 54 | 55 | ``` 56 | host all all 127.0.0.1/32 trust 57 | host all all ::1/128 trust 58 | ``` 59 | 60 | ### 密码认证 61 | 62 | 修改 `/var/lib/pgsql/12/data/pg_hba.conf`: 63 | 64 | ``` 65 | # 出于安全考虑,建议只允许指定数据库或用户远程连接,尽量不要允许默认的管理员帐号 postgres 远程连接 66 | host all all 0.0.0.0/0 password 67 | ``` 68 | 69 | ## 参考资料 70 | 71 | * [官网](https://www.postgresql.org/) 72 | * [Install PostgreSQL](https://www.postgresql.org/download/linux/redhat/) 73 | * [PostgreSQL Authentication Methods](https://www.postgresql.org/docs/current/static/auth-methods.html) 74 | -------------------------------------------------------------------------------- /base/redis.md: -------------------------------------------------------------------------------- 1 | # Redis 2 | 3 | ## 安装 4 | 5 | ``` 6 | sudo yum install -y redis 7 | 8 | sudo systemctl start redis 9 | sudo systemctl enable redis 10 | ``` 11 | -------------------------------------------------------------------------------- /deploy/passenger.md: -------------------------------------------------------------------------------- 1 | # Passenger 2 | 3 | ## 安装 4 | 5 | ``` 6 | sudo yum install -y epel-release yum-utils 7 | sudo yum install -y pygpgme curl 8 | 9 | sudo curl --fail -sSLo /etc/yum.repos.d/passenger.repo https://oss-binaries.phusionpassenger.com/yum/definitions/el-passenger.repo 10 | sudo yum install nginx passenger 11 | ``` 12 | 13 | 修改 `/etc/nginx/conf.d/passenger.conf`: 14 | 15 | ``` 16 | passenger_root /usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini; 17 | # 使用 RVM/rbenv/系统 默认的 ruby 版本。username 根据实际情况修改 18 | passenger_ruby /home/username/.rvm/wrappers/default/ruby; 19 | # passenger_ruby /home/username/.rbenv/shims/ruby; 20 | # passenger_ruby /usr/bin/ruby; 21 | passenger_instance_registry_dir /var/run/passenger-instreg; 22 | ``` 23 | 24 | ## Nginx 配置 25 | 26 | 单独域名: 27 | 28 | ``` 29 | server { 30 | listen 80; 31 | server_name example.com; 32 | root /data/app/your-app/current/public; 33 | 34 | passenger_enabled on; 35 | 36 | access_log /var/log/nginx/your-app.access.log main; 37 | error_log /var/log/nginx/your-app.error.log warn; 38 | } 39 | ``` 40 | 41 | 子路径(sub-uri): 42 | 43 | ``` 44 | location /sub-uri { 45 | alias /data/app/your-app/current/public; 46 | 47 | passenger_enabled on; 48 | passenger_base_uri /sub-uri; 49 | passenger_env_var RAILS_RELATIVE_URL_ROOT /sub-uri; 50 | passenger_app_root /data/app/your-app/current; 51 | } 52 | ``` 53 | 54 | 部署到子路径的详细文档请参考 [Deploy Rails appliction to sub-uri 55 | ](https://bianjp.com/deploy-rails-appliction-to-sub-uri/) 56 | 57 | 默认使用 `/etc/nginx/conf.d/passenger.conf` 中配置的 ruby 版本,可通过 [passenger_ruby](https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_ruby) 指定要使用的 ruby 版本 58 | 59 | __注意:__ Passenger 使用的 ruby 版本必须与部署工具部署(尤其 bundle install)使用 ruby 版本一致 60 | 61 | ## 参考资料 62 | 63 | * [Installation](https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/nginx/oss/el7/install_passenger.html) 64 | * [Configurations](https://www.phusionpassenger.com/library/config/nginx/reference/) 65 | -------------------------------------------------------------------------------- /deploy/python.md: -------------------------------------------------------------------------------- 1 | # 部署 Python 应用 2 | 3 | 使用 [Supervisor](http://supervisord.org/) 监控和管理 Python 应用。 4 | 5 | 查看 [Supervisor 文档](./supervisor.md) 以安装和配置 supervisor。 6 | 7 | ## 部署工具 8 | 9 | Python 应用部署较为简单,直接使用 Shell 脚本部署。 10 | 11 | 将以下两个文件保存到项目根目录,并根据项目实际需要进行修改: 12 | 13 | `deploy.sh`: 14 | 15 | ```shell 16 | #!/usr/bin/bash 17 | 18 | user=your-deploy-user 19 | server=example.com 20 | deploy_dir=/data/app/weixin-vote 21 | supervisor_program_name=weixin-vote 22 | 23 | ssh $user@$server "[ -d $deploy_dir ] || mkdir $deploy_dir" 24 | ssh $user@$server "[ -d $deploy_dir/log ] || mkdir $deploy_dir/log" 25 | rsync -vrh --checksum --delete --exclude-from=deploy_exclude.list ./ $user@$server:$deploy_dir 26 | 27 | if [[ "$1" != "setup" ]]; then 28 | ssh $user@$server "supervisorctl restart $supervisor_program_name:" 29 | fi 30 | ``` 31 | 32 | `deploy_exclude.list`: 33 | 34 | ``` 35 | /.git 36 | /.gitignore 37 | /README.md 38 | /config.py 39 | /deploy_exclude.list 40 | /deploy.sh 41 | /log 42 | __pycache__ 43 | *.pyc 44 | ``` 45 | 46 | 部署只需在项目根目录执行: 47 | 48 | ```shell 49 | ./deploy.sh 50 | ``` 51 | 52 | * `deploy.sh` 须有执行权限 (`chmod 755 deploy.sh`) 53 | * 用户须对服务器有 SSH 连接权限 54 | 55 | ## 部署步骤 56 | 57 | 初次部署: 58 | 59 | 1. 在服务器上创建数据库、安装依赖 60 | 2. 在项目根目录执行 `./deploy.sh setup` 61 | 3. 在服务器上进行必要的修改(如数据库配置),测试应用能否正常启动和运行 62 | 4. 在服务器上添加 supervisor 配置文件,并重载配置 63 | 5. 在服务器上配置 Nginx (若是 web 项目) 64 | 65 | 后续部署: 66 | 67 | 1. 若有新的依赖,或数据库更新,在服务器上手动处理 68 | 2. 在项目根目录执行 `./deploy.sh` 69 | -------------------------------------------------------------------------------- /deploy/rails.md: -------------------------------------------------------------------------------- 1 | # 部署 Rails 应用 2 | 3 | ## 环境需求 4 | 5 | * Ruby 6 | * Gem packages: bundler 7 | * Node.js, npm 8 | * gcc, g++, make 等工具,编译 gem 扩展需要 9 | * mariadb-devel(编译 [mysql2](https://github.com/brianmario/mysql2) gem 需要) 10 | * postgresql-libs postgresql-devel(编译 [pg](https://rubygems.org/gems/pg/) gem 需要) 11 | 12 | 部分非必须 13 | 14 | ## 部署工具 15 | 16 | 使用 [mina](https://github.com/mina-deploy/mina) 部署,相比 [capistrano](https://github.com/capistrano/capistrano),mina 更轻量级,速度更快 17 | 18 | 多个 stage 的配置方法: 19 | 20 | ``` 21 | desc 'Production server' 22 | task :production do 23 | set :domain, 'server' 24 | set :user, 'user' 25 | set :branch, 'master' 26 | end 27 | 28 | desc 'Development server' 29 | task :development do 30 | set :domain, 'server' 31 | set :user, 'user' 32 | set :branch, 'master' 33 | end 34 | ``` 35 | 36 | 使用时在命令前加上 stage 名称,如 37 | 38 | ``` 39 | bundle exec mina production deploy 40 | ``` 41 | 42 | SSH 配置: 43 | 44 | 1. 本地须有 ssh 连接到部署服务器的权限 45 | 2. 若部署服务器有访问远程仓库的权限,设置 `set :forward_agent, false` 46 | 3. 若部署服务器没有访问远程仓库的权限,本地须有访问仓库的权限,且设置 `set :forward_agent, true` 47 | 48 | ## 应用服务器 49 | 50 | * 若同一服务器上部署多个应用,或应用的访问量不大、高峰期很短,使用 [passenger](https://www.phusionpassenger.com/),以减少资源占用 51 | 52 | * 若部署的应用不多,或应用较重要,可使用 [unicorn](http://unicorn.bogomips.org/) 或 [puma](http://puma.io/) 53 | 54 | * 若应用的响应较慢,避免使用 unicorn(只有进程模式,一个请求就要占用一个进程,响应较慢会导致请求排队时间过长) 55 | 56 | ## 日志轮滚 57 | 58 | 为避免日志文件过大,影响性能,应定期切割日志文件 59 | 60 | 使用系统自带功能 logrotate 实现 61 | 62 | 创建 `/etc/logrotate.d/rails` 文件,内容如下: 63 | 64 | ``` 65 | /data/app/*/shared/log/*.log { 66 | su user group 67 | weekly 68 | size 100M 69 | missingok 70 | rotate 10 71 | compress 72 | delaycompress 73 | notifempty 74 | copytruncate 75 | } 76 | ``` 77 | 78 | 修改其中的 `user group` 为日志文件所属的用户和组,按需修改 79 | 80 | ## 开机自动启动 81 | 82 | Passenger 可随 nginx 自动启动 83 | 84 | unicorn, puma, sidekiq 等由于以下特点: 85 | 86 | 1. 每个应用都需单独运行自己的实例,不像 passenger, php-fpm 那样有一个统一的调度进程同时服务多个应用 87 | 2. 一个系统上可能会同时部署多个应用,且应用的部署目录不固定 88 | 3. 这些服务通常由部署工具的插件(如 mina-unicorn,capistrano-puma)负责启动,而部署工具都是在本地运行的,在服务器上无法使用 89 | 4. 虽然那些插件本质上也是在服务器上执行这些服务各自的命令行工具(`bundle exec unicorn`, `bundle exec pumactl` 等)启动服务的,理论上说可以自己在服务器上手动执行,但这些插件一般会设置一些默认的启动参数,若手动启动时与这些插件的参数不同,可能会有意想不到的问题 90 | 91 | 所以,这些服务难以通过 systemd 等进程管理工具管理,需要手动启动。虽然以上问题都可以解决,但若要考虑到可维护性、扩展性就不那么简单了。 92 | -------------------------------------------------------------------------------- /deploy/supervisor.md: -------------------------------------------------------------------------------- 1 | # Supervisor 2 | 3 | [Supervisor](http://supervisord.org/) 是一个在类 UNIX 系统上管理进程的工具,它能让进程在后台执行,控制并发,进程崩溃时自动重启,捕获进程的标准输出等 4 | 5 | 尤其适合那些没有以守护模式运行功能的进程 6 | 7 | 它由 Python 编写,但可以用于任何应用 8 | 9 | ## 安装 10 | 11 | Supervisor 3.x 只支持 Python 2,4.0 计划支持 Python 3。 12 | 13 | ``` 14 | sudo pip2 install supervisor 15 | ``` 16 | 17 | EPEL 源虽有 supervisor, 但版本较旧,不建议使用。 18 | 19 | ## 配置 20 | 21 | 需手动创建配置文件目录、日志目录: 22 | 23 | ``` 24 | sudo mkdir -p /etc/supervisor/programs 25 | sudo mkdir /var/log/supervisor/ 26 | sudo chown $USER: /var/log/supervisor 27 | ``` 28 | 29 | `/etc/supervisor/supervisord.conf`: 30 | 31 | ``` 32 | [unix_http_server] 33 | file = /var/log/supervisor/supervisor.sock 34 | 35 | [supervisord] 36 | pidfile=/var/log/supervisor/supervisord.pid 37 | nodaemon=false 38 | logfile=/var/log/supervisor/supervisord.log 39 | logfile_maxbytes=50MB 40 | logfile_backups=10 41 | loglevel=info 42 | 43 | [rpcinterface:supervisor] 44 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 45 | 46 | [supervisorctl] 47 | serverurl = unix:///var/log/supervisor/supervisor.sock 48 | 49 | [include] 50 | files = programs/*.ini 51 | ``` 52 | 53 | 各个项目的配置文件放在 `/etc/supervisor/programs/` 目录下,每个项目一个配置文件,以便管理。 54 | 55 | ## Systemd service 56 | 57 | 创建 systemd service 以便管理: 58 | 59 | `/usr/lib/systemd/system/supervisord.service`: 60 | 61 | ``` 62 | [Unit] 63 | Description=Supervisor daemon 64 | 65 | [Service] 66 | Type=forking 67 | # 用户名按实际情况修改 68 | User=username 69 | PIDFile=/var/log/supervisor/supervisord.pid 70 | ExecStart=/usr/bin/supervisord 71 | ExecStop=/usr/bin/supervisorctl shutdown 72 | ExecReload=/usr/bin/supervisorctl reload 73 | KillMode=process 74 | Restart=on-failure 75 | RestartSec=3s 76 | 77 | [Install] 78 | WantedBy=multi-user.target 79 | ``` 80 | 81 | 使用 `systemctl` 管理 supervisord 进程: 82 | 83 | ``` 84 | # 添加/修改 service 文件后需执行以使生效 85 | sudo systemctl daemon-reload 86 | 87 | # 启动/停止/重启/重载配置/查看状态 88 | sudo systemctl start/stop/restart/reload/status supervisord 89 | 90 | # 设置/取消自动启动 91 | sudo systemctl enable/disable supervisord 92 | ``` 93 | 94 | ## 常用命令 95 | 96 | ``` 97 | # 查看所有进程状态 98 | supervisorctl status 99 | 100 | # 查看一个或多个进程状态 101 | supervisorctl status [programe-name]* 102 | 103 | # 重新加载配置 104 | supervisorctl reload 105 | 106 | # 启动/停止/重启一个或多个进程 107 | supervisorctl start/stop/restart [program-name]* 108 | 109 | # 启动/停止/重启所有进程 110 | supervisorctl start/stop/restart all 111 | ``` 112 | 113 | 执行 `supervisorctl help` 以了解更多。 114 | 115 | ## 添加应用 116 | 117 | 1. 在 `/etc/supervisor/programs/` 目录下创建配置文件 118 | 2. 执行 `sudo systemctl reload supervisord` 重载配置 119 | 3. 执行 `sudo supervisorctl start [programe-name]` 启动应用。若未禁止自动启动,则不需执行 120 | 121 | 配置文件示例: 122 | 123 | ``` 124 | [program:girls-day-carve] 125 | directory=/data/app/girls-day-carve 126 | command=python3.5 server.py --unix-socket=log/tornado.sock --subpath=/girls-day-carve 127 | process_name=%(program_name)s_%(process_num)01d 128 | numprocs=1 129 | stdout_logfile=/data/app/girls-day-carve/log/stdout.log 130 | stderr_logfile=/data/app/girls-day-carve/log/stderr.log 131 | ``` 132 | 133 | __日志文件路径须是绝对路径__ 134 | 135 | 配置语法参考[官方文档](http://supervisord.org/configuration.html#program-x-section-settings) 136 | 137 | ## 参考资料 138 | 139 | * [官方网站](http://supervisord.org/) 140 | * [配置文档](http://supervisord.org/configuration.html) 141 | * [自动启动](http://supervisord.org/running.html#running-supervisord-automatically-on-startup) 142 | -------------------------------------------------------------------------------- /gitlab/gitlab-ci-usage.md: -------------------------------------------------------------------------------- 1 | # GitLab-CI 使用方法 2 | 3 | GitLab 自带 GitLab-CI,可用于自动构建、测试、部署 4 | 5 | ## 基本概念 6 | 7 | * Job: 任务,执行命令的单元 8 | * 可配置执行环境、依赖、执行的条件、要执行的 shell 命令等 9 | * shell 命令执行成功(返回值为 0)则任务成功,否则失败 10 | * 不同任务完全独立,因此可配置不同的环境、依赖,可并行执行,但需注意每个任务中都要执行安装依赖等命令(为避免重复,可放在 `before_script` 中) 11 | 12 | * Stage: 任务的类别 13 | * 任务的 stage 默认为 test 14 | * 一个 stage 可以包含多个任务 15 | * 不同 stage 的任务按 `stages` 指令指定的顺序(默认为build, test, deploy)执行 16 | * 同一 stage 的多个任务可并行执行 17 | 18 | * Executor: 执行任务的容器类别,如 ssh, docker, virtualbox 等。__我们使用 docker__ 19 | 20 | * Runner: 执行任务的容器 21 | * 分共享和专用两种,共享的可供所有项目使用,专用的只能用于特定项目(一个或多个) 22 | * 项目必须有可用的 runner 才能执行 GitLab-CI 任务 23 | * 创建 runner 只能在安装了 gitlab-runner 的服务器上执行 shell 命令 24 | * 查看/管理项目的 runner 在项目的 Settings -> CI/CD -> Runners 25 | 26 | * Deploy key: 对 git 仓库有只读权限的密钥对的公钥,可用于在部署服务器上拉取代码。在项目的 Settings -> Repository -> Deploy keys 中配置 27 | 28 | * Variables: GitLab-CI 中执行任务时的环境变量,只有对仓库有 master 及以上权限的用户才能查看和管理。可用于保存配置信息(避免写死在 `.gitlab-ci.yml` 中),或敏感信息(如部署使用的 SSH 私钥,直接在 `.gitlab-ci.yml` 中配置有安全风险)。在项目的 Settings -> CI/CD -> Variables 中配置 29 | 30 | ## 配置 31 | 32 | 1. 在项目的 Settings -> General -> Visibility, project features, permissions 中启用 Pipelines 33 | 34 | 2. 确保有可用 runner。创建 runner 只能由 GitLab 服务器管理员操作。尽量使用共享型 runner 以便管理 35 | 36 | 如使用共享 runner,在项目的 Settings -> CI/CD -> Runners 中启用共享 runner 37 | 38 | 3. 在项目代码的根目录下添加 `.gitlab-ci.yml`,配置自动构建的环境(Docker镜像名称)、依赖的服务(MySQL、Redis等,也需是 Docker 镜像名称)、需要执行的任务(stage)等。将文件提交到版本库 39 | 40 | 配置文件语法参考[官方文档](https://docs.gitlab.com/ce/ci/yaml/README.html) 41 | 42 | 4. 如需自动部署,生成一对 SSH 密钥(在任意机器上均可) 43 | 44 | ```bash 45 | ssh-kengen -t rsa -C 'project_name@gitlab-ci' 46 | ``` 47 | 48 | * 为使 GitLab-CI 有权限操作部署服务器: 49 | * 将公钥添加到要部署服务器的 `~/.ssh/authorized_keys` 中 50 | * 将私钥添加到项目的 Secret Variables 中,名称随意,如 "SSH_PRIVATE_KEY" 51 | * `.gitlab-ci.yml` 配置文件中,执行部署命令前从环境变量中读取 SSH 私钥 52 | 53 | * 为使部署服务器有权限拉取代码(若不需要在部署服务器上拉取代码,略过): 54 | * 若自动部署工具(如 mina)启用了 SSH agent forwarding, 将公钥添加到项目的 Deploy Keys 中 55 | * 若未启用,将部署服务器上的 `~/.ssh/id_rsa.pub` 添加到项目的 Deploy Keys 中 56 | 57 | ## 构建邮件提醒 58 | 59 | GitLab 支持在构建失败时邮件提示,但默认未开启 60 | 61 | 可在 Project -> Integrations -> Pipelines emails 中开启 62 | 63 | 管理员用户可在 Admin Area -> Service Templates -> Pipelines emails 中为新项目默认启用 64 | 65 | ## 技巧/注意事项 66 | 67 | 以下部分命令通过修改环境变量 PATH 生效,若放在外部文件中,须通过 `source` 命令引入方有效 68 | 69 | ### 处理 SSH 私钥 70 | 71 | 私钥属敏感信息,不应保存在人人可见的 `.gitlab-ci.yml` 或其它项目文件中,应保存在项目配置的 Variables 中 72 | 73 | 使用以下命令在任务中使用私钥: 74 | 75 | ```bash 76 | if [ -n "$SSH_PRIVATE_KEY" ]; then 77 | eval $(ssh-agent -s) 78 | ssh-add <(echo "$SSH_PRIVATE_KEY") 79 | mkdir -p ~/.ssh && chmod 700 ~/.ssh 80 | # disable host key checking 81 | echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config 82 | fi 83 | ``` 84 | 85 | ### RVM 86 | 87 | 由于 GitLab-CI 使用 docker 容器时使用的是 non-login shell,导致默认无法使用 RVM 88 | 89 | 使用以下命令解决: 90 | 91 | ```bash 92 | if [ -x '/etc/profile.d/rvm.sh' ]; then 93 | source /etc/profile.d/rvm.sh 94 | rvm use default 95 | fi 96 | ``` 97 | 98 | ### 使用服务 99 | 100 | 可以使用任何 docker 镜像作为服务,如 MySQL, Redis 101 | 102 | 这些提供服务的 docker 容器会被链接到执行 GitLab-CI 任务的容器,主机名称通过以下规则从 docker 镜像名称转换: 103 | 104 | * 忽略 ":" 及其后面的版本号 105 | * "/" 替换为 "\_\_" 106 | 107 | 如 "bianjp/mariadb-alpine:latest" 的主机名为 "bianjp__mariadb-alpine","redis:alpine" 的主机名为 "redis" 108 | 109 | 在应用代码中可通过这些主机名使用这些服务 110 | 111 | 为了便于维护,建议在 `.gitlab-ci.yml` 中把主机名定义为变量,在应用代码中动态获取环境变量而非硬编码 112 | 113 | 为减少带宽、内存占用,尽量使用轻量级的 docker 镜像 114 | 115 | ## 示例 116 | 117 | 项目根目录下添加 `.gitlab-ci-before-script.sh`: 118 | 119 | ```bash 120 | #!/bin/bash 121 | 122 | # SSH private key 123 | if [ -n "$SSH_PRIVATE_KEY" ]; then 124 | eval $(ssh-agent -s) 125 | ssh-add <(echo "$SSH_PRIVATE_KEY") 126 | mkdir -p ~/.ssh && chmod 700 ~/.ssh 127 | # disable host key checking 128 | echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config 129 | fi 130 | 131 | # RVM 132 | if [ -x '/etc/profile.d/rvm.sh' ]; then 133 | source /etc/profile.d/rvm.sh 134 | rvm use default 135 | fi 136 | 137 | # locale 138 | export LANG=en_US.UTF-8 139 | export LC_ALL=en_US.UTF-8 140 | ``` 141 | 142 | `.gitlab-ci.yml` 示例: 143 | 144 | ```yaml 145 | image: bianjp/rails-env-centos7:latest 146 | 147 | # 服务、任务运行时的环境变量 148 | variables: 149 | # 用于 bianjp/mariadb-alpine 镜像初始化 150 | MYSQL_ROOT_PASSWORD: 'root' 151 | MYSQL_INITDB_SKIP_TZINFO: 'true' 152 | 153 | # 用于 Rails 配置,在配置文件中动态获取这些环境变量 154 | DB_HOST: 'bianjp__mariadb-alpine' 155 | DB_USERNAME: 'root' 156 | DB_PASSWORD: 'root' 157 | 158 | REDIS_HOST: 'redis' 159 | REDIS_PORT: '6379' 160 | 161 | # 在不同构建之间缓存部分内容 162 | cache: 163 | key: 'global' 164 | paths: 165 | - vendor/bundle 166 | 167 | services: 168 | - bianjp/mariadb-alpine:latest 169 | - redis:alpine 170 | 171 | stages: 172 | - test 173 | - deploy 174 | 175 | before_script: 176 | # 必须使用 source 命令 177 | - source .gitlab-ci-before-script.sh 178 | 179 | # 处理配置文件 180 | - cp config/database.gitlab-ci.yml config/database.yml 181 | - cp config/secrets.gitlab-ci.yml config/secrets.yml 182 | 183 | # 安装依赖 184 | - bundle install --path vendor/bundle 185 | 186 | # 测试 187 | test: 188 | stage: test 189 | script: 190 | - RAILS_ENV=test bundle exec rake db:setup 191 | - bundle exec rake spec 192 | 193 | # 部署到生产服务器 194 | production: 195 | stage: deploy 196 | enrironment: production 197 | script: 198 | - bundle exec mina production deploy 199 | only: 200 | - master 201 | 202 | # 部署到开发服务器 203 | development: 204 | stage: deploy 205 | environment: development 206 | script: 207 | - bundle exec mina dev deploy 208 | only: 209 | - dev 210 | ``` 211 | 212 | ## 参考资料 213 | 214 | * [GitLab-CI documentation](https://docs.gitlab.com/ce/ci/) 215 | * [Using Docker Images](https://docs.gitlab.com/ce/ci/docker/using_docker_images.html) 216 | * [.gitlab-ci.yml usage](https://docs.gitlab.com/ce/ci/yaml/README.html) 217 | * [Using SSH keys](https://docs.gitlab.com/ce/ci/ssh_keys/index.html) 218 | -------------------------------------------------------------------------------- /gitlab/gitlab-ci.md: -------------------------------------------------------------------------------- 1 | # GitLab CI 安装、配置与维护 2 | 3 | GitLab 自带 GitLab-CI,可用于自动构建、测试、部署 4 | 5 | ## 安装 GitLab Runner 6 | 7 | GitLab Runner 是 GitLab-CI 的任务执行者,需单独安装 8 | 9 | 可安装在任意位置,并不需要与 GitLab 在同一台机器 10 | 11 | ### 添加软件源 12 | 13 | 国内使用[清华大学源](https://mirror.tuna.tsinghua.edu.cn/help/gitlab-runner/): 14 | 15 | ```bash 16 | sudo tee /etc/yum.repos.d/gitlab-ci-multi-runner.repo <<-'EOF' 17 | [gitlab-runner] 18 | name=gitlab-runner 19 | baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/yum/el$releasever-$basearch/ 20 | repo_gpgcheck=0 21 | gpgcheck=0 22 | enabled=1 23 | gpgkey=https://packages.gitlab.com/gpg.key 24 | EOF 25 | ``` 26 | 27 | 国外使用 GitLab 官方源: 28 | 29 | ```bash 30 | curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash 31 | ``` 32 | 33 | ### 安装 34 | 35 | ```bash 36 | export GITLAB_RUNNER_DISABLE_SKEL=true 37 | sudo -E yum install gitlab-runner 38 | ``` 39 | 40 | ## 管理命令 41 | 42 | ```bash 43 | # 查看状态/启动/关闭/重启 44 | sudo systemctl status/start/stop/restart gitlab-runner 45 | # 启用/禁用自动启动。安装后默认已启用自动启动 46 | sudo systemctl enable/disable gitlab-runner 47 | ```` 48 | 49 | ## 更新 50 | 51 | 更新前检查[更新日志](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/master/CHANGELOG.md) 52 | 53 | ```bash 54 | sudo yum update 55 | ``` 56 | 57 | ## 安装 Docker 58 | 59 | 使用 docker 作为执行任务的容器 60 | 61 | 参看 [docker 安装与维护](../base/docker.md) 62 | 63 | ## 添加 runner 64 | 65 | 添加后才能在 CI 中使用 66 | 67 | ``` 68 | sudo gitlab-runner register 69 | ``` 70 | 71 | 若添加共享型 runner, token 为 Admin -> Runners 页面所示; 72 | 73 | 若添加专用 runner, token 为小组或项目的 Settings -> Runners 页面所示 74 | 75 | ## 并发度 76 | 77 | 默认每个 runner 的并发度是 1,即同一时间只能有一个构建使用该 runner 78 | 79 | 参考 [Advanced configuration options](https://docs.gitlab.com/runner/configuration/advanced-configuration.html),设置全局的 `concurrent` 和每个 runner 的 `limit` 80 | 81 | 根据系统负载能力酌情设置 82 | 83 | __`limit` > 1 可能会导致缓存经常失效__ 84 | 85 | ## 参考资料 86 | 87 | * [GitLab Runner Documentation](https://docs.gitlab.com/runner/) 88 | * [Install GitLab Runner](https://docs.gitlab.com/runner/install/linux-repository.html) 89 | * [Advanced configuration options](https://docs.gitlab.com/runner/configuration/advanced-configuration.html) 90 | * [清华大学 gitlab-runner 源](https://mirror.tuna.tsinghua.edu.cn/help/gitlab-runner/) 91 | -------------------------------------------------------------------------------- /gitlab/gitlab.md: -------------------------------------------------------------------------------- 1 | # GitLab 2 | 3 | 为便于维护,使用 GitLab CE Omnibus package 安装方式 4 | 5 | ## 安装 6 | 7 | ### 安装依赖,配置环境 8 | 9 | ```bash 10 | sudo yum install -y curl policycoreutils-python openssh-server perl 11 | sudo systemctl enable sshd 12 | sudo systemctl start sshd 13 | # 如果开启了 firewalld, 增加服务配置 14 | # systemctl is-active firewalld.service 15 | sudo firewall-cmd --permanent --add-service=http 16 | sudo firewall-cmd --permanent --add-service=https 17 | sudo systemctl reload firewalld 18 | 19 | sudo yum install postfix 20 | sudo systemctl enable postfix 21 | sudo systemctl start postfix 22 | ``` 23 | 24 | 若系统不支持 IPv6,须修改 `/etc/postfix/main.cf` 25 | 26 | ``` 27 | inet_interfaces = loopback-only 28 | ``` 29 | 30 | ### 添加 GitLab 软件源 31 | 32 | 国内使用[清华大学源](https://mirror.tuna.tsinghua.edu.cn/help/gitlab-ce/): 33 | 34 | ```bash 35 | sudo tee /etc/yum.repos.d/gitlab-ce.repo <<-'EOF' 36 | [gitlab-ce] 37 | name=Gitlab CE Repository 38 | baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/ 39 | gpgcheck=0 40 | enabled=1 41 | EOF 42 | ``` 43 | 44 | 国外使用 GitLab 官方源: 45 | 46 | ```bash 47 | curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash 48 | ``` 49 | 50 | ### 安装 GitLab 51 | 52 | ```bash 53 | sudo yum install gitlab-ce 54 | ``` 55 | 56 | ## 配置 57 | 58 | 配置文件为 `/etc/gitlab/gitlab.rb` 59 | 60 | ```ruby 61 | # 访问地址。可以包含端口号、子路径 62 | external_url 'http://git.example.com' 63 | 64 | # 时区 65 | gitlab_rails['time_zone'] = 'Asia/Shanghai' 66 | 67 | # gitlab 主目录。不可更改! 68 | #jinyuan 69 | user['home'] = "/var/opt/gitlab" 70 | 71 | # 仓库存储目录 72 | # git_data_dirs({ "default" => { "path" => "/var/opt/gitlab/git-data" } }) 73 | 74 | # 备份文件存储目录 75 | # gitlab_rails['backup_path'] = "/var/opt/gitlab/backups" 76 | 77 | # 备份文件保存时间(秒),避免备份文件过多而占用太多磁盘空间 78 | gitlab_rails['backup_keep_time'] = 2592000 # 30 days 79 | 80 | # 添加自定义 nginx 配置文件 81 | # 目的是处理非域名请求,减轻外部攻击、扫描对服务器负载的影响 82 | nginx['custom_nginx_config'] = "include /etc/gitlab/nginx-default.conf;" 83 | 84 | # 日志文件轮滚频率。默认每天,太频繁 85 | logging['logrotate_frequency'] = "monthly" 86 | ``` 87 | 88 | 若使用 HTTPS,修改以下配置: 89 | 90 | ```ruby 91 | external_url "https://git.example.com" 92 | nginx['redirect_http_to_https'] = true 93 | nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.example.crt" 94 | nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.example.com.key" 95 | ``` 96 | 97 | `/etc/gitlab/nginx-default.conf` 内容如下: 98 | 99 | ```nginx 100 | server { 101 | listen 80 default_server; 102 | server_name _; 103 | return 404; 104 | 105 | access_log /var/log/gitlab/nginx/default_access.log; 106 | error_log /var/log/gitlab/nginx/default_error.log; 107 | } 108 | ``` 109 | 110 | 更多配置,查看[配置文档](https://docs.gitlab.com/omnibus/settings/) 111 | 112 | 修改配置文件后需执行以下命令以使配置生效 113 | 114 | ```bash 115 | sudo gitlab-ctl reconfigure 116 | ``` 117 | 118 | 若修改了目录设置,可能需要手动迁移数据,具体操作查看相关文档 119 | 120 | ## 集成 Let's Encrypt SSL 证书 121 | 122 | GitLab 已官方支持集成 Let's Encrypt, 参考官方文档: https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration 123 | 124 | 注意,如果手动管理证书,证书变更后需要重启 GitLab 的 Nginx: `/bin/gitlab-ctl restart nginx` 125 | 126 | ## 命令行工具 127 | 128 | ```bash 129 | # 重新配置/启动/查看状态/停止/重启 130 | sudo gitlab-ctl reconfigure/start/status/stop/restart 131 | # 查看更多命令帮助 132 | sudo gitlab-ctl help 133 | 134 | # 启用/禁用自动启动。安装后默认已启用自动启动 135 | sudo systemctl enable/disable gitlab-runsvdir 136 | 137 | # 检查 gitlab 配置与环境 138 | sudo gitlab-rake gitlab:check 139 | ``` 140 | 141 | ## 升级 142 | 143 | 升级前需检查新版本及所有中间版本的[发布声明](https://about.gitlab.com/releases/archives.html) 144 | 145 | 一般情况下直接 yum 升级即可,升级大版本时则一般需要先升级到当前大版本的最新版再升级到下一个大版本。 146 | 147 | ```bash 148 | sudo yum update gitlab-ce 149 | ``` 150 | 151 | [官方 Omnibus 升级文档](https://docs.gitlab.com/omnibus/update/) 152 | 153 | ## 备份和恢复 154 | 155 | 备份文件存储目录由配置文件中的 `gitlab_rails['backup_path']` 指定,默认为 `/var/opt/gitlab/backups` 156 | 157 | 备份文件名称为 `[TIMESTAMP]_gitlab_backup.tar` 158 | 159 | ### 备份 160 | 161 | ```bash 162 | sudo gitlab-backup create 163 | ``` 164 | 165 | ### 自动定期备份 166 | 167 | 使用 crontab 配置定时任务 168 | 169 | 切换到 root 用户,执行 `crontab -e`,添加以下内容(每周六凌晨4点备份): 170 | 171 | ``` 172 | # Minute Hour Day Month Day_of_week Command 173 | 0 4 * * 6 /opt/gitlab/bin/gitlab-backup create CRON=1 174 | 175 | # 将备份文件同步到数据盘 176 | # 30 4 * * 6 /bin/rsync -tpq /var/opt/gitlab/backups/* /data/gitlab-backup/ 177 | ``` 178 | 179 | 最好将备份文件自动同步到其它介质(如云存储)上 180 | 181 | ### 恢复 182 | 183 | 备份文件须在备份文件存储目录中 184 | 185 | ``` 186 | # 停止使用数据库的进程 187 | sudo gitlab-ctl stop puma 188 | sudo gitlab-ctl stop sidekiq 189 | 190 | # 恢复。若有多个备份文件,需指定 timestamp 191 | sudo gitlab-backup restore [BACKUP=timestamp_of_backup] 192 | 193 | # 重新配置、重启 194 | sudo gitlab-ctl reconfigure 195 | sudo gitlab-ctl restart 196 | 197 | # 检查 198 | sudo gitlab-rake gitlab:check SANITIZE=true 199 | ``` 200 | 201 | __注意:恢复时 GitLab 版本必须与备份时版本完全相同(x.x.x三段均相同)__ 202 | 203 | ## 迁移 204 | 205 | 迁移到其它服务器上时,要迁移 `/etc/gitlab/gitlab-secrets.json`,否则 GitLab-CI Variables 的解密会失败,导致 Project Settings -> Variables 页面无法打开、自动构建失败 206 | 207 | ## 参考资料 208 | 209 | * [Installation](https://about.gitlab.com/install/?version=ce#centos-7) 210 | * [GitLab CE Documentation](https://docs.gitlab.com/ce/) 211 | * [Omnibus Documentation](https://docs.gitlab.com/omnibus/) 212 | * [Omnibus Settings](https://docs.gitlab.com/omnibus/settings/) 213 | * [Backup and Restore](https://docs.gitlab.com/ce/raketasks/backup_restore.html) 214 | * [清华大学 gitlab-ce 源](https://mirror.tuna.tsinghua.edu.cn/help/gitlab-ce/) 215 | -------------------------------------------------------------------------------- /languages/java.md: -------------------------------------------------------------------------------- 1 | # Java 2 | 3 | 使用 [OpenJDK](http://openjdk.java.net/) 4 | 5 | ## 安装 6 | 7 | ``` 8 | # JRE only 9 | sudo yum install java-1.8.0-openjdk 10 | 11 | # JDK 12 | sudo yum install java-1.8.0-openjdk-devel 13 | ``` 14 | 15 | ## 配置 16 | 17 | 有些应用依赖 `JAVA_HOME` 环境变量 18 | 19 | `~/.bash_profile`: 20 | 21 | ```bash 22 | export JAVA_HOME=/usr/lib/jvm/java 23 | # 如果只安装了 JRE 24 | # export JAVA_HOME=/usr/lib/jvm/jre 25 | ``` 26 | 27 | `/usr/lib/jvm/java` 是个符号链接,指向当前使用的 Java 版本。也可设置为 `/usr/lib/jvm/` 下的其它目录 28 | 29 | 这些符号链接是由 `chkconfig` 包提供的 `alternatives` 管理的。如果同时安装了多个 Java 版本,可使用以下命令选择默认使用的版本: 30 | 31 | ```bash 32 | alternatives --config java 33 | ``` 34 | 35 | ## Maven 国内镜像 36 | 37 | 只对 maven 有效,对 Gradle 无效。 38 | 39 | `~/.m2/settings.xml`: 40 | 41 | ``` 42 | 43 | 46 | 47 | 48 | nexus-aliyun 49 | central, jcenter, gradle-plugin 50 | Nexus aliyun 51 | http://maven.aliyun.com/nexus/content/groups/public 52 | 53 | 54 | 55 | ``` 56 | 57 | ## 参考资料 58 | 59 | * [OpenJDK](http://openjdk.java.net/install/) 60 | * [Install OpenJDK on Red Hat Enterprise Linux 6](https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Installation_Guide/Install_OpenJDK_on_Red_Hat_Enterprise_Linux.html) 61 | * [Using Java on RHEL 7 with OpenJDK 8](https://developers.redhat.com/articles/using-java-rhel-7-openjdk-8/) 62 | -------------------------------------------------------------------------------- /languages/nodejs.md: -------------------------------------------------------------------------------- 1 | # Node.js 2 | 3 | ## 安装 4 | 5 | EPEL 源中已有 6.x 版本 6 | 7 | ``` 8 | sudo yum install nodejs 9 | ``` 10 | 11 | 若仍想使用更新版本,可使用 [NodeSource 源](https://github.com/nodesource/distributions): 12 | 13 | ``` 14 | curl -sL https://rpm.nodesource.com/setup_9.x | sudo bash - 15 | # 使用 TUNA 源 16 | sudo sed -i 's#https://rpm.nodesource.com/pub_9.x/#https://mirror.tuna.tsinghua.edu.cn/nodesource/rpm_9.x/#g' /etc/yum.repos.d/nodesource-el.repo 17 | 18 | sudo yum install nodejs 19 | ``` 20 | 21 | ## 安装 Yarn 22 | 23 | ``` 24 | sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo 25 | sudo yum install yarn 26 | ``` 27 | 28 | ## 配置 29 | 30 | 若 npm 官方源速度较慢且不稳定,可改用[淘宝源](http://npm.taobao.org/): 31 | 32 | ``` 33 | cat < ~/.npmrc 34 | registry=https://registry.npm.taobao.org 35 | EOF 36 | ``` 37 | 38 | ## 参考资料 39 | 40 | * [NodeSource](https://nodesource.com/) 41 | * [Yarn Installation](https://yarnpkg.com/en/docs/install) 42 | -------------------------------------------------------------------------------- /languages/php.md: -------------------------------------------------------------------------------- 1 | # PHP 2 | 3 | 使用 Nginx + PHP-FPM 部署 PHP 应用 4 | 5 | ## 安装 6 | 7 | ``` 8 | # 官方源中 php 版本过旧,使用 IUS 源 9 | sudo rpm -Uvh https://centos7.iuscommunity.org/ius-release.rpm 10 | sudo yum update 11 | 12 | sudo yum install php70u-cli php70u-fpm php70u-json php70u-gd php70u-mbstring php70u-mcrypt php70u-opcache php70u-mysqlnd 13 | 14 | sudo systemctl start php-fpm 15 | sudo systemctl enable php-fpm 16 | ``` 17 | 18 | ## 配置 19 | 20 | `/etc/php.ini`: 21 | 22 | ``` 23 | # POST 请求体大小、上传文件大小。按应用需求修改 24 | post_max_size = 8M 25 | upload_max_filesize = 8M 26 | 27 | # 避免 nginx + php-fpm 的安全问题 28 | cgi.fix_pathinfo = 0 29 | 30 | # 时区 31 | date.timezone = Asia/Shanghai 32 | 33 | # 是否自动开启 session 34 | session.auto_start = 0 35 | ``` 36 | 37 | `/etc/php-fpm.d/www.conf`: 38 | 39 | ``` 40 | listen = 127.0.0.1:9000 41 | listen.allowed_clients = 127.0.0.1 42 | user = nginx 43 | group = nginx 44 | 45 | ; 进程管理策略。根据内存大小、负载情况调整 46 | pm = dynamic 47 | pm.max_children = 200 48 | pm.start_servers = 5 49 | pm.min_spare_servers = 5 50 | pm.max_spare_servers = 35 51 | 52 | # 检查负载情况与可用性的路径。注意避免与应用冲突 53 | # 若开启,注意限制访问权限以减少风险 54 | #pm.status_path = /status 55 | #ping.path = /ping 56 | 57 | slowlog = /var/log/php-fpm/www-slow.log 58 | ; 如需开启访问日志,取消注释下一行。若非必要不要开启 59 | ;access.log = /var/log/php-fpm/$pool.access.log 60 | access.format = "%t \"%m %r%Q%q\" %s %{mili}d %{kilo}M %C%%" 61 | 62 | # 注释下一行,或创建该目录并设置用户和组为 nginx。因为 php-fpm 不会自动创建该目录,导致 session 无法保存 63 | ;php_value[session.save_path] = /var/lib/php/session 64 | ``` 65 | 66 | 检查配置是否正确: 67 | 68 | ``` 69 | sudo php-fpm -t 70 | ``` 71 | -------------------------------------------------------------------------------- /languages/python.md: -------------------------------------------------------------------------------- 1 | # Python 2 | 3 | ## Python 3 4 | 5 | ```bash 6 | # 需启用 EPEL 源 7 | sudo yum install python36 python36-devel python36-setuptools 8 | sudo easy_install-3.6 pip 9 | 10 | sudo ln -s /usr/bin/python3.6 /usr/bin/python3 11 | ``` 12 | 13 | ## PyPI 国内镜像 14 | 15 | ``` 16 | # 安装包时需要以 root 用户执行,因此配置文件保存在 root 用户目录 17 | sudo mkdir -p ~root/.pip 18 | sudo touch ~root/.pip/pip.conf 19 | ``` 20 | 21 | 编辑 `~root/.pip/pip.conf`,添加下列源中的一个: 22 | 23 | 中国科技大学源: 24 | 25 | ``` 26 | [global] 27 | index-url = https://pypi.mirrors.ustc.edu.cn/simple 28 | trusted-host=pypi.mirrors.ustc.edu.cn 29 | ``` 30 | 31 | 阿里云源: 32 | 33 | ``` 34 | [global] 35 | index-url = http://mirrors.aliyun.com/pypi/simple/ 36 | trusted-host=mirrors.aliyun.com 37 | ``` 38 | 39 | 阿里云内网源: 40 | 41 | ``` 42 | [global] 43 | index-url = http://mirrors.aliyuncs.com/pypi/simple/ 44 | trusted-host=mirrors.aliyuncs.com 45 | ``` 46 | 47 | ## 常用包 48 | 49 | ``` 50 | # 系统监控工具 51 | sudo pip3 install glances 52 | # For Python 2 53 | sudo pip2 install glances 54 | ``` 55 | -------------------------------------------------------------------------------- /languages/ruby.md: -------------------------------------------------------------------------------- 1 | # Ruby 2 | 3 | 官方源中的版本较低,可使用 RVM 或 rbenv 安装 4 | 5 | ## RVM 6 | 7 | RVM (Ruby Version Manager) 用来安装、管理不同的 Ruby 环境(Ruby 的不同实现、不同版本、不同的 GEM 包集) 8 | 9 | 参考 [rvm 官方安装文档](https://rvm.io/rvm/install) 10 | 11 | ``` 12 | gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 13 | curl -sSL https://get.rvm.io | bash -s stable 14 | 15 | # 允许 rvm 自动更新 16 | echo rvm_autoupdate_flag=2 >> ~/.rvmrc 17 | 18 | # 使用国内 Ruby 镜像 19 | echo "ruby_url=https://cache.ruby-china.org/pub/ruby" >> ~/.rvm/user/db 20 | 21 | source ~/.rvm/scripts/rvm 22 | rvm install 2.3.1 23 | rvm use 2.3.1 --default 24 | gem install bundler 25 | ``` 26 | 27 | __注意:上述 rvm 安装步骤为单用户模式,部署 ruby 应用时使用的用户应为执行上述安装步骤的用户__ 28 | 29 | ## rbenv 30 | 31 | ``` 32 | git clone https://github.com/sstephenson/rbenv.git ~/.rbenv 33 | git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build 34 | git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash 35 | git clone https://github.com/rkh/rbenv-update.git ~/.rbenv/plugins/rbenv-update 36 | # 使用 Ruby China 的镜像安装 Ruby, 国内用户推荐 37 | git clone https://github.com/AndorChen/rbenv-china-mirror.git ~/.rbenv/plugins/rbenv-china-mirror 38 | 39 | tee -a ~/.bash_profile <<-'EOF' 40 | export PATH="$HOME/.rbenv/bin:$PATH" 41 | eval "$(rbenv init -)" 42 | EOF 43 | ``` 44 | 45 | 安装 ruby: 46 | 47 | ``` 48 | rbenv install 2.3.3 49 | # 默认使用版本 50 | rbenv global 2.3.3 51 | ``` 52 | 53 | ## 手动编译安装 54 | 55 | 以 root 身份执行: 56 | 57 | ``` 58 | RUBY_VERSION=2.4.1 59 | RUBY_DOWNLOAD_MIRROR=https://cache.ruby-lang.org/pub/ruby/ 60 | # RUBY_DOWNLOAD_MIRROR=https://cache.ruby-china.org/pub/ruby/ 61 | 62 | yum install -y autoconf gcc gcc-c++ make automake patch 63 | yum install -y git openssh curl which tar gzip bzip2 unzip zip 64 | yum install -y openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel 65 | yum install -y epel-release yum-utils 66 | yum-config-manager --enable epel 67 | 68 | mkdir -p /usr/local/etc 69 | echo -e "install: --no-document\nupdate: --no-document" > /usr/local/etc/gemrc 70 | mkdir /build && cd /build 71 | curl -o ruby.tar.gz "$RUBY_DOWNLOAD_MIRROR/ruby-$RUBY_VERSION.tar.gz" 72 | mkdir ruby && tar -xzf ruby.tar.gz -C ruby --strip-components=1 73 | cd ruby 74 | ./configure --disable-install-doc --enable-shared 75 | make -j"$(nproc)" 76 | make install 77 | cd / && rm -rf /build 78 | ``` 79 | 80 | ``` 81 | gem update --system && gem install bundler 82 | ``` 83 | 84 | ## 配置 85 | 86 | 使用[Ruby China gem 源](https://gems.ruby-china.org/),禁止安装文档 87 | 88 | ``` 89 | cat < ~/.gemrc 90 | --- 91 | :backtrace: false 92 | :bulk_threshold: 1000 93 | :sources: 94 | - https://gems.ruby-china.org/ 95 | :update_sources: true 96 | :verbose: true 97 | gem: "--no-user-install --no-document" 98 | EOF 99 | ``` 100 | 101 | ## 参考资料 102 | 103 | * [RVM](https://rvm.io/) 104 | * [rbenv GitHub Repository](https://github.com/rbenv/rbenv/) 105 | * [Ruby China RVM 实用指南](https://ruby-china.org/wiki/rvm-guide) 106 | * [Ruby China rbenv 实用指南](https://ruby-china.org/wiki/rbenv-guide) 107 | * [Ruby China gem 源](https://gems.ruby-china.org/) 108 | -------------------------------------------------------------------------------- /others/certbot.md: -------------------------------------------------------------------------------- 1 | # Certbot 2 | 3 | Certbot 用于获取 [Let's Encrypt](https://letsencrypt.org/) SSL 证书 4 | 5 | ## 安装 6 | 7 | ``` 8 | # 需启用 EPEL 源 9 | sudo yum install certbot 10 | ``` 11 | 12 | ## 配置 13 | 14 | ``` 15 | sudo mkdir -p /etc/letsencrypt 16 | 17 | sudo tee /etc/letsencrypt/cli.ini < 71 | 72 | Emqtt 73 | The massively scalable MQTT broker 74 | 75 | 76 | 77 | 78 | 79 | EOF 80 | 81 | sudo firewall-cmd --reload 82 | sudo firewall-cmd --permanent --zone=dmz --add-service=emqtt 83 | sudo firewall-cmd --zone=dmz --add-service=emqtt 84 | ``` 85 | 86 | 若使用了非默认端口,需相应修改 `/etc/firewalld/services/emqtt.xml` 87 | 88 | ### 认证 89 | 90 | 安全起见,要对客户端(包括发布者、订阅者)进行认证 91 | 92 | emqttd 支持 ClientID、用户名/密码、IP地址、HTTP Cookie 等多种认证方式 93 | 94 | 我们使用用户名/密码认证方式,并使用 [ACL](https://github.com/emqtt/emqttd/wiki/ACL-Design) 控制权限(发布、订阅) 95 | 96 | 不同类型的客户端使用不同的账号,分配尽量少的权限(操作,topic),以减少安全隐患 97 | 98 | 1. 添加用户名/密码 99 | 100 | 修改 `etc/emqttd.config` 中的 emqttd -> access -> auth: 101 | 102 | ``` 103 | {username, [{"username", "password"}, {"username2", "password2"}]}, 104 | ``` 105 | 106 | 2. 控制权限 107 | 108 | 修改 `etc/acl.config`: 109 | 110 | ``` 111 | {allow, all}. 112 | 113 | {deny, {user, "subscriber"}, publish, ["$SYS/#", "#"]}. 114 | ``` 115 | 116 | __ACL 中的用户名必须存在于 `etc/emqttd.config` 中,否则 emqttd 启动失败__ 117 | 118 | ### Web 管理 119 | 120 | 插件 [emqttd_dashboard](https://github.com/emqtt/emqttd_dashboard) 提供了一个 Web 管理界面,访问地址为 http://server_addr:10803 121 | 122 | 默认账号为: 123 | 124 | * 用户名:admin 125 | * 密码:public 126 | 127 | 安装后应立即修改默认密码 128 | 129 | ## 参考资料 130 | 131 | * [emqtt 官网](http://emqtt.io) 132 | * [emqtt 中文官网](http://emqtt.com) 133 | * [官方文档](http://emqtt.io/docs/index.html) 134 | * [官方 Wiki](https://github.com/emqtt/emqttd/wiki) 135 | -------------------------------------------------------------------------------- /others/nexus.md: -------------------------------------------------------------------------------- 1 | # Nexus Repository Manager OSS 2 | 3 | [Nexus Repository Manager OSS](http://www.sonatype.com/nexus-repository-oss) 用于搭建私有源、镜像代理,支持 maven, docker, bower, npm 等 4 | 5 | ## 安装 Java Runtime 6 | 7 | Nexus 依赖 Java 运行时环境,官方只支持 Oracle Java 8 | 9 | 但 openjdk 也应能正常工作: 10 | 11 | ``` 12 | sudo yum install java-1.8.0-openjdk 13 | ``` 14 | 15 | ## 安装 16 | 17 | 没有 rpm 包可用,只能手动下载安装 18 | 19 | ``` 20 | curl -LO http://download.sonatype.com/nexus/3/latest-unix.tar.gz 21 | tar vxf latest-unix.tar.gz 22 | sudo mv nexus-* /opt 23 | sudo ln -s /opt/nexus-*/ /opt/nexus 24 | 25 | # 创建单独的用户作为运行时用户,避免安全隐患 26 | sudo useradd -M -c "Nexus repository manager" -s /sbin/nologin nexus 27 | sudo chown -R nexus: /opt/nexus/ 28 | 29 | # 添加 systemd 管理服务 30 | sudo tee /etc/systemd/system/nexus.service <<-'EOF' 31 | [Unit] 32 | Description=nexus service 33 | After=network.target 34 | 35 | [Service] 36 | Type=forking 37 | ExecStart=/opt/nexus/bin/nexus start 38 | ExecStop=/opt/nexus/bin/nexus stop 39 | ExecReload=/opt/nexus/bin/nexus force-reload 40 | User=nexus 41 | Restart=on-abort 42 | 43 | [Install] 44 | WantedBy=multi-user.target 45 | EOF 46 | 47 | sudo systemctl daemon-reload 48 | ``` 49 | 50 | ## 配置 51 | 52 | 配置文件保存在安装目录的 `etc`, `bin` 子目录下 53 | 54 | ### 监听地址 55 | 56 | Nexus 默认监听所有 interface 的 8081 端口 57 | 58 | 生产环境下使用 Nginx 作为前端,反向代理到 nexus,因此 nexus 只需监听本地即可 59 | 60 | `/opt/nexus/etc/org.sonatype.nexus.cfg`: 61 | 62 | ``` 63 | application-host=127.0.0.1 64 | 65 | # 若部署在子路径,此处设置子路径 66 | # nexus-context-path=/nexus/ 67 | ``` 68 | 69 | ### 数据目录 70 | 71 | 数据目录默认为安装目录下的 `data` 目录,改为其它目录,以便升级 nexus 72 | 73 | `/opt/nexus/bin/nexus.vmoptions`: 74 | 75 | ``` 76 | -Dkaraf.data=/data/nexus 77 | -Djava.io.tmpdir=/data/nexus/tmp 78 | ``` 79 | 80 | 创建数据目录: 81 | 82 | ``` 83 | sudo mkdir /data/nexus 84 | sudo chown nexus: /data/nexus 85 | ``` 86 | 87 | ### SEO 88 | 89 | 禁止搜索引擎索引,以减少被发现、滥用的风险 90 | 91 | `/opt/nexus/public/robots.txt`: 92 | 93 | ``` 94 | User-agent: * 95 | Disallow: / 96 | ``` 97 | 98 | ### Nginx 99 | 100 | ``` 101 | server { 102 | listen 80; 103 | server_name nexus.example.com; 104 | return 301 https://$host$request_uri; 105 | 106 | access_log /var/log/nginx/nexus.access.log main; 107 | error_log /var/log/nginx/nexus.error.log warn; 108 | } 109 | 110 | server { 111 | listen 443 http2 ssl; 112 | server_name nexus.example.com; 113 | 114 | ssl_certificate /etc/letsencrypt/live/nexus.example.com/fullchain.pem; 115 | ssl_certificate_key /etc/letsencrypt/live/nexus.example.com/privkey.pem; 116 | 117 | proxy_send_timeout 120; 118 | proxy_read_timeout 300; 119 | proxy_buffering off; 120 | keepalive_timeout 55; 121 | tcp_nodelay on; 122 | 123 | # allow large uploads of files 124 | client_max_body_size 1G; 125 | 126 | # optimize downloading files larger than 1G 127 | proxy_max_temp_file_size 2G; 128 | 129 | location / { 130 | proxy_pass http://127.0.0.1:8081; 131 | proxy_set_header Host $http_host; 132 | proxy_set_header X-Real-IP $remote_addr; 133 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 134 | # 若未使用 https,注释该配置 135 | proxy_set_header X-Forwarded-Proto "https"; 136 | } 137 | 138 | access_log /var/log/nginx/nexus.access.log main; 139 | error_log /var/log/nginx/nexus.error.log warn; 140 | } 141 | ``` 142 | 143 | ## 运行 144 | 145 | 使用 systemd 管理 nexus 运行状态: 146 | 147 | ``` 148 | # 查看状态/启动/停止/重启 149 | sudo systemctl start/stop/restart/status nexus 150 | 151 | # 启用/禁用自动启动 152 | sudo systemctl enable/disable nexus 153 | ``` 154 | 155 | 网页端默认的管理账号为: 156 | 157 | * username: admin 158 | * password: admin123 159 | 160 | 首次运行后应立即修改密码 161 | 162 | ## 升级 163 | 164 | 步骤: 165 | 166 | 1. 下载新版本并解压缩到 `/opt/` 目录下,修改其中的配置文件 167 | 2. 停止运行 nexus 168 | 3. 修改 `/opt/nexus` 符号链接,指向最新版本 169 | 4. 启动 nexus 170 | 171 | 由于配置文件保存在安装目录中,每次升级都须重新修改配置文件,比较麻烦,可使用以下脚本简化操作: 172 | 173 | ```shell 174 | #!/usr/bin/bash 175 | # 升级 nexus 版本 176 | # 参数:新版本目录 177 | 178 | set -e 179 | 180 | # nexus 运行时的用户 181 | user=nexus 182 | # 数据目录 183 | data_dir=/data/nexus 184 | 185 | # 新版本文件所在目录 186 | new_version_path=$1 187 | 188 | if [[ -z "$new_version_path" ]]; then 189 | echo "请指定新版本文件所在目录" 190 | exit 1 191 | elsif [[ ! -d "$new_version_path" ]]; 192 | echo "$new_version_path 不是一个正确的目录" 193 | exit 1 194 | fi 195 | 196 | base_name=`basename $new_version_path` 197 | 198 | if [[ -d "/opt/$base_name" ]]; then 199 | echo "/opt/$base_name 已存在" 200 | exit 1 201 | fi 202 | 203 | # 安装文件目录移动到 /opt 204 | sudo mv $new_version_path /opt/ 205 | sudo chown -R $user: /opt/$base_name 206 | 207 | # 修改配置文件。根据实际的配置情况按需修改 208 | cd /opt/$base_name 209 | sudo sed -i 's#^application-host=.*$#application-host=127.0.0.1#' etc/org.sonatype.nexus.cfg 210 | sudo sed -i 's#^-Dkaraf.data=.*$#-Dkaraf.data=/data/nexus#' bin/nexus.vmoptions 211 | sudo sed -i 's#^-Djava.io.tmpdir=.*$#-Djava.io.tmpdir=/data/nexus/tmp#' bin/nexus.vmoptions 212 | sudo tee public/robots.txt <<-'EOF' 213 | User-agent: * 214 | Disallow: / 215 | EOF 216 | 217 | # 重启 nexus 218 | sudo systemctl stop nexus 219 | sudo -sf /opt/$base_name /opt/nexus 220 | sudo systemctl start nexus 221 | ``` 222 | 223 | ## 参考资料 224 | 225 | * [Nexus official site](http://www.sonatype.com/nexus-repository-oss) 226 | * [Download nexus](http://www.sonatype.com/download-oss-sonatype) 227 | * [System requirements](https://support.sonatype.com/hc/en-us/articles/213464208-Sonatype-Nexus-System-Requirements) 228 | * [Documentation](http://books.sonatype.com/nexus-book/3.0/reference/index.html) 229 | * [Oracle Java](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 230 | -------------------------------------------------------------------------------- /others/shadowsoccks.md: -------------------------------------------------------------------------------- 1 | # Shadowsocks 2 | 3 | Python 版实现已不再更新,建议使用 [shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev) 4 | 5 | ## 安装 6 | 7 | ```base 8 | sudo curl -o /etc/yum.repos.d/shadowsocks.repo https://copr.fedorainfracloud.org/coprs/librehat/shadowsocks/repo/epel-7/librehat-shadowsocks-epel-7.repo 9 | sudo yum install shadowsocks-libev 10 | ``` 11 | 12 | ## 配置 13 | 14 | 创建 `/etc/shadowsocks/config.json`: 15 | 16 | ``` 17 | sudo mkdir /etc/shadowsocks 18 | sudo tee /etc/shadowsocks/config.json <