dongwei4652 2018-02-18 15:31
浏览 28
已采纳

带有Apache的VirtualHost的Golang Webapp

Unfortunately I've not been able to deploy a basic Golang WebApp on production server. After going through many documentation and tutorials I understood that I need to run Golang WebApp as a Daemon.

First things first: the production server is a single IP running Ubuntu 16.04 with Apache based multiple VirtualHosts /etc/apache2/sites-enabled/.

Golang environment vars

# set golang environment vars
export GOROOT=/usr/local/go

# set multiple gopaths seperated by ":"
export GOPATH=/var/www/go_projects/gotest.domain2.com

export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$PATH"

Systemd Daemon file

[Unit]
Description=GoTest Webserver

[Service]
Type=simple
WorkingDirectory=/var/www/go_projects/gotest.domain2.com
ExecStart=/var/www/go_projects/gotest.domain2.com/main #binary file

[Install]
WantedBy=multi-user.target

VirtualHost Conf

<VirtualHost *:80>
    ServerName gotest.domain.com
    DocumentRoot /var/www/go_projects/gotest.domain2.com

    <Directory /var/www/go_projects/gotest.domain2.com>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
    </Directory>

Go file

package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

The program on http://gotest.domain2.com unfortunately is not executed. It rather lists the content of DocumentRoot

Manual run returns

admin@xyz:/var/www/go_projects/gotest.domain2.com$ ./main 
2018/02/18 15:52:58 listen tcp :8080: bind: address already in use

What am I missing or is my deployment approach principally wrong? Cheers!

EDIT: As suggested from Michael Ernst, I tried altering the port/proxy settings and here is the result:

http://gotest.domain2.com leads to 503 Service Unavailable

Following is the outcome of sudo netstat -talpen

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          16367       1250/sshd       
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      0          473536      26340/master    
tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      0          16604       1417/dovecot    
tcp        0      0 0.0.0.0:2000            0.0.0.0:*               LISTEN      5001       17289       1652/asterisk   
tcp        0     xx.xx.xx.xx:22       xx.xx.xx.xx:6126      ESTABLISHED 0          615988      13025/sshd: admin [
tcp6       0      0 :::22                   :::*                    LISTEN      0          16369       1250/sshd       
tcp6       0      0 :::25                   :::*                    LISTEN      0          473537      26340/master    
tcp6       0      0 :::3306                 :::*                    LISTEN      111        17564       1391/mysqld     
tcp6       0      0 :::143                  :::*                    LISTEN      0          16605       1417/dovecot    
tcp6       0      0 :::80                   :::*                    LISTEN      0          612412      12554/apache2   
tcp6       0      0 xx.xx.xx.xx:80       xx.xx.xx.xx:6128      FIN_WAIT2   0          0           -               
tcp6       0      0 xx.xx.xx.xx:80       xx.xx.xx.xx:6129      ESTABLISHED 33         615029      12561/apache2   

Any idea where the problem lies?

  • 写回答

1条回答 默认 最新

  • douguanyun2169 2018-02-18 17:07
    关注

    As for configuring apache:

    You need to start the go application and in the apache configuration reverse proxy the request to the port 8080 ( which the go daemon you wrote listens to ). The go application needs to be always running so you might want to boot it at system start. Unlike php, which is called from apache, go should run as binary that is always there.

    As for your port issue:

    Make sure that your application is not yet started and that no other application is listening to port 8080. ( you can use netstat -talpen to see that )

    Edit: Port 8080 is often a http proxy. Is there are proxy or another application running on this point?

    Edit: You can configure your apache like that:

    <VirtualHost *:80> 
      ProxyPreserveHost On
      ProxyRequests Off
      ServerName www.example.com
      ServerAlias example.com
      ProxyPass / http://localhost:8080/
      ProxyPassReverse / http://localhost:8080/
    </VirtualHost>
    

    You might also want to make the port of your go-application configurable so you don't need to re-compile the code in case you need to change the port. Also you can bind to the localhost interface so, in case you don't have a firewall configured, people can only access the go application over apache and not directly talk with the go application

    // define the flag
    port := flags.Int("port", 8080, "port to listen on")
    // parse the flags
    flags.Parse();
    // here you might want to add code to make sure the port is valid.
    // start webserver
    log.Fatal(http.ListenAndServe("localhost:"+strconv.Atoi(*port), nil))
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求帮我调试一下freefem代码
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图