瀏覽代碼

First Commit

master
rpm-mcarman 3 年之前
父節點
當前提交
3601d8b769
共有 22 個文件被更改,包括 803 次插入0 次删除
  1. 二進制
      .DS_Store
  2. +7
    -0
      .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
  3. 二進制
      .swiftpm/xcode/package.xcworkspace/xcuserdata/michielcarman.xcuserdatad/UserInterfaceState.xcuserstate
  4. +14
    -0
      .swiftpm/xcode/xcuserdata/michielcarman.xcuserdatad/xcschemes/xcschememanagement.plist
  5. +77
    -0
      Dockerfile
  6. +239
    -0
      Package.resolved
  7. +35
    -0
      Package.swift
  8. +0
    -0
      Public/.gitkeep
  9. 二進制
      Sources/.DS_Store
  10. 二進制
      Sources/App/.DS_Store
  11. +0
    -0
      Sources/App/Controllers/.gitkeep
  12. +41
    -0
      Sources/App/Controllers/FuelEntryController.swift
  13. +31
    -0
      Sources/App/Controllers/TodoController.swift
  14. +34
    -0
      Sources/App/Migrations/CreateFuelEntry.swift
  15. +14
    -0
      Sources/App/Migrations/CreateTodo.swift
  16. +105
    -0
      Sources/App/Models/FuelEntry.swift
  17. +19
    -0
      Sources/App/Models/Todo.swift
  18. +29
    -0
      Sources/App/configure.swift
  19. +35
    -0
      Sources/App/entrypoint.swift
  20. +34
    -0
      Sources/App/routes.swift
  21. +15
    -0
      Tests/AppTests/AppTests.swift
  22. +74
    -0
      docker-compose.yml

二進制
.DS_Store 查看文件


+ 7
- 0
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 查看文件

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

二進制
.swiftpm/xcode/package.xcworkspace/xcuserdata/michielcarman.xcuserdatad/UserInterfaceState.xcuserstate 查看文件


+ 14
- 0
.swiftpm/xcode/xcuserdata/michielcarman.xcuserdatad/xcschemes/xcschememanagement.plist 查看文件

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Fueling.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

+ 77
- 0
Dockerfile 查看文件

@@ -0,0 +1,77 @@
# ================================
# Build image
# ================================
FROM swift:5.8-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)/App" ./

# 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 ["./App"]
CMD ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]

+ 239
- 0
Package.resolved 查看文件

@@ -0,0 +1,239 @@
{
"pins" : [
{
"identity" : "async-http-client",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/async-http-client.git",
"state" : {
"revision" : "333e60cc90f52973f7ee29cd8e3a7f6adfe79f4e",
"version" : "1.17.0"
}
},
{
"identity" : "async-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/async-kit.git",
"state" : {
"revision" : "a61da00d404ec91d12766f1b9aac7d90777b484d",
"version" : "1.17.0"
}
},
{
"identity" : "console-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/console-kit.git",
"state" : {
"revision" : "447f1046fb4e9df40973fe426ecb24a6f0e8d3b4",
"version" : "4.6.0"
}
},
{
"identity" : "fluent",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/fluent.git",
"state" : {
"revision" : "4b4d8bf15a06fd60137e9c543e5503c4b842654e",
"version" : "4.8.0"
}
},
{
"identity" : "fluent-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/fluent-kit.git",
"state" : {
"revision" : "559dc9c730cde77cc9dac76fba73d6e0855f0220",
"version" : "1.42.0"
}
},
{
"identity" : "fluent-postgres-driver",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/fluent-postgres-driver.git",
"state" : {
"revision" : "afc07463fc5589f5bf95f98ae2719d13ad9fbbcf",
"version" : "2.6.0"
}
},
{
"identity" : "multipart-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/multipart-kit.git",
"state" : {
"revision" : "1adfd69df2da08f7931d4281b257475e32c96734",
"version" : "4.5.4"
}
},
{
"identity" : "postgres-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/postgres-kit.git",
"state" : {
"revision" : "3ad08265aade48fff5f2ec772e96ecf51b7900a2",
"version" : "2.10.0"
}
},
{
"identity" : "postgres-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/postgres-nio.git",
"state" : {
"revision" : "98b8e1b1488c706f8bff9eb07560745630a64679",
"version" : "1.14.0"
}
},
{
"identity" : "routing-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/routing-kit.git",
"state" : {
"revision" : "611bc45c5dfb1f54b84d99b89d1f72191fb6b71b",
"version" : "4.7.2"
}
},
{
"identity" : "sql-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/sql-kit.git",
"state" : {
"revision" : "d547122756534d8224d4599739da0e82e4695623",
"version" : "3.25.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" : "6c89474e62719ddcc1e9614989fff2f68208fe10",
"version" : "1.1.0"
}
},
{
"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" : "33a20e650c33f6d72d822d558333f2085effa3dc",
"version" : "2.5.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" : "f7c46552983b06b0958a1a4c8bc5199406ae4c8a",
"version" : "2.51.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "0e0d0aab665ff1a0659ce75ac003081f2b1c8997",
"version" : "1.19.0"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "6d021a48483dbb273a9be43f65234bdc9185b364",
"version" : "1.26.0"
}
},
{
"identity" : "swift-nio-ssl",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
"revision" : "9d0d5d8798a576fbf674a823734e65e15ca5f2ec",
"version" : "2.23.1"
}
},
{
"identity" : "swift-nio-transport-services",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
"revision" : "59b966415dd336db6f388bbfe3fb43cfa549b981",
"version" : "1.16.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" : "f4b00a5350238fe896d865d96d64f12fcbbeda95",
"version" : "4.76.0"
}
},
{
"identity" : "websocket-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/websocket-kit.git",
"state" : {
"revision" : "2166cbe932b29b6419f9cd751e8b27c647e1238e",
"version" : "2.8.0"
}
}
],
"version" : 2
}

+ 35
- 0
Package.swift 查看文件

@@ -0,0 +1,35 @@
// swift-tools-version:5.8
import PackageDescription

let package = Package(
name: "Fueling",
platforms: [
.macOS(.v12)
],
dependencies: [
// 💧 A server-side Swift web framework.
.package(url: "https://github.com/vapor/vapor.git", from: "4.76.0"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.8.0"),
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0"),
],
targets: [
.executableTarget(
name: "App",
dependencies: [
.product(name: "Fluent", package: "fluent"),
.product(name: "FluentPostgresDriver", package: "fluent-postgres-driver"),
.product(name: "Vapor", package: "vapor")
],
swiftSettings: [
// Enable better optimizations when building in Release configuration. Despite the use of
// the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
// builds. See <https://www.swift.org/server/guides/building.html#building-for-production> for details.
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
]
),
.testTarget(name: "AppTests", dependencies: [
.target(name: "App"),
.product(name: "XCTVapor", package: "vapor"),
])
]
)

+ 0
- 0
Public/.gitkeep 查看文件


二進制
Sources/.DS_Store 查看文件


二進制
Sources/App/.DS_Store 查看文件


+ 0
- 0
Sources/App/Controllers/.gitkeep 查看文件


+ 41
- 0
Sources/App/Controllers/FuelEntryController.swift 查看文件

@@ -0,0 +1,41 @@
//
// FuelEntryController.swift
//
//
// Created by Bill Ryckman on 4/24/23.
//

import Vapor

struct FuelEntryController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let fuelEntries = routes.grouped("fuel_entries")
fuelEntries.get(use: index)
fuelEntries.post(use: create)
fuelEntries.group(":fuelEntryID") { fuelEntry in
fuelEntry.delete(use: delete)
}
}
func index(req: Request) async throws -> [FuelEntry] {
try await FuelEntry.query(on: req.db).all()
}

func create(req: Request) async throws -> FuelEntry {
let fuelEntry = try req.content.decode(FuelEntry.self)
try await fuelEntry.save(on: req.db)
return fuelEntry
}

func delete(req: Request) async throws -> HTTPStatus {
guard let fuelEntry = try await FuelEntry.find(req.parameters.get("fuelEntryID"), on: req.db) else {
throw Abort(.notFound)
}
try await fuelEntry.delete(on: req.db)
return .noContent
}
}





+ 31
- 0
Sources/App/Controllers/TodoController.swift 查看文件

@@ -0,0 +1,31 @@
import Fluent
import Vapor

struct TodoController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let todos = routes.grouped("todos")
todos.get(use: index)
todos.post(use: create)
todos.group(":todoID") { todo in
todo.delete(use: delete)
}
}

func index(req: Request) async throws -> [Todo] {
try await Todo.query(on: req.db).all()
}

func create(req: Request) async throws -> Todo {
let todo = try req.content.decode(Todo.self)
try await todo.save(on: req.db)
return todo
}

func delete(req: Request) async throws -> HTTPStatus {
guard let todo = try await Todo.find(req.parameters.get("todoID"), on: req.db) else {
throw Abort(.notFound)
}
try await todo.delete(on: req.db)
return .noContent
}
}

+ 34
- 0
Sources/App/Migrations/CreateFuelEntry.swift 查看文件

@@ -0,0 +1,34 @@
//
// File.swift
//
//
// Created by Bill Ryckman on 4/26/23.
//

import Vapor
import Fluent

struct CreateFuelEntry: AsyncMigration {
func prepare(on database: Database) async throws {
try await database.schema("fuel_entries")
.id()
.field("timestamp", .datetime)
.field("user_id", .string)
.field("gps_location", .string)
.field("image", .string)
.field("product", .string)
.field("make", .string)
.field("model", .string)
.field("serial_number", .string)
.field("tank_id", .string)
.field("fuel_amount", .double)
.field("fuel_type", .string)
.field("is_override", .bool)
.create()
}

func revert(on database: Database) async throws {
try await database.schema("fuel_entries").delete()
}
}


+ 14
- 0
Sources/App/Migrations/CreateTodo.swift 查看文件

@@ -0,0 +1,14 @@
import Fluent

struct CreateTodo: AsyncMigration {
func prepare(on database: Database) async throws {
try await database.schema("todos")
.id()
.field("title", .string, .required)
.create()
}

func revert(on database: Database) async throws {
try await database.schema("todos").delete()
}
}

+ 105
- 0
Sources/App/Models/FuelEntry.swift 查看文件

@@ -0,0 +1,105 @@
//
// FuelEntry.swift
//
//
// Created by Bill Ryckman on 4/24/23.
//

import Fluent
import Vapor

final class FuelEntry: Model, Content {
static let schema = "fuel_entries"

@ID(key: .id)
var id: UUID?

@Field(key: "timestamp")
var timestamp: Date

@Field(key: "user_id")
var userID: String

@Field(key: "gps_location")
var gpsLocation: String

@Field(key: "image")
var image: String

@Field(key: "product")
var product: String

@Field(key: "make")
var make: String

@Field(key: "model")
var model: String

@Field(key: "serial_number")
var serialNumber: String

@Field(key: "tank_id")
var tankID: String

@Field(key: "fuel_amount")
var fuelAmount: Double

@Field(key: "fuel_type")
var fuelType: String

@Field(key: "is_override")
var isOverride: Bool

init() {}

init(id: UUID? = nil, timestamp: Date, userID: String, gpsLocation: String, image: String, product: String, make: String, model: String, serialNumber: String, tankID: String, fuelAmount: Double, fuelType: String, isOverride: Bool) {
self.id = id
self.timestamp = timestamp
self.userID = userID
self.gpsLocation = gpsLocation
self.image = image
self.product = product
self.make = make
self.model = model
self.serialNumber = serialNumber
self.tankID = tankID
self.fuelAmount = fuelAmount
self.fuelType = fuelType
self.isOverride = isOverride
}
}


//extension FuelEntry: Content {}
//extension FuelEntry: Migration {
// func prepare(on database: FluentKit.Database) -> NIOCore.EventLoopFuture<Void> {
// <#code#>
// }
//
// func revert(on database: FluentKit.Database) -> NIOCore.EventLoopFuture<Void> {
// <#code#>
// }
// func prepare(on database: Database) -> EventLoopFuture<Void> {
// return database.schema("fuel_entries")
// .id()
// .field("timestamp", .datetime)
// .field("user_id", .string)
// .field("gps_location", .string)
// .field("image", .string)
// .field("product", .string)
// .field("make", .string)
// .field("model", .string)
// .field("serial_number", .string)
// .field("tank_id", .string)
// .field("fuel_amount", .double)
// .field("fuel_type", .string)
// .field("is_override", .bool)
// .create()
// }
//
// func revert(on database: Database) -> EventLoopFuture<Void> {
// return database.schema("fuel_entries").delete()
// }
//}
//extension FuelEntry: Parameter {}


+ 19
- 0
Sources/App/Models/Todo.swift 查看文件

@@ -0,0 +1,19 @@
import Fluent
import Vapor

final class Todo: Model, Content {
static let schema = "todos"
@ID(key: .id)
var id: UUID?

@Field(key: "title")
var title: String

init() { }

init(id: UUID? = nil, title: String) {
self.id = id
self.title = title
}
}

+ 29
- 0
Sources/App/configure.swift 查看文件

@@ -0,0 +1,29 @@
import Fluent
import FluentPostgresDriver
import Vapor

// configures your application
public func configure(_ app: Application) async throws {
// uncomment to serve files from /Public folder
// app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))

app.databases.use(.postgres(hostname: "localhost", username: "mcarman", password: "@ng31F@rm0823262", database: "fueling"), as: .psql)

// app.databases.use(.postgres(
// hostname: Environment.get("localhost") ?? "localhost",
// port: Environment.get("5432").flatMap(Int.init(_:)) ?? PostgresConfiguration.ianaPortNumber,
// username: Environment.get("mcarman") ?? "vapor_username",
// //username: Environment.get("bryckman") ?? "vapor_username",
// password: Environment.get("@ng31F@rm0823262" ?? "vapor_password"),
// //password: Environment.get("55H1ck0ry1669") ?? "vapor_password",
// database: Environment.get("fueling") ?? "vapor_database"
// ), as: .psql)
app.http.server.configuration.port = 3001

// app.migrations.add(CreateTodo())
app.migrations.add(CreateFuelEntry())
try await app.autoMigrate().get()

// register routes
try routes(app)
}

+ 35
- 0
Sources/App/entrypoint.swift 查看文件

@@ -0,0 +1,35 @@
import Vapor
import Dispatch
import Logging

/// This extension is temporary and can be removed once Vapor gets this support.
private extension Vapor.Application {
static let baseExecutionQueue = DispatchQueue(label: "vapor.codes.entrypoint")
func runFromAsyncMainEntrypoint() async throws {
try await withCheckedThrowingContinuation { continuation in
Vapor.Application.baseExecutionQueue.async { [self] in
do {
try self.run()
continuation.resume()
} catch {
continuation.resume(throwing: error)
}
}
}
}
}

@main
enum Entrypoint {
static func main() async throws {
var env = try Environment.detect()
try LoggingSystem.bootstrap(from: &env)
let app = Application(env)
defer { app.shutdown() }
try await configure(app)
try await app.runFromAsyncMainEntrypoint()
}
}

+ 34
- 0
Sources/App/routes.swift 查看文件

@@ -0,0 +1,34 @@
//import Fluent
//import Vapor
//
//func routes(_ app: Application) throws {
// app.get { req async in
// "It works!"
// }
//
// app.get("hello") { req async -> String in
// "Hello, world!"
// }
//
// try app.register(collection: TodoController())
//}

import Vapor

func routes(_ app: Application) throws {
let fuelEntryController = FuelEntryController()
app.get("fuel-entries") { req in
try await fuelEntryController.index(req: req)
}
app.post("fuel-entries") { req in
try await fuelEntryController.create(req: req)
}
app.delete("fuel-entries", ":fuelEntryID") { req in
try await fuelEntryController.delete(req: req)
}
}



+ 15
- 0
Tests/AppTests/AppTests.swift 查看文件

@@ -0,0 +1,15 @@
@testable import App
import XCTVapor

final class AppTests: XCTestCase {
func testHelloWorld() async throws {
let app = Application(.testing)
defer { app.shutdown() }
try await configure(app)

try app.test(.GET, "hello", afterResponse: { res in
XCTAssertEqual(res.status, .ok)
XCTAssertEqual(res.body.string, "Hello, world!")
})
}
}

+ 74
- 0
docker-compose.yml 查看文件

@@ -0,0 +1,74 @@
# 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
# Start database: docker-compose up db
# Run migrations: docker-compose run migrate
# Stop all: docker-compose down (add -v to wipe db)
#
version: '3.7'

volumes:
db_data:

x-shared_environment: &shared_environment
LOG_LEVEL: ${LOG_LEVEL:-debug}
DATABASE_HOST: db
DATABASE_NAME: vapor_database
DATABASE_USERNAME: vapor_username
DATABASE_PASSWORD: vapor_password
services:
app:
image: fueling:latest
build:
context: .
environment:
<<: *shared_environment
depends_on:
- db
ports:
- '8080:8080'
# 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", "8080"]
migrate:
image: fueling:latest
build:
context: .
environment:
<<: *shared_environment
depends_on:
- db
command: ["migrate", "--yes"]
deploy:
replicas: 0
revert:
image: fueling:latest
build:
context: .
environment:
<<: *shared_environment
depends_on:
- db
command: ["migrate", "--revert", "--yes"]
deploy:
replicas: 0
db:
image: postgres:15-alpine
volumes:
- db_data:/var/lib/postgresql/data/pgdata
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_USER: vapor_username
POSTGRES_PASSWORD: vapor_password
POSTGRES_DB: vapor_database
ports:
- '5432:5432'

Loading…
取消
儲存