Giter Club home page Giter Club logo

actual-server's People

Contributors

7brend7 avatar albertogasparin avatar bokker avatar dependabot[bot] avatar fstybel avatar intiplink avatar j-f1 avatar jackenmen avatar jlongster avatar kovah avatar kyrias avatar m3nu avatar matissjanis avatar myhrmans avatar nudded avatar partylich avatar psybers avatar rich-howell avatar shazib avatar silvenga avatar suryaatevellore avatar tomafrench avatar trevdor avatar twk3 avatar unexomwid avatar urjeetpatel avatar valloric avatar waseh avatar wmertens avatar zachwhelchel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

actual-server's Issues

"Downloading the file failed. Check your network connection."

I'm not sure when this started or what the cause might be but it could have started after the actual-server image got updated while updating some other docker images. Unfortunately, I don't know if this was in fact when the issue started or which version of the Actual image I was on before updating as I've been using :latest.

Looking for suggestions on how to troubleshoot this. I have backups of the actual data so maybe I can re-import into a new budget?

image

Error on upgrading to 22.12.8

I have just upgraded to the 22.12.8-alpine image from 22.10.25-alpine and receive the following error. The server does not start.

Listening on 0.0.0.0:5006...
Rejection: TypeError: Cannot read properties of undefined (reading 'parse')
    at /app/sync-simple.js:43:48
    at sqliteTransaction (/app/node_modules/better-sqlite3/lib/methods/transaction.js:65:24)
    at WrappedDatabase.transaction (/app/db.js:29:35)
    at addMessages (/app/sync-simple.js:27:6)
    at Object.sync (/app/sync-simple.js:82:14)                                                                                                                          at /app/app-sync.js:114:42                                                                                                                                          at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)                                                                            at next (/app/node_modules/express/lib/router/route.js:137:13)                                                                                                      at Route.dispatch (/app/node_modules/express/lib/router/route.js:112:3)                                                                                             at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)       

Test issue

Setting up some bots, using this as a test issue

armv7 support

It seems that what's available on Docker Hub are amd64 and arm64 images, but sadly no armv7 image. I'd love to be able to run actual-server on some older armv7 boards I have, and was wondering if support could be added.

Trying to connect to server in app returns error in server

I'm trying to run actual-server in an old pc, but after informing "Where's the server" the terminal on the server shows this error:

ERROR IncomingMessage {
  _readableState: ReadableState {
    objectMode: false,
    highWaterMark: 16384,
    buffer: BufferList { head: null, tail: null, length: 0 },
    length: 0,
    pipes: null,
    pipesCount: 0,
    flowing: null,
    ended: false,
    endEmitted: false,
    reading: false,
    sync: true,
    needReadable: false,
    emittedReadable: false,
    readableListening: false,
    resumeScheduled: false,
    emitClose: true,
    autoDestroy: false,
    destroyed: false,
    defaultEncoding: 'utf8',
    awaitDrainWriters: null,
    multiAwaitDrain: false,
    readingMore: true,
    decoder: null,
    encoding: null,
    [Symbol(kPaused)]: null
  },
  readable: true,
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: null,
      pipesCount: 0,
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      emitClose: false,
      autoDestroy: false,
      destroyed: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    readable: true,
    _events: [Object: null prototype] {
      end: [Array],
      timeout: [Function: socketOnTimeout],
      data: [Function: bound socketOnData],
      error: [Function: socketOnError],
      close: [Array],
      drain: [Function: bound socketOnDrain],
      resume: [Function: onSocketResume],
      pause: [Function: onSocketPause]
    },
    _eventsCount: 8,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      bufferedRequest: null,
      lastBufferedRequest: null,
      pendingcb: 0,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      bufferedRequestCount: 0,
      corkedRequestsFree: [Object]
    },
    writable: true,
    allowHalfOpen: true,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: Server {
      insecureHTTPParser: undefined,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _connections: 1,
      _handle: [TCP],
      _usingWorkers: false,
      _workers: [],
      _unref: false,
      allowHalfOpen: true,
      pauseOnConnect: false,
      httpAllowHalfOpen: false,
      timeout: 120000,
      keepAliveTimeout: 5000,
      maxHeadersCount: null,
      headersTimeout: 60000,
      _connectionKey: '4:0.0.0.0:5006',
      [Symbol(IncomingMessage)]: [Function: IncomingMessage],
      [Symbol(ServerResponse)]: [Function: ServerResponse],
      [Symbol(kCapture)]: false,
      [Symbol(asyncId)]: 8
    },
    _server: Server {
      insecureHTTPParser: undefined,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _connections: 1,
      _handle: [TCP],
      _usingWorkers: false,
      _workers: [],
      _unref: false,
      allowHalfOpen: true,
      pauseOnConnect: false,
      httpAllowHalfOpen: false,
      timeout: 120000,
      keepAliveTimeout: 5000,
      maxHeadersCount: null,
      headersTimeout: 60000,
      _connectionKey: '4:0.0.0.0:5006',
      [Symbol(IncomingMessage)]: [Function: IncomingMessage],
      [Symbol(ServerResponse)]: [Function: ServerResponse],
      [Symbol(kCapture)]: false,
      [Symbol(asyncId)]: 8
    },
    timeout: 120000,
    parser: HTTPParser {
      '0': [Function: parserOnHeaders],
      '1': [Function: parserOnHeadersComplete],
      '2': [Function: parserOnBody],
      '3': [Function: parserOnMessageComplete],
      '4': [Function: bound onParserExecute],
      '5': [Function: bound onParserTimeout],
      _headers: [],
      _url: '',
      socket: [Circular],
      incoming: [Circular],
      outgoing: null,
      maxHeaderPairs: 2000,
      _consumed: true,
      onIncoming: [Function: bound parserOnIncoming],
      [Symbol(resource_symbol)]: [HTTPServerAsyncResource]
    },
    on: [Function: socketListenerWrap],
    addListener: [Function: socketListenerWrap],
    prependListener: [Function: socketListenerWrap],
    _paused: false,
    _httpMessage: ServerResponse {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: true,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: false,
      socket: [Circular],
      connection: [Circular],
      _header: null,
      _keepAliveTimeout: 5000,
      _onPendingData: [Function: bound updateOutgoingData],
      _sent100: false,
      _expect_continue: false,
      req: [Circular],
      locals: [Object: null prototype] {},
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    [Symbol(asyncId)]: 10,
    [Symbol(kHandle)]: TCP {
      reading: true,
      onconnection: null,
      _consumed: true,
      [Symbol(owner_symbol)]: [Circular]
    },
    [Symbol(kSetNoDelay)]: false,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: Timeout {
      _idleTimeout: 120000,
      _idlePrev: [TimersList],
      _idleNext: [TimersList],
      _idleStart: 5887,
      _onTimeout: [Function: bound ],
      _timerArgs: undefined,
      _repeat: null,
      _destroyed: false,
      [Symbol(refed)]: false,
      [Symbol(kHasPrimitive)]: false,
      [Symbol(asyncId)]: 11,
      [Symbol(triggerId)]: 10
    },
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0
  },
  connection: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: null,
      pipesCount: 0,
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      emitClose: false,
      autoDestroy: false,
      destroyed: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    readable: true,
    _events: [Object: null prototype] {
      end: [Array],
      timeout: [Function: socketOnTimeout],
      data: [Function: bound socketOnData],
      error: [Function: socketOnError],
      close: [Array],
      drain: [Function: bound socketOnDrain],
      resume: [Function: onSocketResume],
      pause: [Function: onSocketPause]
    },
    _eventsCount: 8,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      bufferedRequest: null,
      lastBufferedRequest: null,
      pendingcb: 0,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      bufferedRequestCount: 0,
      corkedRequestsFree: [Object]
    },
    writable: true,
    allowHalfOpen: true,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: Server {
      insecureHTTPParser: undefined,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _connections: 1,
      _handle: [TCP],
      _usingWorkers: false,
      _workers: [],
      _unref: false,
      allowHalfOpen: true,
      pauseOnConnect: false,
      httpAllowHalfOpen: false,
      timeout: 120000,
      keepAliveTimeout: 5000,
      maxHeadersCount: null,
      headersTimeout: 60000,
      _connectionKey: '4:0.0.0.0:5006',
      [Symbol(IncomingMessage)]: [Function: IncomingMessage],
      [Symbol(ServerResponse)]: [Function: ServerResponse],
      [Symbol(kCapture)]: false,
      [Symbol(asyncId)]: 8
    },
    _server: Server {
      insecureHTTPParser: undefined,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _connections: 1,
      _handle: [TCP],
      _usingWorkers: false,
      _workers: [],
      _unref: false,
      allowHalfOpen: true,
      pauseOnConnect: false,
      httpAllowHalfOpen: false,
      timeout: 120000,
      keepAliveTimeout: 5000,
      maxHeadersCount: null,
      headersTimeout: 60000,
      _connectionKey: '4:0.0.0.0:5006',
      [Symbol(IncomingMessage)]: [Function: IncomingMessage],
      [Symbol(ServerResponse)]: [Function: ServerResponse],
      [Symbol(kCapture)]: false,
      [Symbol(asyncId)]: 8
    },
    timeout: 120000,
    parser: HTTPParser {
      '0': [Function: parserOnHeaders],
      '1': [Function: parserOnHeadersComplete],
      '2': [Function: parserOnBody],
      '3': [Function: parserOnMessageComplete],
      '4': [Function: bound onParserExecute],
      '5': [Function: bound onParserTimeout],
      _headers: [],
      _url: '',
      socket: [Circular],
      incoming: [Circular],
      outgoing: null,
      maxHeaderPairs: 2000,
      _consumed: true,
      onIncoming: [Function: bound parserOnIncoming],
      [Symbol(resource_symbol)]: [HTTPServerAsyncResource]
    },
    on: [Function: socketListenerWrap],
    addListener: [Function: socketListenerWrap],
    prependListener: [Function: socketListenerWrap],
    _paused: false,
    _httpMessage: ServerResponse {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: true,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: false,
      socket: [Circular],
      connection: [Circular],
      _header: null,
      _keepAliveTimeout: 5000,
      _onPendingData: [Function: bound updateOutgoingData],
      _sent100: false,
      _expect_continue: false,
      req: [Circular],
      locals: [Object: null prototype] {},
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    [Symbol(asyncId)]: 10,
    [Symbol(kHandle)]: TCP {
      reading: true,
      onconnection: null,
      _consumed: true,
      [Symbol(owner_symbol)]: [Circular]
    },
    [Symbol(kSetNoDelay)]: false,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: Timeout {
      _idleTimeout: 120000,
      _idlePrev: [TimersList],
      _idleNext: [TimersList],
      _idleStart: 5887,
      _onTimeout: [Function: bound ],
      _timerArgs: undefined,
      _repeat: null,
      _destroyed: false,
      [Symbol(refed)]: false,
      [Symbol(kHasPrimitive)]: false,
      [Symbol(asyncId)]: 11,
      [Symbol(triggerId)]: 10
    },
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0
  },
  httpVersionMajor: 1,
  httpVersionMinor: 1,
  httpVersion: '1.1',
  complete: false,
  headers: {
    host: '192.168.15.131:5006',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0',
    accept: '*/*',
    'accept-language': 'pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3',
    'accept-encoding': 'gzip, deflate',
    referer: 'http://192.168.15.131:5006/static/js/browser-server.456138d4.worker.js',
    dnt: '1',
    connection: 'keep-alive',
    cookie: 'CSRF-Token-Z5X76=rmAVsDp3EN4r9wya2EW53Cr3ccbUCpuS'
  },
  rawHeaders: [
    'Host',
    '192.168.15.131:5006',
    'User-Agent',
    'Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0',
    'Accept',
    '*/*',
    'Accept-Language',
    'pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3',
    'Accept-Encoding',
    'gzip, deflate',
    'Referer',
    'http://192.168.15.131:5006/static/js/browser-server.456138d4.worker.js',
    'DNT',
    '1',
    'Connection',
    'keep-alive',
    'Cookie',
    'CSRF-Token-Z5X76=rmAVsDp3EN4r9wya2EW53Cr3ccbUCpuS'
  ],
  trailers: {},
  rawTrailers: [],
  aborted: false,
  upgrade: false,
  url: '/needs-bootstrap',
  method: 'GET',
  statusCode: null,
  statusMessage: null,
  client: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: null,
      pipesCount: 0,
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      emitClose: false,
      autoDestroy: false,
      destroyed: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    readable: true,
    _events: [Object: null prototype] {
      end: [Array],
      timeout: [Function: socketOnTimeout],
      data: [Function: bound socketOnData],
      error: [Function: socketOnError],
      close: [Array],
      drain: [Function: bound socketOnDrain],
      resume: [Function: onSocketResume],
      pause: [Function: onSocketPause]
    },
    _eventsCount: 8,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      bufferedRequest: null,
      lastBufferedRequest: null,
      pendingcb: 0,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      bufferedRequestCount: 0,
      corkedRequestsFree: [Object]
    },
    writable: true,
    allowHalfOpen: true,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: Server {
      insecureHTTPParser: undefined,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _connections: 1,
      _handle: [TCP],
      _usingWorkers: false,
      _workers: [],
      _unref: false,
      allowHalfOpen: true,
      pauseOnConnect: false,
      httpAllowHalfOpen: false,
      timeout: 120000,
      keepAliveTimeout: 5000,
      maxHeadersCount: null,
      headersTimeout: 60000,
      _connectionKey: '4:0.0.0.0:5006',
      [Symbol(IncomingMessage)]: [Function: IncomingMessage],
      [Symbol(ServerResponse)]: [Function: ServerResponse],
      [Symbol(kCapture)]: false,
      [Symbol(asyncId)]: 8
    },
    _server: Server {
      insecureHTTPParser: undefined,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _connections: 1,
      _handle: [TCP],
      _usingWorkers: false,
      _workers: [],
      _unref: false,
      allowHalfOpen: true,
      pauseOnConnect: false,
      httpAllowHalfOpen: false,
      timeout: 120000,
      keepAliveTimeout: 5000,
      maxHeadersCount: null,
      headersTimeout: 60000,
      _connectionKey: '4:0.0.0.0:5006',
      [Symbol(IncomingMessage)]: [Function: IncomingMessage],
      [Symbol(ServerResponse)]: [Function: ServerResponse],
      [Symbol(kCapture)]: false,
      [Symbol(asyncId)]: 8
    },
    timeout: 120000,
    parser: HTTPParser {
      '0': [Function: parserOnHeaders],
      '1': [Function: parserOnHeadersComplete],
      '2': [Function: parserOnBody],
      '3': [Function: parserOnMessageComplete],
      '4': [Function: bound onParserExecute],
      '5': [Function: bound onParserTimeout],
      _headers: [],
      _url: '',
      socket: [Circular],
      incoming: [Circular],
      outgoing: null,
      maxHeaderPairs: 2000,
      _consumed: true,
      onIncoming: [Function: bound parserOnIncoming],
      [Symbol(resource_symbol)]: [HTTPServerAsyncResource]
    },
    on: [Function: socketListenerWrap],
    addListener: [Function: socketListenerWrap],
    prependListener: [Function: socketListenerWrap],
    _paused: false,
    _httpMessage: ServerResponse {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: true,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: false,
      socket: [Circular],
      connection: [Circular],
      _header: null,
      _keepAliveTimeout: 5000,
      _onPendingData: [Function: bound updateOutgoingData],
      _sent100: false,
      _expect_continue: false,
      req: [Circular],
      locals: [Object: null prototype] {},
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    [Symbol(asyncId)]: 10,
    [Symbol(kHandle)]: TCP {
      reading: true,
      onconnection: null,
      _consumed: true,
      [Symbol(owner_symbol)]: [Circular]
    },
    [Symbol(kSetNoDelay)]: false,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: Timeout {
      _idleTimeout: 120000,
      _idlePrev: [TimersList],
      _idleNext: [TimersList],
      _idleStart: 5887,
      _onTimeout: [Function: bound ],
      _timerArgs: undefined,
      _repeat: null,
      _destroyed: false,
      [Symbol(refed)]: false,
      [Symbol(kHasPrimitive)]: false,
      [Symbol(asyncId)]: 11,
      [Symbol(triggerId)]: 10
    },
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0
  },
  _consuming: false,
  _dumped: false,
  next: [Function: next],
  baseUrl: '/account',
  originalUrl: '/account/needs-bootstrap',
  _parsedUrl: Url {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/needs-bootstrap',
    path: '/needs-bootstrap',
    href: '/needs-bootstrap',
    _raw: '/needs-bootstrap'
  },
  params: {},
  query: {},
  res: ServerResponse {
    _events: [Object: null prototype] { finish: [Function: bound resOnFinish] },
    _eventsCount: 1,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    _last: false,
    chunkedEncoding: false,
    shouldKeepAlive: true,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: true,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: null,
    _hasBody: true,
    _trailer: '',
    finished: false,
    _headerSent: false,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: true,
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      timeout: 120000,
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      _paused: false,
      _httpMessage: [Circular],
      [Symbol(asyncId)]: 10,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 120000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 5887,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 11,
        [Symbol(triggerId)]: 10
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    connection: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: true,
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      timeout: 120000,
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      _paused: false,
      _httpMessage: [Circular],
      [Symbol(asyncId)]: 10,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 120000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 5887,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 11,
        [Symbol(triggerId)]: 10
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _header: null,
    _keepAliveTimeout: 5000,
    _onPendingData: [Function: bound updateOutgoingData],
    _sent100: false,
    _expect_continue: false,
    req: [Circular],
    locals: [Object: null prototype] {},
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      'x-powered-by': [Array],
      'access-control-allow-origin': [Array]
    }
  },
  body: {},
  [Symbol(kCapture)]: false
}
Rejection: TypeError: res.status is not a function
    at middleware (/home/dini/actual-server/util/error-middleware.js:3:7)
    at Layer.handle [as handle_request] (/home/dini/actual-server/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/dini/actual-server/node_modules/express/lib/router/index.js:317:13)
    at /home/dini/actual-server/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/dini/actual-server/node_modules/express/lib/router/index.js:335:12)
    at next (/home/dini/actual-server/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/home/dini/actual-server/node_modules/express/lib/middleware/init.js:40:5)
    at Layer.handle [as handle_request] (/home/dini/actual-server/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/dini/actual-server/node_modules/express/lib/router/index.js:317:13)
    at /home/dini/actual-server/node_modules/express/lib/router/index.js:284:7

Any clues on what I might be doing wrong?

Importing or Creating a New File overwites all the budget files to be the same

I'm trying out actual budget so I can move away from YNAB. I created a Test Budget to play with and it was looking good, so I downloaded my YNAB budget and imported it into actual budget. Then when I went into my Test Budget again it had all of the info that I imported from my YNAB Budget. I then created a New FIle and when I went into my YNAB Budget and my Test Budget, all of the info was gone and it was showing like a brand new File for all three of the budgets that I have.

I am running this on unRaid and I created a path for data persistance like the instructions say to do. Any help is greatly appreciated.

Docs for docker not quite alright

So, I'm not shy from using command-line, but I'd love to see that easy one button setup thing.

For now, the path that most appealed to me was using docker-compose, even more so because I could easily map out the user-files directory to somewhere else I have already set up as personal backup.

Since the docker-compose way mentions a Dockerfile, I figured it must be on the github somewhere and voilá, found it nicely.

https://github.com/actualbudget/actual-server/raw/master/docker/edge-alpine.Dockerfile

image

docker-compose.yml is the same as the docs:

image

But that gave me an error:

$ docker-compose --env-file .env up -d
Creating network "actual-server_default" with the default driver
Building actual_server
Sending build context to Docker daemon  4.608kB
Step 1/15 : FROM alpine:3.17 as base
3.17: Pulling from library/alpine
63b65145d645: Pull complete
Digest: sha256:ff6bdca1701f3a8a67e328815ff2346b0e4067d32ec36b7992c1fdc001dc8517
Status: Downloaded newer image for alpine:3.17
(...)
Removing intermediate container 716829f59e2d
 ---> 7aad3eb6c1f8
Step 4/15 : ADD .yarn ./.yarn
ADD failed: file not found in build context or excluded by .dockerignore: stat .yarn: file does not exist
ERROR: Service 'actual_server' failed to build : Build failed

So I thought, then, I'd get back to the README.md and follow the "pure" Docker path, even though there's no easy way to back up the user-files here, but I could still check Actual out. But that gave me a different error:

image

With a link to this help page. I thought "ok, I'm using the docker version, that should be easy..." specially since there's a link there called "Activating HTTPS".

Nope, no docker guidance for activating HTTPS (I have a small old PC I put Ubuntu server on and use for storage and small stuff, which is why I'm not running on localhost).

Now, I'm not that docker-savvy, I imagine there must be a way I can generate the self-signed certificates and map/volume them into Docker, but I have absolutely no idea on how to do that and would really appreciate some help.

[Bug]: Node 19 unsupported

Moving from where I had mistakenly filed it on actualbudget/actual#726

TLDR: Sql-lite3 version ^7.5.0 is not compatible with node@19.

We could upgrade it -- it does look like better-sqlite3 on the latest version, 8.1.0, installs just fine with the latest node -- but unfortunately, there is no corresponding @types/better-sqlite3 package released yet (I have opened a discussion, though) and the latest one, 7.6.3, uses the incompatible version.

So the agreed solution in the meantime (discussed with @j-f1) could be to set the engines node version to be up to node@18 for easier debugging.

I say for easier debugging, because setting the engines version only gives a warning (or error, if used in conjunction with engineStrict if you are installing the package as a dependency) -- so this would be mostly for documentation purposes.

Upgrading to version 22.10.25 not working in Docker

Hey there,

I just tried to update to the latest version 22.10.25 of actual budget using docker Portainer. Download works fine, but after that the container stays in the state created. When trying to start the service manually I got an HTTP error 400.

Are there any breaking changes that would cause such a behavior?

I use the following docker compose

version: "3"
services:
  actual_server:
    image: jlongster/actual-server:latest
    container_name: actual_server
    ports:
      - "5006:5006"
    volumes:
      - /local_data:/data/
    restart: unless-stopped

Support for accounts with more than 100 millions

Context: Im from Colombia, a dollar is equivalent to 5000 colombian pesos. I have a mortgage of 200M pesos.

Problem, when I create a mortgage with value 214'390720 I'm receiving this error

"[Exception] Error: Can't convert to integer: 21439072000"

Note the additional two 0s at the end

Memory issue with Fly

I have received an email from Fly telling me that Actual crashed because it ran out of memory, if I increase the memory on Fly I will of course be outside the free tier.

I am unclear as to whether this is a bug in Actual or whether others are going to find that the free allocation of memory on Fly will be insufficient long term.

I think the out or memory occurs when downloading for the first time (or when restoring from an exported file).

Unable to build via docker-compose from latest tag (23.3.1)

I tried to build the latest release using the following command docker-compose --env-file $envFile build actual_server.
The build was not successful, I received the following error:

[+] Building 0.2s (2/2) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                            0.1s
 => => transferring dockerfile: 68B                                                                                                                             0.0s 
 => [internal] load .dockerignore                                                                                                                               0.0s
 => => transferring context: 188B                                                                                                                               0.0s 
failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: dockerfile parse error line 1: unknown instruction: DOCKER/STABLE-UBUNTU.DOCKERFILE

This issue does not occur if I build from tag 23.2.9.

Github Container Registry URL 404

The available ghcr.io/actualbudget/actual-server url doesn't seem to be working as it 404s for docker pull. The jlongster/actual-server reference does, at least.

What are the deps?

The README says to "install deps" but doesn't say what they are.

Thanks

Docker: Server ignores ENV port

I'm running Actual-server in a docker on UnRAID. I don't like it having the 5006 port, I like having my dockers on they're own IPs with the default 80 port for WebGUI, because I'm running local DNS so the program should be accesable from 'http://actual.lan'.

So the docker is set to custom IP on the 'br0' interface - when so, containers don't need port mapping (in fact its useless) so the only thing I should need to change is Actuals port. In the documentation it says that the port can be set with an environment variable 'ACTUAL_PORT' - when I set that in the docker with -e 'ACTUAL_PORT'='80' it does nothing.

How to import zip backup

I lost my budget in issue 4. I had a zip backup, but I cannot find where to import it. I only see the option to import YNAB4 and nYNAB budgets.

image

Happy to manually copy db.sqlite and metadata.json with instructions.

Crash - Running out of memory on fly.io when downloading the budget

I am trying to download my budget on a new computer but the app keeps crashing on fly.io. The only way I managed to make it work was to "sacle" the vm to 512mb for the download, then I was able to downscale it to 256 again. Any ideas why the download seems to require more memory?(which fall out of the free tier if I'm correct.)

The app will crash-loop forever with 256Mb, here is the log from fly.io

 2022-06-11T13:17:24.258 runner[7c4ae106] yyz [info] Starting virtual machine
2022-06-11T13:17:24.453 app[7c4ae106] yyz [info] Starting init (commit: e3eb6d2)...
2022-06-11T13:17:24.467 app[7c4ae106] yyz [info] Mounting /dev/vdc at /data w/ uid: 0, gid: 0 and chmod 0755
2022-06-11T13:17:24.478 app[7c4ae106] yyz [info] Preparing to run: `/usr/bin/tini -g -- node app.js` as root
2022-06-11T13:17:24.504 app[7c4ae106] yyz [info] 2022/06/11 13:17:24 listening on [fdaa:0:5f82:a7b:8a0f:0:debd:2]:22 (DNS: [fdaa::3]:53)
2022-06-11T13:17:24.506 app[7c4ae106] yyz [info] [WARN tini (523)] Tini is not running as PID 1 and isn't registered as a child subreaper.
2022-06-11T13:17:24.506 app[7c4ae106] yyz [info] Zombie processes will not be re-parented to Tini, so zombie reaping won't work.
2022-06-11T13:17:24.506 app[7c4ae106] yyz [info] To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
2022-06-11T13:17:25.224 app[7c4ae106] yyz [info] Initializing Actual with user file dir: /data/user-files
2022-06-11T13:17:25.226 app[7c4ae106] yyz [info] Listening on 0.0.0.0:5006...
2022-06-11T13:19:28.352 app[7c4ae106] yyz [info] [ 123.971282] Out of memory: Killed process 528 (node) total-vm:947256kB, anon-rss:200868kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:1420kB oom_score_adj:0
2022-06-11T13:19:28.637 app[7c4ae106] yyz [info] Main child exited normally with code: 137
2022-06-11T13:19:28.638 app[7c4ae106] yyz [info] Starting clean up.
2022-06-11T13:19:28.654 app[7c4ae106] yyz [info] Umounting /dev/vdc from /data
2022-06-11T13:19:35.681 runner[7c4ae106] yyz [info] Starting instance
2022-06-11T13:19:35.828 runner[7c4ae106] yyz [info] Configuring virtual machine
2022-06-11T13:19:35.833 runner[7c4ae106] yyz [info] Pulling container image
2022-06-11T13:19:36.032 runner[7c4ae106] yyz [info] Unpacking image
2022-06-11T13:19:36.044 runner[7c4ae106] yyz [info] Preparing kernel init
2022-06-11T13:19:36.239 runner[7c4ae106] yyz [info] Setting up volume 'actual_data'
2022-06-11T13:19:36.244 runner[7c4ae106] yyz [info] Opening encrypted volume
2022-06-11T13:19:37.599 runner[7c4ae106] yyz [info] Configuring firecracker
2022-06-11T13:19:37.638 runner[7c4ae106] yyz [info] Starting virtual machine
2022-06-11T13:19:37.807 app[7c4ae106] yyz [info] Starting init (commit: e3eb6d2)...
2022-06-11T13:19:37.829 app[7c4ae106] yyz [info] Mounting /dev/vdc at /data w/ uid: 0, gid: 0 and chmod 0755
2022-06-11T13:19:37.833 app[7c4ae106] yyz [info] Preparing to run: `/usr/bin/tini -g -- node app.js` as root
2022-06-11T13:19:37.858 app[7c4ae106] yyz [info] [WARN tini (523)] Tini is not running as PID 1 and isn't registered as a child subreaper.
2022-06-11T13:19:37.858 app[7c4ae106] yyz [info] Zombie processes will not be re-parented to Tini, so zombie reaping won't work.
2022-06-11T13:19:37.858 app[7c4ae106] yyz [info] To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
2022-06-11T13:19:37.860 app[7c4ae106] yyz [info] 2022/06/11 13:19:37 listening on [fdaa:0:5f82:a7b:8a0f:0:debd:2]:22 (DNS: [fdaa::3]:53)
2022-06-11T13:19:38.552 app[7c4ae106] yyz [info] Initializing Actual with user file dir: /data/user-files
2022-06-11T13:19:38.553 app[7c4ae106] yyz [info] Listening on 0.0.0.0:5006...
2022-06-11T13:19:45.440 app[7c4ae106] yyz [info] [ 7.702757] Out of memory: Killed process 528 (node) total-vm:913960kB, anon-rss:201324kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:1392kB oom_score_adj:0
2022-06-11T13:19:45.852 app[7c4ae106] yyz [info] Main child exited normally with code: 137
2022-06-11T13:19:45.852 app[7c4ae106] yyz [info] Starting clean up.
2022-06-11T13:19:45.867 app[7c4ae106] yyz [info] Umounting /dev/vdc from /data
2022-06-11T13:19:53.123 runner[7c4ae106] yyz [info] Starting instance
2022-06-11T13:19:53.276 runner[7c4ae106] yyz [info] Configuring virtual machine
2022-06-11T13:19:53.284 runner[7c4ae106] yyz [info] Pulling container image
2022-06-11T13:19:53.486 runner[7c4ae106] yyz [info] Unpacking image
2022-06-11T13:19:53.496 runner[7c4ae106] yyz [info] Preparing kernel init
2022-06-11T13:19:53.686 runner[7c4ae106] yyz [info] Setting up volume 'actual_data'
2022-06-11T13:19:53.690 runner[7c4ae106] yyz [info] Opening encrypted volume
2022-06-11T13:19:54.868 runner[7c4ae106] yyz [info] Configuring firecracker
2022-06-11T13:19:54.922 runner[7c4ae106] yyz [info] Starting virtual machine
2022-06-11T13:19:55.106 app[7c4ae106] yyz [info] Starting init (commit: e3eb6d2)...
2022-06-11T13:19:55.124 app[7c4ae106] yyz [info] Mounting /dev/vdc at /data w/ uid: 0, gid: 0 and chmod 0755
2022-06-11T13:19:55.133 app[7c4ae106] yyz [info] Preparing to run: `/usr/bin/tini -g -- node app.js` as root
2022-06-11T13:19:55.159 app[7c4ae106] yyz [info] 2022/06/11 13:19:55 listening on [fdaa:0:5f82:a7b:8a0f:0:debd:2]:22 (DNS: [fdaa::3]:53)
2022-06-11T13:19:55.160 app[7c4ae106] yyz [info] [WARN tini (523)] Tini is not running as PID 1 and isn't registered as a child subreaper.
2022-06-11T13:19:55.160 app[7c4ae106] yyz [info] Zombie processes will not be re-parented to Tini, so zombie reaping won't work.
2022-06-11T13:19:55.161 app[7c4ae106] yyz [info] To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
2022-06-11T13:19:55.840 app[7c4ae106] yyz [info] Initializing Actual with user file dir: /data/user-files
2022-06-11T13:19:55.841 app[7c4ae106] yyz [info] Listening on 0.0.0.0:5006... 

Transition to typescript

I'm assuming this is still part of the plan based on this. I setup a solid chunk of the infrastructure in a fork, but I do have some questions. Both docker builds have been updated and seem to be working in my limited testing.

Running locally without docker feels a little convoluted as I currently have it set up. There's only one extra command, but atm I'm copying node_modules and that feels...odd. Including something like ts-node would let us JIT compile any typescript and avoid the current inconvenience, but I didn't want to introduce that dependency (even if it's only for local runs) without some sort of consensus.

Should I go ahead and open a PR now and discuss it there?

Missing Blob File

Hello,

For some reason I can no longer open my budget. The budget is there but when I click to open it I get the browser error below:

image

In the logs I get the error:

Error: file does not exist: /app/user-files/file-3a04f6bc-7621-4447-b13b-5ca41aae93b6.blob

When I list that directory effectively the file does not exist. What does exist is a directory with the same id.

Ran a git pull but was already on latest. Deleted the container and the image and built it again unsuccessfully.

Can somebody help? I'm actually surprised how dependant I am on this app.

Forgot Password

I forgot my password, I logged into the server using docker exec -ti actual-server sh, but I can't seem to find the location where the password is stored. Can anyone advice? Thanks!

SOLVED - Should Settings persist between browsers?

My preference is to show the running balance column in the accounts register and to leave the cleared/uncleared detail (top left of the account window) open. Once I have made these settings they "stick" in that particular browser although I presume they may be reset if I cleared the cache (?).

I use a number of browsers and have to make these settings independently for each.

  1. I am just wondering if it is technically possibly for these settings choices to be saved for the Actual web app itself, rather than just in each browser.
  2. How-about an override to save these settings for all Accounts? I had to go through 20 accounts individually and set them.
  3. A further oddity was that I did not have to select these settings for a couple of my accounts. Might this have something to do with what was already selected when I imported into Fly in the first place?

PS please forgive lack of technical knowledge/explanation.

UPDATE: I have just started a new instance of Actual in PikaPods. I imported the Actual zip file from my Fly set up with all display settings as I wanted them. I can confirm that using this export meant that my display settings DID transfer in the way I desired. I will mark this issue as Closed.

Failed due to unhealthy allocations

First of all, thanks for making Actual open source! I'm trying to set up the server, and have simply followed the guide - but I'm getting a persistent error, and I've got no idea what it is about. Here's the log:

(base) ➜  actual-server git:(master) flyctl launch
Update available 0.0.324 -> v0.0.325.
Run "flyctl version update" to upgrade.
An existing fly.toml file was found for app dry-mountain-7762
App is not running, deploy...
Deploying dry-mountain-7762
==> Validating app configuration
--> Validating app configuration done
Services
TCP 80/443 ⇢ 8080
Remote builder fly-builder-small-night-6252 ready
==> Creating build context
--> Creating build context done
==> Building image with Docker
--> docker host: 20.10.12 linux x86_64
Sending build context to Docker daemon  162.7kB
[+] Building 1.2s (16/16) FINISHED                                                              
 => [internal] load remote build context                                                   0.0s
 => copy /context /                                                                        0.1s
 => [internal] load metadata for docker.io/library/node:16-bullseye-slim                   0.9s
 => [internal] load metadata for docker.io/library/node:16-bullseye                        1.0s
 => [base 1/6] FROM docker.io/library/node:16-bullseye@sha256:dd04637efe3c13087c25a3e6049  0.0s
 => [prod 1/5] FROM docker.io/library/node:16-bullseye-slim@sha256:9ae59bd83f46c6e6b83c05  0.0s
 => CACHED [prod 2/5] RUN apt-get update && apt-get install openssl && apt-get clean -y &  0.0s
 => CACHED [prod 3/5] WORKDIR /app                                                         0.0s
 => CACHED [base 2/6] RUN apt-get update && apt-get install -y openssl                     0.0s
 => CACHED [base 3/6] RUN mkdir /app                                                       0.0s
 => CACHED [base 4/6] WORKDIR /app                                                         0.0s
 => CACHED [base 5/6] ADD yarn.lock package.json ./                                        0.0s
 => CACHED [base 6/6] RUN yarn install --production                                        0.0s
 => CACHED [prod 4/5] COPY --from=base /app /app                                           0.0s
 => [prod 5/5] ADD . .                                                                     0.1s
 => exporting to image                                                                     0.0s
 => => exporting layers                                                                    0.0s
 => => writing image sha256:ac63f083891c5926a14a13f7e55c29ca1915c9d1e02b2d0e5bf359f376af2  0.0s
 => => naming to registry.fly.io/dry-mountain-7762:deployment-1651347806                   0.0s
--> Building image done
==> Pushing image to fly
The push refers to repository [registry.fly.io/dry-mountain-7762]
74504ee14e6d: Pushed 
178a96aac3fa: Layer already exists 
bedfc66b6e0f: Layer already exists 
e9f244d41fd9: Layer already exists 
0baa13659589: Layer already exists 
74f7cf53c3a5: Layer already exists 
8573f1735336: Layer already exists 
afbcd854ab4c: Layer already exists 
9c1b6dd6c1e6: Layer already exists 
deployment-1651347806: digest: sha256:53085102bedad669b5f3cd7b3a2872298771b46dc65aa08d9ce5e2066a60710d size: 2206
--> Pushing image done
Image: registry.fly.io/dry-mountain-7762:deployment-1651347806
Image size: 235 MB
==> Creating release
Release v2 created

You can detach the terminal anytime without stopping the deployment
Monitoring Deployment

1 desired, 1 placed, 0 healthy, 1 unhealthy [health checks: 1 total, 1 critical]
v2 failed - Failed due to unhealthy allocations - no stable job version to auto revert to
Failed Instances

==> Failure #1

Instance
  ID            = faed62c4             
  Process       =                      
  Version       = 2                    
  Region        = lhr                  
  Desired       = run                  
  Status        = running              
  Health Checks = 1 total, 1 critical  
  Restarts      = 0                    
  Created       = 5m9s ago             

Recent Events
TIMESTAMP            TYPE       MESSAGE                 
2022-04-30T19:43:45Z Received   Task received by client 
2022-04-30T19:44:02Z Task Setup Building Task Directory 
2022-04-30T19:44:08Z Started    Task started by client  

Recent Logs
2022-04-30T19:44:04.000 [info] Starting instance
2022-04-30T19:44:05.000 [info] Configuring virtual machine
2022-04-30T19:44:05.000 [info] Pulling container image
2022-04-30T19:44:06.000 [info] Unpacking image
2022-04-30T19:44:06.000 [info] Preparing kernel init
2022-04-30T19:44:07.000 [info] Setting up volume 'actual_data'
2022-04-30T19:44:07.000 [info] Opening encrypted volume
2022-04-30T19:44:08.000 [info] Configuring firecracker
2022-04-30T19:44:08.000 [info] Starting virtual machine
2022-04-30T19:44:08.000 [info] Starting init (commit: 252b7bd)...
2022-04-30T19:44:08.000 [info] Mounting /dev/vdc at /data w/ uid: 0, gid: 0 and chmod 0755
2022-04-30T19:44:08.000 [info] Preparing to run: `docker-entrypoint.sh yarn start` as root
2022-04-30T19:44:08.000 [info] 2022/04/30 19:44:08 listening on [fdaa:0:5fa5:a7b:2809:0:df3e:2]:22 (DNS: [fdaa::3]:53)
2022-04-30T19:44:09.000 [info] yarn run v1.22.18
2022-04-30T19:44:09.000 [info] $ node app
2022-04-30T19:44:09.000 [info] Initializing Actual with user file dir: /data/user-files
2022-04-30T19:44:09.000 [info] Listening on 0.0.0.0:5006...
***v2 failed - Failed due to unhealthy allocations - no stable job version to auto revert to and deploying as v3 

Troubleshooting guide at https://fly.io/docs/getting-started/troubleshooting/
Error abort

Actual-server not accessable via nginx location reverse proxy

I have Actual-server running behind an nginx reverse proxy. If I set it up so that it serves the URL luridarc.com with root server location (/) with a proxy pass to localhost:5006, I don't have any issue accessing it via luridarc.com, but If I try and change the location being served to /budget, when I visit luridarc.com/budget, it just displays a blank white page because it is trying to load the javascript files from the luridarc.com/ location.

How can I configure the actual-server to run from the URL luridarc.com/budget so that it looks for its resources at /budget appropriately?

Actual should not require HTTPS for local traffic

It was a nice surprised to get on to add my grocery receipts to my budget and see that I couldn't access my budget locally anymore.

While I can understand the thought process of "Forced Security" for users, I really dislike the notion of being made to use an HTTPS cert just to access my locally hosted app. I personally do not, and will not, be opening my personal finances up to the world, and want to run everything locally over http for use at home. When Im out, I use a VPN to access my network and use my budget.

Its a great program, but no other selfhosted things out there I can think of (except maybe Code-Server) require a user to set up a cert for proper local access. I understand my infrastructure, and make choices around that, so Itd be great to not be limited by the application for the choices I do make regarding security.

I did read through the documentation page, but the three provided "solutions" aren't really that tenable. It should be my choice to open a service up to the wild west of the internet, and directing users (who may not understand what theyre doing) to do this, just sounds like it will end terribly. I use Wireguard as a vpn, so why should I change that just to be able to use actual at all?

Perhaps a docker environment variable, allowing the end user to choose the security 'strictness' of access could be a solution for providing that option, while leaving things available to users who don't want to go through the process of setting up a local cert, just to use their budget.

"Server is not running at this URL" when using fly.io

When using fly.io and the template toml file, the flyctl launch process works and one can access the app. However when one wants to add a server using the "use this domain" button an error occurs after a while: "Server is not running at this URL
". I have attached the fly.io logs below
logs.txt

Password Change should Invalidate token

In the /change-password endpoint, once the password is changed, it is a good practice to drop the existing token and generate a new token.

In the current scenario, the updated password will only be needed for new clients but the existing clients will continue to be able communicate.

Implementing this will force all the other clients if any to re-login with a new password.

[Bug]: Server sync fails after QFX file import

Verified issue does not already exist?

  • I have searched and found no existing issue

What happened?

Imported a QFX file into a newly-added account, and then got a popup saying sync failed and asking me to fill out this github issue.

Tried on two different machines, tried clearing cache & website data and trying again, tried downloading a different filetype from the bank (.ofx), all resulted in the same problem.

It's just 922 transactions, so not that large.

What error did you receive?

Here's what I see in the developer console:

Error: PostError: <html>

<head><title>413 Request Entity Too Large</title></head>

<body>

<center><h1>413 Request Entity Too Large</h1></center>

<hr><center>nginx/1.22.0 (Ubuntu)</center>

</body>

</html>

Where are you hosting Actual?

Docker

What browsers are you seeing the problem on?

Firefox

Operating System

Linux

Sync Issue - Response has unsupported MIME type 'application/octet-stream' expected 'application/wasm'

An ongoing issue with syncronising budgets between devices still seems to be un-resolved, when loading budget a fallback message falling back to ArrayBuffer instantiation is presented.

This initial message comes after wasm streaming compile failed: TypeError: WebAssembly: Response has unsupported MIME type 'application/octet-stream' expected 'application/wasm'

image

image

This appears to be due to an issue in Expresss - expressjs/express#3589

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements

A bump in Express version appears to resolve the issue with fallback.

Issues around sync can be found here - https://discord.com/channels/937901803608096828/937903364384096257/1006046258173059163 & here https://discord.com/channels/937901803608096828/937903364384096257/1006183778164691036 & here https://discord.com/channels/937901803608096828/937903364384096257/1006183934482190346

edge tag no longer contains all arches

Something changed within the last day because now a single tagged image no longer contains all architectures:

Actual app is blank

If attempting to open your local server results in a file download and a blank page for your Git-based deployment, run git checkout HEAD^ and re-deploy. Pull request #125 should fix the underlying issue soon, but reverting to the previous commit like that will get you back to working for now!

If you’re deploying differently, let us know here or in Discord if that approach doesn’t work for you!

landed in an un-syncable state

Was trying out this app for the first time, made like a test thingy in my local machine. Took the docker-compose file from #7 and it worked well for a while. The locally kept files synced with the docker ones, persisted between restarts as well. But after a few changes, seems like I landed in this un-syncable state where I've lost a few set of rows & this doesn't sync anymore.

Exporting and importing doesn't work as well. Any suggestions?

actual-sync-issue.mov

Note: This has nothing to do w/ the PR - I just wanted to clarify I used it NOT from master.

armv6 support

Previously i did some changes personally by changing to alpine images (debian not supporting armv6 anymore), local build, and it works on this cpu. now that this repo have officially added alpine images, please add support to armv6 cpu.

Tested using RPi zero W and running fine.

edit: on second tought, it seems that bcrypt and sqlite is not build when using github CI, thus its server is "not set up correctly"

Error: "budget directory does not exist" when using specifying ACTUAL_USER_FILES

I set ACTUAL_USER_FILES to "/data" (mentioned in the README), to be able to backup my actual-server data.

When using this setting, syncing does not work any more and I can't close the budget in the Frontend.

I used the latest docker image to run the actual-server.

The error message in the server is:

[Exception] Error: budget directory does not exist
    at loadBudget (/app/node_modules/@actual-app/api/app/bundle.api.js:57516:83)
    at async module.exports../packages/loot-core/src/server/main.js.handlers.load-budget (/app/node_modules/@actual-app/api/app/bundle.api.js:57251:13)
error SELECT timestamp, dataset, row, column, value FROM messages_crdt WHERE timestamp > ?
Rejection: TypeError: Cannot read properties of undefined (reading 'prepare')
    at Module.runQuery (/app/node_modules/@actual-app/api/app/bundle.api.js:45806:41)
    at Module.runQuery (/app/node_modules/@actual-app/api/app/bundle.api.js:54349:82)
    at getMessagesSince (/app/node_modules/@actual-app/api/app/bundle.api.js:61540:54)
    at Object.syncAndReceiveMessages (/app/node_modules/@actual-app/api/app/bundle.api.js:61543:29)
    at syncAPI (/app/sync-full.js:30:45)

Not listening on all addresses by default

The hostname in the default configuration is 0.0.0.0 which will only listen on all available IPv4 addresses. This means the default configuration will not work in IPv6 only environments and work only unreliably in dual stack environments (such as many hosting providers).

The hostname in the default configuration should be changed to :: which will listen on both IP stacks. The notation might suggest that this would make it IPv6 only but this is not the case.

How to connect from mobile app

I downloaded the mobile Actual App from Play Store. It seems to connecting directly to Actual Cloud Servers. How can I change it, so that it points to my selfhosted server instance?

Unable to do anything after update.

Running Actual-Server in docker.
After updating nothing is working. Server showing offline. File won't load.
Getting this error in the logs:

Rejection: TypeError: res.status is not a function at middleware (/app/util/error-middleware.js:3:7) at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/app/node_modules/express/lib/router/index.js:317:13) at /app/node_modules/express/lib/router/index.js:284:7 at Function.process_params (/app/node_modules/express/lib/router/index.js:335:12) at next (/app/node_modules/express/lib/router/index.js:275:10) at expressInit (/app/node_modules/express/lib/middleware/init.js:40:5) at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/app/node_modules/express/lib/router/index.js:317:13) at /app/node_modules/express/lib/router/index.js:284:7

[Feature] Automatic (scheduled) backups

Verified feature request does not already exist?

  • I have searched and found no existing issue

💻

  • Would you like to implement this feature?

Pitch: what problem are you trying to solve?

I'm currently backing up my Actual file(s) manually via the web UI (Settings > Export Data), which appears to be the only method to do so.

Describe your ideal solution to this problem

The backups could be (optionally?) automatic. I personally am running Actual in a container, so it would be sufficient to write them out to /data or some other mountable location. Other environments may need other consideration.

Teaching and learning

This page could use some updates once this feature lands:

https://actualbudget.github.io/docs/Backup-Restore/Backups

The Settings UI could also guide the user on how to configure automatic backups, or what the default behaviors are.

Release Notes

I would like to update to 22.12.9 but I haven't been able to find any release notes for this version. Could someone point me to where the release notes are? If there are none, they should be added so that people know what to expect when they update.

Irreparable "Your data is out of sync" when using account on multiple devices.

👋 Not sure if this is a dupe of #23, so filing separately just in case.

Setup

I'm currently running Actual on a GCP instance, using this Dockerfile as part of a larger docker-compose, at this hash: 44d045f. Nothing seems to have been merged into master since then that would impact this.

Steps to reproduce

  1. Open web UI on two distinct devices, downloading the same account.
  2. On device A, add a new transaction.

Problematic behavior

On device B, you'll get this error on next sync (or load) even. Note that you don't need to add or change anything on B.

a

If you press repair:

b

Expected behavior

I expected to be able to sync and work on an account across multiple devices, given the CRDT logic.

Applying prettier

The repo contains a prettier config and relevant infrastructure, but actually running prettier (eg npx prettier -c .) produces a decent sized list of discrepancies.

Is there a desire to fix prettier's list of complaints? Purely style changes are super noisy imo, so I'm not making any assumptions about the plan.

We've also added eslint-plugin-prettier, but the prettier rule isn't enabled (and thus eslint doesn't actually produce notices for any prettier specific problems).

Error: file does not exist: /data/user-files/file-***.blob

After upgrading to 22.12.9 I get the above error after signing in from a new browser. I am using docker with the following compose:

version: "3"
services:
  budge:
    image: ***/actual-server:latest
    container_name: actual-budget
    volumes:
      - data:/data
    restart: unless-stopped


volumes:
  data:

Checking the filesystem, I don't see the blob file, but I do see the a directory of the same name. If I go back to the previous version (22.10.25 I think), it works fine. If I sync the client after updating, I get the same error after signing out.

Error on fresh install: Server does not look like an Actual server. Is it set up correctly?

Apologies if I'm missing something obvious, I wanted to try to get this to work so that I can access my file from each device on my network.

I followed the quick guide to get it up and running inside of a linux container. but it seems that for some odd reason it can't find itself. Following the instructions in "Configuring the server URL" leads to a confusing error message in the client: Server does not look like an Actual server. Is it set up correctly?

The container sits behind an nginx reverse proxy and is accessible from a custom domain name within my personal network, the names resolve just fine both inside and outside the container. But I've also tried using the actual IP of the reverse proxy and even the IP of the container itself, to no avail. Even in connecting directly to the container's IP and putting that IP into the input.

The nodejs app also spits out this error in stdout:

Oct 18 10:34:55 actual yarn[878]: ERROR Error: Could not locate the bindings file. Tried:
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/build/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/build/Debug/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/build/Release/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/out/Debug/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/Debug/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/out/Release/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/Release/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/build/default/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/compiled/18.11.0/linux/x64/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/addon-build/release/install-root/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/addon-build/debug/install-root/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/addon-build/default/install-root/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:  → /root/actual-server/node_modules/better-sqlite3/lib/binding/node-v108-linux-x64/better_sqlite3.node
Oct 18 10:34:55 actual yarn[878]:     at bindings (/root/actual-server/node_modules/bindings/bindings.js:126:9)
Oct 18 10:34:55 actual yarn[878]:     at new Database (/root/actual-server/node_modules/better-sqlite3/lib/database.js:48:64)
Oct 18 10:34:55 actual yarn[878]:     at openDatabase (/root/actual-server/db.js:38:30)
Oct 18 10:34:55 actual yarn[878]:     at getAccountDb (/root/actual-server/account-db.js:17:17)
Oct 18 10:34:55 actual yarn[878]:     at /root/actual-server/app-account.js:25:19
Oct 18 10:34:55 actual yarn[878]:     at Layer.handle [as handle_request] (/root/actual-server/node_modules/express/lib/router/layer.js:95:5)
Oct 18 10:34:55 actual yarn[878]:     at next (/root/actual-server/node_modules/express/lib/router/route.js:137:13)
Oct 18 10:34:55 actual yarn[878]:     at Route.dispatch (/root/actual-server/node_modules/express/lib/router/route.js:112:3)
Oct 18 10:34:55 actual yarn[878]:     at Layer.handle [as handle_request] (/root/actual-server/node_modules/express/lib/router/layer.js:95:5)
Oct 18 10:34:55 actual yarn[878]:     at /root/actual-server/node_modules/express/lib/router/index.js:281:22 {
Oct 18 10:34:55 actual yarn[878]:   tries: [
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/build/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/build/Debug/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/build/Release/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/out/Debug/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/Debug/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/out/Release/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/Release/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/build/default/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/compiled/18.11.0/linux/x64/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/addon-build/release/install-root/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/addon-build/debug/install-root/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/addon-build/default/install-root/better_sqlite3.node',
Oct 18 10:34:55 actual yarn[878]:     '/root/actual-server/node_modules/better-sqlite3/lib/binding/node-v108-linux-x64/better_sqlite3.node'
Oct 18 10:34:55 actual yarn[878]:   ]
Oct 18 10:34:55 actual yarn[878]: }

My knowledge of nodejs is zero but I'm assuming this is the actual reason behind why I'm unable to connect? Any ideas of what I can do to fix this? Thanks.

Who to contact for security issues

Hello 👋

I run a security community that finds and fixes vulnerabilities in OSS. A researcher (@rootd4ddy) has found a potential issue, which I would be eager to share with you.

Could you add a SECURITY.md file with an e-mail address for me to send further details to? GitHub recommends a security policy to ensure issues are responsibly disclosed, and it would help direct researchers in the future.

Looking forward to hearing from you 👍

(cc @huntr-helper)

Fly.io deployment is not working.

Hi, I've followed your guidelines to deploy the app to fly.io but the app is not responding. Health check is failing and I see the connection refused errors below when I try to open the URL. Am I missing something?

2023-02-16T03:02:27.348 app[ed63d73f] lhr [info] Starting init (commit: 617e840)...

2023-02-16T03:02:27.379 app[ed63d73f] lhr [info] Mounting /dev/vdc at /data w/ uid: 0, gid: 0 and chmod 0755

2023-02-16T03:02:27.384 app[ed63d73f] lhr [info] Preparing to run: `/usr/bin/tini -g -- node app.js` as root

2023-02-16T03:02:27.411 app[ed63d73f] lhr [info] 2023/02/16 03:02:27 listening on [fdaa:1:566d:a7b:8f:4:eccd:2]:22 (DNS: [fdaa::3]:53)

2023-02-16T03:02:27.412 app[ed63d73f] lhr [info] [WARN tini (529)] Tini is not running as PID 1 and isn't registered as a child subreaper.

2023-02-16T03:02:27.412 app[ed63d73f] lhr [info] Zombie processes will not be re-parented to Tini, so zombie reaping won't work.

2023-02-16T03:02:27.412 app[ed63d73f] lhr [info] To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.

2023-02-16T03:02:28.191 app[ed63d73f] lhr [info] Listening on :::5006...

2023-02-16T03:02:28.944 proxy[ed63d73f] lhr [error] instance refused connection

2023-02-16T03:02:33.101 proxy[ed63d73f] lhr [warn] Could not proxy HTTP request. Retrying in 1000 ms (attempt 10)

2023-02-16T03:02:39.665 proxy[ed63d73f] lhr [error] instance refused connection

2023-02-16T03:02:43.914 proxy[ed63d73f] lhr [warn] Could not proxy HTTP request. Retrying in 1000 ms (attempt 10)

2023-02-16T03:02:49.845 proxy[ed63d73f] lhr [error] instance refused connection

2023-02-16T03:02:53.783 proxy[ed63d73f] lhr [warn] Could not proxy HTTP request. Retrying in 1000 ms (attempt 20)

Accounts get mixed up when syncing multiple files

Steps to reproduce:

  1. create file 1, add some accounts, close file 1

  2. create file 2, add some accounts, close file 2

  3. open file 1: file 1 now only shows the accounts that are defined in file 2

  4. close file 1, open file 2: file 2 still shows the accounts defined in file 2, but shows the name of file 1 in the upper left corner

  5. close file 2, "delete file 2 locally", "delete file 2 from all devices", "clear site data" in Chrome dev tools

  6. login to actual again

  7. open file 1: file 1 now shows ALL accounts from file 1 and the deleted file 2, upper left corner still shows the name of deleted file 2

OS: macOS 12.3.1 on arm64
Browser: Google Chrome v100.0.4896.127 and v101.0.4951.41

Option to disable sync

Is there an option to disable the sync feature?

I would prefer to keep the data locally and use my own method of backup.

Edit: I may have misinterpreted the text in the documentation about cloud syncing

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.