2018-04-26 06:30 阅读 58

在elasticbeanstalk上部署私有github repo golang应用程序

I have been struggling trying to deploy my Golang app to AWS EB for couple days.

I am trying to deploy my app on an EB server Preconfigured Docker - Go 1.4 running on 64bit Debian/2.9.2 using the eb cli via the command eb deploy in my app folder.

After couple seconds, I've got an error message saying that my app wasn't deployed because of an error. Looking at the eb-activity.log, here what I can see:

    Parsing meta tags from (status code 200) (download)
    Parsing meta tags from (status code 200)
    get "": found meta tag main.metaImport{Prefix:"", VCS:"git", RepoRoot:""} at
    get "": verifying non-authoritative meta tag
    Parsing meta tags from (status code 200) (download) (download)
    # cd .; git clone /go/src/
    Cloning into '/go/src/'...
    fatal: could not read Username for '': No such device or address
            imports exit status 128
            imports cannot find package "" in any of:
            /usr/src/go/src/ (from $GOROOT)
            /go/src/ (from $GOPATH)

I suppose there is an issue when the server tries to install the app, it seems it's trying to retrieve from my private repo on github ...

I referenced my app sub packages as I supposed this is why it behaves like that.

Is there a way to deploy all my code, forcing my private repo to be populated within the GOROOT src/ so the server doesn't have to try to get it?

I didn't found any proper example from Amazon docs (multi-packages apps) nor from Github.

Am I missing anything? Is there a better solution?

On a side note, I also tried to deploy my compiled binary directly (create a folder where I put only the binary, zip it and upload it on the ebs env) but it didn't worked neither ... Maybe this option requires yet another env config (if so, which one?).

Thanks for your help :)


  • Golang app having the following folders:

    ├── Dockerfile
    ├── server.go
    ├── Gopkg.lock
    ├── Gopkg.toml
    ├── Makefile
    ├── apis
    │   ├── auth.go
    │   ├── auth_test.go
    │   ├── ...
    ├── app
    │   ├── config.go
    │   ├── init.go
    │   ├── logger.go
    │   ├── scope.go
    │   ├── transactional.go
    │   └── version.go
    ├── config
    │   ├──
    │   ├── errors.yaml
    │   └──
    ├── daos
    │   ├── auth.go
    │   ├── auth_test.go
    │   ├── ...
    ├── errors
    │   ├── api_error.go
    │   ├── api_error_test.go
    │   ├── errors.go
    │   ├── errors_test.go
    │   ├── template.go
    │   └── template_test.go
    ├── models
    │   ├── identity.go
    │   ├── ...
    ├── services
    │   ├── auth.go
    │   ├── auth_test.go
    │   ├── ...
    ├── util
    │   ├── paginated_list.go
    │   └── paginated_list_test.go
  • Here is the content of my server.go

    package main
    import (
        _ ""
    func main() {
        // getting env from command line
        // env is either prod, preprod or dev
        // by default, env is prod
        env := flag.String("env", "prod", "environment: prod, preprod or dev")
        router.To("GET,HEAD", "/ping", func(c *routing.Context) error {
           c.Abort() // skip all other middlewares/handlers
           return c.Write("OK " + app.Version)
        // Serve on port 5000
  • My Dockerfile content:

    FROM golang:1.4.2-onbuild
    ADD . /go/src/
    RUN go install
    EXPOSE 5000
    ENTRYPOINT /go/bin/private-repo
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    duan19740319 duan19740319 2018-05-08 13:11

    I finally managed to make it works.

    So I created a brand new eb app (without docker). I then figured out that my app wasn't able to retrieve env vars set in the console somehow ... So what I did is that I forced the env variables to be passed to my app at startup time from my production config file using the script see below :

    #!/bin/bash -xe
    # See
    # -x -> Print each command to stdout before executing it, expand commands
    # -e -> Abort script at first error, when a command exits with non-zero status
    #   (except in until or while loops, if-tests, list constructs)
    # $GOPATH isn't set by default, nor do we have a usable Go workspace :'(
    APP_BUILD_DIR="$GOPATH/src/to-be-defined"     # We will build the app here
    APP_STAGING_DIR="/var/app/staging"            # Current directory
    DEP_VERSION="v0.3.2"                          # Use specific version for stability
    # Install dep, a Go dependency management tool, if not already installed or if
    # the version does not match.
    if ! hash dep 2> /dev/null ||\
        [[ $(dep version | awk 'NR==2{print $3}') != "$DEP_VERSION" ]]; then
        # /usr/local/bin is expected to be on $PATH.
        curl -L \
            -s$DEP_VERSION/dep-linux-amd64 \
            -o /usr/local/bin/dep
        chmod +x /usr/local/bin/dep
    # Remove the $APP_BUILD_DIR just in case it was left behind in a failed build.
    rm -rf $APP_BUILD_DIR
    # Setup the application directory
    mkdir -p $APP_BUILD_DIR
    # mv all files to $APP_BUILD_DIR
    mv * .[^.]* $APP_BUILD_DIR
    # Pull in dependencies into vendor/.
    dep ensure
    # Build the binary with jsoniter tag.
    go build -o application -tags=jsoniter .
    # Modify permissons to make the binary executable.
    chmod +x application
    # Move the binary back to staging dir.
    # Along with the configuration files.
    mkdir $APP_STAGING_DIR/bin
    # By default, `bin/application` is executed. This way, a Procfile isn't needed.
    mv application $APP_STAGING_DIR/bin
    cp -r config $APP_STAGING_DIR
    # TODO: Fix the viper not working with env var
    # Generate prod config from env variables
    /opt/elasticbeanstalk/bin/get-config environment --output YAML | sed s/${ENV_VAR_PREFIX}//g > $APP_STAGING_DIR/config/
    # Copy .ebextensions back to staging directory.
    # cp -r .ebextensions $APP_STAGING_DIR
    # Clean up.
    rm -rf $APP_BUILD_DIR
    echo "Build successful!!"

    My file is called by EBS using this Buildfile:

    make: ./

    Et voilà ! Everything works properly now :)

    点赞 评论 复制链接分享