Skip to content

Commit

Permalink
refactor: workflow, frontend app, and frontend build
Browse files Browse the repository at this point in the history
* fixes create react app bug: facebook/create-react-app#8688
* adds styling to frontend app
* improves frontend dockerfile
* adds additional commands to makefile and README
  • Loading branch information
ivorscott committed Mar 23, 2020
1 parent 6af7142 commit 896676d
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 107 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## The Ultimate Go and React Development Setup with Docker (Part 2)

### Building A Complete Example
### Building A Complete API Example

This repository is paired with a [blog post](https://blog.ivorscott.com/ultimate-go-react-development-setup-with-docker-part2). If you follow along, the project starter is available under the `part2_starter` branch. Part 2 is heavily influenced by [Ardan labs service training](https://github.com/ardanlabs/service-training). I highly recommend their [courses](https://education.ardanlabs.com/).
This repository is paired with a [blog post](https://blog.ivorscott.com/ultimate-go-react-development-setup-with-docker-part2). Part 2 is heavily influenced by [Ardan labs service training](https://github.com/ardanlabs/service-training). I highly recommend their [courses](https://education.ardanlabs.com/).

[Previous blog post](https://blog.ivorscott.com/ultimate-go-react-development-setup-with-docker)

Expand Down Expand Up @@ -445,6 +445,10 @@ make debug-api # use delve on the same api in a separate container (no live relo

make debug-db # use pgcli to inspect postgres db

make rm # remove all containers

make rmi # remove all images

make exec user="..." service="..." cmd="..." # execute command in running container

make tidy # clean up unused api dependencies
Expand All @@ -453,6 +457,8 @@ make test-api # run api tests

make test-client # run client tests

make test-client-watch # run client tests and watch

make migration <name> # create a migration

make version # print current migration version
Expand Down Expand Up @@ -519,7 +525,7 @@ Run the debuggable api. Set a break point on a route handler. Click 'Launch remo

</details>

### Building A Complete Example
### Building A Complete API Example

The Ultimate Go and React Development Setup with Docker (Part 2)

Expand Down
51 changes: 23 additions & 28 deletions client/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,74 +7,69 @@ WORKDIR /client
# 3. Copy both package.json and package-lock.json into /client in the image's filesystem
COPY package*.json ./

# 4. Install only the production node_modules and clean up the cache
RUN npm ci \
&& npm cache clean --force

# 5. Extend the base stage and create a new stage named dev
# 4. Extend the base stage and create a new stage named dev
FROM base as dev

# 6. Set the NODE_ENV and PATH Environment variables
# 5. Set the NODE_ENV and PATH Environment variables
ENV NODE_ENV=development
ENV PATH /client/node_modules/.bin:$PATH

# 7. Provide meta data about the port the container must expose
# 6. Provide meta data about the port the container must expose
EXPOSE 3000

# 8. Create a new /app directory in /client
# 7. Create a new /app directory in /client
RUN mkdir /client/app

# 9. Install development dependencies
RUN npm i --only=development \
&& npm cache clean --force
# 8. Install development dependencies
RUN npm install && npm cache clean --force

# 10. Print npm configuration for debugging purposes
# 9. Print npm configuration for debugging purposes
RUN npm config list

# 11. Set the working directory to /client/app
# 10. Set the working directory to /client/app
WORKDIR /client/app

# 12. Provide the default command for the development container
# 11. Provide the default command for the development container
CMD ["npm", "run", "start"]

# 13. Extend the dev stage and create a new stage called test
# 12. Extend the dev stage and create a new stage called test
FROM dev as test

# 14. Copy the remainder of the client folder source code into the image's filesystem
# 13. Copy the remainder of the client folder source code into the image's filesystem
COPY . .

# 15. Run node_module vulnerability checks
# 14. Run node_module vulnerability checks
RUN npm audit

# 16. Run unit tests in CI
# 15. Run unit tests in CI
RUN CI=true npm test --env=jsdom

# 17. Extend the test stage and create a new stage named build-stage
# 16. Extend the test stage and create a new stage named build-stage
FROM test as build-stage

# 18. Build the production static assets
# 17. Build the production static assets
RUN npm run build

# 19. Install aquasecurity's trivy for robust image scanning
FROM aquasec/trivy:0.4.3 as trivy
# 18. Install aquasecurity's trivy for robust image scanning
FROM aquasec/trivy:0.4.4 as trivy

# 20. Scan the nginx alpine image before production use
# 19. Scan the nginx alpine image before production use
RUN trivy nginx:1.17-alpine && \
echo "No image vulnerabilities" > result

# 21. Extend the nginx apline image and create a new stage named prod
# 20. Extend the nginx apline image and create a new stage named prod
FROM nginx:1.17-alpine as prod

# 22. Copy only the files we want from a few stages into the prod stage
# 21. Copy only the files we want from a few stages into the prod stage
COPY --from=trivy result secure
COPY --from=build-stage /client/app/build /usr/share/nginx/html

# 23. Copy non-root user nginx configuration
# 22. Copy non-root user nginx configuration
# https://hub.docker.com/_/nginx
COPY --from=build-stage /client/app/nginx /etc/nginx/

# 24. Provide meta data about the port the container must expose
# 23. Provide meta data about the port the container must expose
EXPOSE 80

# 25. Define how Docker should test the container to check that it is still working
# 24. Define how Docker should test the container to check that it is still working
HEALTHCHECK CMD [ "wget", "-q", "0.0.0.0:80" ]
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"workbox-webpack-plugin": "4.3.1"
},
"scripts": {
"start": "node scripts/start.js",
"start": "HTTPS=true REACT_APP_API_URL=https://localhost:4000/v1 node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
},
Expand Down
57 changes: 7 additions & 50 deletions client/src/App/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,16 @@ body {
box-sizing: border-box;
// https://css-tricks.com/snippets/css/font-shorthand/
font: normal 400 24px/1.7 "Lato", Helvetica, sans-serif;
background: #000;
color: #777;
padding: 30px;
}

.header {
position: relative;
height: 85vh;
background-image: linear-gradient(
to right bottom,
rgba(126, 2123, 111, 0.8),
rgba(209, 73, 31, 0.6)
rgba(126, 212, 111, 0.8),
rgba(209, 73, 31, 0.8)
),
url("http://getwallpapers.com/wallpaper/full/d/3/a/547521.jpg");
background-size: cover;
Expand Down Expand Up @@ -133,54 +131,13 @@ body {
}
}

.products-feature {
.main {
position: relative;
top: -650px;
margin: 100px;
top: -500px;
text-align: center;
color: #fff;

header {
font-size: 36px;
font-weight: 700;
text-align: center;
margin-bottom: 46px;
}

.products {
display: flex;
flex: 1;
justify-content: center;
&__card {
width: 100%;
min-height: 300px;
max-width: 300px;
margin: 10px;
padding: 12px;
background-color: #fff;
border-radius: 8px;
color: #444;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25),
0 10px 10px rgba(0, 0, 0, 0.22);
}
.a {
position: relative;
top: 0px;
animation: moveInBottom 0.65s ease-out 1s;
animation-fill-mode: backwards;
}
.b {
position: relative;
top: 40px;
animation: moveInBottom 0.65s ease-out 1.2s;
animation-fill-mode: backwards;
}
.c {
position: relative;
top: 80px;
animation: moveInBottom 0.65s ease-out 1.4s;
animation-fill-mode: backwards;
}
}
animation: moveInBottom 0.65s ease-out 1.4s;
animation-fill-mode: backwards;
}

@keyframes moveInLeft {
Expand Down
12 changes: 6 additions & 6 deletions client/src/App/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { render } from '@testing-library/react';
import App from './App';
import React from "react";
import { render } from "@testing-library/react";
import App from "./App";

test('renders learn react link', () => {
test("renders learn react link", () => {
const { getByText } = render(<App />);
const linkElement = getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
const button = getByText(/Sign Up/i);
expect(button).toBeInTheDocument();
});
6 changes: 5 additions & 1 deletion client/src/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ class App extends React.Component<{}, State> {
subtitle="Second hand games"
callToActionText="Sign Up"
/>
<Products products={this.state.products} />
<div className="main">
<h1>The Best Prices</h1>
<h3>Gaming Is Our Passion. Get 20% Off Any 2nd Purchase!</h3>
<Products products={this.state.products} />
</div>
</div>
);
}
Expand Down
26 changes: 26 additions & 0 deletions client/src/App/Products/Products.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.products-feature {
color: #fff;
margin-top: 40px;

.products {
display: flex;
flex: 1;
justify-content: center;
&__card {
display: flex;
flex: 1;
flex-direction: column;
justify-content: center;
width: 100%;
min-height: 300px;
max-width: 300px;
margin: 10px;
padding: 12px;
background-color: #fff;
border-radius: 8px;
color: #444;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25),
0 10px 10px rgba(0, 0, 0, 0.22);
}
}
}
22 changes: 6 additions & 16 deletions client/src/App/Products/Products.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import React from "react";
import { IProduct } from "./types";

const classes = ["a", "b", "c"];
import "./Products.scss";

const Products: React.FC<{ products: IProduct[] }> = ({ products }) => (
<main className="products-feature">
<header>Store</header>
<div className="products">
{products.map((product, index) => {
{products.map(product => {
return (
index < 3 && (
<div
key={product.id}
className={`products__card ${classes[index]}`}
>
<b className="products__card-name">{product.name}</b>
<p className="products__card-description">
{product.description}
</p>
<p className="products__card-price">{product.price}</p>
</div>
)
<div key={product.id} className="products__card">
<b className="products__card-name">{product.name}</b>
<p className="products__card-price">{product.price}</p>
</div>
);
})}
</div>
Expand Down
7 changes: 6 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ services:
- ./api:/api
networks:
- postgres-net
# swap commands to disable live reload
# command: go run ./cmd/api
command: CompileDaemon --build="go build -o main ./cmd/api" -log-prefix=false --command=./main

Expand All @@ -33,9 +34,13 @@ services:
environment:
HTTPS: "true"
REACT_APP_API_URL: https://localhost:$API_PORT/v1
CHOKIDAR_USEPOLLING: "true"
ports:
- $CLIENT_PORT:$CLIENT_PORT
# fixes bug in react-scripts/start.js found in latest create react app release
# https://github.com/facebook/create-react-app/issues/8688
tty: true
stdin_open: true
volumes:
- ./client:/client/app
- /client/app/node_modules
Expand Down Expand Up @@ -63,7 +68,7 @@ services:
networks:
- postgres-net
# run a container without the default seccomp profile
# https://github.com/go-delve/delve/issues/515
# https://github.com/go-delve/delve/issues/515#issuecomment-214911481
security_opt:
- "seccomp:unconfined"
tty: true
Expand Down
19 changes: 18 additions & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,13 @@ exec:

test-client:
@echo [ running client tests ... ]
@docker-compose run client npm test
@cd client; npx jest --notify
@cd ..

test-client-watch:
@echo [ running client tests ... ]
@cd client; npx jest --watchAll
@cd ..

test-api:
@echo [ running api tests ... ]
Expand All @@ -118,6 +124,14 @@ debug-db:
@# includes auto-completion and syntax highlighting. https://www.pgcli.com/
@docker run -it --rm --net $(POSTGRES_NET) dencold/pgcli $(URL)

rm:
@echo [ removing all containers ... ]
docker rm -f `docker ps -aq`

rmi:
@echo [ removing all images ... ]
docker rmi -f `docker images -a -q`

migration:
ifndef name
$(error migration name is missing -> make migration <name>)
Expand All @@ -144,6 +158,7 @@ version:
@docker run --volume $(MIGRATIONS_VOLUME) --network $(POSTGRES_NET) migrate/migrate \
-path /migrations \
-database $(URL) version \
&& echo \
&& echo $(SUCCESS)

up:
Expand Down Expand Up @@ -214,6 +229,8 @@ insert:
.PHONY: db
.PHONY: debug-api
.PHONY: debug-db
.PHONY: rm
.PHONY: rmi
.PHONY: down
.PHONY: dump
.PHONY: force
Expand Down

0 comments on commit 896676d

Please sign in to comment.