$ docker run -it -p 8888:8888 tensorflow/tensorflow:nightly-py3-jupyter
[I 14:54:21.897 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
jupyter_http_over_ws extension initialized. Listening on /http_over_websocket
[I 14:54:22.459 NotebookApp] Serving notebooks from local directory: /tf
[I 14:54:22.459 NotebookApp] The Jupyter Notebook is running at:
[I 14:54:22.461 NotebookApp] http://453c162dd9e3:8888/?token=d233277b7f66020bbc79ea155a906ed4c41fc3846634511d
[I 14:54:22.461 NotebookApp] or http://127.0.0.1:8888/?token=d233277b7f66020bbc79ea155a906ed4c41fc3846634511d
[I 14:54:22.463 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 14:54:22.471 NotebookApp]
To access the notebook, open this file in a browser:
file:///root/.local/share/jupyter/runtime/nbserver-1-open.html
Or copy and paste one of these URLs:
http://453c162dd9e3:8888/?token=d233277b7f66020bbc79ea155a906ed4c41fc3846634511d
or http://127.0.0.1:8888/?token=d233277b7f66020bbc79ea155a906ed4c41fc3846634511d
3. ブラウザからログインする
標準出力されたOr copy and paste one of these URLs配下のURLをコピーしてブラウザアクセスすると、以下の画面が表示されます。
FROM golang:latest
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/api
# モジュールのダウンロード
RUN go get -u github.com/gorilla/mux &&\
go get -u "go.mongodb.org/mongo-driver/mongo"
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
# go build
RUN go build -o api
# API実行コマンドの実行
CMD ["./api"]
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"./api\": permission denied": unknown.
念のためgouserに権限を持たせて実行してみましたが、事象は同じでした。
FROM golang:latest
# gouserの作成
RUN useradd -m -s /bin/bash gouser
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/api
RUN chown gouser:gouser /go/src/api
# モジュールのダウンロード
RUN go get -u github.com/gorilla/mux &&\
go get -u "go.mongodb.org/mongo-driver/mongo"
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY --chown=gouser:gouser ./src .
# go build
RUN go build -o api &&\
chown gouser:gouser api
# gouserに変更
USER gouser
# API実行コマンドの実行
CMD ["./api"]
解決方法
rootでの実行なのにエラーが出るので試行錯誤しましたが、結果的には以下の方法で解決しました。
解決方法:ビルドファイルの名前をapiから別の名前に変更する
FROM golang:latest
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/api
# モジュールのダウンロード
RUN go get -u github.com/gorilla/mux &&\
go get -u "go.mongodb.org/mongo-driver/mongo"
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
# go build
RUN go build -o koratta-api
# API実行コマンドの実行
CMD ["./koratta-api"]
FROM golang:latest
# gouserの作成
RUN useradd -m -s /bin/bash gouser
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/api
RUN chown gouser:gouser /go/src/api
# モジュールのダウンロード
RUN go get -u github.com/gorilla/mux &&\
go get -u "go.mongodb.org/mongo-driver/mongo"
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY --chown=gouser:gouser ./src .
# go build
RUN go build -o koratta-api &&\
chown gouser:gouser api
# gouserに変更
USER gouser
# API実行コマンドの実行
CMD ["/go/src/api/koratta-api"]
package main
import (
"fmt"
"log"
"net/http"
"encoding/json"
"time"
"context"
"os"
"github.com/gorilla/mux"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
)
type category struct {
Categories []struct{
Name string `json:"name"`
}`json:"categories"`
}
func main() {
r := mux.NewRouter()
// localhost:8082/publicでpublicハンドラーを実行
r.Handle("/public", public)
//サーバー起動
if err := http.ListenAndServe(":8082", r); err != nil {
log.Fatal("ListenAndServe:", nil)
}
}
var public = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//MongoDBの認証情報
credential := options.Credential{
Username: "root",
Password: "password",
}
//MongoDBへの接続
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
connect, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://db:27017").SetAuth(credential))
defer connect.Disconnect(ctx)
//collectionの取得
collection, err := connect.Database("recommend").Collection("categories").Find(context.Background(), bson.M{})
if err != nil { log.Fatal(err) }
var results []bson.M
if err = collection.All(context.TODO(), &results); err != nil {
log.Fatal(err)
}
//取得したコレクションの_idエントリを削除
for _, entry_map := range results {
delete(entry_map, "_id")
}
//bson.Mのデータをjson形式に変換
json_result, err := json.Marshal(results)
if err != nil {
fmt.Println("JSON marshal error: ", err)
return
}
//category構造体にJson形式の値を代入
var output category
if err := json.Unmarshal(json_result, &output.Categories); err != nil {
log.Fatal(err)
os.Exit(1)
}
//読み込んだJsonの表示
json.NewEncoder(w).Encode(output)
})
コンテナイメージを作成する
Dockerfileを書いてコンテナイメージをビルドします。
ディレクトリ構造は以下の通りです。
$ tree .
.
├── Dockerfile
└── src
└── main.go
Dockerfileは以下の通りです。
FROM golang:latest
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/searcher
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
RUN go get -u github.com/gorilla/mux
RUN go get -u "go.mongodb.org/mongo-driver/mongo"
RUN go build -o searcher
# ウェブアプリケーション実行コマンドの実行
CMD ["./searcher"]
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
"io/ioutil"
"os"
"html/template"
)
type category struct {
Categories []struct{
Name string `json:"name"`
}`json:"categories"`
}
func main() {
r := mux.NewRouter()
r.Handle("/", index)
//サーバー起動
if err := http.ListenAndServe(":8080", r); err != nil {
log.Fatal("ListenAndServe:", nil)
}
}
var index = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
url := "http://db:8082/public"
req, _ := http.NewRequest("GET", url, nil)
client := new(http.Client)
resp, _ := client.Do(req)
defer resp.Body.Close()
byteArray, _ := ioutil.ReadAll(resp.Body)
var categories category
if err := json.Unmarshal(byteArray, &categories); err != nil {
log.Fatal(err)
os.Exit(1)
}
generateHTML(w, categories, "layout", "index")
})
func generateHTML(writer http.ResponseWriter, data interface{}, filenames ...string) {
var files []string
for _, file := range filenames {
files = append(files, fmt.Sprintf("templates/%s.html", file))
}
templates := template.Must(template.ParseFiles(files...))
templates.ExecuteTemplate(writer, "layout", data)
}
index = http.HandlerFuncでは、dbコンテナから取得したjsonコードを構造体categoryの変数categoriesに代入し、generateHTML関数を呼び出します。generateHTMLは引数で与えられた名前のhtmlファイル、ここではlayout.htmlとindex.htmlを使ってページを生成します。
FROM golang:latest
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/web
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
RUN go get -u github.com/gorilla/mux
RUN go build -o web
# ウェブアプリケーション実行コマンドの実行
CMD ["./web"]
$ docker-compose up -d
Creating db ... done
Creating web ... done
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
da224d318f33 web:latest "./web" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp web
b245c4eb8320 db:latest "./searcher" About a minute ago Up About a minute 0.0.0.0:8082->8082/tcp db