Can't upgrade after installing new docker image

I’m trying to reinstall control on some new hardware. I can bring it up, but under Settings/General, I don’t see an option to upgrade to the latest version. Any idea what could be going wrong?

I’m getting a whole bunch of Alta API Back-End crashes such as:
POST /fe/oops
SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse ()
at /usr/share/access/be/access.js:2:1959910
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /usr/share/access/be/access.js:2:1947417
at async y.pgPool (/usr/share/access/be/access.js:2:2017501)
at async t.handler (/usr/share/access/be/access.js:2:1947399)

Please try entering the container shell and running apt update && apt upgrade.

I’m trying that now. I Some of my confusion was because after activating, I was redirected to the cloud based controller. The API crashes then happened when I tried logging into the locally hosted version.

The upgrade seems stuck at:
Setting up postgresql-common (274.pgdg22.04+1) …
Replacing config file /etc/postgresql-common/createcluster.conf with new version

Progress: [ 89%] [###################################################…]

I’m going to try exporting the working control container and then reimporting it to the new hardware..

I gave up on exporting and importing docker image. Seemed too complicated without knowing entrypoint of image etc.
I got further by doing:
apt-get install --only-upgrade access
This upgraded access to 1.0y
When I tried logging in though, I didn’t get an API crash, but it wouldn’t accept my user/password (with which I can successfully login on old hardware). I saw this in syslog (my plaintext password x’d out):

jhahn@snail:~$ sudo docker exec -it control /usr/bin/bash
root@91ddd3663470:/# tail -f /var/log/syslog
Mar 29 18:40:33 91ddd3663470 access[512]: Alta running on port 3001
Mar 29 18:40:33 91ddd3663470 access[512]: ws mqtt server on port 3101
Mar 29 18:40:33 91ddd3663470 systemd[1]: dmesg.service: Deactivated successfully.
Mar 29 18:40:33 91ddd3663470 access[512]: alta cert expires in  89.95069480324074 days
Mar 29 18:40:33 91ddd3663470 access[512]: syncing IPs
Mar 29 18:40:34 91ddd3663470 access[512]: mqtt connected @PPluusPjH4KQpL2juFtqp
Mar 29 18:40:35 91ddd3663470 systemd[1]: postgresql@15-main.service: New main PID 128 does not belong to service, and PID file is not owned by root. Refusing.
Mar 29 18:40:35 91ddd3663470 systemd[1]: postgresql@15-main.service: New main PID 128 does not belong to service, and PID file is not owned by root. Refusing.
Mar 29 18:40:38 91ddd3663470 systemd[1]: NetworkManager-dispatcher.service: Deactivated successfully.
Mar 29 18:40:58 91ddd3663470 systemd[1]: systemd-hostnamed.service: Deactivated successfully.
Mar 29 18:41:33 91ddd3663470 access[512]: Event: {"eventType":"1minute"}
Mar 29 18:42:00 91ddd3663470 access[512]: START RequestId: eeded4e0-af10-cc6c-8647-1d110781b180
Mar 29 18:42:00 91ddd3663470 access[512]: event is i {
Mar 29 18:42:00 91ddd3663470 access[512]:   options: {
Mar 29 18:42:00 91ddd3663470 access[512]:     timeoutInSeconds: 10,
Mar 29 18:42:00 91ddd3663470 access[512]:     reconfigure: [Function: reconfigure],
Mar 29 18:42:00 91ddd3663470 access[512]:     req: IncomingMessage {
Mar 29 18:42:00 91ddd3663470 access[512]:       _readableState: [ReadableState],
Mar 29 18:42:00 91ddd3663470 access[512]:       _events: [Object: null prototype] {},
Mar 29 18:42:00 91ddd3663470 access[512]:       _eventsCount: 0,
Mar 29 18:42:00 91ddd3663470 access[512]:       _maxListeners: undefined,
Mar 29 18:42:00 91ddd3663470 access[512]:       socket: [Socket],
Mar 29 18:42:00 91ddd3663470 access[512]:       httpVersionMajor: 1,
Mar 29 18:42:00 91ddd3663470 access[512]:       httpVersionMinor: 1,
Mar 29 18:42:00 91ddd3663470 access[512]:       httpVersion: '1.1',
Mar 29 18:42:00 91ddd3663470 access[512]:       complete: true,
Mar 29 18:42:00 91ddd3663470 access[512]:       rawHeaders: [Array],
Mar 29 18:42:00 91ddd3663470 access[512]:       rawTrailers: [],
Mar 29 18:42:00 91ddd3663470 access[512]:       joinDuplicateHeaders: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       aborted: false,
Mar 29 18:42:00 91ddd3663470 access[512]:       upgrade: false,
Mar 29 18:42:00 91ddd3663470 access[512]:       url: '/api/account/login',
Mar 29 18:42:00 91ddd3663470 access[512]:       method: 'POST',
Mar 29 18:42:00 91ddd3663470 access[512]:       statusCode: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       statusMessage: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       client: [Socket],
Mar 29 18:42:00 91ddd3663470 access[512]:       _consuming: true,
Mar 29 18:42:00 91ddd3663470 access[512]:       _dumped: false,
Mar 29 18:42:00 91ddd3663470 access[512]:       next: [Function: T],
Mar 29 18:42:00 91ddd3663470 access[512]:       baseUrl: '',
Mar 29 18:42:00 91ddd3663470 access[512]:       originalUrl: '/api/account/login',
Mar 29 18:42:00 91ddd3663470 access[512]:       _parsedUrl: [Url],
Mar 29 18:42:00 91ddd3663470 access[512]:       params: [Object],
Mar 29 18:42:00 91ddd3663470 access[512]:       query: {},
Mar 29 18:42:00 91ddd3663470 access[512]:       res: [ServerResponse],
Mar 29 18:42:00 91ddd3663470 access[512]:       body: [Object],
Mar 29 18:42:00 91ddd3663470 access[512]:       _body: true,
Mar 29 18:42:00 91ddd3663470 access[512]:       length: undefined,
Mar 29 18:42:00 91ddd3663470 access[512]:       route: [p],
Mar 29 18:42:00 91ddd3663470 access[512]:       [Symbol(kCapture)]: false,
Mar 29 18:42:00 91ddd3663470 access[512]:       [Symbol(kHeaders)]: [Object],
Mar 29 18:42:00 91ddd3663470 access[512]:       [Symbol(kHeadersCount)]: 42,
Mar 29 18:42:00 91ddd3663470 access[512]:       [Symbol(kTrailers)]: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       [Symbol(kTrailersCount)]: 0
Mar 29 18:42:00 91ddd3663470 access[512]:     },
Mar 29 18:42:00 91ddd3663470 access[512]:     startTime: 1743273720936,
Mar 29 18:42:00 91ddd3663470 access[512]:     awsRequestId: 'eeded4e0-af10-cc6c-8647-1d110781b180',
Mar 29 18:42:00 91ddd3663470 access[512]:     accountId: '123456789012'
Mar 29 18:42:00 91ddd3663470 access[512]:   },
Mar 29 18:42:00 91ddd3663470 access[512]:   body: '{"email":"jack-alta@dancingsnails.com","password":"xxxxxxxxxxxx"}',
Mar 29 18:42:00 91ddd3663470 access[512]:   path: '/api/account/login',
Mar 29 18:42:00 91ddd3663470 access[512]:   httpMethod: 'POST',
Mar 29 18:42:00 91ddd3663470 access[512]:   pathParameters: { '0': 'api/account/login' },
Mar 29 18:42:00 91ddd3663470 access[512]:   stageVariables: null,
Mar 29 18:42:00 91ddd3663470 access[512]:   resource: '/{proxy+}',
Mar 29 18:42:00 91ddd3663470 access[512]:   isBase64Encoded: false,
Mar 29 18:42:00 91ddd3663470 access[512]:   headers: {
Mar 29 18:42:00 91ddd3663470 access[512]:     connection: 'upgrade',
Mar 29 18:42:00 91ddd3663470 access[512]:     host: 'local.lp4fhdp5uw6.ddns.manage.alta.inc',
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-mamba-auth': 'AvOz_dk30Jc',
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-forwarded-proto': 'https',
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-forwarded-for': '192.168.2.207',
Mar 29 18:42:00 91ddd3663470 access[512]:     'content-length': '68',
Mar 29 18:42:00 91ddd3663470 access[512]:     'user-agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0',
Mar 29 18:42:00 91ddd3663470 access[512]:     accept: '*/*',
Mar 29 18:42:00 91ddd3663470 access[512]:     'accept-language': 'en-US,en;q=0.5',
Mar 29 18:42:00 91ddd3663470 access[512]:     'accept-encoding': 'gzip, deflate, br, zstd',
Mar 29 18:42:00 91ddd3663470 access[512]:     referer: 'https://local.lp4fhdp5uw6.ddns.manage.alta.inc/',
Mar 29 18:42:00 91ddd3663470 access[512]:     'content-type': 'application/json',
Mar 29 18:42:00 91ddd3663470 access[512]:     'real-agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0',
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-aver': '3205de6e',
Mar 29 18:42:00 91ddd3663470 access[512]:     origin: 'https://local.lp4fhdp5uw6.ddns.manage.alta.inc',
Mar 29 18:42:00 91ddd3663470 access[512]:     dnt: '1',
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-gpc': '1',
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-fetch-dest': 'empty',
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-fetch-mode': 'cors',
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-fetch-site': 'same-origin',
Mar 29 18:42:00 91ddd3663470 access[512]:     priority: 'u=0'
Mar 29 18:42:00 91ddd3663470 access[512]:   },
Mar 29 18:42:00 91ddd3663470 access[512]:   multiValueHeaders: {
Mar 29 18:42:00 91ddd3663470 access[512]:     connection: [ 'upgrade' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     host: [ 'local.lp4fhdp5uw6.ddns.manage.alta.inc' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-mamba-auth': [ 'AvOz_dk30Jc' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-forwarded-proto': [ 'https' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-forwarded-for': [ '192.168.2.207' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'content-length': [ '68' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'user-agent': [
Mar 29 18:42:00 91ddd3663470 access[512]:       'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0'
Mar 29 18:42:00 91ddd3663470 access[512]:     ],
Mar 29 18:42:00 91ddd3663470 access[512]:     accept: [ '*/*' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'accept-language': [ 'en-US', 'en;q=0.5' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'accept-encoding': [ 'gzip', ' deflate', ' br', ' zstd' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     referer: [ 'https://local.lp4fhdp5uw6.ddns.manage.alta.inc/' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'content-type': [ 'application/json' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'real-agent': [
Mar 29 18:42:00 91ddd3663470 access[512]:       'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0'
Mar 29 18:42:00 91ddd3663470 access[512]:     ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'x-aver': [ '3205de6e' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     origin: [ 'https://local.lp4fhdp5uw6.ddns.manage.alta.inc' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     dnt: [ '1' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-gpc': [ '1' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-fetch-dest': [ 'empty' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-fetch-mode': [ 'cors' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     'sec-fetch-site': [ 'same-origin' ],
Mar 29 18:42:00 91ddd3663470 access[512]:     priority: [ 'u=0' ]
Mar 29 18:42:00 91ddd3663470 access[512]:   },
Mar 29 18:42:00 91ddd3663470 access[512]:   multiValueQueryStringParameters: null,
Mar 29 18:42:00 91ddd3663470 access[512]:   queryStringParameters: null,
Mar 29 18:42:00 91ddd3663470 access[512]:   requestContext: {
Mar 29 18:42:00 91ddd3663470 access[512]:     accountId: '123456789012',
Mar 29 18:42:00 91ddd3663470 access[512]:     apiId: 'express',
Mar 29 18:42:00 91ddd3663470 access[512]:     protocol: 'http',
Mar 29 18:42:00 91ddd3663470 access[512]:     httpMethod: 'POST',
Mar 29 18:42:00 91ddd3663470 access[512]:     path: '/api/account/login',
Mar 29 18:42:00 91ddd3663470 access[512]:     stage: 'dev',
Mar 29 18:42:00 91ddd3663470 access[512]:     requestId: 'eeded4e0-af10-cc6c-8647-1d110781b180',
Mar 29 18:42:00 91ddd3663470 access[512]:     requestTimeEpoch: 1743273720936,
Mar 29 18:42:00 91ddd3663470 access[512]:     requestTime: '29/Mar/2025:18:42:00 +0000',
Mar 29 18:42:00 91ddd3663470 access[512]:     resourcePath: '/{proxy+}',
Mar 29 18:42:00 91ddd3663470 access[512]:     resourceId: 'ba76f7',
Mar 29 18:42:00 91ddd3663470 access[512]:     authorizer: { claims: {} },
Mar 29 18:42:00 91ddd3663470 access[512]:     identity: {
Mar 29 18:42:00 91ddd3663470 access[512]:       accessKey: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       accountId: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       caller: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       cognitoIdentityPoolId: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       cognitoIdentityId: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       sourceIp: '127.0.0.1',
Mar 29 18:42:00 91ddd3663470 access[512]:       cognitoAuthenticationType: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       cognitoAuthenticationProvider: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       userArn: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       userAgent: 'Custom User Agent String',
Mar 29 18:42:00 91ddd3663470 access[512]:       user: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       apiKey: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       apiKeyId: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       principalOrgId: null,
Mar 29 18:42:00 91ddd3663470 access[512]:       clientCert: null
Mar 29 18:42:00 91ddd3663470 access[512]:     }
Mar 29 18:42:00 91ddd3663470 access[512]:   }
Mar 29 18:42:00 91ddd3663470 access[512]: }
Mar 29 18:42:01 91ddd3663470 access[512]: #033[31m<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ERROR! >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#033[0m] Ae [Error]: Invalid credentials for jack-alta@dancingsnails.com
Mar 29 18:42:01 91ddd3663470 access[512]:     at ve (/usr/share/access/be/access.js:2:2131440)
Mar 29 18:42:01 91ddd3663470 access[512]:     at async /usr/share/access/be/access.js:2:2085305
Mar 29 18:42:01 91ddd3663470 access[512]:     at async /usr/share/access/be/access.js:2:2080855
Mar 29 18:42:01 91ddd3663470 access[512]:     at async h.pgPool (/usr/share/access/be/access.js:2:2184427)
Mar 29 18:42:01 91ddd3663470 access[512]:     at async t.handler (/usr/share/access/be/access.js:2:2080837) {
Mar 29 18:42:01 91ddd3663470 access[512]:   userError: true
Mar 29 18:42:01 91ddd3663470 access[512]: }
Mar 29 18:42:01 91ddd3663470 access[512]: End - Result:
Mar 29 18:42:01 91ddd3663470 access[512]: "Invalid credentials for jack-alta@dancingsnails.com"
Mar 29 18:42:33 91ddd3663470 access[512]: Event: {"eventType":"1minute"}



I suspect I should be asking how should we be moving a self hosted control to new hardware.

I did manage to move the docker image. I stopped, exported and then imported it to the new hardware. I added “command: /sbin/init” to the yaml file. That seems to work. Is that a reasonable way of doing this?

services:
  control:
    image: mycontrol
    command: /sbin/init
    container_name: control
    networks:
      control_net:
        ipv4_address: <my old control ip>
        mac_address: <my old control mac address>
    tmpfs:
      - /run
      - /run/lock
    volumes:
      - /sys/fs/cgroup/access.scope:/sys/fs/cgroup:rw
    extra_hosts:
      - local.manage.alta.inc:0.0.0.255
    cgroup: host
    security_opt:
      - seccomp=unconfined
    tty: true
    stdin_open: true
    restart: unless-stopped
networks:
  control_net:
    external: true

I think that is fine, but I don’t personally understand why you needed to add a command. If it works, though.

docker export doesn’t export metadata. It just flattens and exports the filesystem. Thus, you need to re-specify any startup commands.