From 48520a7d2dc6534b71644ce36848ec9b250503f1 Mon Sep 17 00:00:00 2001
From: viktorstrate <viktorstrate@gmail.com>
Date: Sun, 5 Apr 2020 18:54:13 +0200
Subject: [PATCH] Further work on single docker container

- Add proper .dockerignore
- Fix photo prefix
- Print public endpoint when server starts
- Discard API_LISTEN_PORT
---
 .dockerignore               | 12 ++++++++++++
 Dockerfile                  |  4 ++--
 api/example.env             |  1 -
 api/graphql/models/photo.go | 17 +++++++++++++----
 api/server.go               | 16 ++++++++--------
 docker-compose.example.yml  | 13 +++++++++----
 ui/.dockerignore            |  3 ---
 7 files changed, 44 insertions(+), 22 deletions(-)
 create mode 100644 .dockerignore
 delete mode 100644 ui/.dockerignore

diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..4ac6094
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,12 @@
+.git
+.gitignore
+.prettierrc
+.vscode
+photos_path
+screenshots
+
+ui/node_modules/
+ui/dist/
+ui/.cache/
+
+api/photo_cache
diff --git a/Dockerfile b/Dockerfile
index 712ac81..93c9f06 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,7 +7,7 @@ ENV GRAPHQL_ENDPOINT=${GRAPHQL_ENDPOINT}
 RUN mkdir -p /app
 WORKDIR /app
 
-COPY ui/package*.json ./
+COPY ui/package*.json /app/
 RUN npm install
 COPY ui /app
 
@@ -22,7 +22,7 @@ COPY api /app
 RUN go get -d -v ./...
 RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o photoview .
 
-# Copy built app to nginx environment
+# Copy api and ui to production environment
 FROM alpine:latest
 
 COPY --from=ui /app/dist /ui
diff --git a/api/example.env b/api/example.env
index 1290b89..2985579 100644
--- a/api/example.env
+++ b/api/example.env
@@ -3,7 +3,6 @@
 MYSQL_URL=user:password@tcp(localhost)/dbname
 
 API_ENDPOINT=http://localhost:4001/
-API_LISTEN_PORT=4001
 
 PUBLIC_ENDPOINT=http://localhost:1234/
 
diff --git a/api/graphql/models/photo.go b/api/graphql/models/photo.go
index 5414869..a649233 100644
--- a/api/graphql/models/photo.go
+++ b/api/graphql/models/photo.go
@@ -2,6 +2,7 @@ package models
 
 import (
 	"database/sql"
+	"log"
 	"net/url"
 	"os"
 	"path"
@@ -64,11 +65,19 @@ func NewPhotosFromRows(rows *sql.Rows) ([]*Photo, error) {
 }
 
 func (p *PhotoURL) URL() string {
-	imageUrl, err := url.Parse(os.Getenv("API_ENDPOINT"))
-	if err != nil {
-		return path.Join("/photo", p.PhotoName)
+
+	publicUrl := os.Getenv("PUBLIC_ENDPOINT")
+	if publicUrl == "" {
+		publicUrl = os.Getenv("API_ENDPOINT")
 	}
-	imageUrl.Path = path.Join(imageUrl.Path, "photo", p.PhotoName)
+
+	imageUrl, err := url.Parse(publicUrl)
+	if err != nil {
+		log.Println("Endpoint url is not properly configured, make sure the PUBLIC_ENDPOINT AND API_ENDPOINT environment variables are set correctly")
+		return p.PhotoName
+	}
+
+	imageUrl.Path = path.Join(imageUrl.Path, "api", "photo", p.PhotoName)
 	return imageUrl.String()
 }
 
diff --git a/api/server.go b/api/server.go
index 788f7be..04bca0a 100644
--- a/api/server.go
+++ b/api/server.go
@@ -75,11 +75,6 @@ func main() {
 
 	devMode := os.Getenv("DEVELOPMENT") == "1"
 
-	port := os.Getenv("API_LISTEN_PORT")
-	if port == "" {
-		port = defaultPort
-	}
-
 	db := database.SetupDatabase()
 	defer db.Close()
 
@@ -134,10 +129,15 @@ func main() {
 	endpointRouter.PathPrefix("/").Handler(spa)
 
 	if devMode {
-		log.Printf("🚀 Graphql playground ready at %s", endpointURL.String())
+		log.Printf("🚀 Graphql playground ready at %s\n", endpointURL.String())
 	} else {
-		log.Printf("Photoview API endpoint available at %s", endpointURL.String())
+		log.Printf("Photoview API endpoint listening at %s\n", endpointURL.String())
+
+		publicEndpoint := os.Getenv("PUBLIC_ENDPOINT")
+		if publicEndpoint != "" && publicEndpoint != endpointURL.String() {
+			log.Printf("Photoview API public endpoint ready at %s\n", publicEndpoint)
+		}
 	}
 
-	log.Fatal(http.ListenAndServe(":"+port, rootRouter))
+	log.Fatal(http.ListenAndServe(":"+endpointURL.Port(), rootRouter))
 }
diff --git a/docker-compose.example.yml b/docker-compose.example.yml
index 72bd31f..9d9739e 100644
--- a/docker-compose.example.yml
+++ b/docker-compose.example.yml
@@ -13,21 +13,26 @@ services:
       - db_data:/var/lib/mysql
 
   photoview:
-    build: .
+    build:
+      context: "."
+      args:
+        - GRAPHQL_ENDPOINT=http://localhost:8000/api/graphql
+
     restart: always
     ports:
       - "8000:80"
     depends_on:
       - db
+
     environment:
       - MYSQL_URL=photoview:photo-secret@tcp(db)/photoview
       - PHOTO_CACHE=/app/cache
       # Change This: The publicly exposed url for the api
       # For example if the server is available from the domain example.com,
       # change this value to http://example.com/api
-      - API_ENDPOINT=http://localhost:8080/
-      - PUBLIC_ENDPOINT=http://localhost:8080/
-      - API_LISTEN_PORT=80
+      - API_ENDPOINT=http://localhost:80/
+      - PUBLIC_ENDPOINT=http://localhost:8000/
+
     volumes:
       # Change This: Link photo paths from the host machine
       # Change this to the directory where your photos are located on your server.
diff --git a/ui/.dockerignore b/ui/.dockerignore
deleted file mode 100644
index 9c3cc99..0000000
--- a/ui/.dockerignore
+++ /dev/null
@@ -1,3 +0,0 @@
-node_modules/
-dist/
-.cache/
\ No newline at end of file
