This commit is contained in:
commit
7dd203f01a
23
.dockerignore
Normal file
23
.dockerignore
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
**/.classpath
|
||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
README.md
|
2
.drone.yml
Normal file
2
.drone.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
kind: template
|
||||||
|
load: docker.yaml
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
**/node_modules
|
||||||
|
**/dist
|
19
Dockerfile
Normal file
19
Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FROM node:alpine AS builder
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
COPY . .
|
||||||
|
RUN npm install --include=dev
|
||||||
|
#
|
||||||
|
# Build mode can be set via NODE_ENV environment variable (development or production)
|
||||||
|
# See project package.json and webpack.config.js
|
||||||
|
#
|
||||||
|
ENV NODE_ENV=development
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
FROM node:alpine
|
||||||
|
RUN npm install http-server -g
|
||||||
|
RUN mkdir /public
|
||||||
|
WORKDIR /public
|
||||||
|
COPY --from=builder /usr/src/app/dist/ ./
|
||||||
|
EXPOSE 8080
|
||||||
|
USER 1000
|
||||||
|
CMD ["http-server"]
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 DigitalOcean
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
155
README.md
Normal file
155
README.md
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# Overview
|
||||||
|
|
||||||
|
Sample javascript application implementing the classic [2048 game](https://en.wikipedia.org/wiki/2048_(video_game)). Main project is based on the [game-2048 library](https://www.npmjs.com/package/game-2048) and [Webpack](https://webpack.js.org).
|
||||||
|
|
||||||
|
Main purpose is to serve as a demo for the [DOKS-CI-CD](https://github.com/digitalocean/container-blueprints/tree/main/DOKS-CI-CD) blueprint.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
To complete all steps and deploy the `2048-game` sample application, you will need:
|
||||||
|
|
||||||
|
1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running.
|
||||||
|
2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction.
|
||||||
|
3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository.
|
||||||
|
4. [NodeJS](https://nodejs.org) and `npm` to build and test the 2048-game application code.
|
||||||
|
5. [Docker Desktop](https://www.docker.com/products/docker-desktop) to build and test the 2048-game application docker image locally.
|
||||||
|
|
||||||
|
## Building the 2048 Game Application
|
||||||
|
|
||||||
|
Main project is `javascript` based, hence you can build the application via `npm`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm install --include=dev
|
||||||
|
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
You can test the application locally, by running below command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
Above command will start a web server in development mode, which you can access at [localhost:8080](http://localhost:8080). Please visit the main library [configuration](https://www.npmjs.com/package/game-2048#config) section from the public npm registry to see all available options.
|
||||||
|
|
||||||
|
## Building the Docker Image
|
||||||
|
|
||||||
|
A sample [Dockerfile](./Dockerfile) is provided in this repository as well, to help you get started with dockerizing the 2048 game app. Depending on the `NODE_ENV` environment variable, you can create and publish a `development` or `production` ready Docker image.
|
||||||
|
|
||||||
|
First, you need to clone this repository (if not already):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/digitalocean/kubernetes-sample-apps.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, change directory to your local copy:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd kubernetes-sample-apps
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, issue below command to build the docker image for the 2048 game app, Below examples assume you already have a [DigitalOcean Docker Registry](https://docs.digitalocean.com/products/container-registry) set up (make sure to replace the `<>` placeholders accordingly):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker build -t registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game ./game-2048-example
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
The sample [Dockerfile](./Dockerfile) provided in this repository is using the [multistage build](https://docs.docker.com/develop/develop-images/multistage-build) feature. It means, the final image contains only the application assets (build process artifacts are automatically discarded).
|
||||||
|
|
||||||
|
Then, you can issue bellow command to launch the `2048-game` container (make sure to replace the `<>` placeholders accordingly):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run --rm -it -p 8080:8080 registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, visit [localhost:8080](http://localhost:8080) to check the 2048 game app in your web browser. Finally, you can push the image to your DigitalOcean docker registry (make sure to replace the `<>` placeholders accordingly):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker push registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
Pushing images to your DigitalOcean docker registry is possible only after a successful authentication. Please read the official DigitalOcean [guide](https://docs.digitalocean.com/products/container-registry/how-to/use-registry-docker-kubernetes) and follow the steps. [Integrating with Kubernetes](https://docs.digitalocean.com/products/container-registry/how-to/use-registry-docker-kubernetes/#kubernetes-integration) step is important as well.
|
||||||
|
|
||||||
|
## Deploying to Kubernetes
|
||||||
|
|
||||||
|
The [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `2048-game` Kubernetes resources.
|
||||||
|
|
||||||
|
First, you need to clone this repository (if not already):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/digitalocean/kubernetes-sample-apps.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, change directory to your local copy:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd kubernetes-sample-apps
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, edit the game-2048 [deployment manifest](kustomize/resources/deployment.yaml) using your favorite text editor (preferably with YAML lint support), and replace the `<>` placeholders. For example, you can use [VS Code](https://code.visualstudio.com/):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
code game-2048-example/kustomize/resources/deployment.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, create 2048 game Kubernetes resources using the kubectl kustomize option (`-k` flag):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -k game-2048-example/kustomize
|
||||||
|
```
|
||||||
|
|
||||||
|
The output looks similar to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
namespace/game-2048 created
|
||||||
|
service/game-2048 created
|
||||||
|
deployment.apps/game-2048 created
|
||||||
|
```
|
||||||
|
|
||||||
|
If everything went well, you should have a new Kubernetes namespace created named `game-2048`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all game-2048 application pods should be up and running):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get all -n game-2048
|
||||||
|
```
|
||||||
|
|
||||||
|
The output looks similar to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
pod/game-2048-f96755947-dgj7z 1/1 Running 0 5m19s
|
||||||
|
|
||||||
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
|
service/game-2048 ClusterIP 10.245.120.202 <none> 8080/TCP 5m21s
|
||||||
|
|
||||||
|
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||||
|
deployment.apps/game-2048 1/1 1 1 5m22s
|
||||||
|
|
||||||
|
NAME DESIRED CURRENT READY AGE
|
||||||
|
replicaset.apps/game-2048-f96755947 1 1 1 5m22s
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, port-forward the `game-2048` service using `kubectl`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl port-forward service/game-2048 -n game-2048 8080:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Open a web browser and point to [localhost:8080](http://localhost:8080/). You should see the `game-2048` welcome page:
|
||||||
|
|
||||||
|
![2048 Game Welcome Page](assets/images/game-2048-welcome-page.png)
|
||||||
|
|
||||||
|
## Cleaning Up
|
||||||
|
|
||||||
|
To clean up all Kubernetes resources created by the 2048 game application, below command must be used:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl delete ns game-2048
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
Kubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k game-2048-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail.
|
7
Tiltfile
Normal file
7
Tiltfile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
os.putenv('DOCKER_DEFAULT_PLATFORM', 'linux/amd64')
|
||||||
|
|
||||||
|
k8s_yaml(kustomize('kustomize'))
|
||||||
|
|
||||||
|
docker_build('game-2048', '.')
|
||||||
|
|
||||||
|
k8s_resource('game-2048', port_forwards='8080')
|
BIN
assets/images/game-2048-welcome-page.png
Normal file
BIN
assets/images/game-2048-welcome-page.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
6921
package-lock.json
generated
Normal file
6921
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
package.json
Normal file
26
package.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "knative-example",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack server --config webpack.config.js --mode development",
|
||||||
|
"build": "webpack",
|
||||||
|
"build-dev": "webpack --mode development",
|
||||||
|
"build-prod": "webpack --mode production",
|
||||||
|
"test": "echo '=== DUMMY TEST ==='"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"game-2048": "^0.0.7"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"css-loader": "^6.7.1",
|
||||||
|
"html-webpack-plugin": "^5.5.0",
|
||||||
|
"style-loader": "^3.3.1",
|
||||||
|
"webpack": "^5.72.1",
|
||||||
|
"webpack-cli": "^4.9.2",
|
||||||
|
"webpack-dev-server": "^4.9.0"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT",
|
||||||
|
"description": "Sample 2048 Game App"
|
||||||
|
}
|
11
src/index.js
Normal file
11
src/index.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import 'game-2048/style/main.css';
|
||||||
|
import Game from 'game-2048';
|
||||||
|
|
||||||
|
var gameContainerDiv = document.createElement('div');
|
||||||
|
gameContainerDiv.setAttribute('id', 'game-container');
|
||||||
|
gameContainerDiv.className = 'container';
|
||||||
|
document.body.appendChild(gameContainerDiv);
|
||||||
|
|
||||||
|
const game = new Game({
|
||||||
|
gameContainer: gameContainerDiv
|
||||||
|
});
|
32
webpack.config.js
Normal file
32
webpack.config.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: process.env.NODE_ENV || 'none',
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/i,
|
||||||
|
use: ["style-loader", "css-loader"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
entry: './src/index.js',
|
||||||
|
output: {
|
||||||
|
filename: 'lib/bundle.js',
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
clean: true,
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
title: '2048 Game',
|
||||||
|
})
|
||||||
|
],
|
||||||
|
devServer: {
|
||||||
|
static: {
|
||||||
|
directory: path.join(__dirname, 'dist'),
|
||||||
|
},
|
||||||
|
compress: true,
|
||||||
|
port: 8080,
|
||||||
|
},
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user