2016-03-14 23 views
6

Ho bisogno di eseguire l'applicazione Golang sulla macchina Docker.Golang Mac OSX build per macchina Docker

Sto lavorando su Mac OSX e Docker funziona sulla parte superiore della macchina virtuale Linux, quindi i file binari creati su Mac non sono eseguibili su Docker.

vedo due modi qui:

  1. compilazione incrociata binari su Mac OS Linux
  2. fonti di progetto copia alla finestra mobile, eseguire 'andare a prendere' e 'andare build' su di esso

Il primo è difficile a causa di CGO (è utilizzato in alcune librerie importate).

Il secondo è molto lento a causa dell'operazione "go get".

Potete dirmi, qual è il modo più comune in questa situazione? O forse sto facendo qualcosa di sbagliato?

+3

Docker memorizza nella cache i livelli immagine e consente di iniziare da un'immagine specifica. Suddividi i comandi nel Dockerfile in modo da poter riutilizzare quanti più strati possibili, e le modifiche nella tua fonte richiedono solo la creazione del tuo pacchetto. – JimB

+0

JimB, ma come posso interrompere il comando 'go get'? RUN go get package1/n RUN go get package2 ... etc e saranno memorizzati nella cache? –

+4

Don 'use' go get', o almeno crea un'immagine base con esso e inizia da lì ('go get 'non dovrebbe essere usato in produzione, quindi molte persone hanno qualche altro metodo per gestire le dipendenze). Una soluzione di base in un singolo Dockerfile consiste nel creare un Makefile o uno script per installare tutti i deps come richiesto, che possono essere inseriti in una singola istruzione RUN. – JimB

risposta

1

Ecco una soluzione per semplificare la compilazione incrociata anche con CGO.

Recentemente mi sono imbattuto in esso dopo aver perso un sacco di tempo per ottenere un nuovo Windows build server per creare la mia app Go. Ora ho solo compilo sul mio Mac e creerà un build server Linux con esso:

https://github.com/karalabe/xgo

Molte grazie a Péter Szilágyi alias karalabe per questo davvero grande pacchetto!

Modo d'uso:

  • hanno Docker esecuzione
  • andare a prendere github.com/karalabe/xgo
  • XGO --targets = windows/amd64 ./

ci sono molte più opzioni!

0

Io uso il primo approccio. Qui è un compito da sbrogliare che il codice go build. Se è impostato il flag di produzione, viene eseguito GOOS=linux CGO_ENABLED=0 go build invece go build. Così il binario lavorerà all'interno di un contenitore finestra mobile

gulp.task('server:build', function() { 
    var build; 

    let options = { 
     env: { 
      'PATH': process.env.PATH, 
      'GOPATH': process.env.GOPATH 
     } 
    } 

    if (argv.prod) { 
     options.env['GOOS'] = 'linux' 
     options.env['CGO_ENABLED'] = '0' 
     console.log("Compiling go binarie to run inside Docker container") 
    } 

    var output = argv.prod ? conf.paths.build + '/prod/bin' : conf.paths.build + '/dev/bin'; 
    build = child.spawnSync('go', ['build', '-o', output, "src/backend/main.go"], options); 
    if (build.stderr.length) { 
     var lines = build.stderr.toString() 
      .split('\n').filter(function(line) { 
       return line.length 
      }); 
     for (var l in lines) 
      util.log(util.colors.red(
       'Error (go install): ' + lines[l] 
      )); 
     notifier.notify({ 
      title: 'Error (go install)', 
      message: lines 
     }); 
    } 
    return build; 
}); 
0

Si potrebbe creare un contenitore Docker dal sistema operativo distinta necessario per il vostro eseguibile e mappare un volume nella directory src. Esegui il contenitore e rendi eseguibile dall'interno del contenitore. Si finisce con un binario che è possibile eseguire sul sistema operativo distinto.