How do I use env.DATABASE_URL with Loopback in Heroku? - heroku

I've removed datasources.json and added a datasources.local.js file.
var postgresURI = process.env.DATABASE_URL;
module.exports = {
db: {
defaultForType: 'postgresql',
connector: 'postgresql',
url: postgresURI
}
};
In model-config.json I have "dataSource": "db" set for all sections.
It throws the following error: User is referencing a dataSource that does not exist: "db".
I understand the error but not why it's being thrown. What I am doing wrong?

As documentation says:
You can override values set in datasources.json in the following files: datasources.local.js or datasources.local.json
So instead of removing datasources.json you might want to keep it with a declaration of "db" in it. While in "datasources.local.js" you need to override environment specific setting which is the url.

Related

Setting the Symfony session storage factory

I'm using Symfony 6 to refactor a CodeIgniter 3 framework. User logging in is done via CodeIgniter so I'd like to read the CI session data (stored in a DB) in Symfony.
I'm trying to use my own session storage factory because the CI session name is dynamically constructed using the hostname and also because of the way CI stores the session in the db is different to Symfony.
I've set the session storage factory in framework.yaml
# config/packages/framework.yaml
session:
storage_factory_id: App\Service\CINativeSessionStorageFactory
And I've configured my services (including my own PDO session handler):
# config/services.yaml
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
bind: # defines the scalar arguments once and apply them to any service defined/created in this file
string $locales: '%app_locales%'
string $defaultLocale: '%locale%'
string $emailSender: '%app.notifications.email_sender%'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/Tests/'
# CodeIgniter Session handler
App\Service\CIPdoSessionHandler:
arguments:
- '%env(DATABASE_URL)%'
- {
db_table: 'ci_sessions',
db_id_col: 'id',
db_data_col: 'data',
db_time_col: 'timestamp',
db_lifetime_col: 'sess_lifetime'
}
properties:
logger: '#logger'
tags:
- { name: monolog.logger, channel: session }
App\Service\CINativeSessionStorageFactory:
arguments:
$handler : '#App\Service\CIPdoSessionHandler'
$options : {
cookie_secure: auto,
cookie_samesite: lax,
gc_maxlifetime: 7200
}
tags:
- { name: monolog.logger, channel: session }
However I am getting these errors in the logs:
[2022-11-30T17:32:16.738059+00:00] php.CRITICAL: Fatal Compile Error: Cannot declare class App\Service\CINativeSessionStorageFactory, because the name is already in use {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Compile Error: Cannot declare class App\\Service\\CINativeSessionStorageFactory, because the name is already in use at /workspace/symfony/src/Service/CINativeSessionStorageFactory.php:16)"} []
[2022-11-30T17:32:16.739841+00:00] request.CRITICAL: Uncaught PHP Exception Symfony\Component\ErrorHandler\Error\FatalError: "Compile Error: Cannot declare class App\Service\CINativeSessionStorageFactory, because the name is already in use" at /workspace/symfony/src/Service/CINativeSessionStorageFactory.php line 16 {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Compile Error: Cannot declare class App\\Service\\CINativeSessionStorageFactory, because the name is already in use at /workspace/symfony/src/Service/CINativeSessionStorageFactory.php:16)"} []
[2022-11-30T17:32:16.741681+00:00] session.DEBUG: Using App\Service\CIPdoSessionHandler [] []
[2022-11-30T17:32:16.741839+00:00] session.DEBUG: Setting session name to ci_session_XXXXXXX [] []
The last two lines indicate that my storage factory is working (at least partially) so I'm unsure as why I'm getting these errors.
The first part of my question is: Where am I going wrong?
As an aside, I noticed that if I set up my framework.yaml like this:
# config/packages/framework.yaml
session:
handler_id: App\Service\CIPdoSessionHandler
storage_factory_id: App\Service\CINativeSessionStorageFactory
Then the handler passed to my constructor was always null
public function __construct(array $options = [], AbstractProxy|\SessionHandlerInterface $handler = null, MetadataBag $metaBag = null, bool $secure = false)
{
// $handler is null!
So the second part of my question is: Do handler_id and storage_factory_id not work together?
Some additional information from trying to debug this issue:
If I save config/services.yaml and then refresh the page - I don't get this message.
If I then refresh the page again - I get the error message.
If I then save config/services.yaml again and refresh the page - I don't get this message
... etc
Is my installation broken? I followed the steps here : https://symfony.com/doc/current/setup.html

CDK/CloudFormation Batch Setup NotStabilized Error

I'm trying to set up a simple Batch Compute Environment using a LaunchTemplate, so that I can specify a larger-than-default volume size:
const templateName = 'my-template'
const jobLaunchTemplate = new ec2.LaunchTemplate(stack, 'Template', {
launchTemplateName: templateName,
blockDevices: [ ..vol config .. ]
})
const computeEnv = new batch.CfnComputeEnvironment(stack, 'CompEnvironment', {
type: 'managed',
computeResources: {
instanceRole: jobRole.roleName,
instanceTypes: [
InstanceType.of(InstanceClass.C4, InstanceSize.LARGE).toString()
],
maxvCpus: 64,
minvCpus: 0,
desiredvCpus: 0,
subnets: vpc.publicSubnets.map(sn => sn.subnetId),
securityGroupIds: [vpc.vpcDefaultSecurityGroup],
type: 'EC2',
launchTemplate: {
launchTemplateName: templateName,
}
},
})
They both initialize fine when not linked, however as soon as the launchTemplate block is added to the compute environment, I get the following error:
Error: Resource handler returned message: "Resource of type 'AWS::Batch::ComputeEnvironment' with identifier 'compute-env-arn' did not stabilize." (RequestToken: token, HandlerErrorCode: NotStabilized)
Any suggestions are greatly appreciated, thanks in advance!
For anyone running into this - check the resource that is being created in the AWS Console - i.e go to aws.amazon.com and refresh the page over and over until you see it created by CF. This gave me a different error message regarding the instance profile not existing (A bit more helpful than the terminal error...)
A simple CfnInstanceProfile did the trick:
new iam.CfnInstanceProfile(stack, "batchInstanceProfile", {
instanceProfileName: jobRole.roleName,
roles: [jobRole.roleName],
});
I faced similar error.
But in my case cdk had created subnetGroups list in cdk.context.json and was trying to use the same in the CfnComputeEnvironment definition.
The problem was; I was using the default vpc and had manually modified few subnets. and cdk.context.json was not updated.
Solved by deleting the cdk.context.json
This file was recreated with correct values in next synth.
Tip for others facing similar problem:
Don't just rely on the error message; watch closely the Cloud-formation Script that's generated from CDK for the resource.

"Error: Unknown dialect undefined" when deploying Strapi 4.0 app to Heroku

I created a Strapi app using the latest version, the new 4.0 and I wanted to deploy it to Heroku. I did follow the Strapi documentation in order to do so, like explained in this page. Now I'm getting an error that I don't understand, I guess it has something to do with postgres. This is the error
2021-12-18T15:26:26.658380+00:00 app[web.1]: [2021-12-18 15:26:26.656] debug: ⛔️ Server wasn't able to start properly.
2021-12-18T15:26:26.659122+00:00 app[web.1]: [2021-12-18 15:26:26.658] error: Unknow dialect undefined
2021-12-18T15:26:26.659123+00:00 app[web.1]: Error: Unknow dialect undefined
2021-12-18T15:26:26.659123+00:00 app[web.1]: at getDialectClass (/app/node_modules/#strapi/database/lib/dialects/index.js:12:13)
2021-12-18T15:26:26.659123+00:00 app[web.1]: at getDialect (/app/node_modules/#strapi/database/lib/dialects/index.js:19:23)
2021-12-18T15:26:26.659124+00:00 app[web.1]: at new Database (/app/node_modules/#strapi/database/lib/index.js:38:20)
2021-12-18T15:26:26.659124+00:00 app[web.1]: at Function.Database.init (/app/node_modules/#strapi/database/lib/index.js:84:33)
2021-12-18T15:26:26.659125+00:00 app[web.1]: at Strapi.bootstrap (/app/node_modules/#strapi/strapi/lib/Strapi.js:347:30)
2021-12-18T15:26:26.659125+00:00 app[web.1]: at Strapi.load (/app/node_modules/#strapi/strapi/lib/Strapi.js:410:16)
2021-12-18T15:26:26.659125+00:00 app[web.1]: at async Strapi.start (/app/node_modules/#strapi/strapi/lib/Strapi.js:161:9)
Apart from doing what is explained in the docs I linked, I just added a few collections using the UI in development mode. How can I fix this error and deploy to Heroku this new 4.0 version of Strapi?
I had a similar issue when I was connecting pg locally and then realised my connection config was incorrect. When I replaced it with v4 template it worked.
path: config/database.js
module.exports = ({ env }) => ({
defaultConnection: "default",
connection: {
client: "postgres",
connection: {
host: env("DATABASE_HOST", "localhost"),
port: env.int("DATABASE_PORT", 5432),
database: env("DATABASE_NAME", "bank"),
username: env("DATABASE_USERNAME", "postgres"),
password: env("DATABASE_PASSWORD", "0000"),
schema: env("DATABASE_SCHEMA", "public"),
},
}
});
And for Heorku as the article suggested:
path: config/env/production/database.js:
const parse = require('pg-connection-string').parse;
const config = parse(process.env.DATABASE_URL);
module.exports = ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: config.host,
port: config.port,
database: config.database,
user: config.user,
password: config.password,
ssl: {
rejectUnauthorized: false
},
},
debug: false,
},
});
PS: make sure you add pg-connection-string to your dependencies before pushing to heroku
getDialectClass - from the error log
const getDialectClass = client => {
switch (client) {
case 'postgres':
return require('./postgresql');
case 'mysql':
return require('./mysql');
case 'sqlite':
return require('./sqlite');
default:
throw new Error(`Unknow dialect ${client}`);
}
};
where the client is - db.config.connection
So if you have been following previous solutions - which talked about a connections object etc ( like this )
module.exports = ({ env }) => ({
defaultConnection: 'default',
connections: {
default: {
connector: 'bookshelf',
settings: {
client: 'postgres',
host: config.host,
port: config.port,
database: config.database,
username: config.user,
password: config.password,
ssl: {
rejectUnauthorized: false,
},
},
options: {
ssl: true,
},
},
},
});
db.config.connection would return undefined. & so it would fail
Configuring the DB with - https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/required/databases.html#configuration-structure
Works fine
If you are using typescript in Strapi, we may encounter this issue too as there is a issue affecting Strapi typescript capabilities.
I can resolve the problem when I downgraded Strapi to 4.3.2 from 4.3.8
You can check this method using heroku/cli from strapi docs here, but it's the same thing, i'm using version 4.0.2, this methods works on older versions V3, i think the docs needs update, most of it is deprecated, for example "fetching only data (example: posts/project etc..) related to the authenticated user who created it", most of resources related to this topic in docs and forum are deprecated solutions that don't work in V4.
For the deployment, i have the same issue, i tried a lot of solutions but it didn't work for me to, but i managed to get the server running like this:
but i got this problem when i visit the "/admin" page:
Strapi is really interesting, let's hope they update the docs soon and someone respond with a solution here.
I fixed this issue by using database url directly. Not sure why the old way does not work in Strapi v4.
module.exports = ({ env }) => ({
defaultConnection: "default",
connection: {
client: "postgres",
connection: {
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
},
}
});
In case someone meets the same problem as me.
In my situation, I am using vim in windows as my text editor. After editing the "config/database.js" file. It left a "database.js~" file in that directory. Then, this filename causes the same problems: "Error: Unknown dialect undefined".
I guess it's a bug in strapi. After removing that file, everything works!
So, the solutions for me. I add this line to my vim config file:
set backupdir=~/.vimbackup
Then create a directory named '.vimbackup' in "C:/User/[me]/" .
Strapi has once again changed the database configuration structure and even their deployment docs use the old and incorrect example.
Here is the most up to date example: Strapi Database Configuration
In strapi v4, you need to use like:
module.exports = ({ env }) => ({
connection: {
client: "postgres",
connection: {
host: env("DATABASE_HOST", "localhost"),
port: env.int("DATABASE_PORT", 5432),
database: env("DATABASE_NAME", "db-name"),
user: env("DATABASE_USERNAME", "postgres"),
password: env("DATABASE_PASSWORD", "password"),
schema: env("DATABASE_SCHEMA", "public"),
},
}
});
it's look like there is a problem in the new strapi version , when i try to create project with typescript support i faced same error , i don't know if you are using typescript in your project but these two solutions solved my problem;
solution (1) :- create compile config ts files with tsc $ tsc .\config\database.ts .\config\server.ts ./ .\config\admin.ts
solution (2) :- downgrade your strapi to 4.3.2 version in the package.json file.
solution (3) :- don't use #latest when creating strapi app instate use 4.3.2 npx create-strapi-app#4.3.2 test-strapi-verion-with-ts --ts
you can use one of theme

Using SocketIo Manager with a default URL

My goal is to add a token in the socketio reconnection from the client (works fine on the first connection, but the query is null on the reconnection, if the server restarted while the client stayed on).
The documentation indicates I need to use the Manager to customize the reconnection behavior (and add a query parameter).
However, I'm getting trouble finding how to use this Manager: I can't find a way to connect to the server.
What I was using without Manager (works fine):
this.socket = io({
query: {
token: 'abc',
}
});
Version with the Manager:
const manager = new Manager(window.location, {
hostname: "localhost",
path: "/socket.io",
port: "8080",
query: {
auth: "123"
}
});
So I tried many approaches (nothing, '', 'http://localhost:8080', 'http://localhost:8080/socket.io', adding those lines to the options:
hostname: "localhost",
path: "/socket.io",
port: "8080" in the options,
But I couldn't connect.
The documentation indicates the default URL is:
url (String) (defaults to window.location)
For some reasons, using window.location as URL refreshes the page infinitely, no matter if I enter it as URL in the io() creator or in the new Manager.
I am using socket.io-client 3.0.3.
Could someone explain me what I'm doing wrong ?
Thanks
Updating to 3.0.4 solved the initial problem, which was to be able to send the token in the initial query.
I also found this code in the doc, which solves the problem:
this.socket.on('reconnect_attempt', () => {
socket.io.opts.query = {
token: 'fgh'
}
});
However, it doesn't solve the problem of the Manager that just doesn't work. I feel like it should be removed from the doc. I illustrated the problem in this repo:
https://github.com/Yvanovitch/socket.io/blob/master/examples/chat/public/main.js

SonarQube - specify location of sonar.properties

I'm trying to deploy SonarQube on Kubernetes using configMaps.
The latest 7.1 image I use has a config in sonar.properties embedded in $SONARQUBE_HOME/conf/ . The directory is not empty and contain also a wrapper.conf file.
I would like to mount the configMap inside my container in a other location than /opt/sonar/conf/ and specify to sonarQube the new path to read the properties.
Is there a way to do that ? (environment variable ? JVM argument ? ...)
It is not recommended to modify this standard configuration in any way. But we can have a look at the SonarQube sourcecode. In this file you can find this code for reading the configuration file:
private static Properties loadPropertiesFile(File homeDir) {
Properties p = new Properties();
File propsFile = new File(homeDir, "conf/sonar.properties");
if (propsFile.exists()) {
...
} else {
LoggerFactory.getLogger(AppSettingsLoaderImpl.class).warn("Configuration file not found: {}", propsFile);
}
return p;
}
So the conf-path and filename is hard coded and you get a warning if the file does not exist. The home directory is found this way:
private static File detectHomeDir() {
try {
File appJar = new File(Class.forName("org.sonar.application.App").getProtectionDomain().getCodeSource().getLocation().toURI());
return appJar.getParentFile().getParentFile();
} catch (...) {
...
}
So this can also not be changed. The code above is used here:
#Override
public AppSettings load() {
Properties p = loadPropertiesFile(homeDir);
p.putAll(CommandLineParser.parseArguments(cliArguments));
p.setProperty(PATH_HOME.getKey(), homeDir.getAbsolutePath());
p = ConfigurationUtils.interpolateVariables(p, System.getenv());
....
}
This suggests that you can use commandline parameters or environment variables in order to change your settings.
For my problem, I defined environment variable to configure database settings in my Kubernetes deployment :
env:
- name: SONARQUBE_JDBC_URL
value: jdbc:sqlserver://mydb:1433;databaseName=sonarqube
- name: SONARQUBE_JDBC_USERNAME
value: sonarqube
- name: SONARQUBE_JDBC_PASSWORD
valueFrom:
secretKeyRef:
name: sonarsecret
key: dbpassword
I needed to use also ldap plugin but it was not possible to configure environment variable in this case. As /opt/sonarqube/conf/ is not empty, I can't use configMap to decouple configuration from image content. So, I build my own sonarqube image adding the ldap jar plugin and ldap setting in sonar.properties :
# General Configuration
sonar.security.realm=LDAP
ldap.url=ldap://myldap:389
ldap.bindDn=CN=mysa=_ServicesAccounts,OU=Users,OU=SVC,DC=net
ldap.bindPassword=****
# User Configuration
ldap.user.baseDn=OU=Users,OU=SVC,DC=net
ldap.user.request=(&(sAMAccountName={0})(objectclass=user))
ldap.user.realNameAttribute=cn
ldap.user.emailAttribute=mail
# Group Configuration
ldap.group.baseDn=OU=Users,OU=SVC,DC=net
ldap.group.request=(&(objectClass=group)(member={dn}))

Resources