Nginx上游不适用于Docker部署堆栈

时间:2019-03-23 21:24:25

标签: docker nginx docker-compose docker-swarm

我正在尝试与docker部署堆栈。

这是我的堆栈的工作方式:

  • nginx-proxy(将用户请求重定向到好的容器)
  • 网站(用于网站的简单nginx)
  • api(Django应用程序,与gunicorn一起启动)
  • nginx-api(提供静态文件和上传的文件,如果是端点,则重定向到API容器)

这是我的docker-compose.yml:

let messageLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.numberOfLines = 0
        label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.regular)
        label.isUserInteractionEnabled = true

        return label
    }()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.addSubview(messageLabel)
        // setup messageLabel constraints 

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapLabel))
        messageLabel.addGestureRecognizer(tapGesture)


    }

//function to get attributed string with url
    func getAttributedString(input : String) -> NSMutableAttributedString {

        let matches = getURLRange(input: input)
        let attributedString = NSMutableAttributedString(string:input)

        for match in matches {
            let url = (input as NSString).substring(with: match.range)

            let linkText = NSMutableAttributedString(string:url, attributes:[NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue) : UIColor.appleBlue()])
            attributedString.replaceCharacters(in: match.range, with: linkText)
        }

        return attributedString
    }

    func getURLRange(input : String) -> [NSTextCheckingResult] {

        let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
        let matches = detector.matches(in: input, options: [], range: NSRange(location: 0, length: input.utf16.count))

        return matches
    }

    //function to get index Of selected Character in string
    func didTapAttributedTextInLabel(label: UILabel, tapLocation: CGPoint) -> Int  {


        //here myLabel is the object of UILabel
        //added this from @warly's answer
        //set font of attributedText
        let attributedText = NSMutableAttributedString(attributedString: messageLabel.attributedText!)
        attributedText.addAttributes([NSAttributedString.Key.font: messageLabel.font], range: NSMakeRange(0, (messageLabel.attributedText?.string.count)!))

        // Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: CGSize(width: messageLabel.frame.width, height: messageLabel.frame.height+100))
        let textStorage = NSTextStorage(attributedString: attributedText)

        // Configure layoutManager and textStorage
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)

        // Configure textContainer
        textContainer.lineFragmentPadding = 0.0
        textContainer.lineBreakMode = messageLabel.lineBreakMode
        textContainer.maximumNumberOfLines = messageLabel.numberOfLines
        let labelSize = messageLabel.bounds.size
        textContainer.size = labelSize

        // get the index of character where user tapped
        let indexOfCharacter = layoutManager.characterIndex(for: tapLocation, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        return indexOfCharacter
    }


    // function to check if URL is taped
    @objc func tapLabel(gesture: UITapGestureRecognizer) {

        let matches = getURLRange(input: (messageLabel.text)!)

        let tapLocation = gesture.location(in: messageLabel)


        let indexOfCharacter = didTapAttributedTextInLabel(label: messageLabel, tapLocation: tapLocation)

        for match in matches {

            if NSLocationInRange(indexOfCharacter, match.range) {

                //open selected URL
                let mainText = messageLabel.text as NSString?
                if let urlToOpen = URL(string: (mainText?.substring(with: match.range))!) {
                    UIApplication.shared.open(urlToOpen)
                } else {
                    print("We have error with URL")
                }
                break
            } else {
                print("Tapped none")
            }

        }

    }

当我使用 docker-compose up 时,一切正常。 但是,当我尝试使用 docker stack进行部署时,请部署--compose-file = docker-compose.yml产品。我的Nginx配置文件找不到其他的上游

这是我的服务 nginx-api 提供的错误:

version: '3.2'

services:
    website:
        container_name: nyl2pronos-website
        image: nyl2pronos-website
        restart: always
        build:
          context: nyl2pronos_webapp
          dockerfile: Dockerfile
        volumes:
            - ./logs/nginx-website:/var/log/nginx
        expose:
            - "80"
        deploy:
            replicas: 10
            update_config:
                parallelism: 5
                delay: 10s

    api:
        container_name: nyl2pronos-api
        build:
            context: nyl2pronos_api
            dockerfile: Dockerfile
        image: nyl2pronos-api
        restart: always
        ports:
            - 8001:80
        expose:
            - "80"      
        depends_on:
            - db
            - memcached
        environment:
            - DJANGO_PRODUCTION=1
        volumes:
            - ./data/api/uploads:/code/uploads
            - ./data/api/static:/code/static

    nginx-api:
        image: nginx:latest
        container_name: nyl2pronos-nginx-api
        restart: always
        expose:
            - "80"
        volumes:          
            - ./data/api/uploads:/uploads
            - ./data/api/static:/static
            - ./nyl2pronos_api/config:/etc/nginx/conf.d
            - ./logs/nginx-api:/var/log/nginx
        depends_on:
            - api

    nginx-proxy:
        image: nginx:latest
        container_name: nyl2pronos-proxy
        restart: always
        ports:
            - 80:80
            - 443:443
        volumes: 
            - ./proxy:/etc/nginx/conf.d
            - /etc/letsencrypt:/etc/letsencrypt
            - ./logs/nginx-proxy:/var/log/nginx
        deploy:
            placement:
                constraints: [node.role == manager]
        depends_on:
            - nginx-api
            - website

请参阅下面的 nginx.conf

2019/03/23 17:32:41 [emerg] 1#1: host not found in upstream "api" in /etc/nginx/conf.d/nginx.conf:2

如果您发现我的配置有问题或可以做得更好,请告诉我!

1 个答案:

答案 0 :(得分:0)

之所以会这样,是因为nginx-api服务先于api服务。

但是我添加了depends_on选项吗?

您是对的,此选项应适用于docker-compose up情况。 但不幸的是不在docker stack deploy上,或者像docs所说的那样:

  

在集群模式下部署堆栈时,depends_on选项将被忽略   带有第3版Compose文件。

好,那我现在该怎么办?

什么都没有。它实际上不是错误-

docker swarm节点(您的堆栈服务)应该在发生错误时自动恢复。 (这就是为什么您定义restart: always选项的原因)。所以无论如何它应该对您有用。

如果仅将compose文件用于部署堆栈,而不是在docker-compose up上使用-您可以完全删除depends_on选项,这对docker堆栈没有任何意义。