如何将 Angular 应用部署在虚拟目录/子目录

假设我们开发了一个 Angular 应用,我们希望将它部署在 https://www.iconben.com/app1,我们该怎么做呢?

这涉及两方面的配置,一方面是 Nginx 配置文件中,配置 server 下面的子目录;另一方面,因为 Angular 应用中的所有请求都会经过 url 拼装,需要让 Angular 知道自己处于子目录的环境下。

前者通过 nginx 配置文件内 server 中配置 location 可以实现(有 root 和 alias 两种用法,若子目录与angular 应用的文件夹不同名,则用 alias 配置):

server {
        server_name   www.iconben.com;
        listen 80;

        location /app1 {
            alias  /srv/www/angular-app1;
            index  index.html  index.htm login.html;
            client_max_body_size  1024m;
        }

        location / {
            root  /srv/www/www.iconben.com;
            try_files $uri $uri/ /index.html;
            index  index.html  index.htm login.html;
            client_max_body_size  1024m;
        }
}

后者通过修改 Angular 应用的 base href 可以实现。即修改index.html 中的 base 标签为 <base href=”app1″>(默认为<base href=””>,表示配置在站点根目录)。

考虑到开发环境多数并非子目录环境,以上这一步要么在打包的时候才实现(如果是 CI/CD 的环境,配置好相关脚本就好);要么则是不修改打包结果,而在 nginx 中用 sub_filter 配置 index.html 被请求的时候动态替换base 标签的 href 值。

以下为完整配置:

server {
        server_name   www.iconben.com;
        listen 80;

        location /app1 {
            alias  /srv/www/angular-app1;
            sub_filter '<base href="/">' '<base href="/app1/">';
            sub_filter_once on;
            try_files $uri $uri/ /app1/index.html;
            index  index.html  index.htm login.html;
            client_max_body_size  1024m;
        }

        location / {
            root  /srv/www/www.iconben.com;
            try_files $uri $uri/ /index.html;
            index  index.html  index.htm login.html;
            client_max_body_size  1024m;
        }
}

网上有很些相关文章,但很多没讲到点子上。

一般官方文档是很好的参考来源。以上配置涉及 angular 部分参考这里

使用容器化的 php-fpm 的文件读写权限问题

手头有两个站点,在服务器上通过 nginx 对外服务,nginx 转发 php 请求给基于 php-fpm 容器。在如下架构下部署了 wordpress 站点。站点能运行,但涉及写文件的时候(譬如上传图片)则会报错。

一开始以为是 nginx 权限问题,查了 nginx 运行在用户 nginx 之下,因此尝试对网站文件夹给予 nginx 用户读写权限,但没解决问题。

后来知道了是 php-fpm 容器使用了 www-data 用户,因此对网站文件给予 www-data 用户读写权限就行了,譬如运行: chown -R www-data:www-data ./wordpress-website/

此操作有一个注意事项,即是多半在 host 系统中没有 www-data 用户,只在 php-fpm 容器中有,因此需要先进入 php-fpm 容器命令行,然后做以上操作。

用CentOS 7和Docker搭建Gitlab环境

先安装好CentOS 7 操作系统

操作之前,先开启ssh,以方便后续操作:
service sshd start
chkconfig sshd on

第一步,系统升级到最新:
yum -y update

第二步,安装docker:
老版本是:yum -y install docker

从Docker官方镜像安装新版本:
https://docs.docker.com/engine/installation/linux/centos/

然后注册自动启动并立即启动:
chkconfig docker on
service docker start

第三步,由于众所周知的原因(Fork the G.F.W.),国内访问Docker Hub常常很慢甚至访问不了,因此可以改用阿里云的Docker Registry(根据服务器选择合适的加速器,阿里云、腾讯都有):

# 系统要求 CentOS 7 以上,Docker 1.9 以上。

sudo cp -n /lib/systemd/system/docker.service /etc/systemd/system/docker.service sudo sed -i “s|ExecStart=/usr/bin/docker daemon|ExecStart=/usr/bin/docker daemon –registry-mirror=https://XXXXX.mirror.aliyuncs.com|g” /etc/systemd/system/docker.service sudo systemctl daemon-reload sudo service docker restart

其中的https://XXXXX.mirror.aliyuncs.com 即是阿里云Docker镜像访问加速器地址。需要自己去申请一下,免费的,路径:管理控制台-容器服务-指南-镜像管理-加速器。

第四步,运行Gitlab-ce Docker镜像:

docker run –detach \
–hostname gitlab.iconben.com \
–publish 443:443 –publish 80:80 –publish 22:22 \
–name gitlab \
–restart always \
–volume /srv/gitlab/config:/etc/gitlab \
–volume /srv/gitlab/logs:/var/log/gitlab \
–volume /srv/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest

以上是用指定参数来运行官方的gitlab(社区版本)的容器。要注意的是,可能在CentOS上默认SELinux是开启的,如果是这样的话,以上命令运行会权限不足,容器运行不成功,此时应该运行如下命令:

docker run --detach \
    --hostname gitlab.iconben.com \
    --publish 443:443 --publish 80:80 --publish 22:22 \
    --name gitlab \
    --restart always \
    --volume /srv/gitlab/config:/etc/gitlab:Z \
    --volume /srv/gitlab/logs:/var/log/gitlab:Z \
    --volume /srv/gitlab/data:/var/opt/gitlab:Z \
    gitlab/gitlab-ce:latest

以上的端口映射,如果本机80端口已经被Apache或者Nginx占用,则需要改到另外端口。22端口也是,可能与sshd冲突,一样可以修改。修改方式有三种:

1,Container生成之前,也就是在执行以上命令行之前,修改命令行参数,如:

docker run –detach \
–hostname gitlab.iconben.com \
–publish 443:443 –publish 880:80 –publish 822:22 \
–name gitlab \
–restart always \
–volume /srv/gitlab/config:/etc/gitlab \
–volume /srv/gitlab/logs:/var/log/gitlab \
–volume /srv/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest

2,如果Container已经生成,这时候可以 docker rm gitlab删除该容器,然后用改过端口的命令行重新生成;

3,如果不想删除重建Container,可以停止docker,然后修改Container的配置文件:

docker stop container
service docker stop
vi /var/lib/docker/%container_id%/hostconfig.yml

在这个文件里面可以修改端口映射,改完再启动。
**注意:一定要停用整个service,改完配置文件,再启动service才生效。否则service还开着的时候,配置修改了也不会生效,还会被自动改回去。

第五步,配置与使用Gitlab

以上步骤操作得当的话,这时候浏览器里面输入网址,就应该已经能访问到gitlab了。初始会要求设置新密码。然后就可以做各种新建用户、新建项目、设置权限等操作了。

有些配置如external url要修改的话,需要改gitlab的配置文件。这时候可以停用gitlab,然后修改,方式有两种:

1,由于存储是加载的外部卷,可以根据之前启动Docker的时候指定的存储卷位置,直接在Host中修改对应文件,如前面例子中的参数:–volume /srv/gitlab/config:/etc/gitlab \,说明在docker内的/etc/gitlab文件夹,在宿主机上实际是放在/srv/gitlab/config位置的。

2,就是通过 docker exec gitlab /usr/bin/bash 来进入docker命令行操作,譬如 vi /etc/gitlab/gitlab.rb来修改gitlab配置文件。

3,追加还有一种方式,就是删除容器(不删除配置和数据),然后用新的参数重新运行创建容器的命令,因为OMNIBUS 的Gitlab容器镜像支持通过命令行直接传递配置进去,这些配置会存储在Docker的容器配置里面,并且会在启动容器后自动覆盖容器内文件系统中所保存的Gitlab配置,具体可以参见OMNIBUS关于Gitlab镜像使用说明的官方文档。