From 7f3586cd36533400b8948569f45100120394a64a Mon Sep 17 00:00:00 2001 From: Stephen Parkinson Date: Mon, 11 Sep 2023 21:08:38 -0700 Subject: [PATCH] vapor again --- Dockerfile | 77 +++++++ Package.resolved | 203 ++++++++++++++++++ Package.swift | 39 ++++ {static => Public}/css/404style.css | 0 {static => Public}/images/bg.jpg | Bin {static => Public}/images/me.jpg | Bin {static => Public}/images/trees.jpg | Bin {static => Public}/media/gif.gif | Bin {static => Public}/media/gif2.gif | Bin {static => Public}/media/song.mp3 | Bin README.md | 1 + .../404.html => Resources/Views/404.leaf | 2 +- .../home.html => Resources/Views/home.leaf | 6 +- .../Views/privacy.leaf | 0 .../Views/welcome.leaf | 6 +- Sources/App/configure.swift | 15 ++ Sources/App/routes.swift | 20 ++ Sources/Run/main.swift | 9 + Tests/AppTests/AppTests.swift | 12 ++ Tests/LinuxMain.swift | 11 + app.py | 30 --- docker-compose.yml | 30 +++ requirements.txt | 2 - 23 files changed, 424 insertions(+), 39 deletions(-) create mode 100644 Dockerfile create mode 100644 Package.resolved create mode 100644 Package.swift rename {static => Public}/css/404style.css (100%) rename {static => Public}/images/bg.jpg (100%) rename {static => Public}/images/me.jpg (100%) rename {static => Public}/images/trees.jpg (100%) rename {static => Public}/media/gif.gif (100%) rename {static => Public}/media/gif2.gif (100%) rename {static => Public}/media/song.mp3 (100%) create mode 100644 README.md rename templates/404.html => Resources/Views/404.leaf (91%) rename templates/home.html => Resources/Views/home.leaf (91%) rename templates/privacy.html => Resources/Views/privacy.leaf (100%) rename templates/welcome.html => Resources/Views/welcome.leaf (99%) create mode 100644 Sources/App/configure.swift create mode 100644 Sources/App/routes.swift create mode 100644 Sources/Run/main.swift create mode 100644 Tests/AppTests/AppTests.swift create mode 100644 Tests/LinuxMain.swift delete mode 100644 app.py create mode 100644 docker-compose.yml delete mode 100644 requirements.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..087e712 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,77 @@ +# ================================ +# Build image +# ================================ +FROM swift:5.7-jammy as build + +# Install OS updates and, if needed, sqlite3 +RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \ + && apt-get -q update \ + && apt-get -q dist-upgrade -y\ + && rm -rf /var/lib/apt/lists/* + +# Set up a build area +WORKDIR /build + +# First just resolve dependencies. +# This creates a cached layer that can be reused +# as long as your Package.swift/Package.resolved +# files do not change. +COPY ./Package.* ./ +RUN swift package resolve + +# Copy entire repo into container +COPY . . + +# Build everything, with optimizations +RUN swift build -c release --static-swift-stdlib + +# Switch to the staging area +WORKDIR /staging + +# Copy main executable to staging area +RUN cp "$(swift build --package-path /build -c release --show-bin-path)/Run" ./ + +# Copy resources bundled by SPM to staging area +RUN find -L "$(swift build --package-path /build -c release --show-bin-path)/" -regex '.*\.resources$' -exec cp -Ra {} ./ \; + +# Copy any resources from the public directory and views directory if the directories exist +# Ensure that by default, neither the directory nor any of its contents are writable. +RUN [ -d /build/Public ] && { mv /build/Public ./Public && chmod -R a-w ./Public; } || true +RUN [ -d /build/Resources ] && { mv /build/Resources ./Resources && chmod -R a-w ./Resources; } || true + +# ================================ +# Run image +# ================================ +FROM ubuntu:jammy + +# Make sure all system packages are up to date, and install only essential packages. +RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \ + && apt-get -q update \ + && apt-get -q dist-upgrade -y \ + && apt-get -q install -y \ + ca-certificates \ + tzdata \ +# If your app or its dependencies import FoundationNetworking, also install `libcurl4`. + # libcurl4 \ +# If your app or its dependencies import FoundationXML, also install `libxml2`. + # libxml2 \ + && rm -r /var/lib/apt/lists/* + +# Create a vapor user and group with /app as its home directory +RUN useradd --user-group --create-home --system --skel /dev/null --home-dir /app vapor + +# Switch to the new home directory +WORKDIR /app + +# Copy built executable and any staged resources from builder +COPY --from=build --chown=vapor:vapor /staging /app + +# Ensure all further commands run as the vapor user +USER vapor:vapor + +# Let Docker bind to port 8080 +EXPOSE 8080 + +# Start the Vapor service when the image is run, default to listening on 8080 in production environment +ENTRYPOINT ["./Run"] +CMD ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"] diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..c902b82 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,203 @@ +{ + "pins" : [ + { + "identity" : "async-http-client", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swift-server/async-http-client.git", + "state" : { + "revision" : "864c8d9e0ead5de7ba70b61c8982f89126710863", + "version" : "1.15.0" + } + }, + { + "identity" : "async-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/async-kit.git", + "state" : { + "revision" : "9acea4c92f51a5885c149904f0d11db4712dda80", + "version" : "1.16.0" + } + }, + { + "identity" : "console-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/console-kit.git", + "state" : { + "revision" : "447f1046fb4e9df40973fe426ecb24a6f0e8d3b4", + "version" : "4.6.0" + } + }, + { + "identity" : "leaf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/leaf.git", + "state" : { + "revision" : "6fe0e843c6599f5189e45c7b08739ebc5c410c3b", + "version" : "4.2.4" + } + }, + { + "identity" : "leaf-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/leaf-kit.git", + "state" : { + "revision" : "62169b44cc79734e11bf44b8d7154865dee5936b", + "version" : "1.10.1" + } + }, + { + "identity" : "multipart-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/multipart-kit.git", + "state" : { + "revision" : "0d55c35e788451ee27222783c7d363cb88092fab", + "version" : "4.5.2" + } + }, + { + "identity" : "routing-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/routing-kit.git", + "state" : { + "revision" : "ffac7b3a127ce1e85fb232f1a6271164628809ad", + "version" : "4.6.0" + } + }, + { + "identity" : "swift-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-algorithms.git", + "state" : { + "revision" : "b14b7f4c528c942f121c8b860b9410b2bf57825e", + "version" : "1.0.0" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "ff3d2212b6b093db7f177d0855adbc4ef9c5f036", + "version" : "1.0.3" + } + }, + { + "identity" : "swift-backtrace", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swift-server/swift-backtrace.git", + "state" : { + "revision" : "f25620d5d05e2f1ba27154b40cafea2b67566956", + "version" : "1.3.3" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2", + "version" : "1.0.4" + } + }, + { + "identity" : "swift-crypto", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-crypto.git", + "state" : { + "revision" : "da0fe44138ab86e380f40a2acbd8a611b07d3f64", + "version" : "2.4.0" + } + }, + { + "identity" : "swift-log", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-log.git", + "state" : { + "revision" : "32e8d724467f8fe623624570367e3d50c5638e46", + "version" : "1.5.2" + } + }, + { + "identity" : "swift-metrics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-metrics.git", + "state" : { + "revision" : "e8bced74bc6d747745935e469f45d03f048d6cbd", + "version" : "2.3.4" + } + }, + { + "identity" : "swift-nio", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio.git", + "state" : { + "revision" : "45167b8006448c79dda4b7bd604e07a034c15c49", + "version" : "2.48.0" + } + }, + { + "identity" : "swift-nio-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-extras.git", + "state" : { + "revision" : "d75ed708d00353acf173ca23018b6bd46f949464", + "version" : "1.17.0" + } + }, + { + "identity" : "swift-nio-http2", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-http2.git", + "state" : { + "revision" : "38feec96bcd929028939107684073554bf01abeb", + "version" : "1.25.2" + } + }, + { + "identity" : "swift-nio-ssl", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-ssl.git", + "state" : { + "revision" : "4fb7ead803e38949eb1d6fabb849206a72c580f3", + "version" : "2.23.0" + } + }, + { + "identity" : "swift-nio-transport-services", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-transport-services.git", + "state" : { + "revision" : "c0d9a144cfaec8d3d596aadde3039286a266c15c", + "version" : "1.15.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + }, + { + "identity" : "vapor", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/vapor.git", + "state" : { + "revision" : "bac0fe31e3b186537eb750d44fae048681e2b773", + "version" : "4.74.0" + } + }, + { + "identity" : "websocket-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/websocket-kit.git", + "state" : { + "revision" : "2b8885974e8d9f522e787805000553f4f7cce8a0", + "version" : "2.7.0" + } + } + ], + "version" : 2 +} diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..9f0586e --- /dev/null +++ b/Package.swift @@ -0,0 +1,39 @@ +// swift-tools-version:5.7 +import PackageDescription + +let package = Package( + name: "smparkin", + platforms: [ + .macOS(.v12) + ], + dependencies: [ + .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"), + .package(url: "https://github.com/vapor/leaf.git", from: "4.0.0"), + ], + targets: [ + .target( + name: "App", + dependencies: [ + .product(name: "Vapor", package: "vapor"), + .product(name: "Leaf", package: "leaf") + ], + swiftSettings: [ + .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release)) + ] + ), + .executableTarget( + name: "Run", + dependencies: [ + .target(name: "App") + ] + ), + .testTarget( + name: "AppTests", + dependencies: [ + .target(name: "App"), + .product(name: "XCTVapor", package: "vapor") + ] + ) + ] +) + diff --git a/static/css/404style.css b/Public/css/404style.css similarity index 100% rename from static/css/404style.css rename to Public/css/404style.css diff --git a/static/images/bg.jpg b/Public/images/bg.jpg similarity index 100% rename from static/images/bg.jpg rename to Public/images/bg.jpg diff --git a/static/images/me.jpg b/Public/images/me.jpg similarity index 100% rename from static/images/me.jpg rename to Public/images/me.jpg diff --git a/static/images/trees.jpg b/Public/images/trees.jpg similarity index 100% rename from static/images/trees.jpg rename to Public/images/trees.jpg diff --git a/static/media/gif.gif b/Public/media/gif.gif similarity index 100% rename from static/media/gif.gif rename to Public/media/gif.gif diff --git a/static/media/gif2.gif b/Public/media/gif2.gif similarity index 100% rename from static/media/gif2.gif rename to Public/media/gif2.gif diff --git a/static/media/song.mp3 b/Public/media/song.mp3 similarity index 100% rename from static/media/song.mp3 rename to Public/media/song.mp3 diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc2ec01 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +smpark.in diff --git a/templates/404.html b/Resources/Views/404.leaf similarity index 91% rename from templates/404.html rename to Resources/Views/404.leaf index 3938855..285613c 100644 --- a/templates/404.html +++ b/Resources/Views/404.leaf @@ -13,7 +13,7 @@ - + diff --git a/templates/home.html b/Resources/Views/home.leaf similarity index 91% rename from templates/home.html rename to Resources/Views/home.leaf index 74c20d9..1603aff 100644 --- a/templates/home.html +++ b/Resources/Views/home.leaf @@ -19,7 +19,7 @@ body,h1,h2,h3,h4,h5,h6 {font-family: "Raleway", sans-serif} -

+

Stephen Parkinson

Software Engineer

@@ -41,7 +41,7 @@ body,h1,h2,h3,h4,h5,h6 {font-family: "Raleway", sans-serif}
- +

@@ -51,7 +51,7 @@ body,h1,h2,h3,h4,h5,h6 {font-family: "Raleway", sans-serif}
- A picture I took + A picture I took
diff --git a/templates/privacy.html b/Resources/Views/privacy.leaf similarity index 100% rename from templates/privacy.html rename to Resources/Views/privacy.leaf diff --git a/templates/welcome.html b/Resources/Views/welcome.leaf similarity index 99% rename from templates/welcome.html rename to Resources/Views/welcome.leaf index 6864b7a..ac4aa4d 100755 --- a/templates/welcome.html +++ b/Resources/Views/welcome.leaf @@ -6,7 +6,7 @@ #dance_floor{ width: 500px; margin: auto; - background: url('/static/media/gif2.gif') center center no-repeat; + background: url('media/gif2.gif') center center no-repeat; } .yolo{ float: left; @@ -21,10 +21,10 @@ - +
- +
diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift new file mode 100644 index 0000000..746898b --- /dev/null +++ b/Sources/App/configure.swift @@ -0,0 +1,15 @@ +import Leaf +import Vapor + +// Called before your application initializes. +public func configure(_ app: Application) throws { + //leaf + app.views.use(.leaf) + + //Register middleware + app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) + app.middleware.use(ErrorMiddleware.default(environment: app.environment)) + + //routes + try routes(app) +} diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift new file mode 100644 index 0000000..01de541 --- /dev/null +++ b/Sources/App/routes.swift @@ -0,0 +1,20 @@ +import Vapor + +// Register your application's routes here. +public func routes(_ app: Application) throws { + app.get("") { req async throws -> View in + return try await req.view.render("home") + } + app.get("index.html") { req async throws -> View in + return try await req.view.render("home") + } + app.get("privacy") { req async throws -> View in + return try await req.view.render("privacy") + } + app.get("welcome") { req async throws -> View in + return try await req.view.render("welcome") + } + app.get("**") { req async throws -> View in + return try await req.view.render("404") + } +} diff --git a/Sources/Run/main.swift b/Sources/Run/main.swift new file mode 100644 index 0000000..373be5f --- /dev/null +++ b/Sources/Run/main.swift @@ -0,0 +1,9 @@ +import App +import Vapor + +var env = try Environment.detect() +try LoggingSystem.bootstrap(from: &env) +let app = Application(env) +defer { app.shutdown() } +try configure(app) +try app.run() diff --git a/Tests/AppTests/AppTests.swift b/Tests/AppTests/AppTests.swift new file mode 100644 index 0000000..d915e80 --- /dev/null +++ b/Tests/AppTests/AppTests.swift @@ -0,0 +1,12 @@ +import XCTest +@testable import App + +class AppTests: XCTestCase { + func testStub() throws { + XCTAssert(true) + } + + static let allTests = [ + ("testStub", testStub), + ] +} diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift new file mode 100644 index 0000000..f78cb77 --- /dev/null +++ b/Tests/LinuxMain.swift @@ -0,0 +1,11 @@ +#if os(Linux) + +import XCTest +@testable import AppTests + +XCTMain([ + // AppTests + testCase(AppTests.allTests), +]) + +#endif diff --git a/app.py b/app.py deleted file mode 100644 index 2531976..0000000 --- a/app.py +++ /dev/null @@ -1,30 +0,0 @@ -from flask import Flask, render_template, request, Response -from flask_api import status -import sys - -app = Flask(__name__) - - -# main smpark.in stuff -@app.route('/', methods=["GET"]) -def home(): - return render_template('home.html') - - -@app.route('/welcome', methods=["GET"]) -def welcome(): - return render_template('welcome.html') - - -@app.route('/privacy', methods=["GET"]) -def privacy(): - return render_template('privacy.html') - - -@app.errorhandler(404) -def fourohfour(): - return render_template('404.html') - - -if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c46e129 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +# Docker Compose file for Vapor +# +# Install Docker on your system to run and test +# your Vapor app in a production-like environment. +# +# Note: This file is intended for testing and does not +# implement best practices for a production deployment. +# +# Learn more: https://docs.docker.com/compose/reference/ +# +# Build images: docker-compose build +# Start app: docker-compose up app +# Stop all: docker-compose down +# +version: '3.7' + +x-shared_environment: &shared_environment + LOG_LEVEL: ${LOG_LEVEL:-debug} + +services: + app: + image: smparkin:latest + build: + context: . + environment: + <<: *shared_environment + ports: + - '8888:8888' + # user: '0' # uncomment to run as root for testing purposes even though Dockerfile defines 'vapor' user. + command: ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8888"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e6aae64..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -flask -flask_api