Skip to content

Commit d3d5e11

Browse files
authored
Dockerize for realase (#15)
* add dockerfile and docker-compose and initial'em * deploy flow:Login and Build and push Docker image to GHCR
1 parent 4fc8488 commit d3d5e11

File tree

9 files changed

+314
-7
lines changed

9 files changed

+314
-7
lines changed

.github/workflows/cd.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# This workflow will build a golang project
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
3+
4+
name: ci-flow
5+
6+
on:
7+
push:
8+
branches: ["dev"]
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
USER_NAME: im-qarch
13+
IMAGE_NAME: go-automatic-chainsaw
14+
15+
jobs:
16+
build-and-push-image:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
packages: write
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v3
25+
26+
- name: Login to GitHub Container Registry
27+
uses: docker/login-action@v3
28+
with:
29+
registry: ${{ env.REGISTRY }}
30+
username: ${{ github.actor }}
31+
password: ${{ secrets.GIT_PERSONAL_ACCESS_TOKEN }}
32+
33+
- name: Extract metadata (tags, labels) for Docker
34+
id: meta
35+
uses: docker/metadata-action@v4
36+
with:
37+
images: ${{ env.REGISTRY }}/${{ env.USER_NAME }}/${{ env.IMAGE_NAME }}
38+
39+
- name: Build and push Docker image
40+
uses: docker/build-push-action@v4
41+
with:
42+
context: .
43+
push: true
44+
tags: ${{ env.REGISTRY }}/${{ env.USER_NAME }}/${{ env.IMAGE_NAME }}:latest
45+
labels: ${{ steps.meta.outputs.labels }}

.github/workflows/go.yml renamed to .github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This workflow will build a golang project
22
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
33

4-
name: ci-test
4+
name: cd-flow
55

66
on:
77
push:

Dockerfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Build stage
2+
FROM golang:alpine3.19 AS builder
3+
WORKDIR /app
4+
COPY . .
5+
RUN go build -o main main.go
6+
7+
# Run stage
8+
FROM alpine:3.19
9+
WORKDIR /app
10+
COPY --from=builder /app/main .
11+
COPY app.env .
12+
COPY start.sh .
13+
COPY wait-for.sh .
14+
COPY db/migration ./db/migration
15+
16+
EXPOSE 8080 9090
17+
CMD [ "/app/main" ]
18+
ENTRYPOINT [ "/app/start.sh" ]

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,23 @@ final config should look like [this](./.github/workflows/ci.yml)
147147
**🟨 Initial [auth-middleware](./api/middleware.go) to handle user access to apis just by right token**
148148

149149
<br />
150+
151+
### 🐳 8. **_Dockerize app for release and [Build a minimal Golang Docker image with a multistage Dockerfile]_**
152+
153+
- first create [Dockerfile](./Dockerfile) in root dir
154+
then go to docker-hub to find-out [golang official image](https://hub.docker.com/_/golang) for docker
155+
write basic config for build your go app and run :
156+
157+
```shell
158+
docker build -t go-automatic-chainsaw:latest . #tag with name of app and base path
159+
```
160+
161+
so let's make it ease with docker-compose
162+
163+
- create [docker compose file](./docker-compose.yml) based on [doc](https://docs.docker.com/compose/gettingstarted/)
164+
165+
```shell
166+
docker compose up
167+
```
168+
169+
<br />

docker-compose.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
services:
2+
postgres:
3+
image: postgres:latest
4+
environment:
5+
- POSTGRES_USER=root
6+
- POSTGRES_PASSWORD=root
7+
- POSTGRES_DB=bank_db
8+
ports:
9+
- "5432:5432"
10+
volumes:
11+
- data-volume:/var/lib/postgresql/data
12+
# redis:
13+
# image: redis:7-alpine
14+
api:
15+
build:
16+
context: .
17+
dockerfile: Dockerfile
18+
ports:
19+
- "8080:8080"
20+
- "9090:9090"
21+
environment:
22+
- DB_SOURCE=postgresql://root:root@postgres:5432/bank_db?sslmode=disable
23+
# - REDIS_ADDRESS=redis:6379
24+
depends_on:
25+
- postgres
26+
# - redis
27+
entrypoint: ["/app/wait-for.sh", "postgres:5432", "--", "/app/start.sh"]
28+
command: ["/app/main"]
29+
volumes:
30+
data-volume:

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ require (
5656
golang.org/x/sys v0.18.0 // indirect
5757
golang.org/x/text v0.14.0 // indirect
5858
google.golang.org/protobuf v1.31.0 // indirect
59-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
6059
gopkg.in/ini.v1 v1.67.0 // indirect
6160
gopkg.in/yaml.v3 v3.0.1 // indirect
6261
)

go.sum

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
4949
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
5050
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
5151
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
52-
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
5352
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
5453
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
55-
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
56-
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
5754
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
5855
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
5956
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
@@ -144,8 +141,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
144141
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
145142
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
146143
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
147-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
148-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
144+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
145+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
149146
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
150147
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
151148
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

start.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
echo "start the app"
6+
exec "$@"

wait-for.sh

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#!/bin/sh
2+
3+
# The MIT License (MIT)
4+
#
5+
# Copyright (c) 2017 Eficode Oy
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
# SOFTWARE.
24+
25+
VERSION="2.2.4"
26+
27+
set -- "$@" -- "$TIMEOUT" "$QUIET" "$PROTOCOL" "$HOST" "$PORT" "$result"
28+
TIMEOUT=15
29+
QUIET=0
30+
# The protocol to make the request with, either "tcp" or "http"
31+
PROTOCOL="tcp"
32+
33+
echoerr() {
34+
if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
35+
}
36+
37+
usage() {
38+
exitcode="$1"
39+
cat << USAGE >&2
40+
Usage:
41+
$0 host:port|url [-t timeout] [-- command args]
42+
-q | --quiet Do not output any status messages
43+
-t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
44+
Defaults to 15 seconds
45+
-v | --version Show the version of this tool
46+
-- COMMAND ARGS Execute command with args after the test finishes
47+
USAGE
48+
exit "$exitcode"
49+
}
50+
51+
wait_for() {
52+
case "$PROTOCOL" in
53+
tcp)
54+
if ! command -v nc >/dev/null; then
55+
echoerr 'nc command is missing!'
56+
exit 1
57+
fi
58+
;;
59+
http)
60+
if ! command -v wget >/dev/null; then
61+
echoerr 'wget command is missing!'
62+
exit 1
63+
fi
64+
;;
65+
esac
66+
67+
TIMEOUT_END=$(($(date +%s) + TIMEOUT))
68+
69+
while :; do
70+
case "$PROTOCOL" in
71+
tcp)
72+
nc -w 1 -z "$HOST" "$PORT" > /dev/null 2>&1
73+
;;
74+
http)
75+
wget --timeout=1 --tries=1 -q "$HOST" -O /dev/null > /dev/null 2>&1
76+
;;
77+
*)
78+
echoerr "Unknown protocol '$PROTOCOL'"
79+
exit 1
80+
;;
81+
esac
82+
83+
result=$?
84+
85+
if [ $result -eq 0 ] ; then
86+
if [ $# -gt 7 ] ; then
87+
for result in $(seq $(($# - 7))); do
88+
result=$1
89+
shift
90+
set -- "$@" "$result"
91+
done
92+
93+
TIMEOUT=$2 QUIET=$3 PROTOCOL=$4 HOST=$5 PORT=$6 result=$7
94+
shift 7
95+
exec "$@"
96+
fi
97+
exit 0
98+
fi
99+
100+
if [ $TIMEOUT -ne 0 -a $(date +%s) -ge $TIMEOUT_END ]; then
101+
echo "Operation timed out" >&2
102+
exit 1
103+
fi
104+
105+
sleep 1
106+
done
107+
}
108+
109+
while :; do
110+
case "$1" in
111+
http://*|https://*)
112+
HOST="$1"
113+
PROTOCOL="http"
114+
shift 1
115+
;;
116+
*:* )
117+
HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
118+
PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
119+
shift 1
120+
;;
121+
-v | --version)
122+
echo $VERSION
123+
exit
124+
;;
125+
-q | --quiet)
126+
QUIET=1
127+
shift 1
128+
;;
129+
-q-*)
130+
QUIET=0
131+
echoerr "Unknown option: $1"
132+
usage 1
133+
;;
134+
-q*)
135+
QUIET=1
136+
result=$1
137+
shift 1
138+
set -- -"${result#-q}" "$@"
139+
;;
140+
-t | --timeout)
141+
TIMEOUT="$2"
142+
shift 2
143+
;;
144+
-t*)
145+
TIMEOUT="${1#-t}"
146+
shift 1
147+
;;
148+
--timeout=*)
149+
TIMEOUT="${1#*=}"
150+
shift 1
151+
;;
152+
--)
153+
shift
154+
break
155+
;;
156+
--help)
157+
usage 0
158+
;;
159+
-*)
160+
QUIET=0
161+
echoerr "Unknown option: $1"
162+
usage 1
163+
;;
164+
*)
165+
QUIET=0
166+
echoerr "Unknown argument: $1"
167+
usage 1
168+
;;
169+
esac
170+
done
171+
172+
if ! [ "$TIMEOUT" -ge 0 ] 2>/dev/null; then
173+
echoerr "Error: invalid timeout '$TIMEOUT'"
174+
usage 3
175+
fi
176+
177+
case "$PROTOCOL" in
178+
tcp)
179+
if [ "$HOST" = "" ] || [ "$PORT" = "" ]; then
180+
echoerr "Error: you need to provide a host and port to test."
181+
usage 2
182+
fi
183+
;;
184+
http)
185+
if [ "$HOST" = "" ]; then
186+
echoerr "Error: you need to provide a host to test."
187+
usage 2
188+
fi
189+
;;
190+
esac
191+
192+
wait_for "$@"

0 commit comments

Comments
 (0)