Răsfoiți Sursa

nginx-golang-postgres: add dev envs config (#275)

* Add Docker Desktop Development Environments config
* Upgrade to Go 1.18
* Replace nginx build with image + read-only bind mount

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
Milas Bowman 3 ani în urmă
părinte
comite
7f5179ea3e

+ 50 - 0
nginx-golang-postgres/.docker/docker-compose.yaml

@@ -0,0 +1,50 @@
+services:
+  backend:
+    build:
+      context: backend
+      target: dev-envs
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
+    secrets:
+      - db-password
+    depends_on:
+      db:
+        condition: service_healthy
+
+  db:
+    image: postgres
+    restart: always
+    user: postgres
+    secrets:
+      - db-password
+    volumes:
+      - db-data:/var/lib/postgresql/data
+    environment:
+      - POSTGRES_DB=example
+      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
+    expose:
+      - 5432
+    healthcheck:
+      test: [ "CMD", "pg_isready" ]
+      interval: 10s
+      timeout: 5s
+      retries: 5
+
+  proxy:
+    image: nginx
+    volumes:
+      - type: bind
+        source: ./proxy/nginx.conf
+        target: /etc/nginx/conf.d/default.conf
+        read_only: true
+    ports:
+      - 80:80
+    depends_on: 
+      - backend
+
+volumes:
+  db-data:
+
+secrets:
+  db-password:
+    file: db/password.txt

+ 33 - 15
nginx-golang-postgres/README.md

@@ -7,29 +7,36 @@ Project structure:
 ├── backend
 │   ├── Dockerfile
 │   ├── go.mod
+│   ├── go.sum
 │   └── main.go
 ├── db
 │   └── password.txt
 ├── compose.yaml
 ├── proxy
-│   ├── conf
-│   └── Dockerfile
+│   └── nginx.conf
 └── README.md
 ```
 
 [_compose.yaml_](compose.yaml)
-```
+```shell
 services:
   backend:
-    build: backend
+    build:
+      context: backend
+      target: builder
     ...
   db:
     image: postgres
     ...
   proxy:
-    build: proxy
+    image: nginx
+    volumes:
+      - type: bind
+        source: ./proxy/nginx.conf
+        target: /etc/nginx/conf.d/default.conf
+        read_only: true
     ports:
-    - 80:80
+      - 80:80
     ...
 ```
 The compose file defines an application with three services `proxy`, `backend` and `db`.
@@ -38,7 +45,7 @@ Make sure port 80 on the host is not already being in use.
 
 ## Deploy with docker compose
 
-```
+```shell
 $ docker compose up -d
 Creating network "nginx-golang-postgres_default" with the default driver
 Pulling db (postgres:)...
@@ -55,21 +62,32 @@ Creating nginx-golang-postgres_proxy_1   ... done
 ## Expected result
 
 Listing containers must show three containers running and the port mapping as below:
-```
-$ docker ps
-CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                NAMES
-5e3ecd0289c0        nginx-golang-postgres_proxy     "nginx -g 'daemon of…"   48 seconds ago      Up 48 seconds       0.0.0.0:80->80/tcp   nginx-golang-postgres_proxy_1
-ffa1410b1c8a        nginx-golang-postgres_backend   "/server"                49 seconds ago      Up 48 seconds       8000/tcp             nginx-golang-postgres_backend_1
-e63be7db7cbc        postgres                        "docker-entrypoint.s…"   49 seconds ago      Up 49 seconds       5432/tcp             nginx-golang-postgres_db_1
+```shell
+$ docker compose ps
+NAME                              COMMAND                  SERVICE             STATUS              PORTS
+nginx-golang-postgres-backend-1   "/code/bin/backend"      backend             running
+nginx-golang-postgres-db-1        "docker-entrypoint.s…"   db                  running (healthy)   5432/tcp
+nginx-golang-postgres-proxy-1     "/docker-entrypoint.…"   proxy               running             0.0.0.0:80->80/tcp
 ```
 
 After the application starts, navigate to `http://localhost:80` in your web browser or run:
-```
+```shell
 $ curl localhost:80
 ["Blog post #0","Blog post #1","Blog post #2","Blog post #3","Blog post #4"]
 ```
 
 Stop and remove the containers
-```
+```shell
 $ docker compose down
 ```
+
+## Use with Docker Development Environments
+
+You can use this sample with the Dev Environments feature of Docker Desktop.
+
+![Screenshot of creating a Dev Environment in Docker Desktop](../dev-envs.png)
+
+To develop directly on the services inside containers, use the HTTPS Git url of the sample:
+```
+https://github.com/docker/awesome-compose/tree/master/nginx-golang-postgres
+```

+ 38 - 7
nginx-golang-postgres/backend/Dockerfile

@@ -1,10 +1,41 @@
-FROM golang:1.13-alpine AS build
-WORKDIR /go/src/github.com/org/repo
+# syntax=docker/dockerfile:1.4
+FROM --platform=$BUILDPLATFORM golang:1.18-alpine AS builder
+
+WORKDIR /code
+
+ENV CGO_ENABLED 0
+ENV GOPATH /go
+ENV GOCACHE /go-build
+
+COPY go.mod go.sum ./
+RUN --mount=type=cache,target=/go/pkg/mod/cache \
+    go mod download
+
 COPY . .
 
-RUN go build -o server .
+RUN --mount=type=cache,target=/go/pkg/mod/cache \
+    --mount=type=cache,target=/go-build \
+    go build -o bin/backend main.go
+
+CMD ["/code/bin/backend"]
+
+FROM builder as dev-envs
+
+RUN <<EOF
+apk update
+apk add git
+EOF
+
+RUN <<EOF
+addgroup -S docker
+adduser -S --shell /bin/bash --ingroup docker vscode
+EOF
+
+# install Docker tools (cli, buildx, compose)
+COPY --from=gloursdocker/docker / /
+
+CMD ["go", "run", "main.go"]
 
-FROM alpine:3.12
-EXPOSE 8000
-COPY --from=build /go/src/github.com/org/repo/server /server
-CMD ["/server"]
+FROM scratch
+COPY --from=builder /code/bin/backend /usr/local/bin/backend
+CMD ["/usr/local/bin/backend"]

+ 4 - 3
nginx-golang-postgres/backend/go.mod

@@ -1,10 +1,11 @@
-module github.com/org/repo
+module github.com/docker/awesome-compose/nginx-golang-postgres/backend
 
-go 1.13
+go 1.18
 
 require (
-	github.com/gorilla/context v1.1.1
 	github.com/gorilla/handlers v1.3.0
 	github.com/gorilla/mux v1.6.2
 	github.com/lib/pq v1.10.3
 )
+
+require github.com/gorilla/context v1.1.1 // indirect

+ 8 - 0
nginx-golang-postgres/backend/go.sum

@@ -0,0 +1,8 @@
+github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/handlers v1.3.0 h1:tsg9qP3mjt1h4Roxp+M1paRjrVBfPSOpBuVclh6YluI=
+github.com/gorilla/handlers v1.3.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
+github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg=
+github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=

+ 21 - 4
nginx-golang-postgres/compose.yaml

@@ -1,13 +1,18 @@
 services:
   backend:
-    build: backend
+    build:
+      context: backend
+      target: builder
     secrets:
       - db-password
     depends_on:
-      - db
+      db:
+        condition: service_healthy
+
   db:
     image: postgres
     restart: always
+    user: postgres
     secrets:
       - db-password
     volumes:
@@ -17,15 +22,27 @@ services:
       - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
     expose:
       - 5432
-    
+    healthcheck:
+      test: [ "CMD", "pg_isready" ]
+      interval: 10s
+      timeout: 5s
+      retries: 5
+
   proxy:
-    build: proxy
+    image: nginx
+    volumes:
+      - type: bind
+        source: ./proxy/nginx.conf
+        target: /etc/nginx/conf.d/default.conf
+        read_only: true
     ports:
       - 80:80
     depends_on: 
       - backend
+
 volumes:
   db-data:
+
 secrets:
   db-password:
     file: db/password.txt

+ 0 - 2
nginx-golang-postgres/proxy/Dockerfile

@@ -1,2 +0,0 @@
-FROM nginx:1.13-alpine
-COPY conf /etc/nginx/conf.d/default.conf

+ 2 - 1
nginx-golang-postgres/proxy/conf → nginx-golang-postgres/proxy/nginx.conf

@@ -2,7 +2,8 @@ server {
     listen       80;
     server_name  localhost;
     location / {
-        proxy_pass   http://backend:8000;
+        proxy_pass          http://backend:8000;
+        proxy_http_version  1.1;
     }
 
 }