stopping for now

This commit is contained in:
Tommy Parnell
2017-01-13 18:05:42 -05:00
parent a0208013bd
commit 2f65e2e904
89 changed files with 2658 additions and 288 deletions

268
01-bitminer/Hashr/.gitignore vendored Normal file
View File

@@ -0,0 +1,268 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/

42
01-bitminer/Hashr/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,42 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceRoot}\\bin\\Debug\\netcoreapp1.1\\Hashr.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceRoot}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command.pickProcess}"
}
]
}

16
01-bitminer/Hashr/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
"version": "0.1.0",
"command": "dotnet",
"isShellCommand": true,
"args": [],
"tasks": [
{
"taskName": "build",
"args": [
"${workspaceRoot}\\project.json"
],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using System.Security.Cryptography;
namespace Hashr.Controllers
{
public class ValuesController : Controller
{ // POST api/values
[HttpPost]
[Route("hashme")]
public async Task<string> HashMe()
{
using(var memstream = new MemoryStream())
using(var sha = SHA256.Create())
{
await this.Request.Body.CopyToAsync(memstream);
return System.Text.Encoding.ASCII.GetString(sha.ComputeHash(memstream.ToArray()));
}
}
}
}

View File

@@ -0,0 +1,15 @@
FROM microsoft/dotnet:1.1.0-sdk-projectjson
WORKDIR /app
ADD project.json project.json
RUN ["dotnet", "restore"]
ADD . .
RUN ["dotnet", "build", "-c", "Release"]
EXPOSE 80/tcp
CMD ["dotnet", "run", "-c", "Release", "--server.urls", "http://*:80"]

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
namespace Hashr
{
public class Program
{
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}

View File

@@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1479/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Hashr": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000/api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,39 @@
# Welcome to ASP.NET Core
We've made some big updates in this release, so its **important** that you spend a few minutes to learn whats new.
You've created a new ASP.NET Core project. [Learn what's new](https://go.microsoft.com/fwlink/?LinkId=518016)
## This application consists of:
* Sample pages using ASP.NET Core MVC
* [Bower](https://go.microsoft.com/fwlink/?LinkId=518004) for managing client-side libraries
* Theming using [Bootstrap](https://go.microsoft.com/fwlink/?LinkID=398939)
## How to
* [Add a Controller and View](https://go.microsoft.com/fwlink/?LinkID=398600)
* [Add an appsetting in config and access it in app.](https://go.microsoft.com/fwlink/?LinkID=699562)
* [Manage User Secrets using Secret Manager.](https://go.microsoft.com/fwlink/?LinkId=699315)
* [Use logging to log a message.](https://go.microsoft.com/fwlink/?LinkId=699316)
* [Add packages using NuGet.](https://go.microsoft.com/fwlink/?LinkId=699317)
* [Add client packages using Bower.](https://go.microsoft.com/fwlink/?LinkId=699318)
* [Target development, staging or production environment.](https://go.microsoft.com/fwlink/?LinkId=699319)
## Overview
* [Conceptual overview of what is ASP.NET Core](https://go.microsoft.com/fwlink/?LinkId=518008)
* [Fundamentals of ASP.NET Core such as Startup and middleware.](https://go.microsoft.com/fwlink/?LinkId=699320)
* [Working with Data](https://go.microsoft.com/fwlink/?LinkId=398602)
* [Security](https://go.microsoft.com/fwlink/?LinkId=398603)
* [Client side development](https://go.microsoft.com/fwlink/?LinkID=699321)
* [Develop on different platforms](https://go.microsoft.com/fwlink/?LinkID=699322)
* [Read more on the documentation site](https://go.microsoft.com/fwlink/?LinkID=699323)
## Run & Deploy
* [Run your app](https://go.microsoft.com/fwlink/?LinkID=517851)
* [Run tools such as EF migrations and more](https://go.microsoft.com/fwlink/?LinkID=517853)
* [Publish to Microsoft Azure Web Apps](https://go.microsoft.com/fwlink/?LinkID=398609)
We would love to hear your [feedback](https://go.microsoft.com/fwlink/?LinkId=518015)

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Hashr
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
}
}

View File

@@ -0,0 +1,10 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

View File

@@ -0,0 +1,62 @@
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.1.0",
"type": "platform"
},
"Microsoft.AspNetCore.Mvc": "1.1.0",
"Microsoft.AspNetCore.Routing": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Configuration.CommandLine": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final"
},
"frameworks": {
"netcoreapp1.1": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true,
"debugType": "portable"
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
"**/*.cshtml",
"appsettings.json",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
},
"tooling": {
"defaultNamespace": "Hashr"
}
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at https://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>

268
01-bitminer/Worker/.gitignore vendored Normal file
View File

@@ -0,0 +1,268 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/

View File

@@ -0,0 +1,11 @@
FROM microsoft/dotnet:1.1.0-sdk-projectjson
WORKDIR /dotnetapp
# copy project.json and restore as distinct layers
ADD project.json .
RUN dotnet restore
# copy and build everything else
ADD . .
ENTRYPOINT ["dotnet", "run", "-c", "Release"]

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Net.Http;
using System.Text;
namespace Worker
{
public class Program
{
static Random rand = new Random();
static HttpClient httpclient = new HttpClient();
public static void Main(string[] args)
{
MainAsync(args).Wait();
}
public static async Task MainAsync(string[] args)
{
while(true)
{
try
{
var bytes = await httpclient.GetByteArrayAsync("http://gen/8");
var results = await httpclient.PostAsync("http://hashr/hashme", new ByteArrayContent(bytes));
results.EnsureSuccessStatusCode();
var hashResults = await results.Content.ReadAsStringAsync();
await httpclient.GetStringAsync($"http://store/store");
await Task.Delay(rand.Next(100, 1000)); //emulate some level of processing time
}
catch(Exception e)
{
Console.WriteLine("WORKER FAILED");
Console.WriteLine(e.Message);
}
}
}
}
}

View File

@@ -0,0 +1,23 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.1.0"
}
},
"frameworks": {
"netcoreapp1.1": {
"imports": "dnxcore50"
}
},
"tooling": {
"defaultNamespace": "Worker"
}
}

View File

@@ -0,0 +1,31 @@
version: "2"
services:
gen:
build: gen
ports:
- "8001:80"
hashr:
build: Hashr
ports:
- "8002:80"
ui:
build: ui
ports:
- "8000:80"
links:
- store
store:
build: store
ports:
- "8003:80"
worker:
build: worker
links:
- hashr
- gen
- store

View File

@@ -1,5 +1,5 @@
FROM python
RUN pip install Flask
COPY rng.py /
CMD ["python", "rng.py"]
COPY gen.py .
CMD ["python", "gen.py"]
EXPOSE 80

View File

@@ -8,19 +8,16 @@ app = Flask(__name__)
# Enable debugging if the DEBUG environment variable is set and starts with Y
app.debug = os.environ.get("DEBUG", "").lower().startswith('y')
hostname = socket.gethostname()
urandom = os.open("/dev/urandom", os.O_RDONLY)
@app.route("/")
def index():
return "RNG running on {}\n".format(hostname)
return "gen running"
@app.route("/<int:how_many_bytes>")
def rng(how_many_bytes):
# Simulate a little bit of delay
def gen(how_many_bytes):
time.sleep(0.1)
return Response(
os.read(urandom, how_many_bytes),
@@ -29,4 +26,3 @@ def rng(how_many_bytes):
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80)

View File

@@ -0,0 +1,7 @@
FROM ruby:alpine
RUN apk add --update build-base
RUN gem install sinatra
RUN gem install thin
ADD app.rb /
CMD ["ruby", "app.rb"]
EXPOSE 80

View File

@@ -0,0 +1,3 @@
source "https://rubygems.org"
gem 'sinatra'
gem 'thin'

View File

@@ -0,0 +1,24 @@
GEM
remote: https://rubygems.org/
specs:
mini_portile2 (2.1.0)
nokogiri (1.7.0.1-x64-mingw32)
mini_portile2 (~> 2.1.0)
rack (1.6.5)
rack-protection (1.5.3)
rack
sinatra (1.4.7)
rack (~> 1.5)
rack-protection (~> 1.4)
tilt (>= 1.3, < 3)
tilt (2.0.5)
PLATFORMS
x64-mingw32
DEPENDENCIES
nokogiri
sinatra
BUNDLED WITH
1.13.7

48
01-bitminer/store/app.rb Normal file
View File

@@ -0,0 +1,48 @@
require 'sinatra'
require 'date'
require 'json'
set :bind, '0.0.0.0'
set :port, 80
get '/' do
content_type :json
getData.to_json
end
get '/store' do
begin
requestDate = DateTime.parse(params['dt'])
rescue
requestDate = DateTime.now
end
hashKey = "#{requestDate.year}-#{requestDate.month}-#{requestDate.day}-#{requestDate.hour}-#{requestDate.minute}-#{requestDate.second}"
puts hashKey
coinsInHash = DB.dbHash[hashKey]
if coinsInHash
coinsInHash = coinsInHash.next
else
puts "setting to zero"
coinsInHash = 0
end
DB.dbHash[hashKey] = coinsInHash
content_type :json
getData.to_json
end
def getData
dt = Time.now
datumHash = (0...60).to_a.map { |e|
dts = dt - e
key = "#{dts.year}-#{dts.month}-#{dts.day}-#{dts.hour}-#{dts.min}-#{dts.sec}"
data = DB.dbHash[key] || 0
{date:dts, value: data}
}
end
class DB
@@DateTimeHash = {}
def self.dbHash
@@DateTimeHash
end
end

View File

@@ -0,0 +1,2 @@
require './app'
run Sinatra::Application

4
01-bitminer/ui/.bowerrc Normal file
View File

@@ -0,0 +1,4 @@
{
"directory": "public/components",
"json": "bower.json"
}

View File

@@ -0,0 +1,10 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

4
01-bitminer/ui/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
node_modules/
public/components
.nyc_output
.sass-cache

View File

@@ -0,0 +1,10 @@
{
"generator-express": {
"promptValues": {
"type": "Basic",
"viewEngine": "EJS",
"cssPreprocessor": "None",
"buildTool": "Gulp"
}
}
}

10
01-bitminer/ui/Dockerfile Normal file
View File

@@ -0,0 +1,10 @@
FROM node:boron-wheezy
RUN npm install -g bower
ADD package.json .
RUN npm install
ADD bower.json bower.json
RUN bower install --allow-root
ADD . .
EXPOSE 80
CMD ["npm", "run", "start"]

69
01-bitminer/ui/app.js Normal file
View File

@@ -0,0 +1,69 @@
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var app = express();
var env = process.env.NODE_ENV || 'development';
app.locals.ENV = env;
app.locals.ENV_DEVELOPMENT = env == 'development';
// view engine setup
app.set('port', process.env.PORT || 80);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// app.use(favicon(__dirname + '/public/img/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
/// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err,
title: 'error'
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {},
title: 'error'
});
});
module.exports = app;

6
01-bitminer/ui/bin/www Normal file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env node
var app = require('../app');
var server = app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + server.address().port);
});

15
01-bitminer/ui/bower.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "ui",
"version": "0.0.1",
"ignore": [
"**/.*",
"node_modules",
"components"
],
"dependencies": {
"rickshaw": "^1.6.0",
"jquery": "^3.1.1",
"underscore": "^1.8.3",
"moment": "^2.17.1"
}
}

View File

@@ -0,0 +1,26 @@
var gulp = require('gulp'),
nodemon = require('gulp-nodemon'),
plumber = require('gulp-plumber'),
livereload = require('gulp-livereload');
gulp.task('develop', function () {
livereload.listen();
nodemon({
script: 'bin/www',
ext: 'js ejs coffee',
stdout: false
}).on('readable', function () {
this.stdout.on('data', function (chunk) {
if(/^Express server listening on port/.test(chunk)){
livereload.changed(__dirname);
}
});
this.stdout.pipe(process.stdout);
this.stderr.pipe(process.stderr);
});
});
gulp.task('default', [
'develop'
]);

View File

@@ -0,0 +1,33 @@
{
"name": "ui",
"version": "0.0.1",
"private": true,
"main": "app.js",
"scripts": {
"start": "node ./bin/www",
"test": "mocha --recursive test",
"test:coverage": "nyc npm test",
"test:unit": "mocha --recursive test/middleware test/models test/routes",
"test:integration": "mocha --recursive test/integration"
},
"dependencies": {
"body-parser": "^1.13.3",
"cookie-parser": "^1.3.3",
"ejs": "^2.3.1",
"express": "^4.13.3",
"morgan": "^1.6.1",
"request": "^2.79.0",
"serve-favicon": "^2.3.0"
},
"devDependencies": {
"chai": "^3.5.0",
"debug": "^2.2.0",
"gulp": "^3.9.0",
"gulp-nodemon": "^2.0.2",
"gulp-livereload": "^3.8.0",
"gulp-plumber": "^1.0.0",
"mocha": "^3.0.2",
"nyc": "^10.0.0",
"supertest": "^2.0.0"
}
}

View File

@@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}

View File

@@ -0,0 +1,21 @@
var express = require('express');
var router = express.Router();
var request = require('request');
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
router.get('/db', (req, res)=>{
request('http://store/', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
res.set('Content-Type', 'application/json');
return res.send(200, body);
});
});
module.exports = router;

View File

@@ -0,0 +1,7 @@
<% include header %>
<%- message %>
<%- error.status %>
<%- error.stack %>
<% include footer %>

View File

@@ -0,0 +1,2 @@
</body>
</html>

View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title><%- title %></title>
<link rel="stylesheet" href="/css/style.css">
<% if (ENV_DEVELOPMENT) { %>
<script src="http://localhost:35729/livereload.js"></script>
<% } %>
</head>
<body>

View File

@@ -0,0 +1,52 @@
<% include header %>
<h1></h1>
<p>bitminer</p>
<div id="chart" style="height:500px"></div>
<link rel="stylesheet" type="text/css" href="/components/rickshaw/rickshaw.css" />
<script src="/components/moment/min/moment.min.js"></script>
<script src="/components/d3/d3.min.js"></script>
<script src="/components/rickshaw/rickshaw.min.js"></script>
<script src="/components/underscore/underscore-min.js"></script>
<script src="/components/jquery/dist/jquery.min.js"></script>
<script>
var data = []
var graph = new Rickshaw.Graph({
element: document.querySelector("#chart"),
renderer: 'area',
series: [{
data: data,
color: 'steelblue'
}]
});
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph,
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
ticksTreatment: "glow"
});
var addData = function(apiData){
data.length = 0
calculatedData = _.chain(apiData)
.map(function(data){
return {x: parseInt(moment.utc(data.date).format('x')), y: data.value}
})
.sortBy(function(mappedObj){return mappedObj.x;}).value();
_.each(calculatedData, function(item){data.push(item)});
graph.update();
};
var updateData = function(){
$.ajax('/db', {
dataType: 'json',
success: addData
});
};
new Rickshaw.Graph.Axis.Time({
graph: graph
});
graph.render();
setInterval(updateData, 1000);
</script>
<% include footer %>

View File

@@ -1,27 +0,0 @@
rng:
build: rng
ports:
- "8001:80"
hasher:
build: hasher
ports:
- "8002:80"
webui:
build: webui
links:
- redis
ports:
- "8000:80"
redis:
image: redis
worker:
build: worker
links:
- rng
- hasher
- redis

View File

@@ -1,6 +0,0 @@
FROM ruby
RUN gem install sinatra
RUN gem install thin
ADD hasher.rb /
CMD ["ruby", "hasher.rb"]
EXPOSE 80

View File

@@ -1,18 +0,0 @@
require 'digest'
require 'sinatra'
require 'socket'
set :bind, '0.0.0.0'
set :port, 80
post '/' do
# Simulate a bit of delay
sleep 0.1
content_type 'text/plain'
"#{Digest::SHA2.new().update(request.body.read)}"
end
get '/' do
"HASHER running on #{Socket.gethostname}\n"
end

View File

@@ -1,5 +0,0 @@
hasher: 80
redis: 6379
rng: 80
webui: 80

View File

@@ -1,5 +0,0 @@
FROM node:4
RUN npm install express
RUN npm install redis
COPY . .
CMD ["node", "webui.js"]

File diff suppressed because one or more lines are too long

View File

@@ -1,93 +0,0 @@
<!doctype html>
<html>
<head>
<title>DockerCoin Miner WebUI</title>
<link rel="stylesheet" type="text/css" href="rickshaw.min.css">
<style>
#graph {
background-color: #eee;
width: 800px;
height: 400px;
}
</style>
<script src="jquery-1.11.3.min.js"></script>
<script src="d3.min.js"></script>
<script src="rickshaw.min.js"></script>
<script>
String.prototype.format = function () {
var args = arguments;
return this.replace(/\{(\d+)\}/g, function (m, n) { return args[n]; });
};
var series = [];
var points = []
var graph = null;
function refresh () {
$.ajax({ url: "json" }).done(function (data) {
series.push(data);
while (series.length < 250) {
data = JSON.parse(JSON.stringify(data));
data.now -= 1;
series.unshift(data);
}
while (series.length > 250) {
series.shift();
}
while (points.length > 0) {
points.pop();
}
for (var i=0; i<series.length-1; i++) {
// Compute instantaneous speed
var s1 = series[i];
var s2 = series[i+1];
var speed = (s2.hashes-s1.hashes)/(s2.now-s1.now);
points.push({ x: s2.now, y: speed });
}
if (graph == null) {
graph = new Rickshaw.Graph({
renderer: "area",
stroke: true,
width: 800,
height: 400,
element: $("#graph")[0],
preserve: true,
series: [
{ name: "Coins",
color: "steelblue",
data: points
}
]
});
graph.render();
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph,
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
ticksTreatment: "glow"
});
yAxis.render();
} else {
graph.update();
$("text").css({
"font-size": "15px",
"font-weight": "normal",
"opacity": 0.5,
});
}
});
}
$(function () {
setInterval(refresh, 1000);
});
</script>
</head>
<body>
<h1>DockerCoin Miner WebUI</h1>
<div id="graph"></div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
jquery-1.11.3.min.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,32 +0,0 @@
var express = require('express');
var app = express();
var redis = require('redis');
var client = redis.createClient(6379, 'redis');
client.on("error", function (err) {
console.error("Redis error", err);
});
app.get('/', function (req, res) {
res.redirect('/index.html');
});
app.get('/json', function (req, res) {
client.hlen('wallet', function (err, coins) {
client.get('hashes', function (err, hashes) {
var now = Date.now() / 1000;
res.json( {
coins: coins,
hashes: hashes,
now: now
});
});
});
});
app.use(express.static('files'));
var server = app.listen(80, function () {
console.log('WEBUI running on port 80');
});

View File

@@ -1,5 +0,0 @@
FROM python
RUN pip install redis
RUN pip install requests
COPY worker.py /
CMD ["python", "worker.py"]

View File

@@ -1,70 +0,0 @@
import logging
import os
from redis import Redis
import requests
import time
DEBUG = os.environ.get("DEBUG", "").lower().startswith("y")
log = logging.getLogger(__name__)
if DEBUG:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
logging.getLogger("requests").setLevel(logging.WARNING)
redis = Redis("redis")
def get_random_bytes():
r = requests.get("http://rng/32")
return r.content
def hash_bytes(data):
r = requests.post("http://hasher/",
data=data,
headers={"Content-Type": "application/octet-stream"})
hex_hash = r.text
return hex_hash
def work_loop(interval=1):
deadline = 0
loops_done = 0
while True:
if time.time() > deadline:
log.info("{} units of work done, updating hash counter"
.format(loops_done))
redis.incrby("hashes", loops_done)
loops_done = 0
deadline = time.time() + interval
work_once()
loops_done += 1
def work_once():
log.debug("Doing one unit of work")
time.sleep(0.1)
random_bytes = get_random_bytes()
hex_hash = hash_bytes(random_bytes)
if not hex_hash.startswith('0'):
log.debug("No coin found")
return
log.info("Coin found: {}...".format(hex_hash[:8]))
created = redis.hset("wallet", hex_hash, random_bytes)
if not created:
log.info("We already had that coin")
if __name__ == "__main__":
while True:
try:
work_loop()
except:
log.exception("In work loop:")
log.error("Waiting 10s and restarting.")
time.sleep(10)

268
02-Phoenix/Hashr/.gitignore vendored Normal file
View File

@@ -0,0 +1,268 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/

42
02-Phoenix/Hashr/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,42 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceRoot}\\bin\\Debug\\netcoreapp1.1\\Hashr.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceRoot}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command.pickProcess}"
}
]
}

16
02-Phoenix/Hashr/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
"version": "0.1.0",
"command": "dotnet",
"isShellCommand": true,
"args": [],
"tasks": [
{
"taskName": "build",
"args": [
"${workspaceRoot}\\project.json"
],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using System.Security.Cryptography;
namespace Hashr.Controllers
{
public class ValuesController : Controller
{
[HttpGetAttribute]
[Route("")]
public string hashr()
{
return "hashr yo whoop whoop!";
}
// POST api/values
[HttpPost]
[Route("hashme")]
public async Task<string> HashMe()
{
using(var memstream = new MemoryStream())
using(var sha = SHA256.Create())
{
await this.Request.Body.CopyToAsync(memstream);
return System.Text.Encoding.ASCII.GetString(sha.ComputeHash(memstream.ToArray()));
}
}
}
}

View File

@@ -0,0 +1,15 @@
FROM microsoft/dotnet:1.1.0-sdk-projectjson
WORKDIR /app
ADD project.json project.json
RUN ["dotnet", "restore"]
ADD . .
RUN ["dotnet", "build", "-c", "Release"]
EXPOSE 80/tcp
CMD ["dotnet", "run", "-c", "Release", "--server.urls", "http://*:80"]

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
namespace Hashr
{
public class Program
{
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}

View File

@@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1479/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Hashr": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000/api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,39 @@
# Welcome to ASP.NET Core
We've made some big updates in this release, so its **important** that you spend a few minutes to learn whats new.
You've created a new ASP.NET Core project. [Learn what's new](https://go.microsoft.com/fwlink/?LinkId=518016)
## This application consists of:
* Sample pages using ASP.NET Core MVC
* [Bower](https://go.microsoft.com/fwlink/?LinkId=518004) for managing client-side libraries
* Theming using [Bootstrap](https://go.microsoft.com/fwlink/?LinkID=398939)
## How to
* [Add a Controller and View](https://go.microsoft.com/fwlink/?LinkID=398600)
* [Add an appsetting in config and access it in app.](https://go.microsoft.com/fwlink/?LinkID=699562)
* [Manage User Secrets using Secret Manager.](https://go.microsoft.com/fwlink/?LinkId=699315)
* [Use logging to log a message.](https://go.microsoft.com/fwlink/?LinkId=699316)
* [Add packages using NuGet.](https://go.microsoft.com/fwlink/?LinkId=699317)
* [Add client packages using Bower.](https://go.microsoft.com/fwlink/?LinkId=699318)
* [Target development, staging or production environment.](https://go.microsoft.com/fwlink/?LinkId=699319)
## Overview
* [Conceptual overview of what is ASP.NET Core](https://go.microsoft.com/fwlink/?LinkId=518008)
* [Fundamentals of ASP.NET Core such as Startup and middleware.](https://go.microsoft.com/fwlink/?LinkId=699320)
* [Working with Data](https://go.microsoft.com/fwlink/?LinkId=398602)
* [Security](https://go.microsoft.com/fwlink/?LinkId=398603)
* [Client side development](https://go.microsoft.com/fwlink/?LinkID=699321)
* [Develop on different platforms](https://go.microsoft.com/fwlink/?LinkID=699322)
* [Read more on the documentation site](https://go.microsoft.com/fwlink/?LinkID=699323)
## Run & Deploy
* [Run your app](https://go.microsoft.com/fwlink/?LinkID=517851)
* [Run tools such as EF migrations and more](https://go.microsoft.com/fwlink/?LinkID=517853)
* [Publish to Microsoft Azure Web Apps](https://go.microsoft.com/fwlink/?LinkID=398609)
We would love to hear your [feedback](https://go.microsoft.com/fwlink/?LinkId=518015)

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Hashr
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
}
}

View File

@@ -0,0 +1,10 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

View File

@@ -0,0 +1,62 @@
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.1.0",
"type": "platform"
},
"Microsoft.AspNetCore.Mvc": "1.1.0",
"Microsoft.AspNetCore.Routing": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Configuration.CommandLine": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final"
},
"frameworks": {
"netcoreapp1.1": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true,
"debugType": "portable"
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
"**/*.cshtml",
"appsettings.json",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
},
"tooling": {
"defaultNamespace": "Hashr"
}
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at https://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>

268
02-Phoenix/Worker/.gitignore vendored Normal file
View File

@@ -0,0 +1,268 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/

View File

@@ -0,0 +1,11 @@
FROM microsoft/dotnet:1.1.0-sdk-projectjson
WORKDIR /dotnetapp
# copy project.json and restore as distinct layers
ADD project.json project.json
RUN dotnet restore
# copy and build everything else
ADD . .
ENTRYPOINT ["dotnet", "run", "-c", "Release"]

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Net.Http;
using System.Text;
namespace Worker
{
public class Program
{
static Random rand = new Random();
static HttpClient httpclient = new HttpClient();
public static void Main(string[] args)
{
MainAsync(args).Wait();
}
public static async Task MainAsync(string[] args)
{
while(true)
{
try
{
var bytes = await httpclient.GetByteArrayAsync("http://gen/8");
var results = await httpclient.PostAsync("http://hashr/hashme", new ByteArrayContent(bytes));
results.EnsureSuccessStatusCode();
var hashResults = await results.Content.ReadAsStringAsync();
await httpclient.GetStringAsync($"http://store/store");
await Task.Delay(rand.Next(100, 1000)); //emulate some level of processing time
}
catch(Exception e)
{
Console.WriteLine("WORKER FAILED");
Console.WriteLine(e.Message);
}
}
}
}
}

View File

@@ -0,0 +1,23 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.1.0"
}
},
"frameworks": {
"netcoreapp1.1": {
"imports": "dnxcore50"
}
},
"tooling": {
"defaultNamespace": "Worker"
}
}

4
02-Phoenix/ui/.bowerrc Normal file
View File

@@ -0,0 +1,4 @@
{
"directory": "public/components",
"json": "bower.json"
}

View File

@@ -0,0 +1,10 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

4
02-Phoenix/ui/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
node_modules/
public/components
.nyc_output
.sass-cache

10
02-Phoenix/ui/.yo-rc.json Normal file
View File

@@ -0,0 +1,10 @@
{
"generator-express": {
"promptValues": {
"type": "Basic",
"viewEngine": "EJS",
"cssPreprocessor": "None",
"buildTool": "Gulp"
}
}
}

10
02-Phoenix/ui/Dockerfile Normal file
View File

@@ -0,0 +1,10 @@
FROM node:boron-wheezy
RUN npm install -g bower
ADD package.json .
RUN npm install
ADD bower.json bower.json
RUN bower install --allow-root
ADD . .
EXPOSE 80
CMD ["npm", "run", "start"]

69
02-Phoenix/ui/app.js Normal file
View File

@@ -0,0 +1,69 @@
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var app = express();
var env = process.env.NODE_ENV || 'development';
app.locals.ENV = env;
app.locals.ENV_DEVELOPMENT = env == 'development';
// view engine setup
app.set('port', process.env.PORT || 80);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// app.use(favicon(__dirname + '/public/img/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
/// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err,
title: 'error'
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {},
title: 'error'
});
});
module.exports = app;

6
02-Phoenix/ui/bin/www Normal file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env node
var app = require('../app');
var server = app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + server.address().port);
});

15
02-Phoenix/ui/bower.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "ui",
"version": "0.0.1",
"ignore": [
"**/.*",
"node_modules",
"components"
],
"dependencies": {
"rickshaw": "^1.6.0",
"jquery": "^3.1.1",
"underscore": "^1.8.3",
"moment": "^2.17.1"
}
}

26
02-Phoenix/ui/gulpfile.js Normal file
View File

@@ -0,0 +1,26 @@
var gulp = require('gulp'),
nodemon = require('gulp-nodemon'),
plumber = require('gulp-plumber'),
livereload = require('gulp-livereload');
gulp.task('develop', function () {
livereload.listen();
nodemon({
script: 'bin/www',
ext: 'js ejs coffee',
stdout: false
}).on('readable', function () {
this.stdout.on('data', function (chunk) {
if(/^Express server listening on port/.test(chunk)){
livereload.changed(__dirname);
}
});
this.stdout.pipe(process.stdout);
this.stderr.pipe(process.stderr);
});
});
gulp.task('default', [
'develop'
]);

View File

@@ -0,0 +1,33 @@
{
"name": "ui",
"version": "0.0.1",
"private": true,
"main": "app.js",
"scripts": {
"start": "node ./bin/www",
"test": "mocha --recursive test",
"test:coverage": "nyc npm test",
"test:unit": "mocha --recursive test/middleware test/models test/routes",
"test:integration": "mocha --recursive test/integration"
},
"dependencies": {
"body-parser": "^1.13.3",
"cookie-parser": "^1.3.3",
"ejs": "^2.3.1",
"express": "^4.13.3",
"morgan": "^1.6.1",
"request": "^2.79.0",
"serve-favicon": "^2.3.0"
},
"devDependencies": {
"chai": "^3.5.0",
"debug": "^2.2.0",
"gulp": "^3.9.0",
"gulp-nodemon": "^2.0.2",
"gulp-livereload": "^3.8.0",
"gulp-plumber": "^1.0.0",
"mocha": "^3.0.2",
"nyc": "^10.0.0",
"supertest": "^2.0.0"
}
}

View File

@@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}

View File

@@ -0,0 +1,21 @@
var express = require('express');
var router = express.Router();
var request = require('request');
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
router.get('/db', (req, res)=>{
request('http://store/', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
res.set('Content-Type', 'application/json');
return res.send(200, body);
});
});
module.exports = router;

View File

@@ -0,0 +1,7 @@
<% include header %>
<%- message %>
<%- error.status %>
<%- error.stack %>
<% include footer %>

View File

@@ -0,0 +1,2 @@
</body>
</html>

View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title><%- title %></title>
<link rel="stylesheet" href="/css/style.css">
<% if (ENV_DEVELOPMENT) { %>
<script src="http://localhost:35729/livereload.js"></script>
<% } %>
</head>
<body>

View File

@@ -0,0 +1,52 @@
<% include header %>
<h1></h1>
<p>bitminer</p>
<div id="chart" style="height:500px"></div>
<link rel="stylesheet" type="text/css" href="/components/rickshaw/rickshaw.css" />
<script src="/components/moment/min/moment.min.js"></script>
<script src="/components/d3/d3.min.js"></script>
<script src="/components/rickshaw/rickshaw.min.js"></script>
<script src="/components/underscore/underscore-min.js"></script>
<script src="/components/jquery/dist/jquery.min.js"></script>
<script>
var data = []
var graph = new Rickshaw.Graph({
element: document.querySelector("#chart"),
renderer: 'area',
series: [{
data: data,
color: 'steelblue'
}]
});
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph,
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
ticksTreatment: "glow"
});
var addData = function(apiData){
data.length = 0
calculatedData = _.chain(apiData)
.map(function(data){
return {x: parseInt(moment.utc(data.date).format('x')), y: data.value}
})
.sortBy(function(mappedObj){return mappedObj.x;}).value();
_.each(calculatedData, function(item){data.push(item)});
graph.update();
};
var updateData = function(){
$.ajax('/db', {
dataType: 'json',
success: addData
});
};
new Rickshaw.Graph.Axis.Time({
graph: graph
});
graph.render();
setInterval(updateData, 1000);
</script>
<% include footer %>

View File

@@ -4,7 +4,7 @@ This is the code for my intro to docker class. These are the materials for an in
## Getting Started
We first need to setup our machines. Click the link for your OS.
We first need to setup our machines. Click the link for your OS. Please read below for specific instructions if required. After you have your machine setup read the [intro](intro.md)
* [Windows 10](https://gist.github.com/TerribleDev/dd424d3d090bcf5634dcf8417411a081)
* [Windows 7](https://gist.github.com/TerribleDev/721fde498ae7e2e17c5c44a9d8e07412)
@@ -13,7 +13,7 @@ We first need to setup our machines. Click the link for your OS.
## macOS Yosemite 10.10.3 or above
### macOS Yosemite 10.10.3 or above
if you are on macOS you can `brew cask install docker-toolbox` or you can download the docker [toolbox here](https://download.docker.com/mac/stable/Docker.dmg). You will then need to install [dotnet core](https://www.microsoft.com/net/core#macos).
@@ -34,14 +34,14 @@ brew cask install dotnet
```
## What you will need
### What you will need
if you prefer to not use the scripts I have made you will need the following installed.
* dotnet core
* docker-toolbox
## Notes about Windows 7, 8, 8.1, server 2012
### Notes about Windows 7, 8, 8.1, server 2012
Since you are on older verisons of windows you will run the docker kernel as a VM in a [hypervisor](https://en.wikipedia.org/wiki/Hypervisor). Your hypervisors are listed below.

82
story.md Normal file
View File

@@ -0,0 +1,82 @@
You are a (somewhat) compentant software enginer that has just joined a new company called bitminer. Bitminer is a fancy crypto currency mining platform, and you have been brought on because you said you knew something about docker in your resume. You are given a laptop, and told to show up the first day with docker, and dotnet core installed (see Readme.md](Readme.md) for specific setup instructions ). You know nothing about the current technology but have heard they are porting a legacy system to dotnet core.
## Day 01
You show up on your first day, and are told to `cd` into the bitminer folder (cd into `01-bitminer`), and they ask you to run `docker-compose up`.
As the text starts flying by, you notice a python app, a ruby app, a javascript app, and 2 dotnet apps being compiled. You assume these people know tons about microservices. You browse to `localhost:8000` and are met with a graph showing coins being mined on your machine. They ask you to stop the app <kbd>Ctrl</kbd> + <kbd>c</kcb> or <kbd>Cmd</kbd> + <kbd>c</kcb>
Your first task as a new employee is to find out why the company cannot mine dockercoins beyond a certain scale. They inform you that they have a fleet of `workers` that talk to a python service called `gen`, which serves up the current transaction. There is a `hashr` app that hashes the transaction, and a `store` for databasing. All of these individual services are being used by seperate `workers`.
First you start the system in detached mode `docker-compose up -d`, and you pull up `localhost:8000` in your browser. You start scaling up the `workers` by running `docker-compose scale worker=5`. Everything seems normal, you see a standard uptick in coin mining. You then go for crazy mode and scale up the workers more `docker-compose scale worker=20` You definitely notice an increase in coin mining, but diminishing returns overall.
You start looking into `gen`, as you assume all python is terrible. On line 21 you notice a clear performance mistake. Someone has accidentally added a sleep to python! You delete the line (please delete line 21). You rebuild the docker image `docker-compose create --build gen` and then you restart the gen service `docker-compose restart gen`.
You now being to mine coins much more efficiently! You are highly impressed by their use of `docker-compose` a tool that can fit many docker containers together.
## Day 02 - The Phoenix project
Impressed by your skills you are put on the Phoenix project. Project Phoenix is, a re-write of the existing infrastructure, because as you all know rewrites are the best way to remove performance bottlenecks. During this rewrite they are unifying almost everything to dotnet, with the exception of the UI team, whom believe its just not cool if its not `js`. Furthermore because you are so knowledgable with docker, they didn't bother docker-izing anything. You are expected to do it without knowing anything about their services, since you are the expert.
You talk to Brent, bitminer's genius application developer. Brent asks you to start off by docker-izing `Hashr` service, noting that he already did the gen service.image containing the `Hashr` application.
You cd into `02-Phoenix/Hashr`, and create a file called `Dockerfile`. You know this is the file docker will use to build the docker image. You read the Hashr `project.json` file, and realize its an dotnet core 1.1 project. You browse to [docker hub](https://hub.docker.com/r/microsoft/dotnet/) to find all docker containers with dotnet builtin. You come across image `1.1.0-sdk-projectjson`, which is what you are looking for. You notice there are a few other images. There are images that do not have an sdk installed, but just the runtime. these images are much smaller, but require you to compile your application outside the container and instead pass your dll's in. Since you don't have any build systems setup, you stick with the sdk, as its faster to get going on.
You add the following to your Dockerfile
```
FROM microsoft/dotnet:1.1.0-sdk-projectjson
WORKDIR /app
```
You then need to pass in the project.json file and restore nuget packages
```
ADD project.json project.json
RUN ["dotnet", "restore"]
```
Next add all your source code and compile
```
ADD . .
RUN ["dotnet", "build", "-c", "Release"]
```
After you need to expose port 80 so the container can route http traffic to your app, and you have to give docker a command to run when the container starts. In this case it will be hashr
```
EXPOSE 80/tcp
CMD ["dotnet", "run", "-c", "Release", "--server.urls", "http://*:80"]
```
The full file should look like this:
```
FROM microsoft/dotnet:1.1.0-sdk-projectjson
WORKDIR /app
ADD project.json project.json
RUN ["dotnet", "restore"]
ADD . .
RUN ["dotnet", "build", "-c", "Release"]
EXPOSE 80/tcp
CMD ["dotnet", "run", "-c", "Release", "--server.urls", "http://*:80"]
```
You run `docker build . -t hashr` which builds the container locally and tags it with the name hashr. You can see it listed if you run `docker images`. You can now run the container locally by executing `docker run -p 8080:80 -d -t hashr` and browsing to `localhost:8080` In the command `-p 8080:80`, you are mapping your local port 8080 to the containers port 80. We can list all running containers by executing `docker ps`. We can stop our container by running `docker kill HashrShaId` or you can kill all running containers by executing `docker kill $(docker ps -q)`